Skip to content

Commit 63a7a13

Browse files
authored
Don't re-scan previously visited blocks in helperexpansion.cpp (#85201)
1 parent 9a7db55 commit 63a7a13

File tree

2 files changed

+55
-22
lines changed

2 files changed

+55
-22
lines changed

src/coreclr/jit/compiler.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -5305,20 +5305,20 @@ class Compiler
53055305
void SplitTreesRandomly();
53065306
void SplitTreesRemoveCommas();
53075307

5308-
template <bool (Compiler::*ExpansionFunction)(BasicBlock*, Statement*, GenTreeCall*)>
5308+
template <bool (Compiler::*ExpansionFunction)(BasicBlock**, Statement*, GenTreeCall*)>
53095309
PhaseStatus fgExpandHelper(bool skipRarelyRunBlocks);
53105310

5311-
template <bool (Compiler::*ExpansionFunction)(BasicBlock*, Statement*, GenTreeCall*)>
5312-
bool fgExpandHelperForBlock(BasicBlock* block);
5311+
template <bool (Compiler::*ExpansionFunction)(BasicBlock**, Statement*, GenTreeCall*)>
5312+
bool fgExpandHelperForBlock(BasicBlock** pBlock);
53135313

53145314
PhaseStatus fgExpandRuntimeLookups();
5315-
bool fgExpandRuntimeLookupsForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call);
5315+
bool fgExpandRuntimeLookupsForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);
53165316

53175317
PhaseStatus fgExpandThreadLocalAccess();
5318-
bool fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call);
5318+
bool fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);
53195319

53205320
PhaseStatus fgExpandStaticInit();
5321-
bool fgExpandStaticInitForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call);
5321+
bool fgExpandStaticInitForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);
53225322

53235323
PhaseStatus fgInsertGCPolls();
53245324
BasicBlock* fgCreateGCPoll(GCPollType pollType, BasicBlock* block);

src/coreclr/jit/helperexpansion.cpp

+49-16
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,28 @@ PhaseStatus Compiler::fgExpandRuntimeLookups()
9393
return fgExpandHelper<&Compiler::fgExpandRuntimeLookupsForCall>(false);
9494
}
9595

