Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Tidy up
Browse files Browse the repository at this point in the history
  • Loading branch information
benaadams committed Jun 5, 2019
1 parent 3ea7b94 commit f2a0c9a
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 121 deletions.
16 changes: 14 additions & 2 deletions src/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -6235,8 +6235,20 @@ class Compiler
void optBlockCopyProp(BasicBlock* block, LclNumToGenTreePtrStack* curSsaName);
void optCopyPropFoldCopyBlks(BasicBlock* block);
void optCopyPropThroughCopyBlk(BasicBlock* block);
bool optTryResolveToLclVars(GenTree* expr, GenTreeLclVarCommon*& srcLclVar, GenTreeLclVarCommon*& dstLclVar);
bool optTryResolveToLclVar(GenTree* op, GenTreeLclVarCommon*& lclVar);
bool optTryGetCopyPropLclVars(GenTree* expr, GenTreeLclVarCommon*& srcLclVar, GenTreeLclVarCommon*& dstLclVar);
bool optTryGetCopyPropLclVar(GenTree* op, GenTreeLclVarCommon*& lclVar);
void optCopyPropUpdateTree(GenTreeStmt* currStmt, GenTreeStmt* updatedStmt, GenTree* newOpt);
#ifndef DEBUG
bool optTryGetCopyPropNewOpt(GenTree* opt, GenTree*& newOpt);
#else
bool optTryGetCopyPropNewOpt(GenTree* opt,
GenTree*& newOpt,
GenTree* currExpr,
GenTree* updatedExpr,
GenTreeLclVarCommon* currLclVar,
GenTreeLclVarCommon* updatedLclVar,
bool isReverse);
#endif
bool optIsSsaLocal(GenTree* tree);
int optCopyProp_LclVarScore(LclVarDsc* lclVarDsc, LclVarDsc* copyVarDsc, bool preferOp2);
void optVnCopyProp();
Expand Down
253 changes: 134 additions & 119 deletions src/jit/copyprop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,14 +294,14 @@ bool Compiler::optIsSsaLocal(GenTree* tree)
*
* Helper to get the LclVar for the Expr.
*/
bool Compiler::optTryResolveToLclVars(GenTree* tree, GenTreeLclVarCommon*& srcLclVar, GenTreeLclVarCommon*& dstLclVar)
bool Compiler::optTryGetCopyPropLclVars(GenTree* tree, GenTreeLclVarCommon*& srcLclVar, GenTreeLclVarCommon*& dstLclVar)
{
if (!optTryResolveToLclVar(tree->gtGetOp2(), srcLclVar))
if (!optTryGetCopyPropLclVar(tree->gtGetOp2(), srcLclVar))
{
return false;
}

if (!optTryResolveToLclVar(tree->gtGetOp1(), dstLclVar))
if (!optTryGetCopyPropLclVar(tree->gtGetOp1(), dstLclVar))
{
return false;
}
Expand All @@ -313,7 +313,7 @@ bool Compiler::optTryResolveToLclVars(GenTree* tree, GenTreeLclVarCommon*& srcLc
*
* Helper to get the LclVar for the Oper.
*/
bool Compiler::optTryResolveToLclVar(GenTree* op, GenTreeLclVarCommon*& lclVar)
bool Compiler::optTryGetCopyPropLclVar(GenTree* op, GenTreeLclVarCommon*& lclVar)
{
if (varTypeIsSIMD(op) || op->IsPhiNode())
{
Expand All @@ -340,6 +340,97 @@ bool Compiler::optTryResolveToLclVar(GenTree* op, GenTreeLclVarCommon*& lclVar)
return false;
}

#ifndef DEBUG
bool Compiler::optTryGetCopyPropNewOpt(GenTree* opt, GenTree*& newOpt)
{
newOpt = gtClone(opt);
if (newOpt == nullptr)
{
// Too complex
return false;
}

return true;
}
#else
bool Compiler::optTryGetCopyPropNewOpt(GenTree* opt,
GenTree*& newOpt,
GenTree* currExpr,
GenTree* updatedExpr,
GenTreeLclVarCommon* currLclVar,
GenTreeLclVarCommon* updatedLclVar,
bool isReverse)
{
newOpt = gtClone(opt);
if (newOpt == nullptr)
{
// Too complex
return false;
}

if (verbose)
{
JITDUMP("CopyBlk based forward copy assertion for ");

if (isReverse)
{
JITDUMP("reverse");
}
else
{
JITDUMP("forward");
}

JITDUMP(" copy assertion for ");
printTreeID(updatedLclVar);
printf(" V%02d @%08X by ", updatedLclVar->gtLclNum, updatedExpr->GetVN(VNK_Conservative));
printTreeID(currLclVar);
printf(" V%02d @%08X.\n", currLclVar->gtLclNum, currExpr->GetVN(VNK_Conservative));

printf("\n***** (before)\n");
gtDispTree(currExpr, nullptr, nullptr, false);
printf("\n");
gtDispTree(updatedExpr, nullptr, nullptr, false);
printf("\n");
}

return true;
}
#endif

void Compiler::optCopyPropUpdateTree(GenTreeStmt* currStmt, GenTreeStmt* updatedStmt, GenTree* newOpt)
{
// Update cost and side-effects for new node
gtPrepareCost(newOpt);

GenTree* updatedExpr = updatedStmt->gtStmtExpr;
gtPrepareCost(updatedExpr);
gtUpdateNodeSideEffects(updatedExpr);
gtUpdateSideEffects(updatedStmt, updatedExpr);

// Clear the current statement
currStmt->gtStmtExpr->gtBashToNOP();

if (fgStmtListThreaded)
{
// Resequence
fgSetStmtSeq(updatedStmt);
fgSetStmtSeq(currStmt);
}

#ifdef DEBUG
if (verbose)
{
printf("Copy propagated to:\n");
printf("\n***** (after)\n");
gtDispTree(currStmt->gtStmtExpr, nullptr, nullptr, false);
printf("\n");
gtDispTree(updatedStmt, nullptr, nullptr, false);
printf("\n");
}
#endif
}

//------------------------------------------------------------------------------
// optBlockCopyProp : Perform copy propagation using currently live definitions on the current block's
// variables. Also as new definitions are encountered update the "curSsaName" which
Expand Down Expand Up @@ -459,42 +550,38 @@ void Compiler::optCopyPropFoldCopyBlks(BasicBlock* block)
prevStmt = currStmt->getPrevStmt();
if (prevStmt == nullptr)
{
// No previous statement to propagate to
break;
}

// Only operate when current is CopyBlk
GenTree* currExpr = currStmt->gtStmtExpr;
if (!currExpr->OperIsCopyBlkOp())
{
continue;
}

// Only operate when prev is also CopyBlk
GenTree* prevExpr = prevStmt->gtStmtExpr;
if (!prevExpr->OperIsCopyBlkOp())
if (!currExpr->OperIsCopyBlkOp() || !prevExpr->OperIsCopyBlkOp())
{
// Only propagate when both are CopyBlk
continue;
}

GenTreeLclVarCommon* currSrcLclVar = nullptr;
GenTreeLclVarCommon* currDstLclVar = nullptr;
if (!optTryResolveToLclVars(currExpr, currSrcLclVar, currDstLclVar))
if (!optTryGetCopyPropLclVars(currExpr, currSrcLclVar, currDstLclVar))
{
continue;
}

GenTreeLclVarCommon* prevSrcLclVar = nullptr;
GenTreeLclVarCommon* prevDstLclVar = nullptr;
if (!optTryResolveToLclVars(prevExpr, prevSrcLclVar, prevDstLclVar))
if (!optTryGetCopyPropLclVars(prevExpr, prevSrcLclVar, prevDstLclVar))
{
continue;
}

assert(currSrcLclVar != nullptr && currDstLclVar != nullptr && prevSrcLclVar != nullptr && prevDstLclVar != nullptr);
assert(currSrcLclVar != nullptr && currDstLclVar != nullptr && prevSrcLclVar != nullptr &&
prevDstLclVar != nullptr);

if (prevDstLclVar->gtLclNum != currSrcLclVar->gtLclNum)
{
// Can only elide if prevDst is same as currSrc LclVar
// Can only elide the copy if prevDst is same as currSrc LclVar
continue;
}

Expand All @@ -510,12 +597,10 @@ void Compiler::optCopyPropFoldCopyBlks(BasicBlock* block)

LclVarDsc* varDsc = &(lvaTable[lclNum]);
LclVarDsc* newVarDsc = &(lvaTable[newLclNum]);
if (newVarDsc->lvIsMultiRegRet != varDsc->lvIsMultiRegRet)
{
continue;
}
if (newVarDsc->lvOverlappingFields || varDsc->lvOverlappingFields)
if (newVarDsc->lvIsMultiRegRet != varDsc->lvIsMultiRegRet || newVarDsc->lvOverlappingFields ||
varDsc->lvOverlappingFields)
{
// Don't propergate if they aren't matching MultiRegRet; or have overlapping fields.
continue;
}

Expand All @@ -524,59 +609,23 @@ void Compiler::optCopyPropFoldCopyBlks(BasicBlock* block)
if (((prevDstLclVar->gtFlags & GTF_VAR_DEF) != 0) && ((currSrcLclVar->gtFlags & GTF_VAR_DEATH) != 0) &&
((currDstLclVar->gtFlags & GTF_VAR_DEF) != 0))
{
GenTree* newOpt1 = gtClone(currExpr->gtOp.gtOp1);
if (newOpt1 == nullptr)
GenTree* newOpt = nullptr;
bool success;
#ifndef DEBUG
success = optTryGetCopyPropNewOpt(currExpr->gtOp.gtOp1, newOpt);
#else
success = optTryGetCopyPropNewOpt(currExpr->gtOp.gtOp1, newOpt, currExpr, prevExpr, currSrcLclVar,
prevDstLclVar, true);
#endif
if (!success)
{
// Too complex
continue;
}

#ifdef DEBUG
if (verbose)
{
JITDUMP("CopyBlk based reverse copy assertion for ");
printTreeID(prevDstLclVar);
printf(" V%02d @%08X by ", lclNum, prevExpr->GetVN(VNK_Conservative));
printTreeID(currDstLclVar);
printf(" V%02d @%08X.\n", newLclNum, currExpr->GetVN(VNK_Conservative));

printf("\n***** " FMT_BB " (before)\n", block->bbNum);
gtDispTree(prevExpr, nullptr, nullptr, false);
printf("\n");
gtDispTree(currExpr, nullptr, nullptr, false);
printf("\n");
}
#endif
// Update the tree
prevExpr->gtOp.gtOp1 = newOpt;

// Move the currExpr dest to the prevExpr dest
gtPrepareCost(newOpt1);
prevExpr->gtOp.gtOp1 = newOpt1;
gtPrepareCost(prevExpr);

gtUpdateNodeSideEffects(prevExpr);
gtUpdateSideEffects(prevStmt, prevExpr);

// Clear the current statement
currExpr->gtBashToNOP();

if (fgStmtListThreaded)
{
fgSetStmtSeq(prevStmt);
fgSetStmtSeq(currStmt);
}

#ifdef DEBUG
if (verbose)
{
printf("Copy propagated to:\n");
printf("\n***** " FMT_BB " (after)\n", block->bbNum);
gtDispTree(prevExpr, nullptr, nullptr, false);
printf("\n");
gtDispTree(currExpr, nullptr, nullptr, false);
printf("\n");
}
#endif
optCopyPropUpdateTree(currStmt, prevStmt, newOpt);
}
}
}
Expand Down Expand Up @@ -626,7 +675,7 @@ void Compiler::optCopyPropThroughCopyBlk(BasicBlock* block)

GenTreeLclVarCommon* currSrcLclVar = nullptr;
GenTreeLclVarCommon* currDstLclVar = nullptr;
if (!optTryResolveToLclVars(currExpr, currSrcLclVar, currDstLclVar))
if (!optTryGetCopyPropLclVars(currExpr, currSrcLclVar, currDstLclVar))
{
continue;
}
Expand All @@ -638,12 +687,13 @@ void Compiler::optCopyPropThroughCopyBlk(BasicBlock* block)

GenTreeLclVarCommon* nextSrcLclVar = nullptr;
GenTreeLclVarCommon* nextDstLclVar = nullptr;
if (!optTryResolveToLclVars(nextExpr, nextSrcLclVar, nextDstLclVar))
if (!optTryGetCopyPropLclVars(nextExpr, nextSrcLclVar, nextDstLclVar))
{
continue;
}

assert(currSrcLclVar != nullptr && currDstLclVar != nullptr && nextSrcLclVar != nullptr && nextDstLclVar != nullptr);
assert(currSrcLclVar != nullptr && currDstLclVar != nullptr && nextSrcLclVar != nullptr &&
nextDstLclVar != nullptr);

GenTreeLclVarCommon* nextLclVar = nullptr;
GenTree* nextOpt = nullptr;
Expand Down Expand Up @@ -675,43 +725,30 @@ void Compiler::optCopyPropThroughCopyBlk(BasicBlock* block)

LclVarDsc* varDsc = &(lvaTable[lclNum]);
LclVarDsc* newVarDsc = &(lvaTable[newLclNum]);
if (newVarDsc->lvIsMultiRegRet != varDsc->lvIsMultiRegRet)
{
continue;
}
if (newVarDsc->lvOverlappingFields || varDsc->lvOverlappingFields)
if (newVarDsc->lvIsMultiRegRet != varDsc->lvIsMultiRegRet || newVarDsc->lvOverlappingFields ||
varDsc->lvOverlappingFields)
{
// Don't propergate if they aren't matching MultiRegRet; or have overlapping fields.
continue;
}

if (((currSrcLclVar->gtFlags & GTF_VAR_DEATH) != 0) && ((currDstLclVar->gtFlags & GTF_VAR_DEF) != 0) &&
((nextLclVar->gtFlags & GTF_VAR_DEATH) != 0))
{
GenTree* newOpt = gtClone(currExpr->gtGetOp2());
if (newOpt == nullptr)
GenTree* newOpt = nullptr;
bool success;
#ifndef DEBUG
success = optTryGetCopyPropNewOpt(currExpr->gtGetOp2(), newOpt);
#else
success = optTryGetCopyPropNewOpt(currExpr->gtGetOp2(), newOpt, currExpr, nextExpr, currSrcLclVar,
nextLclVar, false);
#endif
if (!success)
{
// Too complex
continue;
}

#ifdef DEBUG
if (verbose)
{
JITDUMP("CopyBlk based forward copy assertion for ");
printTreeID(nextLclVar);
printf(" V%02d @%08X by ", lclNum, nextExpr->GetVN(VNK_Conservative));
printTreeID(currSrcLclVar);
printf(" V%02d @%08X.\n", newLclNum, currExpr->GetVN(VNK_Conservative));

printf("\n***** " FMT_BB " (before)\n", block->bbNum);
gtDispTree(currExpr, nullptr, nullptr, false);
printf("\n");
gtDispTree(nextExpr, nullptr, nullptr, false);
printf("\n");
}
#endif
// Update the tree
gtPrepareCost(newOpt);
if (currDstLclVar->gtLclNum == nextSrcLclVar->gtLclNum)
{
newOpt->gtType = nextOpt->gtType;
Expand All @@ -722,30 +759,8 @@ void Compiler::optCopyPropThroughCopyBlk(BasicBlock* block)
newOpt->gtType = nextOpt->gtType;
nextExpr->gtOp.gtOp1 = newOpt;
}
gtPrepareCost(nextExpr);
gtUpdateNodeSideEffects(nextExpr);
gtUpdateSideEffects(nextStmt, nextExpr);

// Clear the current statement
currExpr->gtBashToNOP();

if (fgStmtListThreaded)
{
fgSetStmtSeq(nextStmt);
fgSetStmtSeq(currStmt);
}

#ifdef DEBUG
if (verbose)
{
printf("Copy propagated to:\n");
printf("\n***** " FMT_BB " (after)\n", block->bbNum);
gtDispTree(currExpr, nullptr, nullptr, false);
printf("\n");
gtDispTree(nextExpr, nullptr, nullptr, false);
printf("\n");
}
#endif
optCopyPropUpdateTree(currStmt, nextStmt, newOpt);
}
}
}
Expand Down

0 comments on commit f2a0c9a

Please sign in to comment.