summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPat Gavlin <pgavlin@gmail.com>2016-07-12 17:10:37 -0700
committerGitHub <noreply@github.com>2016-07-12 17:10:37 -0700
commitf12cc106e8ea9df6cfeb5fdcd4564351f8dde890 (patch)
tree3ff220bcd0f5f6a77b37cfd8ba30f712ee63741a /src
parentadb2188ed70751f70a1b9e06aa497bc027cdf8a8 (diff)
parent969f1cd722d776d83ca3a7db4f0441892ce7a703 (diff)
downloadcoreclr-f12cc106e8ea9df6cfeb5fdcd4564351f8dde890.tar.gz
coreclr-f12cc106e8ea9df6cfeb5fdcd4564351f8dde890.tar.bz2
coreclr-f12cc106e8ea9df6cfeb5fdcd4564351f8dde890.zip
Merge pull request #6225 from pgavlin/RationalizeCleanup
Refactor top-level comma rewriting.
Diffstat (limited to 'src')
-rw-r--r--src/jit/compiler.h3
-rw-r--r--src/jit/rationalize.cpp182
-rw-r--r--src/jit/rationalize.h3
3 files changed, 73 insertions, 115 deletions
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index 251b03e033..26f028508d 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -4496,9 +4496,6 @@ private:
GenTree *stmt,
BasicBlock *blk);
- // insert the given subtree 'tree' as a top level statement before 'insertionPoint'. Give it the specified source code IL offset.
- GenTreeStmt* fgSpliceTreeBefore(BasicBlock* block, GenTreeStmt* insertionPoint, GenTree* tree, IL_OFFSETX ilOffset);
-
// insert the given subtree as an embedded statement of parentStmt
GenTreeStmt* fgMakeEmbeddedStmt(BasicBlock *block, GenTreePtr tree, GenTreePtr parentStmt);
diff --git a/src/jit/rationalize.cpp b/src/jit/rationalize.cpp
index 7f8576e890..ba81b87633 100644
--- a/src/jit/rationalize.cpp
+++ b/src/jit/rationalize.cpp
@@ -111,29 +111,6 @@ GenTree *isNodeCallArg(ArrayStack<GenTree *> *parentStack)
}
//------------------------------------------------------------------------------
-// fgSpliceTreeBefore - insert the given subtree 'tree' as a top level statement
-// placed before top level statement 'insertionPoint'
-//------------------------------------------------------------------------------
-
-GenTreeStmt *
-Compiler::fgSpliceTreeBefore(BasicBlock* block, GenTreeStmt* insertionPoint, GenTree* tree, IL_OFFSETX ilOffset)
-{
- assert(tree->gtOper != GT_STMT);
- assert(fgBlockContainsStatementBounded(block, insertionPoint));
-
- GenTreeStmt* newStmt = gtNewStmt(tree, ilOffset);
- newStmt->CopyCosts(tree);
- GenTreePtr newStmtFirstNode = Compiler::fgGetFirstNode(tree);
- newStmt->gtStmt.gtStmtList = newStmtFirstNode;
- newStmtFirstNode->gtPrev = nullptr;
- tree->gtNext = nullptr;
-
- fgInsertStmtBefore(block, insertionPoint, newStmt);
-
- return newStmt;
-}
-
-//------------------------------------------------------------------------------
// fgMakeEmbeddedStmt: insert the given subtree as an embedded statement
//
// Arguments:
@@ -525,71 +502,59 @@ void copyFlags(GenTree *dst, GenTree *src, unsigned mask)
//--------------------------------------------------------------------------------------
-// RewriteTopLevelComma - split a top-level comma into two top level statements.
-// returns (as out params) the two new locations
+// RewriteTopLevelComma - remove a top-level comma by creating a new preceding statement
+// from its LHS and replacing the comma with its RHS (unless the
+// comma's RHS is a NOP, in which case the comma is replaced with
+// its LHS and no new statement is created)
+//
+// Returns the location of the statement that contains the LHS of the removed comma.
//--------------------------------------------------------------------------------------
-void Rationalizer::RewriteTopLevelComma(Location loc, Location* out1, Location* out2)
+Location Rationalizer::RewriteTopLevelComma(Location loc)
{
GenTreeStmt* commaStmt = loc.tree->AsStmt();
- GenTree* commaOp = commaStmt->gtStmtExpr;
+ GenTree* commaOp = commaStmt->gtStmtExpr;
assert(commaOp->OperGet() == GT_COMMA);
- JITDUMP("splitting top level comma!\n");
-
- GenTreeStmt* newStatement1 = comp->fgSpliceTreeBefore(loc.block, commaStmt, commaOp->gtGetOp1(), commaStmt->gtStmtILoffsx);
- GenTreeStmt* newStatement2 = comp->fgSpliceTreeBefore(loc.block, commaStmt, commaOp->gtGetOp2(), commaStmt->gtStmtILoffsx);
-
- comp->fgRemoveStmt(loc.block, commaStmt, false);
-
- // these two subtrees still need to be processed
- loc = Location(newStatement1, loc.block);
- *out1 = Location(newStatement1, loc.block);
- *out2 = Location(newStatement2, loc.block);
-}
-
-//--------------------------------------------------------------------------------------
-// TreeTransformRationalization - Run the set of rationalizations on one statement that
-// transforms its underlying trees but doesn't perform
-// tree walks to introduce new statements.
-//--------------------------------------------------------------------------------------
-
-Location Rationalizer::TreeTransformRationalization(Location loc)
-{
-top:
- assert(loc.tree);
+ GenTree* commaOp1 = commaOp->gtGetOp1();
+ GenTree* commaOp2 = commaOp->gtGetOp2();
- JITDUMP("Tree Transform Rationalization: BB%02u\n", loc.block->bbNum);
- DISPTREE(loc.tree);
- JITDUMP("\n");
+ if (commaOp2->IsNothingNode())
+ {
+#ifdef DEBUG
+ if (comp->verbose)
+ {
+ printf("Replacing GT_COMMA(X, GT_NOP) by X\n");
+ comp->gtDispTree(commaOp);
+ printf("\n");
+ }
+#endif // DEBUG
- comp->compCurStmt = loc.tree;
- comp->compCurBB = loc.block;
+ comp->fgSnipNode(commaStmt, commaOp);
+ comp->fgDeleteTreeFromList(commaStmt, commaOp2);
+ commaStmt->gtStmtExpr = commaOp1;
- // top level comma is a special case
- if (loc.tree->gtStmt.gtStmtExpr->OperGet() == GT_COMMA)
- {
- Location loc1, loc2;
- RewriteTopLevelComma(loc, &loc1, &loc2);
-
- loc = loc1;
- goto top;
+ return loc;
}
- DBEXEC(TRUE, loc.Validate());
- DBEXEC(TRUE, ValidateStatement(loc));
+ JITDUMP("splitting top level comma!\n");
- loc = RewriteSimpleTransforms(loc);
- DBEXEC(TRUE, ValidateStatement(loc));
+ // Replace the comma node in the original statement with the RHS of the comma node.
+ comp->fgDeleteTreeFromList(commaStmt, commaOp1);
+ comp->fgSnipNode(commaStmt, commaOp);
+ commaStmt->gtStmtExpr = commaOp2;
- JITDUMP("comma processing top level statement:\n");
- DISPTREE(loc.tree);
- JITDUMP("\n");
+ // Create and insert a new preceding statement from the LHS of the comma node.
+ GenTreeStmt* newStatement = comp->gtNewStmt(commaOp1, commaStmt->gtStmtILoffsx);
+ newStatement->CopyCosts(commaOp1);
+ newStatement->gtStmtList = Compiler::fgGetFirstNode(commaOp1);
+ newStatement->gtStmtList->gtPrev = nullptr;
+ commaOp1->gtNext = nullptr;
- DuplicateCommaProcessOneTree(comp, this, loc.block, loc.tree);
-
- return loc;
+ comp->fgInsertStmtBefore(loc.block, commaStmt, newStatement);
+
+ return Location(newStatement, loc.block);
}
@@ -847,26 +812,41 @@ Compiler::fgWalkResult Rationalizer::CommaHelper(GenTree **ppTree, Compiler::fgW
// rewrite ASG nodes as either local store or indir store forms
// also remove ADDR nodes
-Location Rationalizer::RewriteSimpleTransforms(Location loc)
+Location Rationalizer::TreeTransformRationalization(Location loc)
{
- GenTreeStmt * statement = (loc.tree)->AsStmt();
- GenTree * tree = statement->gtStmt.gtStmtExpr;
+ GenTree* savedCurStmt = comp->compCurStmt;
+ GenTreeStmt* statement = (loc.tree)->AsStmt();
+ GenTree* tree = statement->gtStmt.gtStmtExpr;
- JITDUMP("RewriteSimpleTransforms, with statement:\n");
+ JITDUMP("TreeTransformRationalization, with statement:\n");
DISPTREE(statement);
JITDUMP("\n");
+ DBEXEC(TRUE, loc.Validate());
+ DBEXEC(TRUE, ValidateStatement(loc));
+
if (statement->gtStmtIsTopLevel())
{
- if (tree->OperGet() == GT_COMMA)
+ comp->compCurBB = loc.block;
+ comp->compCurStmt = statement;
+
+ while (tree->OperGet() == GT_COMMA)
{
- Location loc1, loc2;
- RewriteTopLevelComma(loc, &loc1, &loc2);
- RewriteSimpleTransforms(loc1);
- RewriteSimpleTransforms(loc2);
- return loc1;
+ // RewriteTopLevelComma may create a new preceding statement for the LHS of a
+ // top-level comma. If it does, we need to process that statement now.
+ Location newLoc = RewriteTopLevelComma(loc);
+ if (newLoc.tree != statement)
+ {
+ (void)TreeTransformRationalization(newLoc);
+ }
+
+ // RewriteTopLevelComma also replaces the tree for this statement with the RHS
+ // of the comma (or the LHS, if the RHS is a NOP), so we must reload it for
+ // correctness.
+ tree = statement->gtStmt.gtStmtExpr;
}
- else if (tree->OperKind() & GTK_CONST)
+
+ if (tree->OperKind() & GTK_CONST)
{
// Don't bother generating a top level statement that is just a constant.
// We can get these if we decide to hoist a large constant value out of a loop.
@@ -892,10 +872,15 @@ Location Rationalizer::RewriteSimpleTransforms(Location loc)
tree->gtBashToNOP();
}
+ DuplicateCommaProcessOneTree(comp, this, loc.block, loc.tree);
+
JITDUMP("After simple transforms:\n");
DISPTREE(statement);
JITDUMP("\n");
+ DBEXEC(TRUE, ValidateStatement(loc));
+
+ comp->compCurStmt = savedCurStmt;
return loc;
}
@@ -964,7 +949,7 @@ void Rationalizer::RecursiveRewriteComma(GenTree **ppTree, Compiler::fgWalkData
DISPTREE(stmt);
JITDUMP("\n");
- (void) ((Rationalizer *)tmpState->thisPhase)->RewriteSimpleTransforms(Location(newStmt, tmpState->block));
+ (void) ((Rationalizer *)tmpState->thisPhase)->TreeTransformRationalization(Location(newStmt, tmpState->block));
// In a sense, assignment nodes have two destinations: 1) whatever they are writing to
// and 2) they also produce the value that was written so their parent can consume it.
@@ -997,12 +982,12 @@ void Rationalizer::RecursiveRewriteComma(GenTree **ppTree, Compiler::fgWalkData
DISPTREE(stmt);
JITDUMP("\n");
- (void) ((Rationalizer *)tmpState->thisPhase)->RewriteSimpleTransforms(Location(newStmt, tmpState->block));
+ (void) ((Rationalizer *)tmpState->thisPhase)->TreeTransformRationalization(Location(newStmt, tmpState->block));
if (!nested)
comp->fgFixupIfCallArg(data->parentStack, comma, newSrc);
- (void) ((Rationalizer *)tmpState->thisPhase)->RewriteSimpleTransforms(Location(newStmt, tmpState->block));
+ (void) ((Rationalizer *)tmpState->thisPhase)->TreeTransformRationalization(Location(newStmt, tmpState->block));
return;
}
@@ -1958,29 +1943,6 @@ void Rationalizer::DoPhase()
while (loc.block)
{
RenameUpdatedVars(loc);
-
- // If we have a top-level GT_COMMA(X, GT_NOP), replace it by X.
- if (loc.tree->gtStmt.gtStmtExpr->OperGet() == GT_COMMA)
- {
- GenTree* commaStmt = loc.tree;
- GenTree* commaOp = commaStmt->gtStmt.gtStmtExpr;
- if (commaOp->gtGetOp2()->OperGet() == GT_NOP)
- {
-#ifdef DEBUG
- if (comp->verbose)
- {
- printf("Replacing GT_COMMA(X, GT_NOP) by X\n");
- comp->gtDispTree(commaOp);
- printf("\n");
- }
-#endif // DEBUG
-
- comp->fgSnipNode(commaStmt->AsStmt(), commaOp);
- comp->fgDeleteTreeFromList(commaStmt->AsStmt(), commaOp->gtGetOp2());
- commaStmt->gtStmt.gtStmtExpr = commaOp->gtGetOp1();
- }
- }
-
loc = loc.Next();
}
diff --git a/src/jit/rationalize.h b/src/jit/rationalize.h
index 6d4f54a9c2..b6f6ee752a 100644
--- a/src/jit/rationalize.h
+++ b/src/jit/rationalize.h
@@ -144,8 +144,7 @@ private:
unsigned lclNum,
GenTreePtr rhs);
- void RewriteTopLevelComma (Location loc, Location* out1, Location* out2);
- Location RewriteSimpleTransforms (Location loc);
+ Location RewriteTopLevelComma(Location loc);
// SIMD related transformations
static void RewriteObj(GenTreePtr* ppTree, Compiler::fgWalkData* data);