summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Andreenko <seandree@microsoft.com>2019-03-29 15:17:37 -0700
committerGitHub <noreply@github.com>2019-03-29 15:17:37 -0700
commit311b5e2fe413c6c74a2a3680ab54d8a978651472 (patch)
tree34b80e7da951ba003d59b42f14f928c84a4a02c2
parent4a4ba4d379002c8b8e77ef968f510cf0283201d0 (diff)
downloadcoreclr-311b5e2fe413c6c74a2a3680ab54d8a978651472.tar.gz
coreclr-311b5e2fe413c6c74a2a3680ab54d8a978651472.tar.bz2
coreclr-311b5e2fe413c6c74a2a3680ab54d8a978651472.zip
Use GenTreeStmt* where it is implied. (#22963)
* Extract `impAppendStmt` and `impExtractLastStmt`. * Delete `BEG_STMTS` fake stmt. Use new functions to keep the list updated. * Retype `impTreeList` and `impTreeLast` as statements. Rename `impTreeList` and `impTreeLast` to show that they are statements. * Fix fields that have to be stmt. * Start using GenTreeStmt. Change `optVNAssertionPropCurStmt` to use GenTreeStmt. Replace `GenTree* stmt = block->bbTreeList` with `GenTreeStmt* stmt = block->firstStmt()`. Save results of `FirstNonPhiDef` as `GenTreeStmt`. * Replace do-while with for loop. * Change type inside VNAssertionPropVisitorInfo. * Delete unused args fron `optVNConstantPropOnTree`. * Update fields to be stmt. Update optVNConstantPropCurStmt to use Stmt. Change `lvDefStmt` to stmt. Update LoopCloning structs. Update `optDebugLogLoopCloning`. Make `compCurStmt` a statement. Update declaration name in `BuildNode`. * Clean simple cpp files. Clean valuenum. Clean ssabuilder. Clean simd. Clean optcse. Clean loopcloning. Clean copyprop. Clean optimizer part1. * Start cleaning importer, morph, flowgraph, gentree. * Continue clean functons. Clean assertionprop. Clean morph. Clean gentree. Clean flowgraph. Clean compiler. Clean rangecheck. Clean indirectcalltransofrmer. Clean others. * Create some temp stmt. * Delete unnecessary noway_assert and casts. * Init `impStmtList` and `impLastStmt` in release. * Response review 1.
-rw-r--r--src/jit/assertionprop.cpp120
-rw-r--r--src/jit/block.cpp22
-rw-r--r--src/jit/block.h2
-rw-r--r--src/jit/codegencommon.cpp8
-rw-r--r--src/jit/codegenlinear.cpp19
-rw-r--r--src/jit/compiler.cpp22
-rw-r--r--src/jit/compiler.h195
-rw-r--r--src/jit/compiler.hpp11
-rw-r--r--src/jit/copyprop.cpp12
-rw-r--r--src/jit/earlyprop.cpp4
-rw-r--r--src/jit/flowgraph.cpp283
-rw-r--r--src/jit/gentree.cpp84
-rw-r--r--src/jit/gentree.h12
-rw-r--r--src/jit/gtlist.h2
-rw-r--r--src/jit/importer.cpp273
-rw-r--r--src/jit/indirectcalltransformer.cpp30
-rw-r--r--src/jit/liveness.cpp25
-rw-r--r--src/jit/loopcloning.cpp4
-rw-r--r--src/jit/loopcloning.h12
-rw-r--r--src/jit/lsra.h2
-rw-r--r--src/jit/morph.cpp207
-rw-r--r--src/jit/optcse.cpp79
-rw-r--r--src/jit/optimizer.cpp146
-rw-r--r--src/jit/rangecheck.cpp20
-rw-r--r--src/jit/rangecheck.h6
-rw-r--r--src/jit/rationalize.cpp9
-rw-r--r--src/jit/rationalize.h2
-rw-r--r--src/jit/simd.cpp6
-rw-r--r--src/jit/ssabuilder.cpp29
-rw-r--r--src/jit/valuenum.cpp21
30 files changed, 755 insertions, 912 deletions
diff --git a/src/jit/assertionprop.cpp b/src/jit/assertionprop.cpp
index 3747b2edca..8bb8ce4418 100644
--- a/src/jit/assertionprop.cpp
+++ b/src/jit/assertionprop.cpp
@@ -277,8 +277,8 @@ void Compiler::optAddCopies()
continue;
}
- GenTree* stmt;
- unsigned copyLclNum = lvaGrabTemp(false DEBUGARG("optAddCopies"));
+ GenTreeStmt* stmt;
+ unsigned copyLclNum = lvaGrabTemp(false DEBUGARG("optAddCopies"));
// Because lvaGrabTemp may have reallocated the lvaTable, ensure varDsc
// is still in sync with lvaTable[lclNum];
@@ -438,12 +438,11 @@ void Compiler::optAddCopies()
/* Locate the assignment to varDsc in the lvDefStmt */
stmt = varDsc->lvDefStmt;
- noway_assert(stmt->gtOper == GT_STMT);
optAddCopyLclNum = lclNum; // in
optAddCopyAsgnNode = nullptr; // out
- fgWalkTreePre(&stmt->gtStmt.gtStmtExpr, Compiler::optAddCopiesCallback, (void*)this, false);
+ fgWalkTreePre(&stmt->gtStmtExpr, Compiler::optAddCopiesCallback, (void*)this, false);
noway_assert(optAddCopyAsgnNode);
@@ -477,7 +476,7 @@ void Compiler::optAddCopies()
if (verbose)
{
printf("\nIntroducing a new copy for V%02u\n", lclNum);
- gtDispTree(stmt->gtStmt.gtStmtExpr);
+ gtDispTree(stmt->gtStmtExpr);
printf("\n");
}
#endif
@@ -2373,13 +2372,13 @@ AssertionIndex Compiler::optAssertionIsSubtype(GenTree* tree, GenTree* methodTab
// appropriately decremented. The ref-counts of variables in the side-effect
// nodes will be retained.
//
-GenTree* Compiler::optVNConstantPropOnTree(BasicBlock* block, GenTree* stmt, GenTree* tree)
+GenTree* Compiler::optVNConstantPropOnTree(BasicBlock* block, GenTree* tree)
{
if (tree->OperGet() == GT_JTRUE)
{
// Treat JTRUE separately to extract side effects into respective statements rather
// than using a COMMA separated op1.
- return optVNConstantPropOnJTrue(block, stmt, tree);
+ return optVNConstantPropOnJTrue(block, tree);
}
// If relop is part of JTRUE, this should be optimized as part of the parent JTRUE.
// Or if relop is part of QMARK or anything else, we simply bail here.
@@ -2594,7 +2593,7 @@ GenTree* Compiler::optVNConstantPropOnTree(BasicBlock* block, GenTree* stmt, Gen
*/
GenTree* Compiler::optConstantAssertionProp(AssertionDsc* curAssertion,
GenTree* tree,
- GenTree* stmt DEBUGARG(AssertionIndex index))
+ GenTreeStmt* stmt DEBUGARG(AssertionIndex index))
{
unsigned lclNum = tree->gtLclVarCommon.gtLclNum;
@@ -2783,7 +2782,7 @@ bool Compiler::optAssertionProp_LclVarTypeCheck(GenTree* tree, LclVarDsc* lclVar
*/
GenTree* Compiler::optCopyAssertionProp(AssertionDsc* curAssertion,
GenTree* tree,
- GenTree* stmt DEBUGARG(AssertionIndex index))
+ GenTreeStmt* stmt DEBUGARG(AssertionIndex index))
{
const AssertionDsc::AssertionDscOp1& op1 = curAssertion->op1;
const AssertionDsc::AssertionDscOp2& op2 = curAssertion->op2;
@@ -2852,7 +2851,7 @@ GenTree* Compiler::optCopyAssertionProp(AssertionDsc* curAssertion,
* be nullptr. Returns the modified tree, or nullptr if no assertion prop took place.
*/
-GenTree* Compiler::optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt)
+GenTree* Compiler::optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt)
{
assert(tree->gtOper == GT_LCL_VAR);
// If we have a var definition then bail or
@@ -3049,7 +3048,7 @@ AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqualZero(ASSERT_VALARG_T
* Returns the modified tree, or nullptr if no assertion prop took place
*/
-GenTree* Compiler::optAssertionProp_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt)
+GenTree* Compiler::optAssertionProp_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt)
{
assert(tree->OperKind() & GTK_RELOP);
@@ -3078,7 +3077,7 @@ GenTree* Compiler::optAssertionProp_RelOp(ASSERT_VALARG_TP assertions, GenTree*
* perform Value numbering based relop assertion propagation on the tree.
*
*/
-GenTree* Compiler::optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt)
+GenTree* Compiler::optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt)
{
GenTree* newTree = tree;
GenTree* op1 = tree->gtOp.gtOp1;
@@ -3298,7 +3297,7 @@ GenTree* Compiler::optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions, Gen
* perform local variable name based relop assertion propagation on the tree.
*
*/
-GenTree* Compiler::optAssertionPropLocal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt)
+GenTree* Compiler::optAssertionPropLocal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt)
{
assert(tree->OperGet() == GT_EQ || tree->OperGet() == GT_NE);
@@ -3392,7 +3391,7 @@ GenTree* Compiler::optAssertionPropLocal_RelOp(ASSERT_VALARG_TP assertions, GenT
*
* Returns the modified tree, or nullptr if no assertion prop took place.
*/
-GenTree* Compiler::optAssertionProp_Cast(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt)
+GenTree* Compiler::optAssertionProp_Cast(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt)
{
assert(tree->gtOper == GT_CAST);
@@ -3489,7 +3488,7 @@ GenTree* Compiler::optAssertionProp_Cast(ASSERT_VALARG_TP assertions, GenTree* t
* Given a tree with an array bounds check node, eliminate it because it was
* checked already in the program.
*/
-GenTree* Compiler::optAssertionProp_Comma(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt)
+GenTree* Compiler::optAssertionProp_Comma(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt)
{
// Remove the bounds check as part of the GT_COMMA node since we need parent pointer to remove nodes.
// When processing visits the bounds check, it sets the throw kind to None if the check is redundant.
@@ -3512,7 +3511,7 @@ GenTree* Compiler::optAssertionProp_Comma(ASSERT_VALARG_TP assertions, GenTree*
*
*/
-GenTree* Compiler::optAssertionProp_Ind(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt)
+GenTree* Compiler::optAssertionProp_Ind(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt)
{
assert(tree->OperIsIndir());
@@ -3657,7 +3656,7 @@ AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTree* op, ASSERT_VALAR
* Returns the modified tree, or nullptr if no assertion prop took place.
*
*/
-GenTree* Compiler::optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, GenTree* stmt)
+GenTree* Compiler::optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call)
{
if ((call->gtFlags & GTF_CALL_NULLCHECK) == 0)
{
@@ -3704,9 +3703,9 @@ GenTree* Compiler::optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions, Gen
*
*/
-GenTree* Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, GenTree* stmt)
+GenTree* Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, GenTreeStmt* stmt)
{
- if (optNonNullAssertionProp_Call(assertions, call, stmt))
+ if (optNonNullAssertionProp_Call(assertions, call))
{
return optAssertionProp_Update(call, call, stmt);
}
@@ -3761,7 +3760,7 @@ GenTree* Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCal
* Given a tree consisting of a comma node with a bounds check, remove any
* redundant bounds check that has already been checked in the program flow.
*/
-GenTree* Compiler::optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt)
+GenTree* Compiler::optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, GenTree* tree)
{
if (optLocalAssertionProp)
{
@@ -3896,7 +3895,7 @@ GenTree* Compiler::optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, GenTree
*
*/
-GenTree* Compiler::optAssertionProp_Update(GenTree* newTree, GenTree* tree, GenTree* stmt)
+GenTree* Compiler::optAssertionProp_Update(GenTree* newTree, GenTree* tree, GenTreeStmt* stmt)
{
noway_assert(newTree != nullptr);
@@ -3955,7 +3954,7 @@ GenTree* Compiler::optAssertionProp_Update(GenTree* newTree, GenTree* tree, GenT
* Returns the modified tree, or nullptr if no assertion prop took place.
*/
-GenTree* Compiler::optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt)
+GenTree* Compiler::optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt)
{
switch (tree->gtOper)
{
@@ -3970,7 +3969,7 @@ GenTree* Compiler::optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree,
return optAssertionProp_Ind(assertions, tree, stmt);
case GT_ARR_BOUNDS_CHECK:
- return optAssertionProp_BndsChk(assertions, tree, stmt);
+ return optAssertionProp_BndsChk(assertions, tree);
case GT_COMMA:
return optAssertionProp_Comma(assertions, tree, stmt);
@@ -4501,17 +4500,15 @@ ASSERT_TP* Compiler::optComputeAssertionGen()
{
ASSERT_TP* jumpDestGen = fgAllocateTypeForEachBlk<ASSERT_TP>();
- for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
+ for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
{
ASSERT_TP valueGen = BitVecOps::MakeEmpty(apTraits);
GenTree* jtrue = nullptr;
// Walk the statement trees in this basic block.
- for (GenTree* stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- noway_assert(stmt->gtOper == GT_STMT);
-
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
if (tree->gtOper == GT_JTRUE)
{
@@ -4641,10 +4638,10 @@ ASSERT_TP* Compiler::optInitAssertionDataflowFlags()
// Callback data for the VN based constant prop visitor.
struct VNAssertionPropVisitorInfo
{
- Compiler* pThis;
- GenTree* stmt;
- BasicBlock* block;
- VNAssertionPropVisitorInfo(Compiler* pThis, BasicBlock* block, GenTree* stmt)
+ Compiler* pThis;
+ GenTreeStmt* stmt;
+ BasicBlock* block;
+ VNAssertionPropVisitorInfo(Compiler* pThis, BasicBlock* block, GenTreeStmt* stmt)
: pThis(pThis), stmt(stmt), block(block)
{
}
@@ -4734,8 +4731,7 @@ GenTree* Compiler::optPrepareTreeForReplacement(GenTree* oldTree, GenTree* newTr
//
// Arguments:
// block - The block that contains the JTrue.
-// stmt - The JTrue stmt which can be evaluated to a constant.
-// tree - The JTrue node whose relop evaluates to 0 or non-zero value.
+// test - The JTrue node whose relop evaluates to 0 or non-zero value.
//
// Return Value:
// The jmpTrue tree node that has relop of the form "0 =/!= 0".
@@ -4757,7 +4753,7 @@ GenTree* Compiler::optPrepareTreeForReplacement(GenTree* oldTree, GenTree* newTr
// sensitive to adding new statements. Hence the change is not made directly
// into fgFoldConditional.
//
-GenTree* Compiler::optVNConstantPropOnJTrue(BasicBlock* block, GenTree* stmt, GenTree* test)
+GenTree* Compiler::optVNConstantPropOnJTrue(BasicBlock* block, GenTree* test)
{
GenTree* relop = test->gtGetOp1();
@@ -4802,7 +4798,7 @@ GenTree* Compiler::optVNConstantPropOnJTrue(BasicBlock* block, GenTree* stmt, Ge
// these side effects from the JTrue stmt before insert them back here.
while (sideEffList != nullptr)
{
- GenTree* newStmt;
+ GenTreeStmt* newStmt;
if (sideEffList->OperGet() == GT_COMMA)
{
newStmt = fgInsertStmtNearEnd(block, sideEffList->gtGetOp1());
@@ -4815,7 +4811,7 @@ GenTree* Compiler::optVNConstantPropOnJTrue(BasicBlock* block, GenTree* stmt, Ge
}
// fgMorphBlockStmt could potentially affect stmts after the current one,
// for example when it decides to fgRemoveRestOfBlock.
- fgMorphBlockStmt(block, newStmt->AsStmt() DEBUGARG(__FUNCTION__));
+ fgMorphBlockStmt(block, newStmt DEBUGARG(__FUNCTION__));
}
return test;
@@ -4841,7 +4837,7 @@ GenTree* Compiler::optVNConstantPropOnJTrue(BasicBlock* block, GenTree* stmt, Ge
// evaluates to constant, then the tree is replaced by its side effects and
// the constant node.
//
-Compiler::fgWalkResult Compiler::optVNConstantPropCurStmt(BasicBlock* block, GenTree* stmt, GenTree* tree)
+Compiler::fgWalkResult Compiler::optVNConstantPropCurStmt(BasicBlock* block, GenTreeStmt* stmt, GenTree* tree)
{
// Don't propagate floating-point constants into a TYP_STRUCT LclVar
// This can occur for HFA return values (see hfa_sf3E_r.exe)
@@ -4912,7 +4908,7 @@ Compiler::fgWalkResult Compiler::optVNConstantPropCurStmt(BasicBlock* block, Gen
}
// Perform the constant propagation
- GenTree* newTree = optVNConstantPropOnTree(block, stmt, tree);
+ GenTree* newTree = optVNConstantPropOnTree(block, tree);
if (newTree == nullptr)
{
// Not propagated, keep going.
@@ -4951,13 +4947,13 @@ Compiler::fgWalkResult Compiler::optVNConstantPropCurStmt(BasicBlock* block, Gen
// indirections. This is different from flow based assertions and helps
// unify VN based constant prop and non-null prop in a single pre-order walk.
//
-void Compiler::optVnNonNullPropCurStmt(BasicBlock* block, GenTree* stmt, GenTree* tree)
+void Compiler::optVnNonNullPropCurStmt(BasicBlock* block, GenTreeStmt* stmt, GenTree* tree)
{
ASSERT_TP empty = BitVecOps::UninitVal();
GenTree* newTree = nullptr;
if (tree->OperGet() == GT_CALL)
{
- newTree = optNonNullAssertionProp_Call(empty, tree->AsCall(), stmt);
+ newTree = optNonNullAssertionProp_Call(empty, tree->AsCall());
}
else if (tree->OperIsIndir())
{
@@ -5005,7 +5001,7 @@ Compiler::fgWalkResult Compiler::optVNAssertionPropCurStmtVisitor(GenTree** ppTr
* Returns the skipped next stmt if the current statement or next few
* statements got removed, else just returns the incoming stmt.
*/
-GenTree* Compiler::optVNAssertionPropCurStmt(BasicBlock* block, GenTree* stmt)
+GenTreeStmt* Compiler::optVNAssertionPropCurStmt(BasicBlock* block, GenTreeStmt* stmt)
{
// TODO-Review: EH successor/predecessor iteration seems broken.
// See: SELF_HOST_TESTS_ARM\jit\Directed\ExcepFilters\fault\fault.exe
@@ -5015,23 +5011,23 @@ GenTree* Compiler::optVNAssertionPropCurStmt(BasicBlock* block, GenTree* stmt)
}
// Preserve the prev link before the propagation and morph.
- GenTree* prev = (stmt == block->firstStmt()) ? nullptr : stmt->gtPrev;
+ GenTreeStmt* prev = (stmt == block->firstStmt()) ? nullptr : stmt->getPrevStmt();
// Perform VN based assertion prop first, in case we don't find
// anything in assertion gen.
optAssertionPropagatedCurrentStmt = false;
VNAssertionPropVisitorInfo data(this, block, stmt);
- fgWalkTreePre(&stmt->gtStmt.gtStmtExpr, Compiler::optVNAssertionPropCurStmtVisitor, &data);
+ fgWalkTreePre(&stmt->gtStmtExpr, Compiler::optVNAssertionPropCurStmtVisitor, &data);
if (optAssertionPropagatedCurrentStmt)
{
- fgMorphBlockStmt(block, stmt->AsStmt() DEBUGARG("optVNAssertionPropCurStmt"));
+ fgMorphBlockStmt(block, stmt DEBUGARG("optVNAssertionPropCurStmt"));
}
// Check if propagation removed statements starting from current stmt.
// If so, advance to the next good statement.
- GenTree* nextStmt = (prev == nullptr) ? block->firstStmt() : prev->gtNext;
+ GenTreeStmt* nextStmt = (prev == nullptr) ? block->firstStmt() : prev->getNextStmt();
return nextStmt;
}
@@ -5066,25 +5062,25 @@ void Compiler::optAssertionPropMain()
fgRemoveRestOfBlock = false;
- GenTree* stmt = block->bbTreeList;
- while (stmt)
+ GenTreeStmt* stmt = block->firstStmt();
+ while (stmt != nullptr)
{
// We need to remove the rest of the block.
if (fgRemoveRestOfBlock)
{
fgRemoveStmt(block, stmt);
- stmt = stmt->gtNext;
+ stmt = stmt->getNextStmt();
continue;
}
else
{
// Perform VN based assertion prop before assertion gen.
- GenTree* nextStmt = optVNAssertionPropCurStmt(block, stmt);
+ GenTreeStmt* nextStmt = optVNAssertionPropCurStmt(block, stmt);
// Propagation resulted in removal of the remaining stmts, perform it.
if (fgRemoveRestOfBlock)
{
- stmt = stmt->gtNext;
+ stmt = stmt->getNextStmt();
continue;
}
@@ -5097,13 +5093,13 @@ void Compiler::optAssertionPropMain()
}
// Perform assertion gen for control flow based assertions.
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
optAssertionGen(tree);
}
// Advance the iterator
- stmt = stmt->gtNext;
+ stmt = stmt->getNextStmt();
}
}
@@ -5169,26 +5165,24 @@ void Compiler::optAssertionPropMain()
fgRemoveRestOfBlock = false;
// Walk the statement trees in this basic block
- GenTree* stmt = block->FirstNonPhiDef();
- while (stmt)
+ GenTreeStmt* stmt = block->FirstNonPhiDef();
+ while (stmt != nullptr)
{
- noway_assert(stmt->gtOper == GT_STMT);
-
// Propagation tells us to remove the rest of the block. Remove it.
if (fgRemoveRestOfBlock)
{
fgRemoveStmt(block, stmt);
- stmt = stmt->gtNext;
+ stmt = stmt->getNextStmt();
continue;
}
// Preserve the prev link before the propagation and morph, to check if propagation
// removes the current stmt.
- GenTree* prev = (stmt == block->firstStmt()) ? nullptr : stmt->gtPrev;
+ GenTreeStmt* prevStmt = (stmt == block->firstStmt()) ? nullptr : stmt->getPrevStmt();
optAssertionPropagatedCurrentStmt = false; // set to true if a assertion propagation took place
// and thus we must morph, set order, re-link
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
if (tree->OperIs(GT_JTRUE))
{
@@ -5228,13 +5222,13 @@ void Compiler::optAssertionPropMain()
}
#endif
// Re-morph the statement.
- fgMorphBlockStmt(block, stmt->AsStmt() DEBUGARG("optAssertionPropMain"));
+ fgMorphBlockStmt(block, stmt DEBUGARG("optAssertionPropMain"));
}
// Check if propagation removed statements starting from current stmt.
// If so, advance to the next good statement.
- GenTree* nextStmt = (prev == nullptr) ? block->firstStmt() : prev->gtNext;
- stmt = (stmt == nextStmt) ? stmt->gtNext : nextStmt;
+ GenTreeStmt* nextStmt = (prevStmt == nullptr) ? block->firstStmt() : prevStmt->getNextStmt();
+ stmt = (stmt == nextStmt) ? stmt->getNextStmt() : nextStmt;
}
optAssertionPropagatedCurrentStmt = false; // clear it back as we are done with stmts.
}
diff --git a/src/jit/block.cpp b/src/jit/block.cpp
index 8d1a83f5b4..dfba5c6a1f 100644
--- a/src/jit/block.cpp
+++ b/src/jit/block.cpp
@@ -631,9 +631,9 @@ bool BasicBlock::CloneBlockState(
to->bbTgtStkDepth = from->bbTgtStkDepth;
#endif // DEBUG
- for (GenTree* fromStmt = from->bbTreeList; fromStmt != nullptr; fromStmt = fromStmt->gtNext)
+ for (GenTreeStmt* fromStmt = from->firstStmt(); fromStmt != nullptr; fromStmt = fromStmt->getNextStmt())
{
- auto newExpr = compiler->gtCloneExpr(fromStmt->gtStmt.gtStmtExpr, 0, varNum, varVal);
+ auto newExpr = compiler->gtCloneExpr(fromStmt->gtStmtExpr, 0, varNum, varVal);
if (!newExpr)
{
// gtCloneExpr doesn't handle all opcodes, so may fail to clone a statement.
@@ -809,37 +809,37 @@ bool BasicBlock::isEmpty()
GenTreeStmt* BasicBlock::FirstNonPhiDef()
{
- GenTree* stmt = bbTreeList;
+ GenTreeStmt* stmt = firstStmt();
if (stmt == nullptr)
{
return nullptr;
}
- GenTree* tree = stmt->gtStmt.gtStmtExpr;
+ GenTree* tree = stmt->gtStmtExpr;
while ((tree->OperGet() == GT_ASG && tree->gtOp.gtOp2->OperGet() == GT_PHI) ||
(tree->OperGet() == GT_STORE_LCL_VAR && tree->gtOp.gtOp1->OperGet() == GT_PHI))
{
- stmt = stmt->gtNext;
+ stmt = stmt->getNextStmt();
if (stmt == nullptr)
{
return nullptr;
}
- tree = stmt->gtStmt.gtStmtExpr;
+ tree = stmt->gtStmtExpr;
}
- return stmt->AsStmt();
+ return stmt;
}
-GenTree* BasicBlock::FirstNonPhiDefOrCatchArgAsg()
+GenTreeStmt* BasicBlock::FirstNonPhiDefOrCatchArgAsg()
{
- GenTree* stmt = FirstNonPhiDef();
+ GenTreeStmt* stmt = FirstNonPhiDef();
if (stmt == nullptr)
{
return nullptr;
}
- GenTree* tree = stmt->gtStmt.gtStmtExpr;
+ GenTree* tree = stmt->gtStmtExpr;
if ((tree->OperGet() == GT_ASG && tree->gtOp.gtOp2->OperGet() == GT_CATCH_ARG) ||
(tree->OperGet() == GT_STORE_LCL_VAR && tree->gtOp.gtOp1->OperGet() == GT_CATCH_ARG))
{
- stmt = stmt->gtNext;
+ stmt = stmt->getNextStmt();
}
return stmt;
}
diff --git a/src/jit/block.h b/src/jit/block.h
index 56b1c7313d..d186a79176 100644
--- a/src/jit/block.h
+++ b/src/jit/block.h
@@ -1076,7 +1076,7 @@ struct BasicBlock : private LIR::Range
// Returns the first statement in the statement list of "this" that is
// not an SSA definition (a lcl = phi(...) assignment).
GenTreeStmt* FirstNonPhiDef();
- GenTree* FirstNonPhiDefOrCatchArgAsg();
+ GenTreeStmt* FirstNonPhiDefOrCatchArgAsg();
BasicBlock() : bbLiveIn(VarSetOps::UninitVal()), bbLiveOut(VarSetOps::UninitVal())
{
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index 03e171bc2c..e54342a1d5 100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -11243,13 +11243,13 @@ void CodeGen::genIPmappingGen()
//block has an IL offset and appears in eeBoundaries.
for (BasicBlock * block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
{
- if ((block->bbRefs > 1) && (block->bbTreeList != nullptr))
+ GenTreeStmt* stmt = block->firstStmt();
+ if ((block->bbRefs > 1) && (stmt != nullptr))
{
- noway_assert(block->bbTreeList->gtOper == GT_STMT);
bool found = false;
- if (block->bbTreeList->gtStmt.gtStmtILoffsx != BAD_IL_OFFSET)
+ if (stmt->gtStmtILoffsx != BAD_IL_OFFSET)
{
- IL_OFFSET ilOffs = jitGetILoffs(block->bbTreeList->gtStmt.gtStmtILoffsx);
+ IL_OFFSET ilOffs = jitGetILoffs(stmt->gtStmtILoffsx);
for (unsigned i = 0; i < eeBoundariesCount; ++i)
{
if (eeBoundaries[i].ilOffset == ilOffs)
diff --git a/src/jit/codegenlinear.cpp b/src/jit/codegenlinear.cpp
index 72f9fa68db..6b16e30e89 100644
--- a/src/jit/codegenlinear.cpp
+++ b/src/jit/codegenlinear.cpp
@@ -411,28 +411,25 @@ void CodeGen::genCodeForBBlist()
// Do we have a new IL offset?
if (node->OperGet() == GT_IL_OFFSET)
{
+ GenTreeStmt* ilOffset = node->AsStmt();
genEnsureCodeEmitted(currentILOffset);
- currentILOffset = node->gtStmt.gtStmtILoffsx;
+ currentILOffset = ilOffset->gtStmtILoffsx;
genIPmappingAdd(currentILOffset, firstMapping);
firstMapping = false;
- }
-
#ifdef DEBUG
- if (node->OperGet() == GT_IL_OFFSET)
- {
- noway_assert(node->gtStmt.gtStmtLastILoffs <= compiler->info.compILCodeSize ||
- node->gtStmt.gtStmtLastILoffs == BAD_IL_OFFSET);
+ assert(ilOffset->gtStmtLastILoffs <= compiler->info.compILCodeSize ||
+ ilOffset->gtStmtLastILoffs == BAD_IL_OFFSET);
- if (compiler->opts.dspCode && compiler->opts.dspInstrs &&
- node->gtStmt.gtStmtLastILoffs != BAD_IL_OFFSET)
+ if (compiler->opts.dspCode && compiler->opts.dspInstrs && ilOffset->gtStmtLastILoffs != BAD_IL_OFFSET)
{
- while (genCurDispOffset <= node->gtStmt.gtStmtLastILoffs)
+ while (genCurDispOffset <= ilOffset->gtStmtLastILoffs)
{
genCurDispOffset += dumpSingleInstr(compiler->info.compCode, genCurDispOffset, "> ");
}
}
- }
+
#endif // DEBUG
+ }
genCodeForTreeNode(node);
if (node->gtHasReg() && node->IsUnusedValue())
diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp
index fe02e2c42b..c70e90da6a 100644
--- a/src/jit/compiler.cpp
+++ b/src/jit/compiler.cpp
@@ -4896,7 +4896,7 @@ void Compiler::ResetOptAnnotations()
{
stmt->gtFlags &= ~GTF_STMT_HAS_CSE;
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree != nullptr; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
tree->ClearVN();
tree->ClearAssertion();
@@ -6930,9 +6930,9 @@ Compiler::NodeToIntMap* Compiler::FindReachableNodesInNodeTestData()
for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
{
- for (GenTree* stmt = block->FirstNonPhiDef(); stmt != nullptr; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->FirstNonPhiDef(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
TestLabelAndNum tlAndN;
@@ -7161,10 +7161,6 @@ void Compiler::compCallArgStats()
GenTree* args;
GenTree* argx;
- BasicBlock* block;
- GenTree* stmt;
- GenTree* call;
-
unsigned argNum;
unsigned argDWordNum;
@@ -7183,13 +7179,11 @@ void Compiler::compCallArgStats()
assert(fgStmtListThreaded);
- for (block = fgFirstBB; block; block = block->bbNext)
+ for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
{
- for (stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- assert(stmt->gtOper == GT_STMT);
-
- for (call = stmt->gtStmt.gtStmtList; call; call = call->gtNext)
+ for (GenTree* call = stmt->gtStmtList; call != nullptr; call = call->gtNext)
{
if (call->gtOper != GT_CALL)
continue;
@@ -8819,9 +8813,7 @@ void cBlockIR(Compiler* comp, BasicBlock* block)
if (comp->compRationalIRForm)
{
- GenTree* tree;
-
- foreach_treenode_execution_order(tree, stmt)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
cNodeIR(comp, tree);
}
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index eefa345e6e..87581856dd 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -810,9 +810,9 @@ public:
BYTE* lvGcLayout; // GC layout info for structs
#if ASSERTION_PROP
- BlockSet lvRefBlks; // Set of blocks that contain refs
- GenTree* lvDefStmt; // Pointer to the statement with the single definition
- void lvaDisqualifyVar(); // Call to disqualify a local variable from use in optAddCopies
+ BlockSet lvRefBlks; // Set of blocks that contain refs
+ GenTreeStmt* lvDefStmt; // Pointer to the statement with the single definition
+ void lvaDisqualifyVar(); // Call to disqualify a local variable from use in optAddCopies
#endif
var_types TypeGet() const
{
@@ -2460,11 +2460,11 @@ public:
GenTree* gtNewAssignNode(GenTree* dst, GenTree* src);
- GenTree* gtNewTempAssign(unsigned tmp,
- GenTree* val,
- GenTree** pAfterStmt = nullptr,
- IL_OFFSETX ilOffset = BAD_IL_OFFSET,
- BasicBlock* block = nullptr);
+ GenTree* gtNewTempAssign(unsigned tmp,
+ GenTree* val,
+ GenTreeStmt** pAfterStmt = nullptr,
+ IL_OFFSETX ilOffset = BAD_IL_OFFSET,
+ BasicBlock* block = nullptr);
GenTree* gtNewRefCOMfield(GenTree* objPtr,
CORINFO_RESOLVED_TOKEN* pResolvedToken,
@@ -2518,13 +2518,13 @@ public:
// Create copy of an inline or guarded devirtualization candidate tree.
GenTreeCall* gtCloneCandidateCall(GenTreeCall* call);
- GenTree* gtReplaceTree(GenTree* stmt, GenTree* tree, GenTree* replacementTree);
+ GenTree* gtReplaceTree(GenTreeStmt* stmt, GenTree* tree, GenTree* replacementTree);
- void gtUpdateSideEffects(GenTree* stmt, GenTree* tree);
+ void gtUpdateSideEffects(GenTreeStmt* stmt, GenTree* tree);
void gtUpdateTreeAncestorsSideEffects(GenTree* tree);
- void gtUpdateStmtSideEffects(GenTree* stmt);
+ void gtUpdateStmtSideEffects(GenTreeStmt* stmt);
void gtUpdateNodeSideEffects(GenTree* tree);
@@ -2568,7 +2568,7 @@ public:
unsigned gtSetEvalOrder(GenTree* tree);
- void gtSetStmtInfo(GenTree* stmt);
+ void gtSetStmtInfo(GenTreeStmt* stmt);
// Returns "true" iff "node" has any of the side effects in "flags".
bool gtNodeHasSideEffects(GenTree* node, unsigned flags);
@@ -2732,7 +2732,7 @@ public:
static fgWalkPreFn gtMarkColonCond;
static fgWalkPreFn gtClearColonCond;
- GenTree** gtFindLink(GenTree* stmt, GenTree* node);
+ GenTree** gtFindLink(GenTreeStmt* stmt, GenTree* node);
bool gtHasCatchArg(GenTree* tree);
typedef ArrayStack<GenTree*> GenTreeStack;
@@ -3063,7 +3063,7 @@ public:
void lvaAllocOutgoingArgSpaceVar(); // Set up lvaOutgoingArgSpaceVar
- VARSET_VALRET_TP lvaStmtLclMask(GenTree* stmt);
+ VARSET_VALRET_TP lvaStmtLclMask(GenTreeStmt* stmt);
#ifdef DEBUG
struct lvaStressLclFldArgs
@@ -3533,8 +3533,8 @@ protected:
//----------------- Manipulating the trees and stmts ----------------------
- GenTree* impTreeList; // Trees for the BB being imported
- GenTree* impTreeLast; // The last tree for the current BB
+ GenTreeStmt* impStmtList; // Statements for the BB being imported.
+ GenTreeStmt* impLastStmt; // The last statement for the current BB.
public:
enum
@@ -3544,43 +3544,46 @@ public:
};
void impBeginTreeList();
- void impEndTreeList(BasicBlock* block, GenTree* firstStmt, GenTree* lastStmt);
+ void impEndTreeList(BasicBlock* block, GenTreeStmt* firstStmt, GenTreeStmt* lastStmt);
void impEndTreeList(BasicBlock* block);
- void impAppendStmtCheck(GenTree* stmt, unsigned chkLevel);
- void impAppendStmt(GenTree* stmt, unsigned chkLevel);
- void impInsertStmtBefore(GenTree* stmt, GenTree* stmtBefore);
- GenTree* impAppendTree(GenTree* tree, unsigned chkLevel, IL_OFFSETX offset);
- void impInsertTreeBefore(GenTree* tree, IL_OFFSETX offset, GenTree* stmtBefore);
- void impAssignTempGen(unsigned tmp,
- GenTree* val,
- unsigned curLevel,
- GenTree** pAfterStmt = nullptr,
- IL_OFFSETX ilOffset = BAD_IL_OFFSET,
- BasicBlock* block = nullptr);
+ void impAppendStmtCheck(GenTreeStmt* stmt, unsigned chkLevel);
+ void impAppendStmt(GenTreeStmt* stmt, unsigned chkLevel);
+ void impAppendStmt(GenTreeStmt* stmt);
+ void impInsertStmtBefore(GenTreeStmt* stmt, GenTreeStmt* stmtBefore);
+ GenTreeStmt* impAppendTree(GenTree* tree, unsigned chkLevel, IL_OFFSETX offset);
+ void impInsertTreeBefore(GenTree* tree, IL_OFFSETX offset, GenTreeStmt* stmtBefore);
+ void impAssignTempGen(unsigned tmp,
+ GenTree* val,
+ unsigned curLevel,
+ GenTreeStmt** pAfterStmt = nullptr,
+ IL_OFFSETX ilOffset = BAD_IL_OFFSET,
+ BasicBlock* block = nullptr);
void impAssignTempGen(unsigned tmpNum,
GenTree* val,
CORINFO_CLASS_HANDLE structHnd,
unsigned curLevel,
- GenTree** pAfterStmt = nullptr,
+ GenTreeStmt** pAfterStmt = nullptr,
IL_OFFSETX ilOffset = BAD_IL_OFFSET,
BasicBlock* block = nullptr);
+
+ GenTreeStmt* impExtractLastStmt();
GenTree* impCloneExpr(GenTree* tree,
GenTree** clone,
CORINFO_CLASS_HANDLE structHnd,
unsigned curLevel,
- GenTree** pAfterStmt DEBUGARG(const char* reason));
+ GenTreeStmt** pAfterStmt DEBUGARG(const char* reason));
GenTree* impAssignStruct(GenTree* dest,
GenTree* src,
CORINFO_CLASS_HANDLE structHnd,
unsigned curLevel,
- GenTree** pAfterStmt = nullptr,
+ GenTreeStmt** pAfterStmt = nullptr,
IL_OFFSETX ilOffset = BAD_IL_OFFSET,
BasicBlock* block = nullptr);
GenTree* impAssignStructPtr(GenTree* dest,
GenTree* src,
CORINFO_CLASS_HANDLE structHnd,
unsigned curLevel,
- GenTree** pAfterStmt = nullptr,
+ GenTreeStmt** pAfterStmt = nullptr,
IL_OFFSETX ilOffset = BAD_IL_OFFSET,
BasicBlock* block = nullptr);
@@ -3653,8 +3656,8 @@ private:
bool impNestedStackSpill;
// For displaying instrs with generated native code (-n:B)
- GenTree* impLastILoffsStmt; // oldest stmt added for which we did not gtStmtLastILoffs
- void impNoteLastILoffs();
+ GenTreeStmt* impLastILoffsStmt; // oldest stmt added for which we did not gtStmtLastILoffs
+ void impNoteLastILoffs();
#endif
/* IL offset of the stmt currently being imported. It gets set to
@@ -4247,7 +4250,7 @@ public:
BasicBlock* fgSplitBlockAtBeginning(BasicBlock* curr);
BasicBlock* fgSplitBlockAtEnd(BasicBlock* curr);
- BasicBlock* fgSplitBlockAfterStatement(BasicBlock* curr, GenTree* stmt);
+ BasicBlock* fgSplitBlockAfterStatement(BasicBlock* curr, GenTreeStmt* stmt);
BasicBlock* fgSplitBlockAfterNode(BasicBlock* curr, GenTree* node); // for LIR
BasicBlock* fgSplitEdge(BasicBlock* curr, BasicBlock* succ);
@@ -4257,8 +4260,8 @@ public:
GenTreeStmt* fgNewStmtFromTree(GenTree* tree, IL_OFFSETX offs);
GenTree* fgGetTopLevelQmark(GenTree* expr, GenTree** ppDst = nullptr);
- void fgExpandQmarkForCastInstOf(BasicBlock* block, GenTree* stmt);
- void fgExpandQmarkStmt(BasicBlock* block, GenTree* expr);
+ void fgExpandQmarkForCastInstOf(BasicBlock* block, GenTreeStmt* stmt);
+ void fgExpandQmarkStmt(BasicBlock* block, GenTreeStmt* stmt);
void fgExpandQmarkNodes();
void fgMorph();
@@ -4813,9 +4816,9 @@ public:
void fgRemoveEmptyBlocks();
- void fgRemoveStmt(BasicBlock* block, GenTree* stmt);
+ void fgRemoveStmt(BasicBlock* block, GenTreeStmt* stmt);
- bool fgCheckRemoveStmt(BasicBlock* block, GenTree* stmt);
+ bool fgCheckRemoveStmt(BasicBlock* block, GenTreeStmt* stmt);
void fgCreateLoopPreHeader(unsigned lnum);
@@ -4941,7 +4944,7 @@ public:
void fgTableDispBasicBlock(BasicBlock* block, int ibcColWidth = 0);
void fgDispBasicBlocks(BasicBlock* firstBlock, BasicBlock* lastBlock, bool dumpTrees);
void fgDispBasicBlocks(bool dumpTrees = false);
- void fgDumpStmtTree(GenTree* stmt, unsigned bbNum);
+ void fgDumpStmtTree(GenTreeStmt* stmt, unsigned bbNum);
void fgDumpBlock(BasicBlock* block);
void fgDumpTrees(BasicBlock* firstBlock, BasicBlock* lastBlock);
@@ -4952,7 +4955,7 @@ public:
void fgDebugCheckBlockLinks();
void fgDebugCheckLinks(bool morphTrees = false);
void fgDebugCheckStmtsList(BasicBlock* block, bool morphTrees);
- void fgDebugCheckNodeLinks(BasicBlock* block, GenTree* stmt);
+ void fgDebugCheckNodeLinks(BasicBlock* block, GenTreeStmt* stmt);
void fgDebugCheckNodesUniqueness();
void fgDebugCheckFlags(GenTree* tree);
@@ -5088,7 +5091,9 @@ public:
#ifdef DEBUG
public:
- static bool fgBlockContainsStatementBounded(BasicBlock* block, GenTree* stmt, bool answerOnBoundExceeded = true);
+ static bool fgBlockContainsStatementBounded(BasicBlock* block,
+ GenTreeStmt* stmt,
+ bool answerOnBoundExceeded = true);
#endif
public:
@@ -5098,14 +5103,14 @@ public: // Used by linear scan register allocation
GenTreeStmt* fgInsertStmtNearEnd(BasicBlock* block, GenTree* node);
private:
- GenTree* fgInsertStmtAtBeg(BasicBlock* block, GenTree* stmt);
- GenTree* fgInsertStmtAfter(BasicBlock* block, GenTree* insertionPoint, GenTree* stmt);
+ GenTreeStmt* fgInsertStmtAtBeg(BasicBlock* block, GenTree* node);
+ GenTreeStmt* fgInsertStmtAfter(BasicBlock* block, GenTreeStmt* insertionPoint, GenTreeStmt* stmt);
public: // Used by linear scan register allocation
- GenTree* fgInsertStmtBefore(BasicBlock* block, GenTree* insertionPoint, GenTree* stmt);
+ GenTreeStmt* fgInsertStmtBefore(BasicBlock* block, GenTreeStmt* insertionPoint, GenTreeStmt* stmt);
private:
- GenTree* fgInsertStmtListAfter(BasicBlock* block, GenTree* stmtAfter, GenTree* stmtList);
+ GenTreeStmt* fgInsertStmtListAfter(BasicBlock* block, GenTreeStmt* stmtAfter, GenTreeStmt* stmtList);
// Create a new temporary variable to hold the result of *ppTree,
// and transform the graph accordingly.
@@ -5126,7 +5131,7 @@ private:
GenTree* fgSetTreeSeq(GenTree* tree, GenTree* prev = nullptr, bool isLIR = false);
void fgSetTreeSeqHelper(GenTree* tree, bool isLIR);
void fgSetTreeSeqFinish(GenTree* tree, bool isLIR);
- void fgSetStmtSeq(GenTree* tree);
+ void fgSetStmtSeq(GenTreeStmt* stmt);
void fgSetBlockOrder(BasicBlock* block);
//------------------------- Morphing --------------------------------------
@@ -5218,12 +5223,12 @@ private:
bool ignoreUsedInSIMDIntrinsic = false);
GenTree* fgMorphFieldAssignToSIMDIntrinsicSet(GenTree* tree);
GenTree* fgMorphFieldToSIMDIntrinsicGet(GenTree* tree);
- bool fgMorphCombineSIMDFieldAssignments(BasicBlock* block, GenTree* stmt);
- void impMarkContiguousSIMDFieldAssignments(GenTree* stmt);
+ bool fgMorphCombineSIMDFieldAssignments(BasicBlock* block, GenTreeStmt* stmt);
+ void impMarkContiguousSIMDFieldAssignments(GenTreeStmt* stmt);
// fgPreviousCandidateSIMDFieldAsgStmt is only used for tracking previous simd field assignment
// in function: Complier::impMarkContiguousSIMDFieldAssignments.
- GenTree* fgPreviousCandidateSIMDFieldAsgStmt;
+ GenTreeStmt* fgPreviousCandidateSIMDFieldAsgStmt;
#endif // FEATURE_SIMD
GenTree* fgMorphArrayIndex(GenTree* tree);
@@ -5252,12 +5257,12 @@ private:
void fgMorphTailCall(GenTreeCall* call, void* pfnCopyArgs);
GenTree* fgGetStubAddrArg(GenTreeCall* call);
void fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCall* recursiveTailCall);
- GenTree* fgAssignRecursiveCallArgToCallerParam(GenTree* arg,
- fgArgTabEntry* argTabEntry,
- BasicBlock* block,
- IL_OFFSETX callILOffset,
- GenTree* tmpAssignmentInsertionPoint,
- GenTree* paramAssignmentInsertionPoint);
+ GenTreeStmt* fgAssignRecursiveCallArgToCallerParam(GenTree* arg,
+ fgArgTabEntry* argTabEntry,
+ BasicBlock* block,
+ IL_OFFSETX callILOffset,
+ GenTreeStmt* tmpAssignmentInsertionPoint,
+ GenTreeStmt* paramAssignmentInsertionPoint);
static int fgEstimateCallStackSize(GenTreeCall* call);
GenTree* fgMorphCall(GenTreeCall* call);
void fgMorphCallInline(GenTreeCall* call, InlineResult* result);
@@ -5384,8 +5389,8 @@ private:
unsigned fgCheckInlineDepthAndRecursion(InlineInfo* inlineInfo);
void fgInvokeInlineeCompiler(GenTreeCall* call, InlineResult* result);
void fgInsertInlineeBlocks(InlineInfo* pInlineInfo);
- GenTree* fgInlinePrependStatements(InlineInfo* inlineInfo);
- void fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* block, GenTree* stmt);
+ GenTreeStmt* fgInlinePrependStatements(InlineInfo* inlineInfo);
+ void fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* block, GenTreeStmt* stmt);
#if FEATURE_MULTIREG_RET
GenTree* fgGetStructAsStructPtr(GenTree* tree);
@@ -5468,7 +5473,7 @@ private:
public:
void optInit();
- void optRemoveRangeCheck(GenTree* tree, GenTree* stmt);
+ void optRemoveRangeCheck(GenTree* tree, GenTreeStmt* stmt);
bool optIsRangeCheckRemovable(GenTree* tree);
protected:
@@ -5861,7 +5866,7 @@ protected:
void optUpdateLoopsBeforeRemoveBlock(BasicBlock* block, bool skipUnmarkLoop = false);
- bool optIsLoopTestEvalIntoTemp(GenTree* test, GenTree** newTest);
+ bool optIsLoopTestEvalIntoTemp(GenTreeStmt* testStmt, GenTreeStmt** newTestStmt);
unsigned optIsLoopIncrTree(GenTree* incr);
bool optCheckIterInLoopTest(unsigned loopInd, GenTree* test, BasicBlock* from, BasicBlock* to, unsigned iterVar);
bool optComputeIterInfo(GenTree* incr, BasicBlock* from, BasicBlock* to, unsigned* pIterVar);
@@ -5980,7 +5985,7 @@ protected:
{
treeStmtLst* tslNext;
GenTree* tslTree; // tree node
- GenTree* tslStmt; // statement containing the tree
+ GenTreeStmt* tslStmt; // statement containing the tree
BasicBlock* tslBlock; // block containing the statement
};
@@ -6001,9 +6006,9 @@ protected:
unsigned csdDefWtCnt; // weighted def count
unsigned csdUseWtCnt; // weighted use count (excluding the implicit uses at defs)
- GenTree* csdTree; // treenode containing the 1st occurance
- GenTree* csdStmt; // stmt containing the 1st occurance
- BasicBlock* csdBlock; // block containing the 1st occurance
+ GenTree* csdTree; // treenode containing the 1st occurance
+ GenTreeStmt* csdStmt; // stmt containing the 1st occurance
+ BasicBlock* csdBlock; // block containing the 1st occurance
treeStmtLst* csdTreeList; // list of matching tree nodes: head
treeStmtLst* csdTreeLast; // list of matching tree nodes: tail
@@ -6074,7 +6079,7 @@ public:
protected:
void optValnumCSE_Init();
- unsigned optValnumCSE_Index(GenTree* tree, GenTree* stmt);
+ unsigned optValnumCSE_Index(GenTree* tree, GenTreeStmt* stmt);
unsigned optValnumCSE_Locate();
void optValnumCSE_InitDataFlow();
void optValnumCSE_DataFlow();
@@ -6141,7 +6146,7 @@ public:
VARSET_TP optCopyPropKillSet;
// Copy propagation functions.
- void optCopyProp(BasicBlock* block, GenTree* stmt, GenTree* tree, LclNumToGenTreePtrStack* curSsaName);
+ void optCopyProp(BasicBlock* block, GenTreeStmt* stmt, GenTree* tree, LclNumToGenTreePtrStack* curSsaName);
void optBlockCopyPropPopStacks(BasicBlock* block, LclNumToGenTreePtrStack* curSsaName);
void optBlockCopyProp(BasicBlock* block, LclNumToGenTreePtrStack* curSsaName);
bool optIsSsaLocal(GenTree* tree);
@@ -6519,10 +6524,10 @@ protected:
AssertionIndex optMaxAssertionCount;
public:
- void optVnNonNullPropCurStmt(BasicBlock* block, GenTree* stmt, GenTree* tree);
- fgWalkResult optVNConstantPropCurStmt(BasicBlock* block, GenTree* stmt, GenTree* tree);
- GenTree* optVNConstantPropOnJTrue(BasicBlock* block, GenTree* stmt, GenTree* test);
- GenTree* optVNConstantPropOnTree(BasicBlock* block, GenTree* stmt, GenTree* tree);
+ void optVnNonNullPropCurStmt(BasicBlock* block, GenTreeStmt* stmt, GenTree* tree);
+ fgWalkResult optVNConstantPropCurStmt(BasicBlock* block, GenTreeStmt* stmt, GenTree* tree);
+ GenTree* optVNConstantPropOnJTrue(BasicBlock* block, GenTree* test);
+ GenTree* optVNConstantPropOnTree(BasicBlock* block, GenTree* tree);
GenTree* optPrepareTreeForReplacement(GenTree* extractTree, GenTree* replaceTree);
AssertionIndex GetAssertionCount()
@@ -6544,8 +6549,8 @@ public:
#endif
// Assertion prop data flow functions.
- void optAssertionPropMain();
- GenTree* optVNAssertionPropCurStmt(BasicBlock* block, GenTree* stmt);
+ void optAssertionPropMain();
+ GenTreeStmt* optVNAssertionPropCurStmt(BasicBlock* block, GenTreeStmt* stmt);
bool optIsTreeKnownIntValue(bool vnBased, GenTree* tree, ssize_t* pConstant, unsigned* pIconFlags);
ASSERT_TP* optInitAssertionDataflowFlags();
ASSERT_TP* optComputeAssertionGen();
@@ -6592,24 +6597,24 @@ public:
bool optAssertionProp_LclVarTypeCheck(GenTree* tree, LclVarDsc* lclVarDsc, LclVarDsc* copyVarDsc);
GenTree* optCopyAssertionProp(AssertionDsc* curAssertion,
GenTree* tree,
- GenTree* stmt DEBUGARG(AssertionIndex index));
+ GenTreeStmt* stmt DEBUGARG(AssertionIndex index));
GenTree* optConstantAssertionProp(AssertionDsc* curAssertion,
GenTree* tree,
- GenTree* stmt DEBUGARG(AssertionIndex index));
+ GenTreeStmt* stmt DEBUGARG(AssertionIndex index));
// Assertion propagation functions.
- GenTree* optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
- GenTree* optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
- GenTree* optAssertionProp_Ind(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
- GenTree* optAssertionProp_Cast(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
- GenTree* optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, GenTree* stmt);
- GenTree* optAssertionProp_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
- GenTree* optAssertionProp_Comma(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
- GenTree* optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
- GenTree* optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
- GenTree* optAssertionPropLocal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
- GenTree* optAssertionProp_Update(GenTree* newTree, GenTree* tree, GenTree* stmt);
- GenTree* optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, GenTree* stmt);
+ GenTree* optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt);
+ GenTree* optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt);
+ GenTree* optAssertionProp_Ind(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt);
+ GenTree* optAssertionProp_Cast(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt);
+ GenTree* optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, GenTreeStmt* stmt);
+ GenTree* optAssertionProp_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt);
+ GenTree* optAssertionProp_Comma(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt);
+ GenTree* optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, GenTree* tree);
+ GenTree* optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt);
+ GenTree* optAssertionPropLocal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTreeStmt* stmt);
+ GenTree* optAssertionProp_Update(GenTree* newTree, GenTree* tree, GenTreeStmt* stmt);
+ GenTree* optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call);
// Implied assertion functions.
void optImpliedAssertions(AssertionIndex assertionIndex, ASSERT_TP& activeAssertions);
@@ -6634,8 +6639,8 @@ public:
{
LoopCloneContext* context;
unsigned loopNum;
- GenTree* stmt;
- LoopCloneVisitorInfo(LoopCloneContext* context, unsigned loopNum, GenTree* stmt)
+ GenTreeStmt* stmt;
+ LoopCloneVisitorInfo(LoopCloneContext* context, unsigned loopNum, GenTreeStmt* stmt)
: context(context), loopNum(loopNum), stmt(nullptr)
{
}
@@ -6653,7 +6658,7 @@ public:
bool optCanCloneLoops();
#ifdef DEBUG
- void optDebugLogLoopCloning(BasicBlock* block, GenTree* insertBefore);
+ void optDebugLogLoopCloning(BasicBlock* block, GenTreeStmt* insertBefore);
#endif
void optPerformStaticOptimizations(unsigned loopNum, LoopCloneContext* context DEBUGARG(bool fastPath));
bool optComputeDerefConditions(unsigned loopNum, LoopCloneContext* context);
@@ -8720,8 +8725,8 @@ public:
unsigned compBasicBlockID;
#endif
- BasicBlock* compCurBB; // the current basic block in process
- GenTree* compCurStmt; // the current statement in process
+ BasicBlock* compCurBB; // the current basic block in process
+ GenTreeStmt* compCurStmt; // the current statement in process
#ifdef DEBUG
unsigned compCurStmtNum; // to give all statements an increasing StmtNum when printing dumps
#endif
@@ -10309,14 +10314,6 @@ extern BasicBlock dummyBB;
/*****************************************************************************/
/*****************************************************************************/
-// foreach_treenode_execution_order: An iterator that iterates through all the tree
-// nodes of a statement in execution order.
-// __stmt: a GT_STMT type GenTree*
-// __node: a GenTree*, already declared, that gets updated with each node in the statement, in execution order
-
-#define foreach_treenode_execution_order(__node, __stmt) \
- for ((__node) = (__stmt)->gtStmt.gtStmtList; (__node); (__node) = (__node)->gtNext)
-
// foreach_block: An iterator over all blocks in the function.
// __compiler: the Compiler* object
// __block : a BasicBlock*, already declared, that gets updated each iteration.
diff --git a/src/jit/compiler.hpp b/src/jit/compiler.hpp
index 2eb5ac7b08..901a58ec9e 100644
--- a/src/jit/compiler.hpp
+++ b/src/jit/compiler.hpp
@@ -1308,10 +1308,9 @@ inline GenTree* Compiler::gtUnusedValNode(GenTree* expr)
* operands
*/
-inline void Compiler::gtSetStmtInfo(GenTree* stmt)
+inline void Compiler::gtSetStmtInfo(GenTreeStmt* stmt)
{
- assert(stmt->gtOper == GT_STMT);
- GenTree* expr = stmt->gtStmt.gtStmtExpr;
+ GenTree* expr = stmt->gtStmtExpr;
/* Recursively process the expression */
@@ -1817,17 +1816,15 @@ inline void LclVarDsc::incRefCnts(BasicBlock::weight_t weight, Compiler* comp, R
* referenced in a statement.
*/
-inline VARSET_VALRET_TP Compiler::lvaStmtLclMask(GenTree* stmt)
+inline VARSET_VALRET_TP Compiler::lvaStmtLclMask(GenTreeStmt* stmt)
{
- GenTree* tree;
unsigned varNum;
LclVarDsc* varDsc;
VARSET_TP lclMask(VarSetOps::MakeEmpty(this));
- assert(stmt->gtOper == GT_STMT);
assert(fgStmtListThreaded);
- for (tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
if (tree->gtOper != GT_LCL_VAR)
{
diff --git a/src/jit/copyprop.cpp b/src/jit/copyprop.cpp
index 4611e91b54..29aa92e0d7 100644
--- a/src/jit/copyprop.cpp
+++ b/src/jit/copyprop.cpp
@@ -29,9 +29,9 @@
*/
void Compiler::optBlockCopyPropPopStacks(BasicBlock* block, LclNumToGenTreePtrStack* curSsaName)
{
- for (GenTree* stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
if (!tree->IsLocal())
{
@@ -128,7 +128,7 @@ int Compiler::optCopyProp_LclVarScore(LclVarDsc* lclVarDsc, LclVarDsc* copyVarDs
// tree - The tree to perform copy propagation on
// curSsaName - The map from lclNum to its recently live definitions as a stack
-void Compiler::optCopyProp(BasicBlock* block, GenTree* stmt, GenTree* tree, LclNumToGenTreePtrStack* curSsaName)
+void Compiler::optCopyProp(BasicBlock* block, GenTreeStmt* stmt, GenTree* tree, LclNumToGenTreePtrStack* curSsaName)
{
// TODO-Review: EH successor/predecessor iteration seems broken.
if (block->bbCatchTyp == BBCT_FINALLY || block->bbCatchTyp == BBCT_FAULT)
@@ -315,12 +315,12 @@ void Compiler::optBlockCopyProp(BasicBlock* block, LclNumToGenTreePtrStack* curS
// There are no definitions at the start of the block. So clear it.
compCurLifeTree = nullptr;
VarSetOps::Assign(this, compCurLife, block->bbLiveIn);
- for (GenTree* stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
VarSetOps::ClearD(this, optCopyPropKillSet);
// Walk the tree to find if any local variable can be replaced with current live definitions.
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
treeLifeUpdater.UpdateLife(tree);
@@ -347,7 +347,7 @@ void Compiler::optBlockCopyProp(BasicBlock* block, LclNumToGenTreePtrStack* curS
}
// This logic must be in sync with SSA renaming process.
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
if (!optIsSsaLocal(tree))
{
diff --git a/src/jit/earlyprop.cpp b/src/jit/earlyprop.cpp
index bd4c222664..084ed9bdef 100644
--- a/src/jit/earlyprop.cpp
+++ b/src/jit/earlyprop.cpp
@@ -195,7 +195,7 @@ void Compiler::optEarlyProp()
// Walk the stmt tree in linear order to rewrite any array length reference with a
// constant array length.
bool isRewritten = false;
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree != nullptr; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
GenTree* rewrittenTree = optEarlyPropRewriteTree(tree);
if (rewrittenTree != nullptr)
@@ -258,7 +258,7 @@ GenTree* Compiler::optEarlyPropRewriteTree(GenTree* tree)
// * stmtExpr void (top level)
// \--* indir int
// \--* lclVar ref V02 loc0
- if (compCurStmt->gtStmt.gtStmtExpr == tree)
+ if (compCurStmt->gtStmtExpr == tree)
{
return nullptr;
}
diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp
index 3f830f6f4c..976b0a30cb 100644
--- a/src/jit/flowgraph.cpp
+++ b/src/jit/flowgraph.cpp
@@ -270,7 +270,7 @@ void Compiler::fgInstrumentMethod()
HRESULT res = info.compCompHnd->allocBBProfileBuffer(countOfBlocks, &bbProfileBufferStart);
- GenTree* stmt;
+ GenTreeStmt* stmt;
if (!SUCCEEDED(res))
{
@@ -507,12 +507,12 @@ bool Compiler::fgBBisScratch(BasicBlock* block)
// budget doing this per method compiled.
// If the budget is exceeded, return 'answerOnBoundExceeded' as the answer.
/* static */
-bool Compiler::fgBlockContainsStatementBounded(BasicBlock* block, GenTree* stmt, bool answerOnBoundExceeded /*= true*/)
+bool Compiler::fgBlockContainsStatementBounded(BasicBlock* block,
+ GenTreeStmt* stmt,
+ bool answerOnBoundExceeded /*= true*/)
{
const __int64 maxLinks = 1000000000;
- assert(stmt->gtOper == GT_STMT);
-
__int64* numTraversed = &JitTls::GetCompiler()->compNumStatementLinksTraversed;
if (*numTraversed > maxLinks)
@@ -539,7 +539,7 @@ bool Compiler::fgBlockContainsStatementBounded(BasicBlock* block, GenTree* stmt,
//
// Arguments:
// block - The block into which 'stmt' will be inserted.
-// stmt - The statement to be inserted.
+// node - The node to be inserted.
//
// Return Value:
// Returns the new (potentially) GT_STMT node.
@@ -550,18 +550,23 @@ bool Compiler::fgBlockContainsStatementBounded(BasicBlock* block, GenTree* stmt,
// In other cases, if there are any phi assignments and/or an assignment of
// the GT_CATCH_ARG, we insert after those.
-GenTree* Compiler::fgInsertStmtAtBeg(BasicBlock* block, GenTree* stmt)
+GenTreeStmt* Compiler::fgInsertStmtAtBeg(BasicBlock* block, GenTree* node)
{
- if (stmt->gtOper != GT_STMT)
+ GenTreeStmt* stmt;
+ if (node->gtOper == GT_STMT)
+ {
+ stmt = node->AsStmt();
+ }
+ else
{
- stmt = gtNewStmt(stmt);
+ stmt = gtNewStmt(node);
}
GenTree* list = block->firstStmt();
if (!stmt->IsPhiDefnStmt())
{
- GenTree* insertBeforeStmt = block->FirstNonPhiDefOrCatchArgAsg();
+ GenTreeStmt* insertBeforeStmt = block->FirstNonPhiDefOrCatchArgAsg();
if (insertBeforeStmt != nullptr)
{
return fgInsertStmtBefore(block, insertBeforeStmt, stmt);
@@ -743,11 +748,9 @@ GenTreeStmt* Compiler::fgInsertStmtNearEnd(BasicBlock* block, GenTree* node)
* Note that the gtPrev list of statement nodes is circular, but the gtNext list is not.
*/
-GenTree* Compiler::fgInsertStmtAfter(BasicBlock* block, GenTree* insertionPoint, GenTree* stmt)
+GenTreeStmt* Compiler::fgInsertStmtAfter(BasicBlock* block, GenTreeStmt* insertionPoint, GenTreeStmt* stmt)
{
assert(block->bbTreeList != nullptr);
- noway_assert(insertionPoint->gtOper == GT_STMT);
- noway_assert(stmt->gtOper == GT_STMT);
assert(fgBlockContainsStatementBounded(block, insertionPoint));
assert(!fgBlockContainsStatementBounded(block, stmt, false));
@@ -779,11 +782,9 @@ GenTree* Compiler::fgInsertStmtAfter(BasicBlock* block, GenTree* insertionPoint,
// Insert the given tree or statement before GT_STMT node "insertionPoint".
// Returns the newly inserted GT_STMT node.
-GenTree* Compiler::fgInsertStmtBefore(BasicBlock* block, GenTree* insertionPoint, GenTree* stmt)
+GenTreeStmt* Compiler::fgInsertStmtBefore(BasicBlock* block, GenTreeStmt* insertionPoint, GenTreeStmt* stmt)
{
assert(block->bbTreeList != nullptr);
- noway_assert(insertionPoint->gtOper == GT_STMT);
- noway_assert(stmt->gtOper == GT_STMT);
assert(fgBlockContainsStatementBounded(block, insertionPoint));
assert(!fgBlockContainsStatementBounded(block, stmt, false));
@@ -817,22 +818,22 @@ GenTree* Compiler::fgInsertStmtBefore(BasicBlock* block, GenTree* insertionPoint
* Return the last statement stmtList.
*/
-GenTree* Compiler::fgInsertStmtListAfter(BasicBlock* block, // the block where stmtAfter is in.
- GenTree* stmtAfter, // the statement where stmtList should be inserted
- // after.
- GenTree* stmtList)
+GenTreeStmt* Compiler::fgInsertStmtListAfter(BasicBlock* block, // the block where stmtAfter is in.
+ GenTreeStmt* stmtAfter, // the statement where stmtList should be inserted
+ // after.
+ GenTreeStmt* stmtList)
{
// Currently we can handle when stmtAfter and stmtList are non-NULL. This makes everything easy.
- noway_assert(stmtAfter && stmtAfter->gtOper == GT_STMT);
- noway_assert(stmtList && stmtList->gtOper == GT_STMT);
+ noway_assert(stmtAfter);
+ noway_assert(stmtList);
- GenTree* stmtLast = stmtList->gtPrev; // Last statement in a non-empty list, circular in the gtPrev list.
+ GenTreeStmt* stmtLast = stmtList->getPrevStmt(); // Last statement in a non-empty list, circular in the gtPrev list.
noway_assert(stmtLast);
noway_assert(stmtLast->gtNext == nullptr);
- GenTree* stmtNext = stmtAfter->gtNext;
+ GenTreeStmt* stmtNext = stmtAfter->getNextStmt();
- if (!stmtNext)
+ if (stmtNext == nullptr)
{
stmtAfter->gtNext = stmtList;
stmtList->gtPrev = stmtAfter;
@@ -3895,11 +3896,11 @@ bool Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block)
//
// More formally, if control flow targets an instruction, that instruction must be the
// start of a new sequence point.
- if (newStmt->gtNext)
+ GenTreeStmt* nextStmt = newStmt->getNextStmt();
+ if (nextStmt != nullptr)
{
// Is it possible for gtNext to be NULL?
- noway_assert(newStmt->gtNext->gtOper == GT_STMT);
- newStmt->gtStmtILoffsx = newStmt->gtNextStmt->gtStmtILoffsx;
+ newStmt->gtStmtILoffsx = nextStmt->gtStmtILoffsx;
}
}
@@ -9220,12 +9221,11 @@ IL_OFFSET Compiler::fgFindBlockILOffset(BasicBlock* block)
// could have a similar function for LIR that searches for GT_IL_OFFSET nodes.
assert(!block->IsLIR());
- for (GenTree* stmt = block->bbTreeList; stmt != nullptr; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- assert(stmt->IsStatement());
- if (stmt->gtStmt.gtStmtILoffsx != BAD_IL_OFFSET)
+ if (stmt->gtStmtILoffsx != BAD_IL_OFFSET)
{
- return jitGetILoffs(stmt->gtStmt.gtStmtILoffsx);
+ return jitGetILoffs(stmt->gtStmtILoffsx);
}
}
@@ -9321,13 +9321,13 @@ BasicBlock* Compiler::fgSplitBlockAtEnd(BasicBlock* curr)
// fgSplitBlockAfterStatement - Split the given block, with all code after
// the given statement going into the second block.
//------------------------------------------------------------------------------
-BasicBlock* Compiler::fgSplitBlockAfterStatement(BasicBlock* curr, GenTree* stmt)
+BasicBlock* Compiler::fgSplitBlockAfterStatement(BasicBlock* curr, GenTreeStmt* stmt)
{
assert(!curr->IsLIR()); // No statements in LIR, so you can't use this function.
BasicBlock* newBlock = fgSplitBlockAtEnd(curr);
- if (stmt)
+ if (stmt != nullptr)
{
newBlock->bbTreeList = stmt->gtNext;
if (newBlock->bbTreeList)
@@ -9898,13 +9898,11 @@ void Compiler::fgRemoveEmptyBlocks()
*
*/
-void Compiler::fgRemoveStmt(BasicBlock* block, GenTree* node)
+void Compiler::fgRemoveStmt(BasicBlock* block, GenTreeStmt* stmt)
{
- noway_assert(node);
assert(fgOrder == FGOrderTree);
GenTreeStmt* tree = block->firstStmt();
- GenTreeStmt* stmt = node->AsStmt();
#ifdef DEBUG
if (verbose &&
@@ -10004,15 +10002,13 @@ inline bool OperIsControlFlow(genTreeOps oper)
* Returns true if it did remove the statement.
*/
-bool Compiler::fgCheckRemoveStmt(BasicBlock* block, GenTree* node)
+bool Compiler::fgCheckRemoveStmt(BasicBlock* block, GenTreeStmt* stmt)
{
if (opts.compDbgCode)
{
return false;
}
- GenTreeStmt* stmt = node->AsStmt();
-
GenTree* tree = stmt->gtStmtExpr;
genTreeOps oper = tree->OperGet();
@@ -10299,19 +10295,19 @@ void Compiler::fgCompactBlocks(BasicBlock* block, BasicBlock* bNext)
}
// Now proceed with the updated bbTreeLists.
- GenTree* stmtList1 = block->firstStmt();
- GenTree* stmtList2 = bNext->firstStmt();
+ GenTreeStmt* stmtList1 = block->firstStmt();
+ GenTreeStmt* stmtList2 = bNext->firstStmt();
/* the block may have an empty list */
- if (stmtList1)
+ if (stmtList1 != nullptr)
{
- GenTree* stmtLast1 = block->lastStmt();
+ GenTreeStmt* stmtLast1 = block->lastStmt();
/* The second block may be a GOTO statement or something with an empty bbTreeList */
- if (stmtList2)
+ if (stmtList2 != nullptr)
{
- GenTree* stmtLast2 = bNext->lastStmt();
+ GenTreeStmt* stmtLast2 = bNext->lastStmt();
/* append list2 to list 1 */
@@ -13943,7 +13939,7 @@ bool Compiler::fgOptimizeEmptyBlock(BasicBlock* block)
}
else
{
- GenTree* nopStmt = fgInsertStmtAtEnd(block, nop);
+ GenTreeStmt* nopStmt = fgInsertStmtAtEnd(block, nop);
fgSetStmtSeq(nopStmt);
gtSetStmtInfo(nopStmt);
}
@@ -14457,7 +14453,7 @@ bool Compiler::fgOptimizeUncondBranchToSimpleCond(BasicBlock* block, BasicBlock*
GenTree* cloned = gtCloneExpr(stmt->gtStmtExpr);
noway_assert(cloned);
- GenTree* jmpStmt = gtNewStmt(cloned);
+ GenTreeStmt* jmpStmt = gtNewStmt(cloned);
block->bbJumpKind = BBJ_COND;
block->bbJumpDest = target->bbJumpDest;
@@ -14727,9 +14723,8 @@ bool Compiler::fgOptimizeBranch(BasicBlock* bJump)
assert(!bJump->IsLIR());
assert(!bDest->IsLIR());
- GenTreeStmt* stmt;
- unsigned estDupCostSz = 0;
- for (stmt = bDest->firstStmt(); stmt; stmt = stmt->gtNextStmt)
+ unsigned estDupCostSz = 0;
+ for (GenTreeStmt* stmt = bDest->firstStmt(); stmt != nullptr; stmt = stmt->gtNextStmt)
{
GenTree* expr = stmt->gtStmtExpr;
@@ -14830,101 +14825,64 @@ bool Compiler::fgOptimizeBranch(BasicBlock* bJump)
/* Looks good - duplicate the conditional block */
- GenTree* newStmtList = nullptr; // new stmt list to be added to bJump
- GenTree* newStmtLast = nullptr;
- bool cloneExprFailed = false;
+ GenTreeStmt* newStmtList = nullptr; // new stmt list to be added to bJump
+ GenTreeStmt* newLastStmt = nullptr;
/* Visit all the statements in bDest */
- for (GenTree* curStmt = bDest->bbTreeList; curStmt; curStmt = curStmt->gtNext)
+ for (GenTreeStmt* curStmt = bDest->firstStmt(); curStmt != nullptr; curStmt = curStmt->getNextStmt())
{
- /* Clone/substitute the expression */
-
- stmt = gtCloneExpr(curStmt)->AsStmt();
-
- // cloneExpr doesn't handle everything
+ // Clone/substitute the expression.
+ GenTreeStmt* stmt = gtCloneExpr(curStmt)->AsStmt();
+ // cloneExpr doesn't handle everything.
if (stmt == nullptr)
{
- cloneExprFailed = true;
- break;
+ return false;
}
/* Append the expression to our list */
if (newStmtList != nullptr)
{
- newStmtLast->gtNext = stmt;
+ newLastStmt->gtNext = stmt;
}
else
{
newStmtList = stmt;
}
- stmt->gtPrev = newStmtLast;
- newStmtLast = stmt;
- }
-
- if (cloneExprFailed)
- {
- return false;
- }
-
- noway_assert(newStmtLast != nullptr);
- noway_assert(stmt != nullptr);
- noway_assert(stmt->gtOper == GT_STMT);
-
- if ((newStmtLast == nullptr) || (stmt == nullptr) || (stmt->gtOper != GT_STMT))
- {
- return false;
+ stmt->gtPrev = newLastStmt;
+ newLastStmt = stmt;
}
- /* Get to the condition node from the statement tree */
-
- GenTree* condTree = stmt->gtStmtExpr;
+ // Get to the condition node from the statement tree.
+ GenTree* condTree = newLastStmt->gtStmtExpr;
noway_assert(condTree->gtOper == GT_JTRUE);
- if (condTree->gtOper != GT_JTRUE)
- {
- return false;
- }
-
- //
- // Set condTree to the operand to the GT_JTRUE
- //
+ // Set condTree to the operand to the GT_JTRUE.
condTree = condTree->gtOp.gtOp1;
- //
- // This condTree has to be a RelOp comparison
- //
+ // This condTree has to be a RelOp comparison.
if (condTree->OperIsCompare() == false)
{
return false;
}
- //
- // Find the last statement in the bJump block
- //
- GenTreeStmt* lastStmt = nullptr;
- for (stmt = bJump->firstStmt(); stmt; stmt = stmt->gtNextStmt)
- {
- lastStmt = stmt;
- }
- stmt = bJump->firstStmt();
-
- /* Join the two linked lists */
- newStmtLast->gtNext = nullptr;
+ // Join the two linked lists.
+ GenTreeStmt* lastStmt = bJump->lastStmt();
if (lastStmt != nullptr)
{
- stmt->gtPrev = newStmtLast;
+ GenTreeStmt* stmt = bJump->firstStmt();
+ stmt->gtPrev = newLastStmt;
lastStmt->gtNext = newStmtList;
newStmtList->gtPrev = lastStmt;
}
else
{
bJump->bbTreeList = newStmtList;
- newStmtList->gtPrev = newStmtLast;
+ newStmtList->gtPrev = newLastStmt;
}
//
@@ -14994,7 +14952,7 @@ bool Compiler::fgOptimizeBranch(BasicBlock* bJump)
{
// Dump out the newStmtList that we created
printf("\nfgOptimizeBranch added these statements(s) at the end of " FMT_BB ":\n", bJump->bbNum);
- for (stmt = newStmtList->AsStmt(); stmt; stmt = stmt->gtNextStmt)
+ for (GenTreeStmt* stmt = newStmtList; stmt != nullptr; stmt = stmt->getNextStmt())
{
gtDispTree(stmt);
}
@@ -16102,9 +16060,9 @@ void Compiler::fgReorderBlocks()
if (bPrev->bbJumpKind == BBJ_COND)
{
/* Reverse the bPrev jump condition */
- GenTree* condTest = bPrev->lastStmt();
+ GenTreeStmt* condTestStmt = bPrev->lastStmt();
- condTest = condTest->gtStmt.gtStmtExpr;
+ GenTree* condTest = condTestStmt->gtStmtExpr;
noway_assert(condTest->gtOper == GT_JTRUE);
condTest->gtOp.gtOp1 = gtReverseCond(condTest->gtOp.gtOp1);
@@ -19009,24 +18967,22 @@ void Compiler::fgSetBlockOrder()
/*****************************************************************************/
-void Compiler::fgSetStmtSeq(GenTree* tree)
+void Compiler::fgSetStmtSeq(GenTreeStmt* stmt)
{
GenTree list; // helper node that we use to start the StmtList
// It's located in front of the first node in the list
- noway_assert(tree->gtOper == GT_STMT);
-
/* Assign numbers and next/prev links for this tree */
fgTreeSeqNum = 0;
fgTreeSeqLst = &list;
fgTreeSeqBeg = nullptr;
- fgSetTreeSeqHelper(tree->gtStmt.gtStmtExpr, false);
+ fgSetTreeSeqHelper(stmt->gtStmtExpr, false);
/* Record the address of the first node */
- tree->gtStmt.gtStmtList = fgTreeSeqBeg;
+ stmt->gtStmtList = fgTreeSeqBeg;
#ifdef DEBUG
@@ -19042,7 +18998,7 @@ void Compiler::fgSetStmtSeq(GenTree* tree)
GenTree* temp;
GenTree* last;
- for (temp = list.gtNext, last = &list; temp; last = temp, temp = temp->gtNext)
+ for (temp = list.gtNext, last = &list; temp != nullptr; last = temp, temp = temp->gtNext)
{
if (temp->gtPrev != last)
{
@@ -19056,10 +19012,10 @@ void Compiler::fgSetStmtSeq(GenTree* tree)
BAD_LIST:;
printf("\n");
- gtDispTree(tree->gtStmt.gtStmtExpr);
+ gtDispTree(stmt->gtStmtExpr);
printf("\n");
- for (GenTree* bad = &list; bad; bad = bad->gtNext)
+ for (GenTree* bad = &list; bad != nullptr; bad = bad->gtNext)
{
printf(" entry at ");
printTreeID(bad);
@@ -19096,42 +19052,32 @@ void Compiler::fgSetStmtSeq(GenTree* tree)
void Compiler::fgSetBlockOrder(BasicBlock* block)
{
- GenTree* tree;
-
- tree = block->bbTreeList;
- if (!tree)
- {
- return;
- }
-
- for (;;)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- fgSetStmtSeq(tree);
+ fgSetStmtSeq(stmt);
/* Are there any more trees in this basic block? */
- if (tree->gtNext == nullptr)
+ if (stmt->gtNext == nullptr)
{
/* last statement in the tree list */
- noway_assert(block->lastStmt() == tree);
+ noway_assert(block->lastStmt() == stmt);
break;
}
#ifdef DEBUG
- if (block->bbTreeList == tree)
+ if (block->bbTreeList == stmt)
{
/* first statement in the list */
- noway_assert(tree->gtPrev->gtNext == nullptr);
+ assert(stmt->gtPrev->gtNext == nullptr);
}
else
{
- noway_assert(tree->gtPrev->gtNext == tree);
+ assert(stmt->gtPrev->gtNext == stmt);
}
- noway_assert(tree->gtNext->gtPrev == tree);
+ assert(stmt->gtNext->gtPrev == stmt);
#endif // DEBUG
-
- tree = tree->gtNext;
}
}
@@ -19204,26 +19150,18 @@ unsigned Compiler::fgGetCodeEstimate(BasicBlock* block)
break;
}
- GenTree* tree = block->FirstNonPhiDef();
- if (tree)
+ for (GenTreeStmt* stmt = block->FirstNonPhiDef(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- do
+ if (stmt->gtCostSz < MAX_COST)
{
- noway_assert(tree->gtOper == GT_STMT);
-
- if (tree->gtCostSz < MAX_COST)
- {
- costSz += tree->gtCostSz;
- }
- else
- {
- // We could walk the tree to find out the real gtCostSz,
- // but just using MAX_COST for this trees code size works OK
- costSz += tree->gtCostSz;
- }
-
- tree = tree->gtNext;
- } while (tree);
+ costSz += stmt->gtCostSz;
+ }
+ else
+ {
+ // We could walk the tree to find out the real gtCostSz,
+ // but just using MAX_COST for this trees code size works OK
+ costSz += stmt->gtCostSz;
+ }
}
return costSz;
@@ -20468,7 +20406,7 @@ void Compiler::fgDispBasicBlocks(bool dumpTrees)
/*****************************************************************************/
// Increment the stmtNum and dump the tree using gtDispTree
//
-void Compiler::fgDumpStmtTree(GenTree* stmt, unsigned bbNum)
+void Compiler::fgDumpStmtTree(GenTreeStmt* stmt, unsigned bbNum)
{
compCurStmtNum++; // Increment the current stmtNum
@@ -20480,7 +20418,7 @@ void Compiler::fgDumpStmtTree(GenTree* stmt, unsigned bbNum)
}
else
{
- gtDispTree(stmt->gtStmt.gtStmtExpr);
+ gtDispTree(stmt->gtStmtExpr);
}
}
@@ -20497,10 +20435,11 @@ void Compiler::fgDumpBlock(BasicBlock* block)
if (!block->IsLIR())
{
- for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->gtNextStmt)
+ GenTreeStmt* firstStmt = block->firstStmt();
+ for (GenTreeStmt* stmt = firstStmt; stmt != nullptr; stmt = stmt->getNextStmt())
{
fgDumpStmtTree(stmt, block->bbNum);
- if (stmt == block->bbTreeList)
+ if (stmt == firstStmt)
{
block->bbStmtNum = compCurStmtNum; // Set the block->bbStmtNum
}
@@ -21488,7 +21427,7 @@ void Compiler::fgDebugCheckFlagsHelper(GenTree* tree, unsigned treeFlags, unsign
// DEBUG routine to check correctness of the internal gtNext, gtPrev threading of a statement.
// This threading is only valid when fgStmtListThreaded is true.
// This calls an alternate method for FGOrderLinear.
-void Compiler::fgDebugCheckNodeLinks(BasicBlock* block, GenTree* node)
+void Compiler::fgDebugCheckNodeLinks(BasicBlock* block, GenTreeStmt* stmt)
{
// LIR blocks are checked using BasicBlock::CheckLIR().
if (block->IsLIR())
@@ -21497,8 +21436,6 @@ void Compiler::fgDebugCheckNodeLinks(BasicBlock* block, GenTree* node)
// TODO: return?
}
- GenTreeStmt* stmt = node->AsStmt();
-
assert(fgStmtListThreaded);
noway_assert(stmt->gtStmtList);
@@ -22866,7 +22803,7 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
#ifdef DEBUG
- GenTree* currentDumpStmt = nullptr;
+ GenTreeStmt* currentDumpStmt = nullptr;
if (verbose)
{
@@ -22889,7 +22826,7 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
}
// Prepend statements
- GenTree* stmtAfter = fgInlinePrependStatements(pInlineInfo);
+ GenTreeStmt* stmtAfter = fgInlinePrependStatements(pInlineInfo);
#ifdef DEBUG
if (verbose)
@@ -22916,7 +22853,7 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
// Inlinee contains just one BB. So just insert its statement list to topBlock.
if (InlineeCompiler->fgFirstBB->bbTreeList)
{
- stmtAfter = fgInsertStmtListAfter(iciBlock, stmtAfter, InlineeCompiler->fgFirstBB->bbTreeList);
+ stmtAfter = fgInsertStmtListAfter(iciBlock, stmtAfter, InlineeCompiler->fgFirstBB->firstStmt());
// Copy inlinee bbFlags to caller bbFlags.
const unsigned __int64 inlineeBlockFlags = InlineeCompiler->fgFirstBB->bbFlags;
@@ -22934,12 +22871,10 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
{
do
{
- currentDumpStmt = currentDumpStmt->gtNext;
+ currentDumpStmt = currentDumpStmt->getNextStmt();
printf("\n");
- noway_assert(currentDumpStmt->gtOper == GT_STMT);
-
gtDispTree(currentDumpStmt);
printf("\n");
@@ -23219,14 +23154,14 @@ _Done:
// and are are given the same inline context as the call any calls
// added here will appear to have been part of the immediate caller.
-GenTree* Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
+GenTreeStmt* Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
{
BasicBlock* block = inlineInfo->iciBlock;
GenTreeStmt* callStmt = inlineInfo->iciStmt;
IL_OFFSETX callILOffset = callStmt->gtStmtILoffsx;
GenTreeStmt* postStmt = callStmt->gtNextStmt;
- GenTree* afterStmt = callStmt; // afterStmt is the place where the new statements should be inserted after.
- GenTree* newStmt = nullptr;
+ GenTreeStmt* afterStmt = callStmt; // afterStmt is the place where the new statements should be inserted after.
+ GenTreeStmt* newStmt = nullptr;
GenTreeCall* call = inlineInfo->iciCall->AsCall();
noway_assert(call->gtOper == GT_CALL);
@@ -23599,7 +23534,7 @@ GenTree* Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
// we skip nulling the locals, since it can interfere
// with tail calls introduced by the local.
-void Compiler::fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* block, GenTree* stmtAfter)
+void Compiler::fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* block, GenTreeStmt* stmtAfter)
{
// If this inlinee was passed a runtime lookup generic context and
// ignores it, we can decrement the "generic context was used" ref
@@ -23649,8 +23584,8 @@ void Compiler::fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* bloc
JITDUMP("fgInlineAppendStatements: nulling out gc ref inlinee locals.\n");
- GenTree* callStmt = inlineInfo->iciStmt;
- IL_OFFSETX callILOffset = callStmt->gtStmt.gtStmtILoffsx;
+ GenTreeStmt* callStmt = inlineInfo->iciStmt;
+ IL_OFFSETX callILOffset = callStmt->gtStmtILoffsx;
CORINFO_METHOD_INFO* InlineeMethodInfo = InlineeCompiler->info.compMethodInfo;
const unsigned lclCnt = InlineeMethodInfo->locals.numArgs;
InlLclVarInfo* lclVarInfo = inlineInfo->lclVarInfo;
@@ -23700,8 +23635,8 @@ void Compiler::fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* bloc
}
// Assign null to the local.
- GenTree* nullExpr = gtNewTempAssign(tmpNum, gtNewZeroConNode(lclTyp));
- GenTree* nullStmt = gtNewStmt(nullExpr, callILOffset);
+ GenTree* nullExpr = gtNewTempAssign(tmpNum, gtNewZeroConNode(lclTyp));
+ GenTreeStmt* nullStmt = gtNewStmt(nullExpr, callILOffset);
if (stmtAfter == nullptr)
{
diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp
index 69e774cf9b..833d115cb2 100644
--- a/src/jit/gentree.cpp
+++ b/src/jit/gentree.cpp
@@ -571,17 +571,11 @@ void GenTree::DumpNodeSizes(FILE* fp)
void Compiler::fgWalkAllTreesPre(fgWalkPreFn* visitor, void* pCallBackData)
{
- BasicBlock* block;
-
- for (block = fgFirstBB; block; block = block->bbNext)
+ for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
{
- GenTree* tree;
-
- for (tree = block->bbTreeList; tree; tree = tree->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- assert(tree->gtOper == GT_STMT);
-
- fgWalkTreePre(&tree->gtStmt.gtStmtExpr, visitor, pCallBackData);
+ fgWalkTreePre(&stmt->gtStmtExpr, visitor, pCallBackData);
}
}
}
@@ -3591,7 +3585,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
// under a struct assignment would not be considered for addressing modes.
if (compCurStmt != nullptr)
{
- GenTree* expr = compCurStmt->gtStmt.gtStmtExpr;
+ GenTree* expr = compCurStmt->gtStmtExpr;
if ((expr->OperGet() == GT_ASG) &&
((expr->gtGetOp1() == tree) || (expr->gtGetOp2() == tree)))
{
@@ -7619,7 +7613,7 @@ GenTreeCall* Compiler::gtCloneCandidateCall(GenTreeCall* call)
// but this method will sequence 'replacementTree', and insert it into the
// proper place in the statement sequence.
-GenTree* Compiler::gtReplaceTree(GenTree* stmt, GenTree* tree, GenTree* replacementTree)
+GenTree* Compiler::gtReplaceTree(GenTreeStmt* stmt, GenTree* tree, GenTree* replacementTree)
{
assert(fgStmtListThreaded);
assert(tree != nullptr);
@@ -7629,14 +7623,14 @@ GenTree* Compiler::gtReplaceTree(GenTree* stmt, GenTree* tree, GenTree* replacem
GenTree** treePtr = nullptr;
GenTree* treeParent = tree->gtGetParent(&treePtr);
- assert(treeParent != nullptr || tree == stmt->gtStmt.gtStmtExpr);
+ assert(treeParent != nullptr || tree == stmt->gtStmtExpr);
if (treePtr == nullptr)
{
// Replace the stmt expr and rebuild the linear order for "stmt".
assert(treeParent == nullptr);
assert(fgOrder != FGOrderLinear);
- stmt->gtStmt.gtStmtExpr = tree;
+ stmt->gtStmtExpr = tree;
fgSetStmtSeq(stmt);
}
else
@@ -7683,8 +7677,8 @@ GenTree* Compiler::gtReplaceTree(GenTree* stmt, GenTree* tree, GenTree* replacem
{
// Update the linear oder start of "stmt" if treeFirstNode
// appears to have replaced the original first node.
- assert(treeFirstNode == stmt->gtStmt.gtStmtList);
- stmt->gtStmt.gtStmtList = fgGetFirstNode(replacementTree);
+ assert(treeFirstNode == stmt->gtStmtList);
+ stmt->gtStmtList = fgGetFirstNode(replacementTree);
}
if (treeNextNode != nullptr)
@@ -7708,7 +7702,7 @@ GenTree* Compiler::gtReplaceTree(GenTree* stmt, GenTree* tree, GenTree* replacem
// Note: If tree's order hasn't been established, the method updates side effect
// flags on all statement's nodes.
-void Compiler::gtUpdateSideEffects(GenTree* stmt, GenTree* tree)
+void Compiler::gtUpdateSideEffects(GenTreeStmt* stmt, GenTree* tree)
{
if (fgStmtListThreaded)
{
@@ -7743,9 +7737,9 @@ void Compiler::gtUpdateTreeAncestorsSideEffects(GenTree* tree)
// Arguments:
// stmt - The statement to update side effects on
-void Compiler::gtUpdateStmtSideEffects(GenTree* stmt)
+void Compiler::gtUpdateStmtSideEffects(GenTreeStmt* stmt)
{
- fgWalkTree(&stmt->gtStmt.gtStmtExpr, fgUpdateSideEffectsPre, fgUpdateSideEffectsPost);
+ fgWalkTree(&stmt->gtStmtExpr, fgUpdateSideEffectsPre, fgUpdateSideEffectsPost);
}
//------------------------------------------------------------------------
@@ -9705,16 +9699,17 @@ void Compiler::gtDispNode(GenTree* tree, IndentStack* indentStack, __in __in_z _
{
if (opts.compDbgInfo)
{
- IL_OFFSET endIL = tree->gtStmt.gtStmtLastILoffs;
+ GenTreeStmt* stmt = tree->AsStmt();
+ IL_OFFSET endIL = stmt->gtStmtLastILoffs;
printf("(IL ");
- if (tree->gtStmt.gtStmtILoffsx == BAD_IL_OFFSET)
+ if (stmt->gtStmtILoffsx == BAD_IL_OFFSET)
{
printf(" ???");
}
else
{
- printf("0x%03X", jitGetILoffs(tree->gtStmt.gtStmtILoffsx));
+ printf("0x%03X", jitGetILoffs(stmt->gtStmtILoffsx));
}
printf("...");
if (endIL == BAD_IL_OFFSET)
@@ -12572,12 +12567,9 @@ GenTree* Compiler::gtTryRemoveBoxUpstreamEffects(GenTree* op, BoxRemovalOptions
assert(op->IsBoxedValue());
// grab related parts for the optimization
- GenTreeBox* box = op->AsBox();
- GenTree* asgStmt = box->gtAsgStmtWhenInlinedBoxValue;
- GenTree* copyStmt = box->gtCopyStmtWhenInlinedBoxValue;
-
- assert(asgStmt->gtOper == GT_STMT);
- assert(copyStmt->gtOper == GT_STMT);
+ GenTreeBox* box = op->AsBox();
+ GenTreeStmt* asgStmt = box->gtAsgStmtWhenInlinedBoxValue;
+ GenTreeStmt* copyStmt = box->gtCopyStmtWhenInlinedBoxValue;
JITDUMP("gtTryRemoveBoxUpstreamEffects: %s to %s of BOX (valuetype)"
" [%06u] (assign/newobj [%06u] copy [%06u])\n",
@@ -12586,7 +12578,7 @@ GenTree* Compiler::gtTryRemoveBoxUpstreamEffects(GenTree* op, BoxRemovalOptions
dspTreeID(asgStmt), dspTreeID(copyStmt));
// If we don't recognize the form of the assign, bail.
- GenTree* asg = asgStmt->gtStmt.gtStmtExpr;
+ GenTree* asg = asgStmt->gtStmtExpr;
if (asg->gtOper != GT_ASG)
{
JITDUMP(" bailing; unexpected assignment op %s\n", GenTree::OpName(asg->gtOper));
@@ -12633,7 +12625,7 @@ GenTree* Compiler::gtTryRemoveBoxUpstreamEffects(GenTree* op, BoxRemovalOptions
}
// If we don't recognize the form of the copy, bail.
- GenTree* copy = copyStmt->gtStmt.gtStmtExpr;
+ GenTree* copy = copyStmt->gtStmtExpr;
if (copy->gtOper != GT_ASG)
{
// GT_RET_EXPR is a tolerable temporary failure.
@@ -12788,7 +12780,7 @@ GenTree* Compiler::gtTryRemoveBoxUpstreamEffects(GenTree* op, BoxRemovalOptions
// value as the copy is fairly cheap and likely
// the optimizer can trim things down to just the
// minimal side effect parts.
- copyStmt->gtStmt.gtStmtExpr = copySrc;
+ copyStmt->gtStmtExpr = copySrc;
JITDUMP(" to scalar read via [%06u]\n", dspTreeID(copySrc));
}
else
@@ -12797,7 +12789,7 @@ GenTree* Compiler::gtTryRemoveBoxUpstreamEffects(GenTree* op, BoxRemovalOptions
// source struct; there's no need to read the
// entire thing, and no place to put it.
assert(copySrc->gtOper == GT_OBJ || copySrc->gtOper == GT_IND || copySrc->gtOper == GT_FIELD);
- copyStmt->gtStmt.gtStmtExpr = copySrc;
+ copyStmt->gtStmtExpr = copySrc;
if (options == BR_REMOVE_AND_NARROW || options == BR_REMOVE_AND_NARROW_WANT_TYPE_HANDLE)
{
@@ -12950,11 +12942,11 @@ GenTree* Compiler::gtOptimizeEnumHasFlag(GenTree* thisOp, GenTree* flagOp)
}
else
{
- const unsigned thisTmp = lvaGrabTemp(true DEBUGARG("Enum:HasFlag this temp"));
- GenTree* thisAsg = gtNewTempAssign(thisTmp, thisVal);
- GenTree* thisAsgStmt = thisOp->AsBox()->gtCopyStmtWhenInlinedBoxValue;
- thisAsgStmt->gtStmt.gtStmtExpr = thisAsg;
- thisValOpt = gtNewLclvNode(thisTmp, type);
+ const unsigned thisTmp = lvaGrabTemp(true DEBUGARG("Enum:HasFlag this temp"));
+ GenTree* thisAsg = gtNewTempAssign(thisTmp, thisVal);
+ GenTreeStmt* thisAsgStmt = thisOp->AsBox()->gtCopyStmtWhenInlinedBoxValue;
+ thisAsgStmt->gtStmtExpr = thisAsg;
+ thisValOpt = gtNewLclvNode(thisTmp, type);
}
if (flagVal->IsIntegralConst())
@@ -12966,12 +12958,12 @@ GenTree* Compiler::gtOptimizeEnumHasFlag(GenTree* thisOp, GenTree* flagOp)
}
else
{
- const unsigned flagTmp = lvaGrabTemp(true DEBUGARG("Enum:HasFlag flag temp"));
- GenTree* flagAsg = gtNewTempAssign(flagTmp, flagVal);
- GenTree* flagAsgStmt = flagOp->AsBox()->gtCopyStmtWhenInlinedBoxValue;
- flagAsgStmt->gtStmt.gtStmtExpr = flagAsg;
- flagValOpt = gtNewLclvNode(flagTmp, type);
- flagValOptCopy = gtNewLclvNode(flagTmp, type);
+ const unsigned flagTmp = lvaGrabTemp(true DEBUGARG("Enum:HasFlag flag temp"));
+ GenTree* flagAsg = gtNewTempAssign(flagTmp, flagVal);
+ GenTreeStmt* flagAsgStmt = flagOp->AsBox()->gtCopyStmtWhenInlinedBoxValue;
+ flagAsgStmt->gtStmtExpr = flagAsg;
+ flagValOpt = gtNewLclvNode(flagTmp, type);
+ flagValOptCopy = gtNewLclvNode(flagTmp, type);
}
// Turn the call into (thisValTmp & flagTmp) == flagTmp.
@@ -14425,7 +14417,7 @@ DONE:
// May set compFloatingPointUsed.
GenTree* Compiler::gtNewTempAssign(
- unsigned tmp, GenTree* val, GenTree** pAfterStmt, IL_OFFSETX ilOffset, BasicBlock* block)
+ unsigned tmp, GenTree* val, GenTreeStmt** pAfterStmt, IL_OFFSETX ilOffset, BasicBlock* block)
{
// Self-assignment is a nop.
if (val->OperGet() == GT_LCL_VAR && val->gtLclVarCommon.gtLclNum == tmp)
@@ -15157,13 +15149,11 @@ static Compiler::fgWalkResult gtFindLinkCB(GenTree** pTree, Compiler::fgWalkData
return Compiler::WALK_CONTINUE;
}
-GenTree** Compiler::gtFindLink(GenTree* stmt, GenTree* node)
+GenTree** Compiler::gtFindLink(GenTreeStmt* stmt, GenTree* node)
{
- assert(stmt->gtOper == GT_STMT);
-
FindLinkData data = {node, nullptr};
- fgWalkResult result = fgWalkTreePre(&stmt->gtStmt.gtStmtExpr, gtFindLinkCB, &data);
+ fgWalkResult result = fgWalkTreePre(&stmt->gtStmtExpr, gtFindLinkCB, &data);
if (result == WALK_ABORT)
{
diff --git a/src/jit/gentree.h b/src/jit/gentree.h
index 6893c35ce4..5d45427a39 100644
--- a/src/jit/gentree.h
+++ b/src/jit/gentree.h
@@ -2812,14 +2812,14 @@ struct GenTreeBox : public GenTreeUnOp
}
// This is the statement that contains the assignment tree when the node is an inlined GT_BOX on a value
// type
- GenTree* gtAsgStmtWhenInlinedBoxValue;
+ GenTreeStmt* gtAsgStmtWhenInlinedBoxValue;
// And this is the statement that copies from the value being boxed to the box payload
- GenTree* gtCopyStmtWhenInlinedBoxValue;
+ GenTreeStmt* gtCopyStmtWhenInlinedBoxValue;
- GenTreeBox(var_types type,
- GenTree* boxOp,
- GenTree* asgStmtWhenInlinedBoxValue,
- GenTree* copyStmtWhenInlinedBoxValue)
+ GenTreeBox(var_types type,
+ GenTree* boxOp,
+ GenTreeStmt* asgStmtWhenInlinedBoxValue,
+ GenTreeStmt* copyStmtWhenInlinedBoxValue)
: GenTreeUnOp(GT_BOX, type, boxOp)
, gtAsgStmtWhenInlinedBoxValue(asgStmtWhenInlinedBoxValue)
, gtCopyStmtWhenInlinedBoxValue(copyStmtWhenInlinedBoxValue)
diff --git a/src/jit/gtlist.h b/src/jit/gtlist.h
index 2421a8f033..c46bfefd72 100644
--- a/src/jit/gtlist.h
+++ b/src/jit/gtlist.h
@@ -244,8 +244,6 @@ GTNODE(CALL , GenTreeCall ,0,(GTK_SPECIAL|GTK_NOCONTAIN))
//-----------------------------------------------------------------------------
// Statement operator nodes:
//-----------------------------------------------------------------------------
-
-GTNODE(BEG_STMTS , GenTree ,0,(GTK_SPECIAL|GTK_NOVALUE))// used only temporarily in importer by impBegin/EndTreeList()
GTNODE(STMT , GenTreeStmt ,0,(GTK_SPECIAL|GTK_NOVALUE))// top-level list nodes in bbTreeList
GTNODE(RETURN , GenTreeOp ,0,(GTK_UNOP|GTK_NOVALUE)) // return from current function
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index 5e012e3672..a69d5589a9 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -63,12 +63,10 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void Compiler::impInit()
{
-
+ impStmtList = impLastStmt = nullptr;
#ifdef DEBUG
- impTreeList = nullptr;
- impTreeLast = nullptr;
impInlinedCodeSize = 0;
-#endif
+#endif // DEBUG
}
/*****************************************************************************
@@ -409,15 +407,12 @@ void Compiler::impRestoreStackState(SavedStack* savePtr)
}
}
-/*****************************************************************************
- *
- * Get the tree list started for a new basic block.
- */
+//------------------------------------------------------------------------
+// impBeginTreeList: Get the tree list started for a new basic block.
+//
inline void Compiler::impBeginTreeList()
{
- assert(impTreeList == nullptr && impTreeLast == nullptr);
-
- impTreeList = impTreeLast = new (this, GT_BEG_STMTS) GenTree(GT_BEG_STMTS, TYP_VOID);
+ assert(impStmtList == nullptr && impLastStmt == nullptr);
}
/*****************************************************************************
@@ -427,11 +422,8 @@ inline void Compiler::impBeginTreeList()
* directly only for handling CEE_LEAVEs out of finally-protected try's.
*/
-inline void Compiler::impEndTreeList(BasicBlock* block, GenTree* firstStmt, GenTree* lastStmt)
+inline void Compiler::impEndTreeList(BasicBlock* block, GenTreeStmt* firstStmt, GenTreeStmt* lastStmt)
{
- assert(firstStmt->gtOper == GT_STMT);
- assert(lastStmt->gtOper == GT_STMT);
-
/* Make the list circular, so that we can easily walk it backwards */
firstStmt->gtPrev = lastStmt;
@@ -446,42 +438,35 @@ inline void Compiler::impEndTreeList(BasicBlock* block, GenTree* firstStmt, GenT
block->bbFlags |= BBF_IMPORTED;
}
-/*****************************************************************************
- *
- * Store the current tree list in the given basic block.
- */
-
+//------------------------------------------------------------------------
+// impEndTreeList: Store the current tree list in the given basic block.
+//
+// Arguments:
+// block - the basic block to store into.
+//
inline void Compiler::impEndTreeList(BasicBlock* block)
{
- assert(impTreeList->gtOper == GT_BEG_STMTS);
-
- GenTree* firstTree = impTreeList->gtNext;
-
- if (!firstTree)
+ if (impStmtList == nullptr)
{
- /* The block should not already be marked as imported */
+ // The block should not already be marked as imported.
assert((block->bbFlags & BBF_IMPORTED) == 0);
- // Empty block. Just mark it as imported
+ // Empty block. Just mark it as imported.
block->bbFlags |= BBF_IMPORTED;
}
else
{
- // Ignore the GT_BEG_STMTS
- assert(firstTree->gtPrev == impTreeList);
-
- impEndTreeList(block, firstTree, impTreeLast);
+ impEndTreeList(block, impStmtList, impLastStmt);
}
#ifdef DEBUG
if (impLastILoffsStmt != nullptr)
{
- impLastILoffsStmt->gtStmt.gtStmtLastILoffs = compIsForInlining() ? BAD_IL_OFFSET : impCurOpcOffs;
- impLastILoffsStmt = nullptr;
+ impLastILoffsStmt->gtStmtLastILoffs = compIsForInlining() ? BAD_IL_OFFSET : impCurOpcOffs;
+ impLastILoffsStmt = nullptr;
}
-
- impTreeList = impTreeLast = nullptr;
#endif
+ impStmtList = impLastStmt = nullptr;
}
/*****************************************************************************
@@ -490,12 +475,11 @@ inline void Compiler::impEndTreeList(BasicBlock* block)
* that this has only limited value as we can only check [0..chkLevel).
*/
-inline void Compiler::impAppendStmtCheck(GenTree* stmt, unsigned chkLevel)
+inline void Compiler::impAppendStmtCheck(GenTreeStmt* stmt, unsigned chkLevel)
{
#ifndef DEBUG
return;
#else
- assert(stmt->gtOper == GT_STMT);
if (chkLevel == (unsigned)CHECK_SPILL_ALL)
{
@@ -507,7 +491,7 @@ inline void Compiler::impAppendStmtCheck(GenTree* stmt, unsigned chkLevel)
return;
}
- GenTree* tree = stmt->gtStmt.gtStmtExpr;
+ GenTree* tree = stmt->gtStmtExpr;
// Calls can only be appended if there are no GTF_GLOB_EFFECT on the stack
@@ -556,11 +540,8 @@ inline void Compiler::impAppendStmtCheck(GenTree* stmt, unsigned chkLevel)
* interference with stmt and spill if needed.
*/
-inline void Compiler::impAppendStmt(GenTree* stmt, unsigned chkLevel)
+inline void Compiler::impAppendStmt(GenTreeStmt* stmt, unsigned chkLevel)
{
- assert(stmt->gtOper == GT_STMT);
- noway_assert(impTreeLast != nullptr);
-
if (chkLevel == (unsigned)CHECK_SPILL_ALL)
{
chkLevel = verCurrentState.esStackDepth;
@@ -573,7 +554,7 @@ inline void Compiler::impAppendStmt(GenTree* stmt, unsigned chkLevel)
/* If the statement being appended has any side-effects, check the stack
to see if anything needs to be spilled to preserve correct ordering. */
- GenTree* expr = stmt->gtStmt.gtStmtExpr;
+ GenTree* expr = stmt->gtStmtExpr;
unsigned flags = expr->gtFlags & GTF_GLOB_EFFECT;
// Assignment to (unaliased) locals don't count as a side-effect as
@@ -634,14 +615,7 @@ inline void Compiler::impAppendStmt(GenTree* stmt, unsigned chkLevel)
impAppendStmtCheck(stmt, chkLevel);
- /* Point 'prev' at the previous node, so that we can walk backwards */
-
- stmt->gtPrev = impTreeLast;
-
- /* Append the expression statement to the list */
-
- impTreeLast->gtNext = stmt;
- impTreeLast = stmt;
+ impAppendStmt(stmt);
#ifdef FEATURE_SIMD
impMarkContiguousSIMDFieldAssignments(stmt);
@@ -650,7 +624,7 @@ inline void Compiler::impAppendStmt(GenTree* stmt, unsigned chkLevel)
/* Once we set impCurStmtOffs in an appended tree, we are ready to
report the following offsets. So reset impCurStmtOffs */
- if (impTreeLast->gtStmt.gtStmtILoffsx == impCurStmtOffs)
+ if (impLastStmt->gtStmtILoffsx == impCurStmtOffs)
{
impCurStmtOffsSet(BAD_IL_OFFSET);
}
@@ -669,21 +643,62 @@ inline void Compiler::impAppendStmt(GenTree* stmt, unsigned chkLevel)
#endif
}
+//------------------------------------------------------------------------
+// impAppendStmt: Add the statement to the current stmts list.
+//
+// Arguments:
+// stmt - the statement to add.
+//
+inline void Compiler::impAppendStmt(GenTreeStmt* stmt)
+{
+ if (impStmtList == nullptr)
+ {
+ // The stmt is the first in the list.
+ impStmtList = stmt;
+ }
+ else
+ {
+ // Append the expression statement to the existing list.
+ impLastStmt->gtNext = stmt;
+ stmt->gtPrev = impLastStmt;
+ }
+ impLastStmt = stmt;
+}
+
+//------------------------------------------------------------------------
+// impExtractLastStmt: Extract the last statement from the current stmts list.
+//
+// Return Value:
+// The extracted statement.
+//
+// Notes:
+// It assumes that the stmt will be reinserted later.
+//
+GenTreeStmt* Compiler::impExtractLastStmt()
+{
+ assert(impLastStmt != nullptr);
+
+ GenTreeStmt* stmt = impLastStmt;
+ impLastStmt = impLastStmt->gtPrevStmt;
+ if (impLastStmt == nullptr)
+ {
+ impStmtList = nullptr;
+ }
+ return stmt;
+}
+
/*****************************************************************************
*
* Insert the given GT_STMT "stmt" before GT_STMT "stmtBefore"
*/
-inline void Compiler::impInsertStmtBefore(GenTree* stmt, GenTree* stmtBefore)
+inline void Compiler::impInsertStmtBefore(GenTreeStmt* stmt, GenTreeStmt* stmtBefore)
{
- assert(stmt->gtOper == GT_STMT);
- assert(stmtBefore->gtOper == GT_STMT);
-
- GenTree* stmtPrev = stmtBefore->gtPrev;
- stmt->gtPrev = stmtPrev;
- stmt->gtNext = stmtBefore;
- stmtPrev->gtNext = stmt;
- stmtBefore->gtPrev = stmt;
+ GenTreeStmt* stmtPrev = stmtBefore->getPrevStmt();
+ stmt->gtPrev = stmtPrev;
+ stmt->gtNext = stmtBefore;
+ stmtPrev->gtNext = stmt;
+ stmtBefore->gtPrev = stmt;
}
/*****************************************************************************
@@ -692,19 +707,19 @@ inline void Compiler::impInsertStmtBefore(GenTree* stmt, GenTree* stmtBefore)
* Return the newly created statement.
*/
-GenTree* Compiler::impAppendTree(GenTree* tree, unsigned chkLevel, IL_OFFSETX offset)
+GenTreeStmt* Compiler::impAppendTree(GenTree* tree, unsigned chkLevel, IL_OFFSETX offset)
{
assert(tree);
/* Allocate an 'expression statement' node */
- GenTree* expr = gtNewStmt(tree, offset);
+ GenTreeStmt* stmt = gtNewStmt(tree, offset);
/* Append the statement to the current block's stmt list */
- impAppendStmt(expr, chkLevel);
+ impAppendStmt(stmt, chkLevel);
- return expr;
+ return stmt;
}
/*****************************************************************************
@@ -712,17 +727,15 @@ GenTree* Compiler::impAppendTree(GenTree* tree, unsigned chkLevel, IL_OFFSETX of
* Insert the given exression tree before GT_STMT "stmtBefore"
*/
-void Compiler::impInsertTreeBefore(GenTree* tree, IL_OFFSETX offset, GenTree* stmtBefore)
+void Compiler::impInsertTreeBefore(GenTree* tree, IL_OFFSETX offset, GenTreeStmt* stmtBefore)
{
- assert(stmtBefore->gtOper == GT_STMT);
-
/* Allocate an 'expression statement' node */
- GenTree* expr = gtNewStmt(tree, offset);
+ GenTreeStmt* stmt = gtNewStmt(tree, offset);
/* Append the statement to the current block's stmt list */
- impInsertStmtBefore(expr, stmtBefore);
+ impInsertStmtBefore(stmt, stmtBefore);
}
/*****************************************************************************
@@ -731,12 +744,12 @@ void Compiler::impInsertTreeBefore(GenTree* tree, IL_OFFSETX offset, GenTree* st
* curLevel is the stack level for which the spill to the temp is being done.
*/
-void Compiler::impAssignTempGen(unsigned tmp,
- GenTree* val,
- unsigned curLevel,
- GenTree** pAfterStmt, /* = NULL */
- IL_OFFSETX ilOffset, /* = BAD_IL_OFFSET */
- BasicBlock* block /* = NULL */
+void Compiler::impAssignTempGen(unsigned tmp,
+ GenTree* val,
+ unsigned curLevel,
+ GenTreeStmt** pAfterStmt, /* = NULL */
+ IL_OFFSETX ilOffset, /* = BAD_IL_OFFSET */
+ BasicBlock* block /* = NULL */
)
{
GenTree* asg = gtNewTempAssign(tmp, val);
@@ -745,8 +758,8 @@ void Compiler::impAssignTempGen(unsigned tmp,
{
if (pAfterStmt)
{
- GenTree* asgStmt = gtNewStmt(asg, ilOffset);
- *pAfterStmt = fgInsertStmtAfter(block, *pAfterStmt, asgStmt);
+ GenTreeStmt* asgStmt = gtNewStmt(asg, ilOffset);
+ *pAfterStmt = fgInsertStmtAfter(block, *pAfterStmt, asgStmt);
}
else
{
@@ -763,7 +776,7 @@ void Compiler::impAssignTempGen(unsigned tmpNum,
GenTree* val,
CORINFO_CLASS_HANDLE structType,
unsigned curLevel,
- GenTree** pAfterStmt, /* = NULL */
+ GenTreeStmt** pAfterStmt, /* = NULL */
IL_OFFSETX ilOffset, /* = BAD_IL_OFFSET */
BasicBlock* block /* = NULL */
)
@@ -805,8 +818,8 @@ void Compiler::impAssignTempGen(unsigned tmpNum,
{
if (pAfterStmt)
{
- GenTree* asgStmt = gtNewStmt(asg, ilOffset);
- *pAfterStmt = fgInsertStmtAfter(block, *pAfterStmt, asgStmt);
+ GenTreeStmt* asgStmt = gtNewStmt(asg, ilOffset);
+ *pAfterStmt = fgInsertStmtAfter(block, *pAfterStmt, asgStmt);
}
else
{
@@ -1052,13 +1065,13 @@ GenTreeArgList* Compiler::impPopRevList(unsigned count, CORINFO_SIG_INFO* sig, u
// The tree that should be appended to the statement list that represents the assignment.
//
// Notes:
-// Temp assignments may be appended to impTreeList if spilling is necessary.
+// Temp assignments may be appended to impStmtList if spilling is necessary.
GenTree* Compiler::impAssignStruct(GenTree* dest,
GenTree* src,
CORINFO_CLASS_HANDLE structHnd,
unsigned curLevel,
- GenTree** pAfterStmt, /* = nullptr */
+ GenTreeStmt** pAfterStmt, /* = nullptr */
IL_OFFSETX ilOffset, /* = BAD_IL_OFFSET */
BasicBlock* block /* = nullptr */
)
@@ -1131,13 +1144,13 @@ GenTree* Compiler::impAssignStruct(GenTree* dest,
// The tree that should be appended to the statement list that represents the assignment.
//
// Notes:
-// Temp assignments may be appended to impTreeList if spilling is necessary.
+// Temp assignments may be appended to impStmtList if spilling is necessary.
GenTree* Compiler::impAssignStructPtr(GenTree* destAddr,
GenTree* src,
CORINFO_CLASS_HANDLE structHnd,
unsigned curLevel,
- GenTree** pAfterStmt, /* = NULL */
+ GenTreeStmt** pAfterStmt, /* = NULL */
IL_OFFSETX ilOffset, /* = BAD_IL_OFFSET */
BasicBlock* block /* = NULL */
)
@@ -1347,7 +1360,7 @@ GenTree* Compiler::impAssignStructPtr(GenTree* destAddr,
// Insert op1 after '*pAfterStmt'
*pAfterStmt = fgInsertStmtAfter(block, *pAfterStmt, gtNewStmt(src->gtOp.gtOp1, ilOffset));
}
- else if (impTreeLast != nullptr)
+ else if (impLastStmt != nullptr)
{
// Do the side-effect as a separate statement.
impAppendTree(src->gtOp.gtOp1, curLevel, ilOffset);
@@ -1453,17 +1466,17 @@ GenTree* Compiler::impGetStructAddr(GenTree* structVal,
{
assert(structVal->gtOp.gtOp2->gtType == type); // Second thing is the struct
- GenTree* oldTreeLast = impTreeLast;
- structVal->gtOp.gtOp2 = impGetStructAddr(structVal->gtOp.gtOp2, structHnd, curLevel, willDeref);
- structVal->gtType = TYP_BYREF;
+ GenTreeStmt* oldLastStmt = impLastStmt;
+ structVal->gtOp.gtOp2 = impGetStructAddr(structVal->gtOp.gtOp2, structHnd, curLevel, willDeref);
+ structVal->gtType = TYP_BYREF;
- if (oldTreeLast != impTreeLast)
+ if (oldLastStmt != impLastStmt)
{
// Some temp assignment statement was placed on the statement list
// for Op2, but that would be out of order with op1, so we need to
// spill op1 onto the statement list after whatever was last
// before we recursed on Op2 (i.e. before whatever Op2 appended).
- impInsertTreeBefore(structVal->gtOp.gtOp1, impCurStmtOffs, oldTreeLast->gtNext);
+ impInsertTreeBefore(structVal->gtOp.gtOp1, impCurStmtOffs, oldLastStmt->getNextStmt());
structVal->gtOp.gtOp1 = gtNewNothingNode();
}
@@ -2608,7 +2621,7 @@ GenTree* Compiler::impCloneExpr(GenTree* tree,
GenTree** pClone,
CORINFO_CLASS_HANDLE structHnd,
unsigned curLevel,
- GenTree** pAfterStmt DEBUGARG(const char* reason))
+ GenTreeStmt** pAfterStmt DEBUGARG(const char* reason))
{
if (!(tree->gtFlags & GTF_GLOB_EFFECT))
{
@@ -2646,9 +2659,8 @@ inline void Compiler::impCurStmtOffsSet(IL_OFFSET offs)
{
if (compIsForInlining())
{
- GenTree* callStmt = impInlineInfo->iciStmt;
- assert(callStmt->gtOper == GT_STMT);
- impCurStmtOffs = callStmt->gtStmt.gtStmtILoffsx;
+ GenTreeStmt* callStmt = impInlineInfo->iciStmt;
+ impCurStmtOffs = callStmt->gtStmtILoffsx;
}
else
{
@@ -2714,15 +2726,14 @@ void Compiler::impNoteLastILoffs()
// We should have added a statement for the current basic block
// Is this assert correct ?
- assert(impTreeLast);
- assert(impTreeLast->gtOper == GT_STMT);
+ assert(impLastStmt);
- impTreeLast->gtStmt.gtStmtLastILoffs = compIsForInlining() ? BAD_IL_OFFSET : impCurOpcOffs;
+ impLastStmt->gtStmtLastILoffs = compIsForInlining() ? BAD_IL_OFFSET : impCurOpcOffs;
}
else
{
- impLastILoffsStmt->gtStmt.gtStmtLastILoffs = compIsForInlining() ? BAD_IL_OFFSET : impCurOpcOffs;
- impLastILoffsStmt = nullptr;
+ impLastILoffsStmt->gtStmtLastILoffs = compIsForInlining() ? BAD_IL_OFFSET : impCurOpcOffs;
+ impLastILoffsStmt = nullptr;
}
}
@@ -3056,12 +3067,9 @@ GenTree* Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig)
// If it's not then we just return NULL and we don't optimize this call
//
- //
- // It is possible the we don't have any statements in the block yet
- //
- if (impTreeLast->gtOper != GT_STMT)
+ // It is possible the we don't have any statements in the block yet.
+ if (impLastStmt == nullptr)
{
- assert(impTreeLast->gtOper == GT_BEG_STMTS);
return nullptr;
}
@@ -3069,7 +3077,7 @@ GenTree* Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig)
// We start by looking at the last statement, making sure it's an assignment, and
// that the target of the assignment is the array passed to InitializeArray.
//
- GenTree* arrayAssignment = impTreeLast->gtStmt.gtStmtExpr;
+ GenTree* arrayAssignment = impLastStmt->gtStmtExpr;
if ((arrayAssignment->gtOper != GT_ASG) || (arrayAssignment->gtOp.gtOp1->gtOper != GT_LCL_VAR) ||
(arrayLocalNode->gtOper != GT_LCL_VAR) ||
(arrayAssignment->gtOp.gtOp1->gtLclVarCommon.gtLclNum != arrayLocalNode->gtLclVarCommon.gtLclNum))
@@ -4513,7 +4521,7 @@ void Compiler::verConvertBBToThrowVerificationException(BasicBlock* block DEBUGA
#ifdef DEBUG
// we need this since BeginTreeList asserts otherwise
- impTreeList = impTreeLast = nullptr;
+ impStmtList = impLastStmt = nullptr;
block->bbFlags &= ~BBF_IMPORTED;
if (logMsg)
@@ -5806,7 +5814,7 @@ void Compiler::impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken)
GenTree* asg = gtNewTempAssign(impBoxTemp, op1);
- GenTree* asgStmt = impAppendTree(asg, (unsigned)CHECK_SPILL_NONE, impCurStmtOffs);
+ GenTreeStmt* asgStmt = impAppendTree(asg, (unsigned)CHECK_SPILL_NONE, impCurStmtOffs);
op1 = gtNewLclvNode(impBoxTemp, TYP_REF);
op2 = gtNewIconNode(TARGET_POINTER_SIZE, TYP_I_IMPL);
@@ -5847,7 +5855,7 @@ void Compiler::impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken)
impSpillSideEffects(true, (unsigned)CHECK_SPILL_ALL DEBUGARG("impImportAndPushBox"));
// Set up this copy as a second assignment.
- GenTree* copyStmt = impAppendTree(op1, (unsigned)CHECK_SPILL_NONE, impCurStmtOffs);
+ GenTreeStmt* copyStmt = impAppendTree(op1, (unsigned)CHECK_SPILL_NONE, impCurStmtOffs);
op1 = gtNewLclvNode(impBoxTemp, TYP_REF);
@@ -9103,7 +9111,7 @@ void Compiler::impImportLeave(BasicBlock* block)
}
#endif
- GenTree* lastStmt;
+ GenTreeStmt* lastStmt;
if (endCatches)
{
@@ -9113,11 +9121,11 @@ void Compiler::impImportLeave(BasicBlock* block)
}
else
{
- lastStmt = endLFin;
+ lastStmt = endLFin->AsStmt();
}
// note that this sets BBF_IMPORTED on the block
- impEndTreeList(callBlock, endLFin, lastStmt);
+ impEndTreeList(callBlock, endLFin->AsStmt(), lastStmt);
}
step = fgNewBBafter(BBJ_ALWAYS, callBlock, true);
@@ -9194,7 +9202,7 @@ void Compiler::impImportLeave(BasicBlock* block)
}
#endif
- GenTree* lastStmt;
+ GenTreeStmt* lastStmt;
if (endCatches)
{
@@ -9204,10 +9212,10 @@ void Compiler::impImportLeave(BasicBlock* block)
}
else
{
- lastStmt = endLFin;
+ lastStmt = endLFin->AsStmt();
}
- impEndTreeList(finalStep, endLFin, lastStmt);
+ impEndTreeList(finalStep, endLFin->AsStmt(), lastStmt);
finalStep->bbJumpDest = leaveTarget; // this is the ultimate destination of the LEAVE
@@ -16748,7 +16756,7 @@ SPILLSTACK:
// on the stack, its lifetime is hard to determine, simply
// don't reuse such temps.
- GenTree* addStmt = nullptr;
+ GenTreeStmt* addStmt = nullptr;
/* Do the successors of 'block' have any other predecessors ?
We do not want to do some of the optimizations related to multiRef
@@ -16760,14 +16768,9 @@ SPILLSTACK:
{
case BBJ_COND:
- /* Temporarily remove the 'jtrue' from the end of the tree list */
+ addStmt = impExtractLastStmt();
- assert(impTreeLast);
- assert(impTreeLast->gtOper == GT_STMT);
- assert(impTreeLast->gtStmt.gtStmtExpr->gtOper == GT_JTRUE);
-
- addStmt = impTreeLast;
- impTreeLast = impTreeLast->gtPrev;
+ assert(addStmt->gtStmtExpr->gtOper == GT_JTRUE);
/* Note if the next block has more than one ancestor */
@@ -16807,14 +16810,8 @@ SPILLSTACK:
BasicBlock** jmpTab;
unsigned jmpCnt;
- /* Temporarily remove the GT_SWITCH from the end of the tree list */
-
- assert(impTreeLast);
- assert(impTreeLast->gtOper == GT_STMT);
- assert(impTreeLast->gtStmt.gtStmtExpr->gtOper == GT_SWITCH);
-
- addStmt = impTreeLast;
- impTreeLast = impTreeLast->gtPrev;
+ addStmt = impExtractLastStmt();
+ assert(addStmt->gtStmtExpr->gtOper == GT_SWITCH);
jmpCnt = block->bbJumpSwt->bbsCount;
jmpTab = block->bbJumpSwt->bbsDstTab;
@@ -16965,9 +16962,9 @@ SPILLSTACK:
are spilling to the temps already used by a previous block),
we need to spill addStmt */
- if (addStmt && !newTemps && gtHasRef(addStmt->gtStmt.gtStmtExpr, tempNum, false))
+ if (addStmt != nullptr && !newTemps && gtHasRef(addStmt->gtStmtExpr, tempNum, false))
{
- GenTree* addTree = addStmt->gtStmt.gtStmtExpr;
+ GenTree* addTree = addStmt->gtStmtExpr;
if (addTree->gtOper == GT_JTRUE)
{
@@ -17025,7 +17022,7 @@ SPILLSTACK:
/* Put back the 'jtrue'/'switch' if we removed it earlier */
- if (addStmt)
+ if (addStmt != nullptr)
{
impAppendStmt(addStmt, (unsigned)CHECK_SPILL_NONE);
}
@@ -19181,9 +19178,6 @@ BOOL Compiler::impInlineIsGuaranteedThisDerefBeforeAnySideEffects(GenTree* ad
BasicBlock* block = compCurBB;
- GenTree* stmt;
- GenTree* expr;
-
if (block != fgFirstBB)
{
return FALSE;
@@ -19200,10 +19194,9 @@ BOOL Compiler::impInlineIsGuaranteedThisDerefBeforeAnySideEffects(GenTree* ad
return FALSE;
}
- for (stmt = impTreeList->gtNext; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = impStmtList; stmt != nullptr; stmt = stmt->gtNextStmt)
{
- expr = stmt->gtStmt.gtStmtExpr;
-
+ GenTree* expr = stmt->gtStmtExpr;
if (GTF_GLOBALLY_VISIBLE_SIDE_EFFECTS(expr->gtFlags))
{
return FALSE;
diff --git a/src/jit/indirectcalltransformer.cpp b/src/jit/indirectcalltransformer.cpp
index e0782b5b73..44dc345853 100644
--- a/src/jit/indirectcalltransformer.cpp
+++ b/src/jit/indirectcalltransformer.cpp
@@ -333,14 +333,14 @@ private:
//
virtual void CreateCheck()
{
- checkBlock = CreateAndInsertBasicBlock(BBJ_COND, currBlock);
- GenTree* fatPointerMask = new (compiler, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, FAT_POINTER_MASK);
- GenTree* fptrAddressCopy = compiler->gtCloneExpr(fptrAddress);
- GenTree* fatPointerAnd = compiler->gtNewOperNode(GT_AND, TYP_I_IMPL, fptrAddressCopy, fatPointerMask);
- GenTree* zero = new (compiler, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, 0);
- GenTree* fatPointerCmp = compiler->gtNewOperNode(GT_NE, TYP_INT, fatPointerAnd, zero);
- GenTree* jmpTree = compiler->gtNewOperNode(GT_JTRUE, TYP_VOID, fatPointerCmp);
- GenTree* jmpStmt = compiler->fgNewStmtFromTree(jmpTree, stmt->gtStmt.gtStmtILoffsx);
+ checkBlock = CreateAndInsertBasicBlock(BBJ_COND, currBlock);
+ GenTree* fatPointerMask = new (compiler, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, FAT_POINTER_MASK);
+ GenTree* fptrAddressCopy = compiler->gtCloneExpr(fptrAddress);
+ GenTree* fatPointerAnd = compiler->gtNewOperNode(GT_AND, TYP_I_IMPL, fptrAddressCopy, fatPointerMask);
+ GenTree* zero = new (compiler, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, 0);
+ GenTree* fatPointerCmp = compiler->gtNewOperNode(GT_NE, TYP_INT, fatPointerAnd, zero);
+ GenTree* jmpTree = compiler->gtNewOperNode(GT_JTRUE, TYP_VOID, fatPointerCmp);
+ GenTreeStmt* jmpStmt = compiler->fgNewStmtFromTree(jmpTree, stmt->gtStmtILoffsx);
compiler->fgInsertStmtAtEnd(checkBlock, jmpStmt);
}
@@ -350,8 +350,8 @@ private:
//
virtual void CreateThen()
{
- thenBlock = CreateAndInsertBasicBlock(BBJ_ALWAYS, checkBlock);
- GenTree* copyOfOriginalStmt = compiler->gtCloneExpr(stmt)->AsStmt();
+ thenBlock = CreateAndInsertBasicBlock(BBJ_ALWAYS, checkBlock);
+ GenTreeStmt* copyOfOriginalStmt = compiler->gtCloneExpr(stmt)->AsStmt();
compiler->fgInsertStmtAtEnd(thenBlock, copyOfOriginalStmt);
}
@@ -566,8 +566,8 @@ private:
{
const unsigned thisTempNum = compiler->lvaGrabTemp(true DEBUGARG("guarded devirt this temp"));
// lvaSetClass(thisTempNum, ...);
- GenTree* asgTree = compiler->gtNewTempAssign(thisTempNum, thisTree);
- GenTree* asgStmt = compiler->fgNewStmtFromTree(asgTree, stmt->gtStmt.gtStmtILoffsx);
+ GenTree* asgTree = compiler->gtNewTempAssign(thisTempNum, thisTree);
+ GenTreeStmt* asgStmt = compiler->fgNewStmtFromTree(asgTree, stmt->gtStmtILoffsx);
compiler->fgInsertStmtAtEnd(checkBlock, asgStmt);
thisTree = compiler->gtNewLclvNode(thisTempNum, TYP_REF);
@@ -586,9 +586,9 @@ private:
GenTree* targetMethodTable = compiler->gtNewIconEmbClsHndNode(clsHnd);
// Compare and jump to else (which does the indirect call) if NOT equal
- GenTree* methodTableCompare = compiler->gtNewOperNode(GT_NE, TYP_INT, targetMethodTable, methodTable);
- GenTree* jmpTree = compiler->gtNewOperNode(GT_JTRUE, TYP_VOID, methodTableCompare);
- GenTree* jmpStmt = compiler->fgNewStmtFromTree(jmpTree, stmt->gtStmt.gtStmtILoffsx);
+ GenTree* methodTableCompare = compiler->gtNewOperNode(GT_NE, TYP_INT, targetMethodTable, methodTable);
+ GenTree* jmpTree = compiler->gtNewOperNode(GT_JTRUE, TYP_VOID, methodTableCompare);
+ GenTreeStmt* jmpStmt = compiler->fgNewStmtFromTree(jmpTree, stmt->gtStmtILoffsx);
compiler->fgInsertStmtAtEnd(checkBlock, jmpStmt);
}
diff --git a/src/jit/liveness.cpp b/src/jit/liveness.cpp
index 99f4db7da5..e06df340a3 100644
--- a/src/jit/liveness.cpp
+++ b/src/jit/liveness.cpp
@@ -487,7 +487,7 @@ void Compiler::fgPerBlockLocalVarLiveness()
}
else
{
- for (GenTreeStmt* stmt = block->FirstNonPhiDef(); stmt; stmt = stmt->gtNextStmt)
+ for (GenTreeStmt* stmt = block->FirstNonPhiDef(); stmt != nullptr; stmt = stmt->getNextStmt())
{
compCurStmt = stmt;
for (GenTree* node = stmt->gtStmtList; node != nullptr; node = node->gtNext)
@@ -985,7 +985,7 @@ void Compiler::fgExtendDbgLifetimes()
GenTree* initNode = gtNewAssignNode(varNode, zero);
// Create a statement for the initializer, sequence it, and append it to the current BB.
- GenTree* initStmt = gtNewStmt(initNode);
+ GenTreeStmt* initStmt = gtNewStmt(initNode);
gtSetStmtInfo(initStmt);
fgSetStmtSeq(initStmt);
fgInsertStmtNearEnd(block, initStmt);
@@ -1792,8 +1792,7 @@ void Compiler::fgComputeLife(VARSET_TP& life,
VARSET_TP keepAliveVars(VarSetOps::Union(this, volatileVars, compCurBB->bbScope));
noway_assert(VarSetOps::IsSubset(this, keepAliveVars, life));
- noway_assert(compCurStmt->gtOper == GT_STMT);
- noway_assert(endNode || (startNode == compCurStmt->gtStmt.gtStmtExpr));
+ noway_assert(endNode || (startNode == compCurStmt->gtStmtExpr));
// NOTE: Live variable analysis will not work if you try
// to use the result of an assignment node directly!
@@ -2243,7 +2242,7 @@ bool Compiler::fgRemoveDeadStore(GenTree** pTree,
/* This is a "NORMAL" statement with the
* assignment node hanging from the GT_STMT node */
- noway_assert(compCurStmt->gtStmt.gtStmtExpr == asgNode);
+ noway_assert(compCurStmt->gtStmtExpr == asgNode);
JITDUMP("top level assign\n");
/* Check for side effects */
@@ -2290,7 +2289,7 @@ bool Compiler::fgRemoveDeadStore(GenTree** pTree,
/* Replace the assignment statement with the list of side effects */
noway_assert(sideEffList->gtOper != GT_STMT);
- *pTree = compCurStmt->gtStmt.gtStmtExpr = sideEffList;
+ *pTree = compCurStmt->gtStmtExpr = sideEffList;
#ifdef DEBUG
*treeModf = true;
#endif // DEBUG
@@ -2635,7 +2634,7 @@ void Compiler::fgInterBlockLocalVarLiveness()
{
/* Get the first statement in the block */
- GenTree* firstStmt = block->FirstNonPhiDef();
+ GenTreeStmt* firstStmt = block->FirstNonPhiDef();
if (firstStmt == nullptr)
{
@@ -2644,24 +2643,22 @@ void Compiler::fgInterBlockLocalVarLiveness()
/* Walk all the statements of the block backwards - Get the LAST stmt */
- GenTree* nextStmt = block->bbTreeList->gtPrev;
+ GenTreeStmt* nextStmt = block->lastStmt();
do
{
#ifdef DEBUG
bool treeModf = false;
#endif // DEBUG
- noway_assert(nextStmt);
- noway_assert(nextStmt->gtOper == GT_STMT);
+ noway_assert(nextStmt != nullptr);
compCurStmt = nextStmt;
- nextStmt = nextStmt->gtPrev;
+ nextStmt = nextStmt->getPrevStmt();
/* Compute the liveness for each tree node in the statement */
bool stmtInfoDirty = false;
- fgComputeLife(life, compCurStmt->gtStmt.gtStmtExpr, nullptr, volatileVars,
- &stmtInfoDirty DEBUGARG(&treeModf));
+ fgComputeLife(life, compCurStmt->gtStmtExpr, nullptr, volatileVars, &stmtInfoDirty DEBUGARG(&treeModf));
if (stmtInfoDirty)
{
@@ -2674,7 +2671,7 @@ void Compiler::fgInterBlockLocalVarLiveness()
if (verbose && treeModf)
{
printf("\nfgComputeLife modified tree:\n");
- gtDispTree(compCurStmt->gtStmt.gtStmtExpr);
+ gtDispTree(compCurStmt->gtStmtExpr);
printf("\n");
}
#endif // DEBUG
diff --git a/src/jit/loopcloning.cpp b/src/jit/loopcloning.cpp
index f741ff81b7..14ee2d993d 100644
--- a/src/jit/loopcloning.cpp
+++ b/src/jit/loopcloning.cpp
@@ -687,13 +687,13 @@ void LoopCloneContext::CondToStmtInBlock(Compiler* comp
cond = comp->gtNewOperNode(reverse ? GT_NE : GT_EQ, TYP_INT, cond, comp->gtNewIconNode(0));
// Add jmpTrue "cond == 0" to slow path.
- GenTree* stmt = comp->fgNewStmtFromTree(comp->gtNewOperNode(GT_JTRUE, TYP_VOID, cond));
+ GenTreeStmt* stmt = comp->fgNewStmtFromTree(comp->gtNewOperNode(GT_JTRUE, TYP_VOID, cond));
// Add stmt to the block.
comp->fgInsertStmtAtEnd(block, stmt);
// Remorph.
- comp->fgMorphBlockStmt(block, stmt->AsStmt() DEBUGARG("Loop cloning condition"));
+ comp->fgMorphBlockStmt(block, stmt DEBUGARG("Loop cloning condition"));
}
//--------------------------------------------------------------------------------------------------
diff --git a/src/jit/loopcloning.h b/src/jit/loopcloning.h
index d0ec6b6b98..a455377aeb 100644
--- a/src/jit/loopcloning.h
+++ b/src/jit/loopcloning.h
@@ -208,13 +208,13 @@ struct LcMdArrayOptInfo : public LcOptInfo
*/
struct LcJaggedArrayOptInfo : public LcOptInfo
{
- unsigned dim; // "dim" represents upto what level of the rank this optimization applies to.
- // For example, a[i][j][k] could be the jagged array but if "dim" is 2,
- // then this node is treated as though it were a[i][j]
- ArrIndex arrIndex; // ArrIndex representation of the array.
- GenTree* stmt; // "stmt" where the optimization opportunity occurs.
+ unsigned dim; // "dim" represents upto what level of the rank this optimization applies to.
+ // For example, a[i][j][k] could be the jagged array but if "dim" is 2,
+ // then this node is treated as though it were a[i][j]
+ ArrIndex arrIndex; // ArrIndex representation of the array.
+ GenTreeStmt* stmt; // "stmt" where the optimization opportunity occurs.
- LcJaggedArrayOptInfo(ArrIndex& arrIndex, unsigned dim, GenTree* stmt)
+ LcJaggedArrayOptInfo(ArrIndex& arrIndex, unsigned dim, GenTreeStmt* stmt)
: LcOptInfo(this, LcJaggedArray), dim(dim), arrIndex(arrIndex), stmt(stmt)
{
}
diff --git a/src/jit/lsra.h b/src/jit/lsra.h
index 8494699a0d..d1c8697fc9 100644
--- a/src/jit/lsra.h
+++ b/src/jit/lsra.h
@@ -1526,7 +1526,7 @@ private:
#endif // !_TARGET_XARCH_
// This is the main entry point for building the RefPositions for a node.
// These methods return the number of sources.
- int BuildNode(GenTree* stmt);
+ int BuildNode(GenTree* tree);
void getTgtPrefOperands(GenTreeOp* tree, bool& prefOp1, bool& prefOp2);
bool supportsSpecialPutArg();
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp
index 78f43eb101..2369d1eda5 100644
--- a/src/jit/morph.cpp
+++ b/src/jit/morph.cpp
@@ -7715,19 +7715,19 @@ GenTree* Compiler::fgGetStubAddrArg(GenTreeCall* call)
void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCall* recursiveTailCall)
{
assert(recursiveTailCall->IsTailCallConvertibleToLoop());
- GenTree* last = block->lastStmt();
- assert(recursiveTailCall == last->gtStmt.gtStmtExpr);
+ GenTreeStmt* lastStmt = block->lastStmt();
+ assert(recursiveTailCall == lastStmt->gtStmtExpr);
// Transform recursive tail call into a loop.
- GenTree* earlyArgInsertionPoint = last;
- IL_OFFSETX callILOffset = last->gtStmt.gtStmtILoffsx;
+ GenTreeStmt* earlyArgInsertionPoint = lastStmt;
+ IL_OFFSETX callILOffset = lastStmt->gtStmtILoffsx;
// Hoist arg setup statement for the 'this' argument.
GenTree* thisArg = recursiveTailCall->gtCallObjp;
if (thisArg && !thisArg->IsNothingNode() && !thisArg->IsArgPlaceHolderNode())
{
- GenTree* thisArgStmt = gtNewStmt(thisArg, callILOffset);
+ GenTreeStmt* thisArgStmt = gtNewStmt(thisArg, callILOffset);
fgInsertStmtBefore(block, earlyArgInsertionPoint, thisArgStmt);
}
@@ -7770,8 +7770,8 @@ void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCa
// [000057] - A---------- \--* = int
// [000056] D------N---- \--* lclVar int V01 arg1
- GenTree* tmpAssignmentInsertionPoint = last;
- GenTree* paramAssignmentInsertionPoint = last;
+ GenTreeStmt* tmpAssignmentInsertionPoint = lastStmt;
+ GenTreeStmt* paramAssignmentInsertionPoint = lastStmt;
// Process early args. They may contain both setup statements for late args and actual args.
// Early args don't include 'this' arg. We need to account for that so that the call to gtArgEntryByArgNum
@@ -7786,17 +7786,17 @@ void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCa
if ((earlyArg->gtFlags & GTF_LATE_ARG) != 0)
{
// This is a setup node so we need to hoist it.
- GenTree* earlyArgStmt = gtNewStmt(earlyArg, callILOffset);
+ GenTreeStmt* earlyArgStmt = gtNewStmt(earlyArg, callILOffset);
fgInsertStmtBefore(block, earlyArgInsertionPoint, earlyArgStmt);
}
else
{
// This is an actual argument that needs to be assigned to the corresponding caller parameter.
fgArgTabEntry* curArgTabEntry = gtArgEntryByArgNum(recursiveTailCall, earlyArgIndex);
- GenTree* paramAssignStmt =
+ GenTreeStmt* paramAssignStmt =
fgAssignRecursiveCallArgToCallerParam(earlyArg, curArgTabEntry, block, callILOffset,
tmpAssignmentInsertionPoint, paramAssignmentInsertionPoint);
- if ((tmpAssignmentInsertionPoint == last) && (paramAssignStmt != nullptr))
+ if ((tmpAssignmentInsertionPoint == lastStmt) && (paramAssignStmt != nullptr))
{
// All temp assignments will happen before the first param assignment.
tmpAssignmentInsertionPoint = paramAssignStmt;
@@ -7813,11 +7813,11 @@ void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCa
// A late argument is an actual argument that needs to be assigned to the corresponding caller's parameter.
GenTree* lateArg = lateArgs->Current();
fgArgTabEntry* curArgTabEntry = gtArgEntryByLateArgIndex(recursiveTailCall, lateArgIndex);
- GenTree* paramAssignStmt =
+ GenTreeStmt* paramAssignStmt =
fgAssignRecursiveCallArgToCallerParam(lateArg, curArgTabEntry, block, callILOffset,
tmpAssignmentInsertionPoint, paramAssignmentInsertionPoint);
- if ((tmpAssignmentInsertionPoint == last) && (paramAssignStmt != nullptr))
+ if ((tmpAssignmentInsertionPoint == lastStmt) && (paramAssignStmt != nullptr))
{
// All temp assignments will happen before the first param assignment.
tmpAssignmentInsertionPoint = paramAssignStmt;
@@ -7829,10 +7829,10 @@ void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCa
// block won't be in the loop (it's assumed to have no predecessors), we need to update the special local here.
if (!info.compIsStatic && (lvaArg0Var != info.compThisArg))
{
- var_types thisType = lvaTable[info.compThisArg].TypeGet();
- GenTree* arg0 = gtNewLclvNode(lvaArg0Var, thisType);
- GenTree* arg0Assignment = gtNewAssignNode(arg0, gtNewLclvNode(info.compThisArg, thisType));
- GenTree* arg0AssignmentStmt = gtNewStmt(arg0Assignment, callILOffset);
+ var_types thisType = lvaTable[info.compThisArg].TypeGet();
+ GenTree* arg0 = gtNewLclvNode(lvaArg0Var, thisType);
+ GenTree* arg0Assignment = gtNewAssignNode(arg0, gtNewLclvNode(info.compThisArg, thisType));
+ GenTreeStmt* arg0AssignmentStmt = gtNewStmt(arg0Assignment, callILOffset);
fgInsertStmtBefore(block, paramAssignmentInsertionPoint, arg0AssignmentStmt);
}
@@ -7873,15 +7873,15 @@ void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCa
GenTree* zero = gtNewZeroConNode(genActualType(lclType));
init = gtNewAssignNode(lcl, zero);
}
- GenTree* initStmt = gtNewStmt(init, callILOffset);
- fgInsertStmtBefore(block, last, initStmt);
+ GenTreeStmt* initStmt = gtNewStmt(init, callILOffset);
+ fgInsertStmtBefore(block, lastStmt, initStmt);
}
}
}
}
// Remove the call
- fgRemoveStmt(block, last);
+ fgRemoveStmt(block, lastStmt);
// Set the loop edge. Ensure we have a scratch block and then target the
// next block. Loop detection needs to see a pred out of the loop, so
@@ -7910,12 +7910,12 @@ void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCa
// Return Value:
// parameter assignment statement if one was inserted; nullptr otherwise.
-GenTree* Compiler::fgAssignRecursiveCallArgToCallerParam(GenTree* arg,
- fgArgTabEntry* argTabEntry,
- BasicBlock* block,
- IL_OFFSETX callILOffset,
- GenTree* tmpAssignmentInsertionPoint,
- GenTree* paramAssignmentInsertionPoint)
+GenTreeStmt* Compiler::fgAssignRecursiveCallArgToCallerParam(GenTree* arg,
+ fgArgTabEntry* argTabEntry,
+ BasicBlock* block,
+ IL_OFFSETX callILOffset,
+ GenTreeStmt* tmpAssignmentInsertionPoint,
+ GenTreeStmt* paramAssignmentInsertionPoint)
{
// Call arguments should be assigned to temps first and then the temps should be assigned to parameters because
// some argument trees may reference parameters directly.
@@ -7953,7 +7953,7 @@ GenTree* Compiler::fgAssignRecursiveCallArgToCallerParam(GenTree* arg,
// any caller parameters. Some common cases are handled above but we may be able to eliminate
// more temp assignments.
- GenTree* paramAssignStmt = nullptr;
+ GenTreeStmt* paramAssignStmt = nullptr;
if (needToAssignParameter)
{
if (argInTemp == nullptr)
@@ -7961,12 +7961,12 @@ GenTree* Compiler::fgAssignRecursiveCallArgToCallerParam(GenTree* arg,
// The argument is not assigned to a temp. We need to create a new temp and insert an assignment.
// TODO: we can avoid a temp assignment if we can prove that the argument tree
// doesn't involve any caller parameters.
- unsigned tmpNum = lvaGrabTemp(true DEBUGARG("arg temp"));
- lvaTable[tmpNum].lvType = arg->gtType;
- GenTree* tempSrc = arg;
- GenTree* tempDest = gtNewLclvNode(tmpNum, tempSrc->gtType);
- GenTree* tmpAssignNode = gtNewAssignNode(tempDest, tempSrc);
- GenTree* tmpAssignStmt = gtNewStmt(tmpAssignNode, callILOffset);
+ unsigned tmpNum = lvaGrabTemp(true DEBUGARG("arg temp"));
+ lvaTable[tmpNum].lvType = arg->gtType;
+ GenTree* tempSrc = arg;
+ GenTree* tempDest = gtNewLclvNode(tmpNum, tempSrc->gtType);
+ GenTree* tmpAssignNode = gtNewAssignNode(tempDest, tempSrc);
+ GenTreeStmt* tmpAssignStmt = gtNewStmt(tmpAssignNode, callILOffset);
fgInsertStmtBefore(block, tmpAssignmentInsertionPoint, tmpAssignStmt);
argInTemp = gtNewLclvNode(tmpNum, tempSrc->gtType);
}
@@ -8291,7 +8291,7 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call)
assg = fgMorphTree(assg);
// Create the assignment statement and insert it before the current statement.
- GenTree* assgStmt = gtNewStmt(assg, compCurStmt->AsStmt()->gtStmtILoffsx);
+ GenTreeStmt* assgStmt = gtNewStmt(assg, compCurStmt->gtStmtILoffsx);
fgInsertStmtBefore(compCurBB, compCurStmt, assgStmt);
// Return the temp.
@@ -15233,11 +15233,11 @@ bool Compiler::fgFoldConditional(BasicBlock* block)
{
noway_assert(block->bbTreeList && block->bbTreeList->gtPrev);
- GenTree* stmt = block->bbTreeList->gtPrev;
+ GenTreeStmt* lastStmt = block->lastStmt();
- noway_assert(stmt->gtNext == nullptr);
+ noway_assert(lastStmt->gtNext == nullptr);
- if (stmt->gtStmt.gtStmtExpr->gtOper == GT_CALL)
+ if (lastStmt->gtStmtExpr->gtOper == GT_CALL)
{
noway_assert(fgRemoveRestOfBlock);
@@ -15260,13 +15260,13 @@ bool Compiler::fgFoldConditional(BasicBlock* block)
goto DONE_COND;
}
- noway_assert(stmt->gtStmt.gtStmtExpr->gtOper == GT_JTRUE);
+ noway_assert(lastStmt->gtStmtExpr->gtOper == GT_JTRUE);
/* Did we fold the conditional */
- noway_assert(stmt->gtStmt.gtStmtExpr->gtOp.gtOp1);
+ noway_assert(lastStmt->gtStmtExpr->gtOp.gtOp1);
GenTree* cond;
- cond = stmt->gtStmt.gtStmtExpr->gtOp.gtOp1;
+ cond = lastStmt->gtStmtExpr->gtOp.gtOp1;
if (cond->OperKind() & GTK_CONST)
{
@@ -15278,7 +15278,7 @@ bool Compiler::fgFoldConditional(BasicBlock* block)
/* remove the statement from bbTreelist - No need to update
* the reference counts since there are no lcl vars */
- fgRemoveStmt(block, stmt);
+ fgRemoveStmt(block, lastStmt);
// block is a BBJ_COND that we are folding the conditional for
// bTaken is the path that will always be taken from block
@@ -15441,11 +15441,11 @@ bool Compiler::fgFoldConditional(BasicBlock* block)
{
noway_assert(block->bbTreeList && block->bbTreeList->gtPrev);
- GenTree* stmt = block->bbTreeList->gtPrev;
+ GenTreeStmt* lastStmt = block->lastStmt();
- noway_assert(stmt->gtNext == nullptr);
+ noway_assert(lastStmt->gtNext == nullptr);
- if (stmt->gtStmt.gtStmtExpr->gtOper == GT_CALL)
+ if (lastStmt->gtStmtExpr->gtOper == GT_CALL)
{
noway_assert(fgRemoveRestOfBlock);
@@ -15475,13 +15475,13 @@ bool Compiler::fgFoldConditional(BasicBlock* block)
goto DONE_SWITCH;
}
- noway_assert(stmt->gtStmt.gtStmtExpr->gtOper == GT_SWITCH);
+ noway_assert(lastStmt->gtStmtExpr->gtOper == GT_SWITCH);
/* Did we fold the conditional */
- noway_assert(stmt->gtStmt.gtStmtExpr->gtOp.gtOp1);
+ noway_assert(lastStmt->gtStmtExpr->gtOp.gtOp1);
GenTree* cond;
- cond = stmt->gtStmt.gtStmtExpr->gtOp.gtOp1;
+ cond = lastStmt->gtStmtExpr->gtOp.gtOp1;
if (cond->OperKind() & GTK_CONST)
{
@@ -15492,7 +15492,7 @@ bool Compiler::fgFoldConditional(BasicBlock* block)
/* remove the statement from bbTreelist - No need to update
* the reference counts since there are no lcl vars */
- fgRemoveStmt(block, stmt);
+ fgRemoveStmt(block, lastStmt);
/* modify the flow graph */
@@ -15718,8 +15718,6 @@ void Compiler::fgMorphStmts(BasicBlock* block, bool* lnot, bool* loadw)
GenTree* prev = nullptr;
for (; stmt != nullptr; prev = stmt->gtStmtExpr, stmt = stmt->gtNextStmt)
{
- assert(stmt->gtOper == GT_STMT);
-
if (fgRemoveRestOfBlock)
{
fgRemoveStmt(block, stmt);
@@ -15883,16 +15881,16 @@ void Compiler::fgMorphStmts(BasicBlock* block, bool* lnot, bool* loadw)
{
if ((block->bbJumpKind == BBJ_COND) || (block->bbJumpKind == BBJ_SWITCH))
{
- GenTree* first = block->bbTreeList;
+ GenTreeStmt* first = block->firstStmt();
noway_assert(first);
- GenTree* last = first->gtPrev;
- noway_assert(last && last->gtNext == nullptr);
- GenTree* lastStmt = last->gtStmt.gtStmtExpr;
+ GenTreeStmt* lastStmt = block->lastStmt();
+ noway_assert(lastStmt && lastStmt->gtNext == nullptr);
+ GenTree* last = lastStmt->gtStmtExpr;
- if (((block->bbJumpKind == BBJ_COND) && (lastStmt->gtOper == GT_JTRUE)) ||
- ((block->bbJumpKind == BBJ_SWITCH) && (lastStmt->gtOper == GT_SWITCH)))
+ if (((block->bbJumpKind == BBJ_COND) && (last->gtOper == GT_JTRUE)) ||
+ ((block->bbJumpKind == BBJ_SWITCH) && (last->gtOper == GT_SWITCH)))
{
- GenTree* op1 = lastStmt->gtOp.gtOp1;
+ GenTree* op1 = last->gtOp.gtOp1;
if (op1->OperKind() & GTK_RELOP)
{
@@ -15900,7 +15898,7 @@ void Compiler::fgMorphStmts(BasicBlock* block, bool* lnot, bool* loadw)
op1->gtFlags &= ~GTF_RELOP_JMP_USED;
}
- last->gtStmt.gtStmtExpr = fgMorphTree(op1);
+ lastStmt->gtStmtExpr = fgMorphTree(op1);
}
}
@@ -16029,8 +16027,8 @@ void Compiler::fgMorphBlocks()
//
// TODO: Need to characterize the last top level stmt of a block ending with BBJ_RETURN.
- GenTree* last = (block->bbTreeList != nullptr) ? block->bbTreeList->gtPrev : nullptr;
- GenTree* ret = (last != nullptr) ? last->gtStmt.gtStmtExpr : nullptr;
+ GenTreeStmt* lastStmt = block->lastStmt();
+ GenTree* ret = (lastStmt != nullptr) ? lastStmt->gtStmtExpr : nullptr;
if ((ret != nullptr) && (ret->OperGet() == GT_RETURN) && ((ret->gtFlags & GTF_RET_MERGED) != 0))
{
@@ -16061,9 +16059,8 @@ void Compiler::fgMorphBlocks()
noway_assert(compMethodHasRetVal());
// This block must be ending with a GT_RETURN
- noway_assert(last != nullptr);
- noway_assert(last->gtOper == GT_STMT);
- noway_assert(last->gtNext == nullptr);
+ noway_assert(lastStmt != nullptr);
+ noway_assert(lastStmt->getNextStmt() == nullptr);
noway_assert(ret != nullptr);
// GT_RETURN must have non-null operand as the method is returning the value assigned to
@@ -16071,42 +16068,41 @@ void Compiler::fgMorphBlocks()
noway_assert(ret->OperGet() == GT_RETURN);
noway_assert(ret->gtGetOp1() != nullptr);
- GenTree* pAfterStatement = last;
- IL_OFFSETX offset = last->AsStmt()->gtStmtILoffsx;
- GenTree* tree =
+ GenTreeStmt* pAfterStatement = lastStmt;
+ IL_OFFSETX offset = lastStmt->gtStmtILoffsx;
+ GenTree* tree =
gtNewTempAssign(genReturnLocal, ret->gtGetOp1(), &pAfterStatement, offset, block);
if (tree->OperIsCopyBlkOp())
{
tree = fgMorphCopyBlock(tree);
}
- if (pAfterStatement == last)
+ if (pAfterStatement == lastStmt)
{
- last->gtStmt.gtStmtExpr = tree;
+ lastStmt->gtStmtExpr = tree;
}
else
{
// gtNewTempAssign inserted additional statements after last
- fgRemoveStmt(block, last);
- last = fgInsertStmtAfter(block, pAfterStatement, gtNewStmt(tree, offset));
+ fgRemoveStmt(block, lastStmt);
+ lastStmt = fgInsertStmtAfter(block, pAfterStatement, gtNewStmt(tree, offset));
}
// make sure that copy-prop ignores this assignment.
- last->gtStmt.gtStmtExpr->gtFlags |= GTF_DONT_CSE;
+ lastStmt->gtStmtExpr->gtFlags |= GTF_DONT_CSE;
}
else if (ret != nullptr && ret->OperGet() == GT_RETURN)
{
// This block ends with a GT_RETURN
- noway_assert(last != nullptr);
- noway_assert(last->gtOper == GT_STMT);
- noway_assert(last->gtNext == nullptr);
+ noway_assert(lastStmt != nullptr);
+ noway_assert(lastStmt->getNextStmt() == nullptr);
// Must be a void GT_RETURN with null operand; delete it as this block branches to oneReturn
// block
noway_assert(ret->TypeGet() == TYP_VOID);
noway_assert(ret->gtGetOp1() == nullptr);
- fgRemoveStmt(block, last);
+ fgRemoveStmt(block, lastStmt);
}
#ifdef DEBUG
if (verbose)
@@ -16459,7 +16455,7 @@ GenTree* Compiler::fgGetTopLevelQmark(GenTree* expr, GenTree** ppDst /* = NULL *
* tmp has the result.
*
*/
-void Compiler::fgExpandQmarkForCastInstOf(BasicBlock* block, GenTree* stmt)
+void Compiler::fgExpandQmarkForCastInstOf(BasicBlock* block, GenTreeStmt* stmt)
{
#ifdef DEBUG
if (verbose)
@@ -16469,7 +16465,7 @@ void Compiler::fgExpandQmarkForCastInstOf(BasicBlock* block, GenTree* stmt)
}
#endif // DEBUG
- GenTree* expr = stmt->gtStmt.gtStmtExpr;
+ GenTree* expr = stmt->gtStmtExpr;
GenTree* dst = nullptr;
GenTree* qmark = fgGetTopLevelQmark(expr, &dst);
@@ -16570,23 +16566,23 @@ void Compiler::fgExpandQmarkForCastInstOf(BasicBlock* block, GenTree* stmt)
// Append cond1 as JTRUE to cond1Block
GenTree* jmpTree = gtNewOperNode(GT_JTRUE, TYP_VOID, condExpr);
- GenTree* jmpStmt = fgNewStmtFromTree(jmpTree, stmt->gtStmt.gtStmtILoffsx);
+ GenTree* jmpStmt = fgNewStmtFromTree(jmpTree, stmt->gtStmtILoffsx);
fgInsertStmtAtEnd(cond1Block, jmpStmt);
// Append cond2 as JTRUE to cond2Block
jmpTree = gtNewOperNode(GT_JTRUE, TYP_VOID, cond2Expr);
- jmpStmt = fgNewStmtFromTree(jmpTree, stmt->gtStmt.gtStmtILoffsx);
+ jmpStmt = fgNewStmtFromTree(jmpTree, stmt->gtStmtILoffsx);
fgInsertStmtAtEnd(cond2Block, jmpStmt);
// AsgBlock should get tmp = op1 assignment.
trueExpr = gtNewTempAssign(dst->AsLclVarCommon()->GetLclNum(), trueExpr);
- GenTree* trueStmt = fgNewStmtFromTree(trueExpr, stmt->gtStmt.gtStmtILoffsx);
+ GenTree* trueStmt = fgNewStmtFromTree(trueExpr, stmt->gtStmtILoffsx);
fgInsertStmtAtEnd(asgBlock, trueStmt);
// Since we are adding helper in the JTRUE false path, reverse the cond2 and add the helper.
gtReverseCond(cond2Expr);
GenTree* helperExpr = gtNewTempAssign(dst->AsLclVarCommon()->GetLclNum(), true2Expr);
- GenTree* helperStmt = fgNewStmtFromTree(helperExpr, stmt->gtStmt.gtStmtILoffsx);
+ GenTree* helperStmt = fgNewStmtFromTree(helperExpr, stmt->gtStmtILoffsx);
fgInsertStmtAtEnd(helperBlock, helperStmt);
// Finally remove the nested qmark stmt.
@@ -16651,9 +16647,9 @@ void Compiler::fgExpandQmarkForCastInstOf(BasicBlock* block, GenTree* stmt)
* If the qmark assigns to a variable, then create tmps for "then"
* and "else" results and assign the temp to the variable as a writeback step.
*/
-void Compiler::fgExpandQmarkStmt(BasicBlock* block, GenTree* stmt)
+void Compiler::fgExpandQmarkStmt(BasicBlock* block, GenTreeStmt* stmt)
{
- GenTree* expr = stmt->gtStmt.gtStmtExpr;
+ GenTree* expr = stmt->gtStmtExpr;
// Retrieve the Qmark node to be expanded.
GenTree* dst = nullptr;
@@ -16785,7 +16781,7 @@ void Compiler::fgExpandQmarkStmt(BasicBlock* block, GenTree* stmt)
}
GenTree* jmpTree = gtNewOperNode(GT_JTRUE, TYP_VOID, qmark->gtGetOp1());
- GenTree* jmpStmt = fgNewStmtFromTree(jmpTree, stmt->gtStmt.gtStmtILoffsx);
+ GenTree* jmpStmt = fgNewStmtFromTree(jmpTree, stmt->gtStmtILoffsx);
fgInsertStmtAtEnd(condBlock, jmpStmt);
// Remove the original qmark statement.
@@ -16811,7 +16807,7 @@ void Compiler::fgExpandQmarkStmt(BasicBlock* block, GenTree* stmt)
{
trueExpr = gtNewTempAssign(lclNum, trueExpr);
}
- GenTree* trueStmt = fgNewStmtFromTree(trueExpr, stmt->gtStmt.gtStmtILoffsx);
+ GenTreeStmt* trueStmt = fgNewStmtFromTree(trueExpr, stmt->gtStmtILoffsx);
fgInsertStmtAtEnd(thenBlock, trueStmt);
}
@@ -16822,7 +16818,7 @@ void Compiler::fgExpandQmarkStmt(BasicBlock* block, GenTree* stmt)
{
falseExpr = gtNewTempAssign(lclNum, falseExpr);
}
- GenTree* falseStmt = fgNewStmtFromTree(falseExpr, stmt->gtStmt.gtStmtILoffsx);
+ GenTreeStmt* falseStmt = fgNewStmtFromTree(falseExpr, stmt->gtStmtILoffsx);
fgInsertStmtAtEnd(elseBlock, falseStmt);
}
@@ -16845,11 +16841,11 @@ void Compiler::fgExpandQmarkNodes()
{
if (compQmarkUsed)
{
- for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
+ for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
{
- for (GenTree* stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- GenTree* expr = stmt->gtStmt.gtStmtExpr;
+ GenTree* expr = stmt->gtStmtExpr;
#ifdef DEBUG
fgPreExpandQmarkChecks(expr);
#endif
@@ -16871,11 +16867,11 @@ void Compiler::fgExpandQmarkNodes()
*/
void Compiler::fgPostExpandQmarkChecks()
{
- for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
+ for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
{
- for (GenTree* stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- GenTree* expr = stmt->gtStmt.gtStmtExpr;
+ GenTree* expr = stmt->gtStmtExpr;
fgWalkTreePre(&expr, Compiler::fgAssertNoQmark, nullptr);
}
}
@@ -18770,9 +18766,9 @@ void Compiler::fgMarkAddressExposedLocals()
// Make the current basic block address available globally
compCurBB = block;
- for (GenTree* stmt = block->bbTreeList; stmt != nullptr; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- visitor.VisitStmt(stmt->AsStmt());
+ visitor.VisitStmt(stmt);
}
}
}
@@ -18794,11 +18790,10 @@ void Compiler::fgMarkAddressExposedLocals()
// if this funciton successfully optimized the stmts, then return true. Otherwise
// return false;
-bool Compiler::fgMorphCombineSIMDFieldAssignments(BasicBlock* block, GenTree* stmt)
+bool Compiler::fgMorphCombineSIMDFieldAssignments(BasicBlock* block, GenTreeStmt* stmt)
{
- noway_assert(stmt->gtOper == GT_STMT);
- GenTree* tree = stmt->gtStmt.gtStmtExpr;
+ GenTree* tree = stmt->gtStmtExpr;
assert(tree->OperGet() == GT_ASG);
GenTree* originalLHS = tree->gtOp.gtOp1;
@@ -18815,15 +18810,15 @@ bool Compiler::fgMorphCombineSIMDFieldAssignments(BasicBlock* block, GenTree* st
return false;
}
- var_types simdType = getSIMDTypeForSize(simdSize);
- int assignmentsCount = simdSize / genTypeSize(baseType) - 1;
- int remainingAssignments = assignmentsCount;
- GenTree* curStmt = stmt->gtNext;
- GenTree* lastStmt = stmt;
+ var_types simdType = getSIMDTypeForSize(simdSize);
+ int assignmentsCount = simdSize / genTypeSize(baseType) - 1;
+ int remainingAssignments = assignmentsCount;
+ GenTreeStmt* curStmt = stmt->getNextStmt();
+ GenTreeStmt* lastStmt = stmt;
while (curStmt != nullptr && remainingAssignments > 0)
{
- GenTree* exp = curStmt->gtStmt.gtStmtExpr;
+ GenTree* exp = curStmt->gtStmtExpr;
if (exp->OperGet() != GT_ASG)
{
break;
@@ -18841,7 +18836,7 @@ bool Compiler::fgMorphCombineSIMDFieldAssignments(BasicBlock* block, GenTree* st
prevRHS = curRHS;
lastStmt = curStmt;
- curStmt = curStmt->gtNext;
+ curStmt = curStmt->getNextStmt();
}
if (remainingAssignments > 0)
@@ -18865,7 +18860,7 @@ bool Compiler::fgMorphCombineSIMDFieldAssignments(BasicBlock* block, GenTree* st
for (int i = 0; i < assignmentsCount; i++)
{
- fgRemoveStmt(block, stmt->gtNext);
+ fgRemoveStmt(block, stmt->getNextStmt());
}
GenTree* copyBlkDst = createAddressNodeForSIMDInit(originalLHS, simdSize);
@@ -18908,12 +18903,12 @@ bool Compiler::fgMorphCombineSIMDFieldAssignments(BasicBlock* block, GenTree* st
GenTree* dstNode = gtNewOperNode(GT_IND, simdType, copyBlkDst);
tree = gtNewAssignNode(dstNode, simdStructNode);
- stmt->gtStmt.gtStmtExpr = tree;
+ stmt->gtStmtExpr = tree;
// Since we generated a new address node which didn't exist before,
// we should expose this address manually here.
LocalAddressVisitor visitor(this);
- visitor.VisitStmt(stmt->AsStmt());
+ visitor.VisitStmt(stmt);
#ifdef DEBUG
if (verbose)
diff --git a/src/jit/optcse.cpp b/src/jit/optcse.cpp
index fd20c77058..31789328c3 100644
--- a/src/jit/optcse.cpp
+++ b/src/jit/optcse.cpp
@@ -394,7 +394,7 @@ void Compiler::optValnumCSE_Init()
// we return that index. There currently is a limit on the number of CSEs
// that we can have of MAX_CSE_CNT (64)
//
-unsigned Compiler::optValnumCSE_Index(GenTree* tree, GenTree* stmt)
+unsigned Compiler::optValnumCSE_Index(GenTree* tree, GenTreeStmt* stmt)
{
unsigned key;
unsigned hash;
@@ -611,11 +611,8 @@ unsigned Compiler::optValnumCSE_Locate()
{
// Locate CSE candidates and assign them indices
- for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
+ for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
{
- GenTree* stmt;
- GenTree* tree;
-
/* Make the block publicly available */
compCurBB = block;
@@ -625,13 +622,11 @@ unsigned Compiler::optValnumCSE_Locate()
noway_assert((block->bbFlags & (BBF_VISITED | BBF_MARKED)) == 0);
/* Walk the statement trees in this basic block */
- for (stmt = block->FirstNonPhiDef(); stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->FirstNonPhiDef(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- noway_assert(stmt->gtOper == GT_STMT);
-
/* We walk the tree in the forwards direction (bottom up) */
bool stmtHasArrLenCandidate = false;
- for (tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
if (tree->OperIsCompare() && stmtHasArrLenCandidate)
{
@@ -998,11 +993,8 @@ void Compiler::optValnumCSE_Availablity()
#endif
EXPSET_TP available_cses = BitVecOps::MakeEmpty(cseTraits);
- for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
+ for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
{
- GenTree* stmt;
- GenTree* tree;
-
// Make the block publicly available
compCurBB = block;
@@ -1015,13 +1007,11 @@ void Compiler::optValnumCSE_Availablity()
// Walk the statement trees in this basic block
- for (stmt = block->FirstNonPhiDef(); stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->FirstNonPhiDef(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- noway_assert(stmt->gtOper == GT_STMT);
-
// We walk the tree in the forwards direction (bottom up)
- for (tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
if (IS_CSE_INDEX(tree->gtCSEnum))
{
@@ -2135,10 +2125,9 @@ public:
do
{
/* Process the next node in the list */
- GenTree* exp = lst->tslTree;
- GenTree* stm = lst->tslStmt;
- noway_assert(stm->gtOper == GT_STMT);
- BasicBlock* blk = lst->tslBlock;
+ GenTree* exp = lst->tslTree;
+ GenTreeStmt* stmt = lst->tslStmt;
+ BasicBlock* blk = lst->tslBlock;
/* Advance to the next node in the list */
lst = lst->tslNext;
@@ -2372,21 +2361,21 @@ public:
// cannot add any new exceptions
}
- // Walk the statement 'stm' and find the pointer
+ // Walk the statement 'stmt' and find the pointer
// in the tree is pointing to 'exp'
//
- GenTree** link = m_pCompiler->gtFindLink(stm, exp);
+ GenTree** link = m_pCompiler->gtFindLink(stmt, exp);
#ifdef DEBUG
if (link == nullptr)
{
printf("\ngtFindLink failed: stm=");
- Compiler::printTreeID(stm);
+ Compiler::printTreeID(stmt);
printf(", exp=");
Compiler::printTreeID(exp);
printf("\n");
printf("stm =");
- m_pCompiler->gtDispTree(stm);
+ m_pCompiler->gtDispTree(stmt);
printf("\n");
printf("exp =");
m_pCompiler->gtDispTree(exp);
@@ -2409,7 +2398,7 @@ public:
assert(m_pCompiler->fgRemoveRestOfBlock == false);
/* re-morph the statement */
- m_pCompiler->fgMorphBlockStmt(blk, stm->AsStmt() DEBUGARG("optValnumCSE"));
+ m_pCompiler->fgMorphBlockStmt(blk, stmt DEBUGARG("optValnumCSE"));
} while (lst != nullptr);
}
@@ -2887,27 +2876,17 @@ void Compiler::optOptimizeCSEs()
void Compiler::optCleanupCSEs()
{
- // We must clear the BBF_VISITED and BBF_MARKED flags
- //
- for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
+ // We must clear the BBF_VISITED and BBF_MARKED flags.
+ for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
{
- // And clear all the "visited" bits on the block
- //
+ // And clear all the "visited" bits on the block.
block->bbFlags &= ~(BBF_VISITED | BBF_MARKED);
- /* Walk the statement trees in this basic block */
-
- GenTree* stmt;
-
- // Initialize 'stmt' to the first non-Phi statement
- stmt = block->FirstNonPhiDef();
-
- for (; stmt; stmt = stmt->gtNext)
+ // Walk the statement trees in this basic block.
+ for (GenTreeStmt* stmt = block->FirstNonPhiDef(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- noway_assert(stmt->gtOper == GT_STMT);
-
- /* We must clear the gtCSEnum field */
- for (GenTree* tree = stmt->gtStmt.gtStmtExpr; tree; tree = tree->gtPrev)
+ // We must clear the gtCSEnum field.
+ for (GenTree* tree = stmt->gtStmtExpr; tree; tree = tree->gtPrev)
{
tree->gtCSEnum = NO_CSE;
}
@@ -2929,18 +2908,12 @@ void Compiler::optEnsureClearCSEInfo()
{
assert((block->bbFlags & (BBF_VISITED | BBF_MARKED)) == 0);
- /* Walk the statement trees in this basic block */
-
- GenTree* stmt;
-
// Initialize 'stmt' to the first non-Phi statement
- stmt = block->FirstNonPhiDef();
-
- for (; stmt; stmt = stmt->gtNext)
+ GenTreeStmt* stmt = block->FirstNonPhiDef();
+ // Walk the statement trees in this basic block
+ for (; stmt != nullptr; stmt = stmt->getNextStmt())
{
- assert(stmt->gtOper == GT_STMT);
-
- for (GenTree* tree = stmt->gtStmt.gtStmtExpr; tree; tree = tree->gtPrev)
+ for (GenTree* tree = stmt->gtStmtExpr; tree; tree = tree->gtPrev)
{
assert(tree->gtCSEnum == NO_CSE);
}
diff --git a/src/jit/optimizer.cpp b/src/jit/optimizer.cpp
index 0be4456d8d..431f4d5ab1 100644
--- a/src/jit/optimizer.cpp
+++ b/src/jit/optimizer.cpp
@@ -925,7 +925,7 @@ bool Compiler::optComputeIterInfo(GenTree* incr, BasicBlock* from, BasicBlock* t
// Arguments:
// testStmt - is the JTRUE statement that is of the form: jmpTrue (Vtmp != 0)
// where Vtmp contains the actual loop test result.
-// newStmt - contains the statement that is the actual test stmt involving
+// newTestStmt - contains the statement that is the actual test stmt involving
// the loop iterator.
//
// Return Value:
@@ -939,9 +939,9 @@ bool Compiler::optComputeIterInfo(GenTree* incr, BasicBlock* from, BasicBlock* t
// This method just retrieves what it thinks is the "test" node,
// the callers are expected to verify that "iterVar" is used in the test.
//
-bool Compiler::optIsLoopTestEvalIntoTemp(GenTree* testStmt, GenTree** newTest)
+bool Compiler::optIsLoopTestEvalIntoTemp(GenTreeStmt* testStmt, GenTreeStmt** newTestStmt)
{
- GenTree* test = testStmt->gtStmt.gtStmtExpr;
+ GenTree* test = testStmt->gtStmtExpr;
if (test->gtOper != GT_JTRUE)
{
@@ -960,13 +960,13 @@ bool Compiler::optIsLoopTestEvalIntoTemp(GenTree* testStmt, GenTree** newTest)
{
// Get the previous statement to get the def (rhs) of Vtmp to see
// if the "test" is evaluated into Vtmp.
- GenTree* prevStmt = testStmt->gtPrev;
+ GenTreeStmt* prevStmt = testStmt->getPrevStmt();
if (prevStmt == nullptr)
{
return false;
}
- GenTree* tree = prevStmt->gtStmt.gtStmtExpr;
+ GenTree* tree = prevStmt->gtStmtExpr;
if (tree->OperGet() == GT_ASG)
{
GenTree* lhs = tree->gtOp.gtOp1;
@@ -977,7 +977,7 @@ bool Compiler::optIsLoopTestEvalIntoTemp(GenTree* testStmt, GenTree** newTest)
{
if (rhs->OperIsCompare())
{
- *newTest = prevStmt;
+ *newTestStmt = prevStmt;
return true;
}
}
@@ -1031,19 +1031,19 @@ bool Compiler::optExtractInitTestIncr(
// Check if last two statements in the loop body are the increment of the iterator
// and the loop termination test.
noway_assert(bottom->bbTreeList != nullptr);
- GenTree* test = bottom->bbTreeList->gtPrev;
- noway_assert(test != nullptr && test->gtNext == nullptr);
+ GenTreeStmt* testStmt = bottom->lastStmt();
+ noway_assert(testStmt != nullptr && testStmt->gtNext == nullptr);
- GenTree* newTest;
- if (optIsLoopTestEvalIntoTemp(test, &newTest))
+ GenTreeStmt* newTestStmt;
+ if (optIsLoopTestEvalIntoTemp(testStmt, &newTestStmt))
{
- test = newTest;
+ testStmt = newTestStmt;
}
- // Check if we have the incr tree before the test tree, if we don't,
+ // Check if we have the incr stmt before the test stmt, if we don't,
// check if incr is part of the loop "top".
- GenTree* incr = test->gtPrev;
- if (incr == nullptr || optIsLoopIncrTree(incr->gtStmt.gtStmtExpr) == BAD_VAR_NUM)
+ GenTreeStmt* incrStmt = testStmt->getPrevStmt();
+ if (incrStmt == nullptr || optIsLoopIncrTree(incrStmt->gtStmtExpr) == BAD_VAR_NUM)
{
if (top == nullptr || top->bbTreeList == nullptr || top->bbTreeList->gtPrev == nullptr)
{
@@ -1051,10 +1051,10 @@ bool Compiler::optExtractInitTestIncr(
}
// If the prev stmt to loop test is not incr, then check if we have loop test evaluated into a tmp.
- GenTree* topLast = top->bbTreeList->gtPrev;
- if (optIsLoopIncrTree(topLast->gtStmt.gtStmtExpr) != BAD_VAR_NUM)
+ GenTreeStmt* toplastStmt = top->lastStmt();
+ if (optIsLoopIncrTree(toplastStmt->gtStmtExpr) != BAD_VAR_NUM)
{
- incr = topLast;
+ incrStmt = toplastStmt;
}
else
{
@@ -1062,21 +1062,21 @@ bool Compiler::optExtractInitTestIncr(
}
}
- assert(test != incr);
+ assert(testStmt != incrStmt);
// Find the last statement in the loop pre-header which we expect to be the initialization of
// the loop iterator.
- GenTree* phdr = head->bbTreeList;
- if (phdr == nullptr)
+ GenTreeStmt* phdrStmt = head->firstStmt();
+ if (phdrStmt == nullptr)
{
return false;
}
- GenTree* init = phdr->gtPrev;
- noway_assert(init != nullptr && (init->gtNext == nullptr));
+ GenTreeStmt* initStmt = phdrStmt->getPrevStmt();
+ noway_assert(initStmt != nullptr && (initStmt->gtNext == nullptr));
// If it is a duplicated loop condition, skip it.
- if (init->gtFlags & GTF_STMT_CMPADD)
+ if (initStmt->gtFlags & GTF_STMT_CMPADD)
{
bool doGetPrev = true;
#ifdef DEBUG
@@ -1084,28 +1084,24 @@ bool Compiler::optExtractInitTestIncr(
{
// Previous optimization passes may have inserted compiler-generated
// statements other than duplicated loop conditions.
- doGetPrev = (init->gtPrev != nullptr);
+ doGetPrev = (initStmt->gtPrev != nullptr);
}
else
{
// Must be a duplicated loop condition.
- noway_assert(init->gtStmt.gtStmtExpr->gtOper == GT_JTRUE);
+ noway_assert(initStmt->gtStmtExpr->gtOper == GT_JTRUE);
}
#endif // DEBUG
if (doGetPrev)
{
- init = init->gtPrev;
+ initStmt = initStmt->getPrevStmt();
}
- noway_assert(init != nullptr);
+ noway_assert(initStmt != nullptr);
}
- noway_assert(init->gtOper == GT_STMT);
- noway_assert(test->gtOper == GT_STMT);
- noway_assert(incr->gtOper == GT_STMT);
-
- *ppInit = init->gtStmt.gtStmtExpr;
- *ppTest = test->gtStmt.gtStmtExpr;
- *ppIncr = incr->gtStmt.gtStmtExpr;
+ *ppInit = initStmt->gtStmtExpr;
+ *ppTest = testStmt->gtStmtExpr;
+ *ppIncr = incrStmt->gtStmtExpr;
return true;
}
@@ -1308,12 +1304,12 @@ bool Compiler::optRecordLoop(BasicBlock* head,
block = block->bbNext;
for (GenTreeStmt* stmt = block->firstStmt(); stmt; stmt = stmt->gtNextStmt)
{
- if (stmt->gtStmt.gtStmtExpr == incr)
+ if (stmt->gtStmtExpr == incr)
{
break;
}
printf("\n");
- gtDispTree(stmt->gtStmt.gtStmtExpr);
+ gtDispTree(stmt->gtStmtExpr);
}
} while (block != bottom);
}
@@ -3796,7 +3792,7 @@ void Compiler::optUnrollLoops()
// Remove the test; we're doing a full unroll.
GenTreeStmt* testCopyStmt = newBlock->lastStmt();
- GenTree* testCopyExpr = testCopyStmt->gtStmt.gtStmtExpr;
+ GenTree* testCopyExpr = testCopyStmt->gtStmtExpr;
assert(testCopyExpr->gtOper == GT_JTRUE);
GenTree* sideEffList = nullptr;
gtExtractSideEffList(testCopyExpr, &sideEffList, GTF_SIDE_EFFECT | GTF_ORDER_SIDEEFF);
@@ -3806,7 +3802,7 @@ void Compiler::optUnrollLoops()
}
else
{
- testCopyStmt->gtStmt.gtStmtExpr = sideEffList;
+ testCopyStmt->gtStmtExpr = sideEffList;
}
newBlock->bbJumpKind = BBJ_NONE;
@@ -4024,21 +4020,21 @@ bool Compiler::optReachWithoutCall(BasicBlock* topBB, BasicBlock* botBB)
* Find the loop termination test at the bottom of the loop
*/
-static GenTree* optFindLoopTermTest(BasicBlock* bottom)
+static GenTreeStmt* optFindLoopTermTest(BasicBlock* bottom)
{
- GenTree* testt = bottom->bbTreeList;
+ GenTreeStmt* testStmt = bottom->firstStmt();
- assert(testt && testt->gtOper == GT_STMT);
+ assert(testStmt);
- GenTree* result = testt->gtPrev;
+ GenTreeStmt* result = testStmt->getPrevStmt();
#ifdef DEBUG
- while (testt->gtNext)
+ while (testStmt->gtNext != nullptr)
{
- testt = testt->gtNext;
+ testStmt = testStmt->getNextStmt();
}
- assert(testt == result);
+ assert(testStmt == result);
#endif
return result;
@@ -4132,7 +4128,7 @@ void Compiler::fgOptWhileLoop(BasicBlock* block)
return;
}
- GenTree* condStmt = optFindLoopTermTest(bTest);
+ GenTreeStmt* condStmt = optFindLoopTermTest(bTest);
// bTest must only contain only a jtrue with no other stmts, we will only clone
// the conditional, so any other statements will not get cloned
@@ -4145,9 +4141,7 @@ void Compiler::fgOptWhileLoop(BasicBlock* block)
/* Get to the condition node from the statement tree */
- noway_assert(condStmt->gtOper == GT_STMT);
-
- GenTree* condTree = condStmt->gtStmt.gtStmtExpr;
+ GenTree* condTree = condStmt->gtStmtExpr;
noway_assert(condTree->gtOper == GT_JTRUE);
condTree = condTree->gtOp.gtOp1;
@@ -4267,13 +4261,13 @@ void Compiler::fgOptWhileLoop(BasicBlock* block)
/* Create a statement entry out of the condition and
append the condition test at the end of 'block' */
- GenTree* copyOfCondStmt = fgInsertStmtAtEnd(block, condTree);
+ GenTreeStmt* copyOfCondStmt = fgInsertStmtAtEnd(block, condTree);
copyOfCondStmt->gtFlags |= GTF_STMT_CMPADD;
if (opts.compDbgInfo)
{
- copyOfCondStmt->gtStmt.gtStmtILoffsx = condStmt->gtStmt.gtStmtILoffsx;
+ copyOfCondStmt->gtStmtILoffsx = condStmt->gtStmtILoffsx;
}
// Flag the block that received the copy as potentially having an array/vtable
@@ -4885,18 +4879,18 @@ bool Compiler::optComputeDerefConditions(unsigned loopNum, LoopCloneContext* con
//
// Arguments:
// block - the block in which the helper call needs to be inserted.
-// insertBefore - the tree before which the helper call will be inserted.
+// insertBefore - the stmt before which the helper call will be inserted.
//
-void Compiler::optDebugLogLoopCloning(BasicBlock* block, GenTree* insertBefore)
+void Compiler::optDebugLogLoopCloning(BasicBlock* block, GenTreeStmt* insertBefore)
{
if (JitConfig.JitDebugLogLoopCloning() == 0)
{
return;
}
- GenTree* logCall = gtNewHelperCallNode(CORINFO_HELP_DEBUG_LOG_LOOP_CLONING, TYP_VOID);
- GenTree* stmt = fgNewStmtFromTree(logCall);
+ GenTree* logCall = gtNewHelperCallNode(CORINFO_HELP_DEBUG_LOG_LOOP_CLONING, TYP_VOID);
+ GenTreeStmt* stmt = fgNewStmtFromTree(logCall);
fgInsertStmtBefore(block, insertBefore, stmt);
- fgMorphBlockStmt(block, stmt->AsStmt() DEBUGARG("Debug log loop cloning"));
+ fgMorphBlockStmt(block, stmt DEBUGARG("Debug log loop cloning"));
}
#endif
@@ -6041,7 +6035,6 @@ bool Compiler::optIsVarAssigned(BasicBlock* beg, BasicBlock* end, GenTree* skip,
for (GenTreeStmt* stmt = beg->firstStmt(); stmt; stmt = stmt->gtNextStmt)
{
- noway_assert(stmt->gtOper == GT_STMT);
if (fgWalkTreePre(&stmt->gtStmtExpr, optIsVarAssgCB, &desc))
{
result = true;
@@ -6104,9 +6097,8 @@ int Compiler::optIsSetAssgLoop(unsigned lnum, ALLVARSET_VALARG_TP vars, varRefKi
{
noway_assert(beg);
- for (GenTreeStmt* stmt = beg->FirstNonPhiDef(); stmt; stmt = stmt->gtNextStmt)
+ for (GenTreeStmt* stmt = beg->FirstNonPhiDef(); stmt != nullptr; stmt = stmt->gtNextStmt)
{
- noway_assert(stmt->gtOper == GT_STMT);
fgWalkTreePre(&stmt->gtStmtExpr, optIsVarAssgCB, &desc);
if (desc.ivaMaskIncomplete)
@@ -6238,7 +6230,7 @@ void Compiler::optPerformHoistExpr(GenTree* origExpr, unsigned lnum)
compCurBB = preHead;
hoist = fgMorphTree(hoist);
- GenTree* hoistStmt = gtNewStmt(hoist);
+ GenTreeStmt* hoistStmt = gtNewStmt(hoist);
hoistStmt->gtFlags |= GTF_STMT_CMPADD;
/* simply append the statement at the end of the preHead's list */
@@ -6699,7 +6691,7 @@ void Compiler::optHoistLoopExprsForBlock(BasicBlock* blk, unsigned lnum, LoopHoi
return;
}
- for (GenTreeStmt* stmt = blk->FirstNonPhiDef(); stmt; stmt = stmt->gtNextStmt)
+ for (GenTreeStmt* stmt = blk->FirstNonPhiDef(); stmt != nullptr; stmt = stmt->getNextStmt())
{
GenTree* stmtTree = stmt->gtStmtExpr;
bool hoistable;
@@ -7337,9 +7329,9 @@ void Compiler::fgCreateLoopPreHeader(unsigned lnum)
// into the phi via the loop header block will now flow through the preheader
// block from the header block.
- for (GenTree* stmt = top->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = top->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- GenTree* tree = stmt->gtStmt.gtStmtExpr;
+ GenTree* tree = stmt->gtStmtExpr;
if (tree->OperGet() != GT_ASG)
{
break;
@@ -7579,9 +7571,9 @@ void Compiler::optComputeLoopSideEffectsOfBlock(BasicBlock* blk)
MemoryKindSet memoryHavoc = emptyMemoryKindSet;
// Now iterate over the remaining statements, and their trees.
- for (GenTree* stmts = blk->FirstNonPhiDef(); (stmts != nullptr); stmts = stmts->gtNext)
+ for (GenTreeStmt* stmt = blk->FirstNonPhiDef(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- for (GenTree* tree = stmts->gtStmt.gtStmtList; (tree != nullptr); tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
genTreeOps oper = tree->OperGet();
@@ -7902,13 +7894,12 @@ void Compiler::AddModifiedElemTypeAllContainingLoops(unsigned lnum, CORINFO_CLAS
// tree - Range check tree
// stmt - Statement the tree belongs to
-void Compiler::optRemoveRangeCheck(GenTree* tree, GenTree* stmt)
+void Compiler::optRemoveRangeCheck(GenTree* tree, GenTreeStmt* stmt)
{
#if !REARRANGE_ADDS
noway_assert(!"can't remove range checks without REARRANGE_ADDS right now");
#endif
- noway_assert(stmt->gtOper == GT_STMT);
noway_assert(tree->gtOper == GT_COMMA);
GenTree* bndsChkTree = tree->gtOp.gtOp1;
@@ -8113,13 +8104,12 @@ bool Compiler::optIdentifyLoopOptInfo(unsigned loopNum, LoopCloneContext* contex
for (BasicBlock* block = beg; block != end->bbNext; block = block->bbNext)
{
compCurBB = block;
- for (GenTree* stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
info.stmt = stmt;
const bool lclVarsOnly = false;
const bool computeStack = false;
- fgWalkTreePre(&stmt->gtStmt.gtStmtExpr, optCanOptimizeByLoopCloningVisitor, &info, lclVarsOnly,
- computeStack);
+ fgWalkTreePre(&stmt->gtStmtExpr, optCanOptimizeByLoopCloningVisitor, &info, lclVarsOnly, computeStack);
}
}
@@ -8581,14 +8571,14 @@ void Compiler::optOptimizeBoolsGcStress(BasicBlock* condBlock)
}
noway_assert(condBlock->bbJumpKind == BBJ_COND);
- GenTree* condStmt = condBlock->bbTreeList->gtPrev->gtStmt.gtStmtExpr;
+ GenTree* cond = condBlock->lastStmt()->gtStmtExpr;
- noway_assert(condStmt->gtOper == GT_JTRUE);
+ noway_assert(cond->gtOper == GT_JTRUE);
bool isBool;
GenTree* relop;
- GenTree* comparand = optIsBoolCond(condStmt, &relop, &isBool);
+ GenTree* comparand = optIsBoolCond(cond, &relop, &isBool);
if (comparand == nullptr || !varTypeIsGC(comparand->TypeGet()))
{
@@ -8793,22 +8783,20 @@ void Compiler::optOptimizeBools()
/* The second block must contain a single statement */
- GenTree* s2 = b2->bbTreeList;
+ GenTreeStmt* s2 = b2->firstStmt();
if (s2->gtPrev != s2)
{
continue;
}
- noway_assert(s2->gtOper == GT_STMT);
- GenTree* t2 = s2->gtStmt.gtStmtExpr;
+ GenTree* t2 = s2->gtStmtExpr;
noway_assert(t2->gtOper == GT_JTRUE);
/* Find the condition for the first block */
- GenTree* s1 = b1->bbTreeList->gtPrev;
+ GenTreeStmt* s1 = b1->lastStmt();
- noway_assert(s1->gtOper == GT_STMT);
- GenTree* t1 = s1->gtStmt.gtStmtExpr;
+ GenTree* t1 = s1->gtStmtExpr;
noway_assert(t1->gtOper == GT_JTRUE);
if (b2->countOfInEdges() > 1)
diff --git a/src/jit/rangecheck.cpp b/src/jit/rangecheck.cpp
index 8255afeecf..96fcaf9561 100644
--- a/src/jit/rangecheck.cpp
+++ b/src/jit/rangecheck.cpp
@@ -188,7 +188,7 @@ bool RangeCheck::BetweenBounds(Range& range, int lower, GenTree* upper)
return false;
}
-void RangeCheck::OptimizeRangeCheck(BasicBlock* block, GenTree* stmt, GenTree* treeParent)
+void RangeCheck::OptimizeRangeCheck(BasicBlock* block, GenTreeStmt* stmt, GenTree* treeParent)
{
// Check if we are dealing with a bounds check node.
if (treeParent->OperGet() != GT_COMMA)
@@ -1257,11 +1257,11 @@ void RangeCheck::MapStmtDefs(const Location& loc)
struct MapMethodDefsData
{
- RangeCheck* rc;
- BasicBlock* block;
- GenTree* stmt;
+ RangeCheck* rc;
+ BasicBlock* block;
+ GenTreeStmt* stmt;
- MapMethodDefsData(RangeCheck* rc, BasicBlock* block, GenTree* stmt) : rc(rc), block(block), stmt(stmt)
+ MapMethodDefsData(RangeCheck* rc, BasicBlock* block, GenTreeStmt* stmt) : rc(rc), block(block), stmt(stmt)
{
}
};
@@ -1282,12 +1282,12 @@ Compiler::fgWalkResult MapMethodDefsVisitor(GenTree** ptr, Compiler::fgWalkData*
void RangeCheck::MapMethodDefs()
{
// First, gather where all definitions occur in the program and store it in a map.
- for (BasicBlock* block = m_pCompiler->fgFirstBB; block; block = block->bbNext)
+ for (BasicBlock* block = m_pCompiler->fgFirstBB; block != nullptr; block = block->bbNext)
{
- for (GenTree* stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
MapMethodDefsData data(this, block, stmt);
- m_pCompiler->fgWalkTreePre(&stmt->gtStmt.gtStmtExpr, MapMethodDefsVisitor, &data, false, true);
+ m_pCompiler->fgWalkTreePre(&stmt->gtStmtExpr, MapMethodDefsVisitor, &data, false, true);
}
}
m_fMappedDefs = true;
@@ -1313,9 +1313,9 @@ void RangeCheck::OptimizeRangeChecks()
// Walk through trees looking for arrBndsChk node and check if it can be optimized.
for (BasicBlock* block = m_pCompiler->fgFirstBB; block; block = block->bbNext)
{
- for (GenTree* stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree; tree = tree->gtNext)
{
if (IsOverBudget())
{
diff --git a/src/jit/rangecheck.h b/src/jit/rangecheck.h
index 4c580e4739..643273d25d 100644
--- a/src/jit/rangecheck.h
+++ b/src/jit/rangecheck.h
@@ -415,10 +415,10 @@ public:
struct Location
{
BasicBlock* block;
- GenTree* stmt;
+ GenTreeStmt* stmt;
GenTreeLclVarCommon* tree;
GenTree* parent;
- Location(BasicBlock* block, GenTree* stmt, GenTreeLclVarCommon* tree, GenTree* parent)
+ Location(BasicBlock* block, GenTreeStmt* stmt, GenTreeLclVarCommon* tree, GenTree* parent)
: block(block), stmt(stmt), tree(tree), parent(parent)
{
}
@@ -463,7 +463,7 @@ public:
// Given a "tree" node, check if it contains array bounds check node and
// optimize to remove it, if possible. Requires "stmt" and "block" that
// contain the tree.
- void OptimizeRangeCheck(BasicBlock* block, GenTree* stmt, GenTree* tree);
+ void OptimizeRangeCheck(BasicBlock* block, GenTreeStmt* stmt, GenTree* tree);
// Given the index expression try to find its range.
// The range of a variable depends on its rhs which in turn depends on its constituent variables.
diff --git a/src/jit/rationalize.cpp b/src/jit/rationalize.cpp
index d51634b6db..cf5f44acd1 100644
--- a/src/jit/rationalize.cpp
+++ b/src/jit/rationalize.cpp
@@ -228,10 +228,9 @@ void Rationalizer::RewriteIntrinsicAsUserCall(GenTree** use, ArrayStack<GenTree*
#ifdef DEBUG
-void Rationalizer::ValidateStatement(GenTree* tree, BasicBlock* block)
+void Rationalizer::ValidateStatement(GenTreeStmt* stmt, BasicBlock* block)
{
- assert(tree->gtOper == GT_STMT);
- DBEXEC(TRUE, JitTls::GetCompiler()->fgDebugCheckNodeLinks(block, tree));
+ DBEXEC(TRUE, JitTls::GetCompiler()->fgDebugCheckNodeLinks(block, stmt));
}
// sanity checks that apply to all kinds of IR
@@ -241,11 +240,11 @@ void Rationalizer::SanityCheck()
BasicBlock* block;
foreach_block(comp, block)
{
- for (GenTree* statement = block->bbTreeList; statement != nullptr; statement = statement->gtNext)
+ for (GenTreeStmt* statement = block->firstStmt(); statement != nullptr; statement = statement->getNextStmt())
{
ValidateStatement(statement, block);
- for (GenTree* tree = statement->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = statement->gtStmtList; tree; tree = tree->gtNext)
{
// QMARK nodes should have been removed before this phase.
assert(tree->OperGet() != GT_QMARK);
diff --git a/src/jit/rationalize.h b/src/jit/rationalize.h
index 297db3618d..83ec879a74 100644
--- a/src/jit/rationalize.h
+++ b/src/jit/rationalize.h
@@ -15,7 +15,7 @@ public:
Rationalizer(Compiler* comp);
#ifdef DEBUG
- static void ValidateStatement(GenTree* tree, BasicBlock* block);
+ static void ValidateStatement(GenTreeStmt* stmt, BasicBlock* block);
// general purpose sanity checking of de facto standard GenTree
void SanityCheck();
diff --git a/src/jit/simd.cpp b/src/jit/simd.cpp
index af3c568b9a..b4cecb3e20 100644
--- a/src/jit/simd.cpp
+++ b/src/jit/simd.cpp
@@ -2274,13 +2274,13 @@ GenTree* Compiler::createAddressNodeForSIMDInit(GenTree* tree, unsigned simdSize
// Arguments:
// stmt - GenTree*. Input statement node.
-void Compiler::impMarkContiguousSIMDFieldAssignments(GenTree* stmt)
+void Compiler::impMarkContiguousSIMDFieldAssignments(GenTreeStmt* stmt)
{
if (!featureSIMD || opts.OptimizationDisabled())
{
return;
}
- GenTree* expr = stmt->gtStmt.gtStmtExpr;
+ GenTree* expr = stmt->gtStmtExpr;
if (expr->OperGet() == GT_ASG && expr->TypeGet() == TYP_FLOAT)
{
GenTree* curDst = expr->gtOp.gtOp1;
@@ -2300,7 +2300,7 @@ void Compiler::impMarkContiguousSIMDFieldAssignments(GenTree* stmt)
else if (fgPreviousCandidateSIMDFieldAsgStmt != nullptr)
{
assert(index > 0);
- GenTree* prevAsgExpr = fgPreviousCandidateSIMDFieldAsgStmt->gtStmt.gtStmtExpr;
+ GenTree* prevAsgExpr = fgPreviousCandidateSIMDFieldAsgStmt->gtStmtExpr;
GenTree* prevDst = prevAsgExpr->gtOp.gtOp1;
GenTree* prevSrc = prevAsgExpr->gtOp.gtOp2;
if (!areArgumentsContiguous(prevDst, curDst) || !areArgumentsContiguous(prevSrc, curSrc))
diff --git a/src/jit/ssabuilder.cpp b/src/jit/ssabuilder.cpp
index 594e99dbe1..7ad1651449 100644
--- a/src/jit/ssabuilder.cpp
+++ b/src/jit/ssabuilder.cpp
@@ -113,7 +113,7 @@ void Compiler::fgResetForSsa()
blk->bbPostOrderNum = 0;
for (GenTreeStmt* stmt = blk->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree != nullptr; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
if (tree->IsLocal())
{
@@ -652,7 +652,7 @@ void SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock* b, const BlkToBlkV
static GenTree* GetPhiNode(BasicBlock* block, unsigned lclNum)
{
// Walk the statements for phi nodes.
- for (GenTree* stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
// A prefix of the statements of the block are phi definition nodes. If we complete processing
// that prefix, exit.
@@ -661,7 +661,7 @@ static GenTree* GetPhiNode(BasicBlock* block, unsigned lclNum)
break;
}
- GenTree* tree = stmt->gtStmt.gtStmtExpr;
+ GenTree* tree = stmt->gtStmtExpr;
GenTree* phiLhs = tree->gtOp.gtOp1;
assert(phiLhs->OperGet() == GT_LCL_VAR);
@@ -756,7 +756,7 @@ void SsaBuilder::InsertPhiFunctions(BasicBlock** postOrder, int count)
GenTree* phiAsg = m_pCompiler->gtNewAssignNode(phiLhs, phiRhs);
- GenTree* stmt = m_pCompiler->fgInsertStmtAtBeg(bbInDomFront, phiAsg);
+ GenTreeStmt* stmt = m_pCompiler->fgInsertStmtAtBeg(bbInDomFront, phiAsg);
m_pCompiler->gtSetStmtInfo(stmt);
m_pCompiler->fgSetStmtSeq(stmt);
}
@@ -991,7 +991,7 @@ void SsaBuilder::AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigne
bool phiFound = false;
#endif
// A prefix of blocks statements will be SSA definitions. Search those for "lclNum".
- for (GenTree* stmt = handler->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = handler->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
// If the tree is not an SSA def, break out of the loop: we're done.
if (!stmt->IsPhiDefnStmt())
@@ -999,7 +999,7 @@ void SsaBuilder::AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigne
break;
}
- GenTree* tree = stmt->gtStmt.gtStmtExpr;
+ GenTree* tree = stmt->gtStmtExpr;
assert(tree->IsPhiDefn());
@@ -1172,16 +1172,16 @@ void SsaBuilder::BlockRenameVariables(BasicBlock* block, SsaRenameState* pRename
// We need to iterate over phi definitions, to give them SSA names, but we need
// to know which are which, so we don't add phi definitions to handler phi arg lists.
// Statements are phi defns until they aren't.
- bool isPhiDefn = true;
- GenTree* firstNonPhi = block->FirstNonPhiDef();
- for (GenTree* stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
+ bool isPhiDefn = true;
+ GenTreeStmt* firstNonPhi = block->FirstNonPhiDef();
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
if (stmt == firstNonPhi)
{
isPhiDefn = false;
}
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree; tree = tree->gtNext)
{
TreeRenameVariables(tree, block, pRenameState, isPhiDefn);
}
@@ -1239,9 +1239,10 @@ void SsaBuilder::AssignPhiNodeRhsVariables(BasicBlock* block, SsaRenameState* pR
for (BasicBlock* succ : block->GetAllSuccs(m_pCompiler))
{
// Walk the statements for phi nodes.
- for (GenTree* stmt = succ->bbTreeList; stmt != nullptr && stmt->IsPhiDefnStmt(); stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = succ->firstStmt(); stmt != nullptr && stmt->IsPhiDefnStmt();
+ stmt = stmt->getNextStmt())
{
- GenTree* tree = stmt->gtStmt.gtStmtExpr;
+ GenTree* tree = stmt->gtStmtExpr;
assert(tree->IsPhiDefn());
// Get the phi node from GT_ASG.
@@ -1376,9 +1377,9 @@ void SsaBuilder::AssignPhiNodeRhsVariables(BasicBlock* block, SsaRenameState* pR
// For a filter, we consider the filter to be the "real" handler.
BasicBlock* handlerStart = succTry->ExFlowBlock();
- for (GenTree* stmt = handlerStart->bbTreeList; stmt; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = handlerStart->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- GenTree* tree = stmt->gtStmt.gtStmtExpr;
+ GenTree* tree = stmt->gtStmtExpr;
// Check if the first n of the statements are phi nodes. If not, exit.
if (tree->OperGet() != GT_ASG || tree->gtOp.gtOp2 == nullptr ||
diff --git a/src/jit/valuenum.cpp b/src/jit/valuenum.cpp
index 4280d872b0..88fbbcc3f0 100644
--- a/src/jit/valuenum.cpp
+++ b/src/jit/valuenum.cpp
@@ -5759,10 +5759,9 @@ void Compiler::fgValueNumber()
for (BasicBlock* blk = fgFirstBB; blk != nullptr; blk = blk->bbNext)
{
// Now iterate over the block's statements, and their trees.
- for (GenTree* stmts = blk->FirstNonPhiDef(); stmts != nullptr; stmts = stmts->gtNext)
+ for (GenTreeStmt* stmt = blk->FirstNonPhiDef(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- assert(stmts->IsStatement());
- for (GenTree* tree = stmts->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
tree->gtVNPair.SetBoth(ValueNumStore::NoVN);
}
@@ -5925,12 +5924,12 @@ void Compiler::fgValueNumberBlock(BasicBlock* blk)
// First: visit phi's. If "newVNForPhis", give them new VN's. If not,
// first check to see if all phi args have the same value.
- GenTree* firstNonPhi = blk->FirstNonPhiDef();
- for (GenTree* phiDefs = blk->bbTreeList; phiDefs != firstNonPhi; phiDefs = phiDefs->gtNext)
+ GenTreeStmt* firstNonPhi = blk->FirstNonPhiDef();
+ for (GenTreeStmt* phiDefStmt = blk->firstStmt(); phiDefStmt != firstNonPhi; phiDefStmt = phiDefStmt->getNextStmt())
{
// TODO-Cleanup: It has been proposed that we should have an IsPhiDef predicate. We would use it
// in Block::FirstNonPhiDef as well.
- GenTree* phiDef = phiDefs->gtStmt.gtStmtExpr;
+ GenTree* phiDef = phiDefStmt->gtStmtExpr;
assert(phiDef->OperGet() == GT_ASG);
GenTreeLclVarCommon* newSsaVar = phiDef->gtOp.gtOp1->AsLclVarCommon();
@@ -6133,21 +6132,19 @@ void Compiler::fgValueNumberBlock(BasicBlock* blk)
}
// Now iterate over the remaining statements, and their trees.
- for (GenTree* stmt = firstNonPhi; stmt != nullptr; stmt = stmt->gtNext)
+ for (GenTreeStmt* stmt = firstNonPhi; stmt != nullptr; stmt = stmt->getNextStmt())
{
- assert(stmt->IsStatement());
-
#ifdef DEBUG
compCurStmtNum++;
if (verbose)
{
printf("\n***** " FMT_BB ", stmt %d (before)\n", blk->bbNum, compCurStmtNum);
- gtDispTree(stmt->gtStmt.gtStmtExpr);
+ gtDispTree(stmt->gtStmtExpr);
printf("\n");
}
#endif
- for (GenTree* tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
+ for (GenTree* tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
fgValueNumberTree(tree);
}
@@ -6156,7 +6153,7 @@ void Compiler::fgValueNumberBlock(BasicBlock* blk)
if (verbose)
{
printf("\n***** " FMT_BB ", stmt %d (after)\n", blk->bbNum, compCurStmtNum);
- gtDispTree(stmt->gtStmt.gtStmtExpr);
+ gtDispTree(stmt->gtStmtExpr);
printf("\n");
if (stmt->gtNext)
{