summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPat Gavlin <pagavlin@microsoft.com>2016-07-11 15:03:42 -0700
committerPat Gavlin <pagavlin@microsoft.com>2016-07-12 15:19:01 -0700
commit9f60b6cda6d9437ce7f5a9e430b4ac49f71183de (patch)
treef1c652da81c6b634032b855354636c1ca86497e2 /src
parent36efe1f7527ed207b25283832b035a0db0fee2c8 (diff)
downloadcoreclr-9f60b6cda6d9437ce7f5a9e430b4ac49f71183de.tar.gz
coreclr-9f60b6cda6d9437ce7f5a9e430b4ac49f71183de.tar.bz2
coreclr-9f60b6cda6d9437ce7f5a9e430b4ac49f71183de.zip
Refactor top-level comma rewriting.
Top-level commas were being handled in three separate parts of rationalize: TreeTransformRationalization, RewriteSimpleTransforms, and DoPhase. Furthermore, the transform performed by the latter was distinct from the transforms performed by the former two parts, as those parts called out to RewriteTopLevelComma in order to do the necessary rewrite. This change collects the two transforms in RewriteTopLevelComma and centralizes the comma handling in RewriteSimpleTransforms. With the comma handling centralized in RewriteSimpleTransforms, TreeTransformRationalization was not doing much of anything, so it has been removed and RewriteSimpleTransforms renamed to TreeTransformRationalization.
Diffstat (limited to 'src')
-rw-r--r--src/jit/compiler.h3
-rw-r--r--src/jit/rationalize.cpp177
-rw-r--r--src/jit/rationalize.h3
3 files changed, 68 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..bd9b2893d3 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,36 @@ 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;
+ Location newLoc = RewriteTopLevelComma(loc);
+ if (newLoc.tree != statement)
+ {
+ (void)TreeTransformRationalization(newLoc);
+ }
+
+ 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 +867,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 +944,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 +977,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 +1938,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);