Use LIR utilities in the intrinsic rewriter.
authorPat Gavlin <pagavlin@microsoft.com>
Mon, 26 Jun 2017 21:40:15 +0000 (14:40 -0700)
committerPat Gavlin <pagavlin@microsoft.com>
Mon, 26 Jun 2017 23:16:20 +0000 (16:16 -0700)
This simplifies the code a bit and prepares it for some changes to
perform single-pass rationalization.

Commit migrated from https://github.com/dotnet/coreclr/commit/115a357068bde4ba5a1432d9f5811c3446a830e7

src/coreclr/src/jit/lir.h
src/coreclr/src/jit/rationalize.cpp

index 71c1147..088b5e5 100644 (file)
@@ -8,6 +8,7 @@
 class Compiler;
 struct GenTree;
 struct BasicBlock;
+class Rationalizer;
 
 class LIR final
 {
@@ -236,6 +237,7 @@ public:
     {
         friend class LIR;
         friend struct BasicBlock;
+        friend class Rationalizer;
 
     private:
         Range(GenTree* firstNode, GenTree* lastNode);
index 11ba34d..cd73ba4 100644 (file)
@@ -145,11 +145,11 @@ void Rationalizer::RewriteNodeAsCall(GenTree**             use,
 #endif
                                      GenTreeArgList* args)
 {
-    GenTree* tree          = *use;
-    GenTree* treeFirstNode = comp->fgGetFirstNode(tree);
-    GenTree* treeLastNode  = tree;
-    GenTree* treePrevNode  = treeFirstNode->gtPrev;
-    GenTree* treeNextNode  = treeLastNode->gtNext;
+    GenTree* const tree           = *use;
+    GenTree* const treeFirstNode  = comp->fgGetFirstNode(tree);
+    GenTree* const insertionPoint = treeFirstNode->gtPrev;
+
+    BlockRange().Remove(treeFirstNode, tree);
 
     // Create the call node
     GenTreeCall* call = comp->gtNewCallNode(CT_USER_FUNC, callHnd, tree->gtType, args);
@@ -180,41 +180,22 @@ void Rationalizer::RewriteNodeAsCall(GenTree**             use,
         *use = call;
     }
 
-    // Rebuild the evaluation order.
-    comp->gtSetStmtInfo(m_statement);
-
-    // Rebuild the execution order.
-    comp->fgSetTreeSeq(call, treePrevNode);
-
-    // Restore linear-order Prev and Next for "call".
-    if (treePrevNode)
-    {
-        treeFirstNode         = comp->fgGetFirstNode(call);
-        treeFirstNode->gtPrev = treePrevNode;
-        treePrevNode->gtNext  = treeFirstNode;
-    }
-    else
+    if (treeFirstNode == m_statement->gtStmt.gtStmtList)
     {
         // Update the linear order start of "m_statement" if treeFirstNode
         // appears to have replaced the original first node.
-        assert(treeFirstNode == m_statement->gtStmt.gtStmtList);
-        m_statement->gtStmt.gtStmtList = comp->fgGetFirstNode(call);
+        assert(treeFirstNode == m_statement->gtStmtList);
+        m_statement->gtStmtList = comp->fgGetFirstNode(call);
     }
 
-    if (treeNextNode)
-    {
-        treeLastNode         = call;
-        treeLastNode->gtNext = treeNextNode;
-        treeNextNode->gtPrev = treeLastNode;
-    }
+    comp->gtSetEvalOrder(call);
+    BlockRange().InsertAfter(insertionPoint, LIR::Range(comp->fgSetTreeSeq(call), call));
 
     // Propagate flags of "call" to its parents.
     // 0 is current node, so start at 1
     for (int i = 1; i < parents.Height(); i++)
     {
-        GenTree* node = parents.Index(i);
-        node->gtFlags |= GTF_CALL;
-        node->gtFlags |= call->gtFlags & GTF_ALL_EFFECT;
+        parents.Index(i)->gtFlags |= (call->gtFlags & GTF_ALL_EFFECT) | GTF_CALL;
     }
 
     // Since "tree" is replaced with "call", pop "tree" node (i.e the current node)
@@ -1010,18 +991,17 @@ void Rationalizer::DoPhase()
         comp->compCurBB = block;
         m_block         = block;
 
+        GenTreeStmt* firstStatement = block->firstStmt();
+        block->MakeLIR(nullptr, nullptr);
+
         // Establish the first and last nodes for the block. This is necessary in order for the LIR
         // utilities that hang off the BasicBlock type to work correctly.
-        GenTreeStmt* firstStatement = block->firstStmt();
         if (firstStatement == nullptr)
         {
             // No statements in this block; skip it.
-            block->MakeLIR(nullptr, nullptr);
             continue;
         }
 
-        GenTreeStmt* lastStatement = block->lastStmt();
-
         // Rewrite intrinsics that are not supported by the target back into user calls.
         // This needs to be done before the transition to LIR because it relies on the use
         // of fgMorphArgs, which is designed to operate on HIR. Once this is done for a
@@ -1029,14 +1009,15 @@ void Rationalizer::DoPhase()
         //
         // This walk also clears the GTF_VAR_USEDEF bit on locals, which is not necessary
         // in the backend.
-        GenTree* lastNodeInPreviousStatement = nullptr;
-        for (GenTreeStmt* statement = firstStatement; statement != nullptr; statement = statement->getNextStmt())
+        for (GenTreeStmt *statement = firstStatement; statement != nullptr; statement = statement->getNextStmt())
         {
             assert(statement->gtStmtList != nullptr);
             assert(statement->gtStmtList->gtPrev == nullptr);
             assert(statement->gtStmtExpr != nullptr);
             assert(statement->gtStmtExpr->gtNext == nullptr);
 
+            BlockRange().InsertAtEnd(LIR::Range(statement->gtStmtList, statement->gtStmtExpr));
+
             m_statement = statement;
             comp->fgWalkTreePost(&statement->gtStmtExpr,
                                  [](GenTree** use, Compiler::fgWalkData* walkData) -> Compiler::fgWalkResult {
@@ -1056,19 +1037,8 @@ void Rationalizer::DoPhase()
                                      return Compiler::WALK_CONTINUE;
                                  },
                                  this, true);
-
-            GenTree* firstNodeInStatement = statement->gtStmtList;
-            if (lastNodeInPreviousStatement != nullptr)
-            {
-                lastNodeInPreviousStatement->gtNext = firstNodeInStatement;
-            }
-
-            firstNodeInStatement->gtPrev = lastNodeInPreviousStatement;
-            lastNodeInPreviousStatement  = statement->gtStmtExpr;
         }
 
-        block->MakeLIR(firstStatement->gtStmtList, lastStatement->gtStmtExpr);
-
         // Rewrite HIR nodes into LIR nodes.
         for (GenTreeStmt *statement = firstStatement, *nextStatement; statement != nullptr; statement = nextStatement)
         {
@@ -1086,7 +1056,6 @@ void Rationalizer::DoPhase()
                 BlockRange().InsertBefore(statement->gtStmtList, statement);
             }
 
-            m_statement = statement;
             comp->fgWalkTreePost(&statement->gtStmtExpr,
                                  [](GenTree** use, Compiler::fgWalkData* walkData) -> Compiler::fgWalkResult {
                                      return reinterpret_cast<Rationalizer*>(walkData->pCallbackData)