#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);
*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)
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
//
// 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 {
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)
{
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)