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

Commit

Permalink
Fix embedded temporary creation
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedn committed Jun 20, 2016
1 parent ec0881e commit 83fa0db
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 3 deletions.
64 changes: 62 additions & 2 deletions src/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,67 @@ GenTreePtr Lowering::CreateLocalTempAsg(GenTreePtr rhs,
return store;
}

//-----------------------------------------------------------------------------------------------
// CreateEmbeddedTemporary: Store the result of the given tree in a newly created temporary local
// variable and replace the original use of the tree with the temporary.
//
// Arguments:
// ppTree - a pointer to the tree use to replace.
//
// Return Value:
// The newly created store statement.
//
// Assumptions:
// This may only be called during tree lowering. The callee must ensure that the tree has already
// been lowered and is part of compCurStmt and that compCurStmt is in compCurBB.
//
// Notes:
// The newly created statement is usually an embedded statement but it can also be a top-level
// statement if the tree to be replaced extends to the begining of the current statement. If
// a top-level statement is created any embedded statements contained in the tree move to the
// the new top-level statement, before the current statement. Such embedded statements need to
// be lowered here because the normal lowering code path won't reach them anymore.
//
// TODO-Cleanup:
// Some uses of fgInsertEmbeddedFormTemp in lowering could be replaced with this to avoid
// duplication, see LowerArrElem for example.

GenTreeStmt* Lowering::CreateEmbeddedTemporary(GenTree** ppTree)
{
GenTreeStmt* newStmt = comp->fgInsertEmbeddedFormTemp(ppTree);

// The tree is assumed to be already lowered so the newly created statement
// should not be lowered again.
newStmt->gtFlags |= GTF_STMT_SKIP_LOWER;

assert(newStmt->gtStmtExpr->OperIsLocalStore());

// If the newly created statement is top-level then we need to manually lower its embedded
// statements, the tree is lowered but some of its embedded statements are yet to be lowered.
if (newStmt->gtStmtIsTopLevel())
{
GenTree* curStmt = comp->compCurStmt;

for (GenTree* nextEmbeddedStmt = newStmt->gtStmtNextIfEmbedded();
nextEmbeddedStmt != nullptr;
nextEmbeddedStmt = nextEmbeddedStmt->gtStmt.gtStmtNextIfEmbedded())
{
// A previous call to CreateEmbeddedTemporary could have created already lowered
// embedded statements from the tree.
if ((nextEmbeddedStmt->gtFlags & GTF_STMT_SKIP_LOWER) != 0)
continue;

comp->compCurStmt = nextEmbeddedStmt;
comp->fgWalkTreePost(&nextEmbeddedStmt->gtStmt.gtStmtExpr, &Lowering::LowerNodeHelper, this, true);
nextEmbeddedStmt->gtFlags |= GTF_STMT_SKIP_LOWER;
}

comp->compCurStmt = curStmt;
}

return newStmt;
}

// This is the main entry point for Lowering.

// In addition to that, LowerNode is also responsible for initializing the
Expand Down Expand Up @@ -3871,8 +3932,7 @@ void Lowering::LowerSignedDivOrMod(GenTreePtr* ppTree, Compiler::fgWalkData* dat
{
// We need to use the dividend node multiple times so its value needs to be
// computed once and stored in a temp variable.
GenTreeStmt* newStmt = comp->fgInsertEmbeddedFormTemp(&(divMod->gtOp.gtOp1));
newStmt->gtFlags |= GTF_STMT_SKIP_LOWER;
CreateEmbeddedTemporary(&(divMod->gtOp.gtOp1));
dividend = divMod->gtGetOp1();

GenTreeStmt* curStmt = comp->compCurStmt->AsStmt();
Expand Down
2 changes: 1 addition & 1 deletion src/jit/lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ class Lowering : public Phase
static bool NodesAreEquivalentLeaves (GenTreePtr candidate, GenTreePtr storeInd);

GenTreePtr CreateLocalTempAsg (GenTreePtr rhs, unsigned refCount, GenTreePtr *ppLclVar = nullptr);

GenTreeStmt* CreateEmbeddedTemporary(GenTree** ppTree);
bool AreSourcesPossiblyModified (GenTree* use, GenTree* src1, GenTree *src2);
void ReplaceNode (GenTree** ppTreeLocation,
GenTree* replacementNode,
Expand Down

0 comments on commit 83fa0db

Please sign in to comment.