From 4a7d4faf7183d5471c7f71e46c92c4b8018bed9f Mon Sep 17 00:00:00 2001 From: Pat Gavlin Date: Mon, 26 Jun 2017 14:40:15 -0700 Subject: [PATCH] Use LIR utilities in the intrinsic rewriter. 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 | 2 ++ src/coreclr/src/jit/rationalize.cpp | 65 ++++++++++--------------------------- 2 files changed, 19 insertions(+), 48 deletions(-) diff --git a/src/coreclr/src/jit/lir.h b/src/coreclr/src/jit/lir.h index 71c1147..088b5e5 100644 --- a/src/coreclr/src/jit/lir.h +++ b/src/coreclr/src/jit/lir.h @@ -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); diff --git a/src/coreclr/src/jit/rationalize.cpp b/src/coreclr/src/jit/rationalize.cpp index 11ba34d..cd73ba4 100644 --- a/src/coreclr/src/jit/rationalize.cpp +++ b/src/coreclr/src/jit/rationalize.cpp @@ -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(walkData->pCallbackData) -- 2.7.4