Skip to content

Commit b274938

Browse files
authored
JIT: some reworking for conditional escape analysis (#112194)
Reduce the amount of graph walking needed somewhat. Use compile time handles consistently.
1 parent 5148d9a commit b274938

File tree

1 file changed

+39
-37
lines changed

1 file changed

+39
-37
lines changed

src/coreclr/jit/objectalloc.cpp

+39-37
Original file line numberDiff line numberDiff line change
@@ -1840,7 +1840,7 @@ GenTree* ObjectAllocator::IsGuard(BasicBlock* block, GuardInfo* info)
18401840
info->m_local = addr->AsLclVar()->GetLclNum();
18411841
bool isNonNull = false;
18421842
bool isExact = false;
1843-
info->m_type = (CORINFO_CLASS_HANDLE)op2->AsIntCon()->gtIconVal;
1843+
info->m_type = (CORINFO_CLASS_HANDLE)op2->AsIntCon()->gtCompileTimeHandle;
18441844

18451845
JITDUMP("... " FMT_BB " is guard for V%02u\n", block->bbNum, info->m_local);
18461846
return tree;
@@ -2347,10 +2347,10 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info)
23472347
// object in the blocks we intend to clone (and beyond). Verify those have the
23482348
// expected def-use behavior.
23492349
//
2350-
// The goal of all this is to try and ensure that if we rewrite all the T,V,U appeances
2350+
// The goal of all this is to try and ensure that if we rewrite all the T,V,U appearances
23512351
// to new locals in the cloned code we get proper behavior.
23522352
//
2353-
// There is one distingushed local V (info.m_local) that holds the result of the
2353+
// There is one distinguished local V (info.m_local) that holds the result of the
23542354
// initial GDV and is the local tested in subsequent GDVs. It must have a single def.
23552355
//
23562356
// The other locals are either temps T that refer to the allocated object between
@@ -2373,7 +2373,7 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info)
23732373
// Tv's use should be at the def of V.
23742374
//
23752375
// For the U's: all Ui appearances should be dominated by the def of V; all Ui defs
2376-
// should have another Ui or V as their source. (We should also verfy each Ui is
2376+
// should have another Ui or V as their source. (We should also verify each Ui is
23772377
// single-def and the def dominates all the Ui uses, but this may not work out...?)
23782378
//
23792379
// Also we do not expect any Ti or Ui use to be a GDV guard. U's typically arise from
@@ -2422,45 +2422,50 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info)
24222422
BitVecTraits traits(comp->compBasicBlockID, comp);
24232423
BitVec visitedBlocks(BitVecOps::MakeEmpty(&traits));
24242424
toVisit.Push(allocBlock);
2425+
BitVecOps::AddElemD(&traits, visitedBlocks, allocBlock->bbID);
24252426

2426-
// todo -- some kind of runaway size limit
2427+
// We don't expect to have to search very far
24272428
//
2429+
unsigned searchCount = 0;
2430+
unsigned const searchLimit = 25;
2431+
24282432
while (toVisit.Height() > 0)
24292433
{
2430-
BasicBlock* const visitBlock = toVisit.Pop();
2431-
if (!BitVecOps::TryAddElemD(&traits, visitedBlocks, visitBlock->bbID))
2434+
BasicBlock* const block = toVisit.Pop();
2435+
2436+
if (searchCount > searchLimit)
24322437
{
2433-
continue;
2438+
JITDUMP("Too many blocks between alloc and def block\n");
2439+
return false;
24342440
}
24352441

2436-
if (visitBlock != allocBlock)
2442+
if (block != allocBlock)
24372443
{
2438-
visited->push_back(visitBlock);
2444+
visited->push_back(block);
24392445
}
24402446

24412447
// We expect this stretch of blocks to all be in the same EH region.
24422448
//
2443-
if (!BasicBlock::sameEHRegion(allocBlock, visitBlock))
2449+
if (!BasicBlock::sameEHRegion(allocBlock, block))
24442450
{
2445-
JITDUMP("Unexpected: new EH region at " FMT_BB "\n", visitBlock->bbNum);
2451+
JITDUMP("Unexpected: new EH region at " FMT_BB "\n", block->bbNum);
24462452
return false;
24472453
}
24482454

2449-
if (visitBlock == defBlock)
2455+
if (block == defBlock)
24502456
{
24512457
continue;
24522458
}
24532459

2454-
JITDUMP("walking through " FMT_BB "\n", visitBlock->bbNum);
2460+
JITDUMP("walking through " FMT_BB "\n", block->bbNum);
24552461

2456-
for (BasicBlock* const succ : visitBlock->Succs())
2457-
{
2458-
if (BitVecOps::IsMember(&traits, visitedBlocks, succ->bbID))
2462+
block->VisitRegularSuccs(comp, [&](BasicBlock* succ) {
2463+
if (BitVecOps::TryAddElemD(&traits, visitedBlocks, succ->bbID))
24592464
{
2460-
continue;
2465+
toVisit.Push(succ);
24612466
}
2462-
toVisit.Push(succ);
2463-
}
2467+
return BasicBlockVisit::Continue;
2468+
});
24642469
}
24652470

