diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index f9cf55b8feeecb..b033882343557d 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3949,7 +3949,7 @@ class Compiler static bool gtHasRef(GenTree* tree, unsigned lclNum); - bool gtHasLocalsWithAddrOp(GenTree* tree); + bool gtHasLocalValueWithAddrOp(GenTree* tree); bool gtHasAddressExposedLocals(GenTree* tree); unsigned gtSetCallArgsOrder(CallArgs* args, bool lateArgs, int* callCostEx, int* callCostSz); diff --git a/src/coreclr/jit/fgopt.cpp b/src/coreclr/jit/fgopt.cpp index 8496bd23e6cbbd..bee457be869516 100644 --- a/src/coreclr/jit/fgopt.cpp +++ b/src/coreclr/jit/fgopt.cpp @@ -5817,8 +5817,8 @@ bool Compiler::fgCanMoveFirstStatementIntoPred(bool early, Statement* firstStmt, if (early) { - tree1Flags |= gtHasLocalsWithAddrOp(tree1) ? GTF_GLOB_REF : GTF_EMPTY; - tree2Flags |= gtHasLocalsWithAddrOp(tree2) ? GTF_GLOB_REF : GTF_EMPTY; + tree1Flags |= gtHasLocalValueWithAddrOp(tree1) ? GTF_GLOB_REF : GTF_EMPTY; + tree2Flags |= gtHasLocalValueWithAddrOp(tree2) ? GTF_GLOB_REF : GTF_EMPTY; } // We do not support embedded statements in the terminator node. diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 638ca0ce6db455..c960acf8fb1a95 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -3247,19 +3247,23 @@ GenTree** GenTree::EffectiveUse(GenTree** use) } //------------------------------------------------------------------------------ -// gtHasLocalsWithAddrOp: -// Check if this tree contains locals with lvHasLdAddrOp or -// IsAddressExposed() flags set. Does a full tree walk. +// gtHasLocalValueWithAddrOp: +// Check if this tree contains uses of the value of locals with lvHasLdAddrOp +// or IsAddressExposed() flags set. Does a full tree walk. // // Paramters: // tree - the tree // // Return Value: -// True if any sub tree is such a local. +// True if any sub tree is such a local use. +// +// Remarks: +// Only GT_LCL_VAR and GT_LCL_FLD nodes are considered; addresses of locals +// (GT_LCL_ADDR) and stores to locals are not. // -bool Compiler::gtHasLocalsWithAddrOp(GenTree* tree) +bool Compiler::gtHasLocalValueWithAddrOp(GenTree* tree) { - struct LocalsWithAddrOpVisitor : GenTreeVisitor + struct LocalValueWithAddrOpVisitor : GenTreeVisitor { enum { @@ -3267,13 +3271,18 @@ bool Compiler::gtHasLocalsWithAddrOp(GenTree* tree) DoLclVarsOnly = true, }; - LocalsWithAddrOpVisitor(Compiler* comp) + LocalValueWithAddrOpVisitor(Compiler* comp) : GenTreeVisitor(comp) { } fgWalkResult PreOrderVisit(GenTree** use, GenTree* user) { + if (!(*use)->OperIs(GT_LCL_VAR, GT_LCL_FLD)) + { + return WALK_CONTINUE; + } + LclVarDsc* varDsc = m_compiler->lvaGetDesc((*use)->AsLclVarCommon()); if (varDsc->lvHasLdAddrOp || varDsc->IsAddressExposed()) { @@ -3284,7 +3293,7 @@ bool Compiler::gtHasLocalsWithAddrOp(GenTree* tree) } }; - LocalsWithAddrOpVisitor visitor(this); + LocalValueWithAddrOpVisitor visitor(this); return visitor.WalkTree(&tree, nullptr) == WALK_ABORT; } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 806c8334838b4e..29c72a194877da 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -420,7 +420,7 @@ void Compiler::impAppendStmt(Statement* stmt, unsigned chkLevel, bool checkConsu // We don't mark indirections off of "aliased" locals with GLOB_REF, but they must still be // considered as such in the interference checking. - if (((flags & GTF_GLOB_REF) == 0) && !impIsAddressInLocal(value) && gtHasLocalsWithAddrOp(value)) + if (((flags & GTF_GLOB_REF) == 0) && gtHasLocalValueWithAddrOp(value)) { flags |= GTF_GLOB_REF; } @@ -1843,10 +1843,8 @@ void Compiler::impSpillSideEffect(bool spillGlobEffects, unsigned i DEBUGARG(con GenTree* tree = stackState.esStack[i].val; if ((tree->gtFlags & spillFlags) != 0 || - (spillGlobEffects && // Only consider the following when spillGlobEffects == true - !impIsAddressInLocal(tree) && // No need to spill the LCL_ADDR nodes. - gtHasLocalsWithAddrOp(tree))) // Spill if we still see GT_LCL_VAR that contains lvHasLdAddrOp or - // lvAddrTaken flag. + // Spill if we still see uses of locals that have lvHasLdAddrOp or are address exposed. + (spillGlobEffects && gtHasLocalValueWithAddrOp(tree))) { impSpillStackEntry(i, BAD_VAR_NUM DEBUGARG(false) DEBUGARG(reason)); } @@ -13970,7 +13968,7 @@ void Compiler::impInlineRecordArgInfo(InlineInfo* pInlineInfo, // which is safe in this case. // // Instead mark the arg as having a caller local ref. - if (!argInfo->argIsInvariant && gtHasLocalsWithAddrOp(curArgVal)) + if (gtHasLocalValueWithAddrOp(curArgVal)) { argInfo->argHasCallerLocalRef = true; } diff --git a/src/coreclr/jit/indirectcalltransformer.cpp b/src/coreclr/jit/indirectcalltransformer.cpp index c51ab4d0831295..56c9e953be4dc7 100644 --- a/src/coreclr/jit/indirectcalltransformer.cpp +++ b/src/coreclr/jit/indirectcalltransformer.cpp @@ -221,7 +221,7 @@ class IndirectCallTransformer for (GenTree** use : m_origCall->UseEdges()) { GenTree* node = *use; - if (((node->gtFlags & GTF_ALL_EFFECT) != 0) || m_compiler->gtHasLocalsWithAddrOp(node)) + if (((node->gtFlags & GTF_ALL_EFFECT) != 0) || m_compiler->gtHasLocalValueWithAddrOp(node)) { SpillUseToTemp(block, use); }