96-
bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call)
96+
//------------------------------------------------------------------------------
97+
// fgExpandRuntimeLookupsForCall : partially expand runtime lookups helper calls
98+
// to add a nullcheck [+ size check] and a fast path
99+
//
100+
// Arguments:
101+
// pBlock - Block containing the helper call to expand. If expansion is performed,
102+
// this is updated to the new block that was an outcome of block splitting.
103+
// stmt - Statement containing the helper call
104+
// call - The helper call
105+
//
106+
// Returns:
107+
// true if a runtime lookup was found and expanded.
108+
//
109+
// Notes:
110+
// The runtime lookup itself is needed to access a handle in code shared between
111+
// generic instantiations. The lookup depends on the typeContext which is only available at
112+
// runtime, and not at compile - time. See ASCII block diagrams in comments below for
113+
// better understanding how this phase expands runtime lookups.
114+
//
115+
bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call)
97116
{
117+
BasicBlock* block = *pBlock;
98118
assert(call->IsHelperCall());
99119

100120
if (!call->IsExpRuntimeLookup())
@@ -150,6 +170,7 @@ bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock* block, Statement* stmt,
150170
GenTree** callUse = nullptr;
151171
Statement* newFirstStmt = nullptr;
152172
block = fgSplitBlockBeforeTree(block, stmt, call, &newFirstStmt, &callUse);
173+
*pBlock = block;
153174
assert(prevBb != nullptr && block != nullptr);
154175

155176
// Block ops inserted by the split need to be morphed here since we are after morph.
@@ -433,9 +454,10 @@ PhaseStatus Compiler::fgExpandThreadLocalAccess()
433454
// that access fields marked with [ThreadLocal].
434455
//
435456
// Arguments:
436-
// block - Block containing the helper call to expand
437-
// stmt - Statement containing the helper call
438-
// call - The helper call
457+
// pBlock - Block containing the helper call to expand. If expansion is performed,
458+
// this is updated to the new block that was an outcome of block splitting.
459+
// stmt - Statement containing the helper call
460+
// call - The helper call
439461
//
440462
//
441463
// Returns:
@@ -450,8 +472,9 @@ PhaseStatus Compiler::fgExpandThreadLocalAccess()
450472
// If the entry is not present, the helper is called, which would make an entry of current static block
451473
// in the cache.
452474
//
453-
bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call)
475+
bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call)
454476
{
477+
BasicBlock* block = *pBlock;
455478
assert(call->IsHelperCall());
456479
if (!call->IsExpTLSFieldAccess())
457480
{
@@ -489,6 +512,7 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* st
489512
Statement* newFirstStmt = nullptr;
490513
DebugInfo debugInfo = stmt->GetDebugInfo();
491514
block = fgSplitBlockBeforeTree(block, stmt, call, &newFirstStmt, &callUse);
515+
*pBlock = block;
492516
assert(prevBb != nullptr && block != nullptr);
493517

494518
// Block ops inserted by the split need to be morphed here since we are after morph.
@@ -682,7 +706,7 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* st
682706
// Returns:
683707
// true if there was any helper that was expanded.
684708
//
685-
template <bool (Compiler::*ExpansionFunction)(BasicBlock*, Statement*, GenTreeCall*)>
709+
template <bool (Compiler::*ExpansionFunction)(BasicBlock**, Statement*, GenTreeCall*)>
686710
PhaseStatus Compiler::fgExpandHelper(bool skipRarelyRunBlocks)
687711
{
688712
PhaseStatus result = PhaseStatus::MODIFIED_NOTHING;
@@ -695,9 +719,14 @@ PhaseStatus Compiler::fgExpandHelper(bool skipRarelyRunBlocks)
695719
}
696720

697721
// Expand and visit the last block again to find more candidates
698-
while (fgExpandHelperForBlock<ExpansionFunction>(block))
722+
INDEBUG(BasicBlock* origBlock = block);
723+
while (fgExpandHelperForBlock<ExpansionFunction>(&block))
699724
{
700725
result = PhaseStatus::MODIFIED_EVERYTHING;
726+
#ifdef DEBUG
727+
assert(origBlock != block);
728+
origBlock = block;
729+
#endif
701730
}
702731
}
703732

@@ -715,16 +744,17 @@ PhaseStatus Compiler::fgExpandHelper(bool skipRarelyRunBlocks)
715744
// invoke `fgExpand` if any of the tree node was a helper call.
716745
//
717746
// Arguments:
718-
// block - block to scan for static initializations
747+
// pBlock - Block containing the helper call to expand. If expansion is performed,
748+
// this is updated to the new block that was an outcome of block splitting.
719749
// fgExpand - function that expands the helper call
720750
//
721751
// Returns:
722752
// true if a helper was expanded
723753
//
724-
template <bool (Compiler::*ExpansionFunction)(BasicBlock*, Statement*, GenTreeCall*)>
725-
bool Compiler::fgExpandHelperForBlock(BasicBlock* block)
754+
template <bool (Compiler::*ExpansionFunction)(BasicBlock**, Statement*, GenTreeCall*)>
755+
bool Compiler::fgExpandHelperForBlock(BasicBlock** pBlock)
726756
{
727-
for (Statement* const stmt : block->NonPhiStatements())
757+
for (Statement* const stmt : (*pBlock)->NonPhiStatements())
728758
{
729759
if ((stmt->GetRootNode()->gtFlags & GTF_CALL) == 0)
730760
{
@@ -739,7 +769,7 @@ bool Compiler::fgExpandHelperForBlock(BasicBlock* block)
739769
continue;
740770
}
741771

742-
if ((this->*ExpansionFunction)(block, stmt, tree->AsCall()))
772+
if ((this->*ExpansionFunction)(pBlock, stmt, tree->AsCall()))
743773
{
744774
return true;
745775
}
@@ -796,15 +826,17 @@ PhaseStatus Compiler::fgExpandStaticInit()
796826
// Also, see fgExpandStaticInit's comments.
797827
//
798828
// Arguments:
799-
// block - call's block
800-
// stmt - call's statement
801-
// call - call that represents a static initialization
829+
// pBlock - Block containing the helper call to expand. If expansion is performed,
830+
// this is updated to the new block that was an outcome of block splitting.
831+
// stmt - Statement containing the helper call
832+
// call - The helper call
802833
//
803834
// Returns:
804835
// true if a static initialization was expanded
805836
//
806-
bool Compiler::fgExpandStaticInitForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call)
837+
bool Compiler::fgExpandStaticInitForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call)
807838
{
839+
BasicBlock* block = *pBlock;
808840
assert(call->IsHelperCall());
809841

810842
bool isGc = false;
@@ -848,6 +880,7 @@ bool Compiler::fgExpandStaticInitForCall(BasicBlock* block, Statement* stmt, Gen
848880
GenTree** callUse = nullptr;
849881
Statement* newFirstStmt = nullptr;
850882
block = fgSplitBlockBeforeTree(block, stmt, call, &newFirstStmt, &callUse);
883+
*pBlock = block;
851884
assert(prevBb != nullptr && block != nullptr);
852885

853886
// Block ops inserted by the split need to be morphed here since we are after morph.

0 commit comments

Comments
 (0)