24662471
JITDUMP("def block " FMT_BB " post-dominates allocation site " FMT_BB "\n", defBlock->bbNum, allocBlock->bbNum);
@@ -2617,14 +2622,18 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info)
26172622

26182623
for (EnumeratorVarAppearance* const a : *(ev->m_appearances))
26192624
{
2620-
if (!comp->m_domTree->Dominates(defBlock, a->m_block))
2625+
BasicBlock* const aBlock = a->m_block;
2626+
if (!comp->m_domTree->Dominates(defBlock, aBlock))
26212627
{
26222628
JITDUMP("%sV%02u %s in " FMT_BB " not dominated by def " FMT_BB "\n", ev->m_isUseTemp ? "Use temp" : "",
26232629
lclNum, a->m_isDef ? "def" : "use", a->m_block->bbNum, defBlock->bbNum);
26242630
return false;
26252631
}
26262632

2627-
toVisit.Push(a->m_block);
2633+
if (BitVecOps::TryAddElemD(&traits, visitedBlocks, aBlock->bbID))
2634+
{
2635+
toVisit.Push(aBlock);
2636+
}
26282637
}
26292638
}
26302639

@@ -2637,23 +2646,19 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info)
26372646
//
26382647
while (toVisit.Height() > 0)
26392648
{
2640-
BasicBlock* const visitBlock = toVisit.Pop();
2641-
if (!BitVecOps::TryAddElemD(&traits, visitedBlocks, visitBlock->bbID))
2642-
{
2643-
continue;
2644-
}
2645-
visited->push_back(visitBlock);
2649+
BasicBlock* const block = toVisit.Pop();
2650+
visited->push_back(block);
26462651

26472652
// If we see try region entries here, we will handle them below.
26482653
//
2649-
if (comp->bbIsTryBeg(visitBlock))
2654+
if (comp->bbIsTryBeg(block))
26502655
{
2651-
toVisitTryEntry->push_back(visitBlock);
2656+
toVisitTryEntry->push_back(block);
26522657
}
26532658

2654-
JITDUMP("walking back through " FMT_BB "\n", visitBlock->bbNum);
2659+
JITDUMP("walking back through " FMT_BB "\n", block->bbNum);
26552660

2656-
for (FlowEdge* predEdge = comp->BlockPredsWithEH(visitBlock); predEdge != nullptr;
2661+
for (FlowEdge* predEdge = comp->BlockPredsWithEH(block); predEdge != nullptr;
26572662
predEdge = predEdge->getNextPredEdge())
26582663
{
26592664
BasicBlock* const predBlock = predEdge->getSourceBlock();
@@ -2662,11 +2667,10 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info)
26622667
// (consider eh paths?)
26632668
//
26642669
assert(comp->m_domTree->Dominates(defBlock, predBlock));
2665-
if (BitVecOps::IsMember(&traits, visitedBlocks, predBlock->bbID))
2670+
if (BitVecOps::TryAddElemD(&traits, visitedBlocks, predBlock->bbID))
26662671
{
2667-
continue;
2672+
toVisit.Push(predBlock);
26682673
}
2669-
toVisit.Push(predBlock);
26702674
}
26712675
}
26722676

@@ -2754,8 +2758,6 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info)
27542758

27552759
// Save off blocks that we need to clone
27562760
//
2757-
// TODO: use postorder nums to keeping the vector and bitvec?
2758-
//
27592761
info->m_blocksToClone = visited;
27602762
info->m_blocks = visitedBlocks;
27612763
info->m_canClone = true;

0 commit comments

Comments
 (0)