@@ -1840,7 +1840,7 @@ GenTree* ObjectAllocator::IsGuard(BasicBlock* block, GuardInfo* info)
1840
1840
info->m_local = addr->AsLclVar ()->GetLclNum ();
1841
1841
bool isNonNull = false ;
1842
1842
bool isExact = false ;
1843
- info->m_type = (CORINFO_CLASS_HANDLE)op2->AsIntCon ()->gtIconVal ;
1843
+ info->m_type = (CORINFO_CLASS_HANDLE)op2->AsIntCon ()->gtCompileTimeHandle ;
1844
1844
1845
1845
JITDUMP (" ... " FMT_BB " is guard for V%02u\n " , block->bbNum , info->m_local );
1846
1846
return tree;
@@ -2347,10 +2347,10 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info)
2347
2347
// object in the blocks we intend to clone (and beyond). Verify those have the
2348
2348
// expected def-use behavior.
2349
2349
//
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
2351
2351
// to new locals in the cloned code we get proper behavior.
2352
2352
//
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
2354
2354
// initial GDV and is the local tested in subsequent GDVs. It must have a single def.
2355
2355
//
2356
2356
// The other locals are either temps T that refer to the allocated object between
@@ -2373,7 +2373,7 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info)
2373
2373
// Tv's use should be at the def of V.
2374
2374
//
2375
2375
// 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
2377
2377
// single-def and the def dominates all the Ui uses, but this may not work out...?)
2378
2378
//
2379
2379
// 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)
2422
2422
BitVecTraits traits (comp->compBasicBlockID , comp);
2423
2423
BitVec visitedBlocks (BitVecOps::MakeEmpty (&traits));
2424
2424
toVisit.Push (allocBlock);
2425
+ BitVecOps::AddElemD (&traits, visitedBlocks, allocBlock->bbID );
2425
2426
2426
- // todo -- some kind of runaway size limit
2427
+ // We don't expect to have to search very far
2427
2428
//
2429
+ unsigned searchCount = 0 ;
2430
+ unsigned const searchLimit = 25 ;
2431
+
2428
2432
while (toVisit.Height () > 0 )
2429
2433
{
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)
2432
2437
{
2433
- continue ;
2438
+ JITDUMP (" Too many blocks between alloc and def block\n " );
2439
+ return false ;
2434
2440
}
2435
2441
2436
- if (visitBlock != allocBlock)
2442
+ if (block != allocBlock)
2437
2443
{
2438
- visited->push_back (visitBlock );
2444
+ visited->push_back (block );
2439
2445
}
2440
2446
2441
2447
// We expect this stretch of blocks to all be in the same EH region.
2442
2448
//
2443
- if (!BasicBlock::sameEHRegion (allocBlock, visitBlock ))
2449
+ if (!BasicBlock::sameEHRegion (allocBlock, block ))
2444
2450
{
2445
- JITDUMP (" Unexpected: new EH region at " FMT_BB " \n " , visitBlock ->bbNum );
2451
+ JITDUMP (" Unexpected: new EH region at " FMT_BB " \n " , block ->bbNum );
2446
2452
return false ;
2447
2453
}
2448
2454
2449
- if (visitBlock == defBlock)
2455
+ if (block == defBlock)
2450
2456
{
2451
2457
continue ;
2452
2458
}
2453
2459
2454
- JITDUMP (" walking through " FMT_BB " \n " , visitBlock ->bbNum );
2460
+ JITDUMP (" walking through " FMT_BB " \n " , block ->bbNum );
2455
2461
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 ))
2459
2464
{
2460
- continue ;
2465
+ toVisit. Push (succ) ;
2461
2466
}
2462
- toVisit. Push (succ) ;
2463
- }
2467
+ return BasicBlockVisit::Continue ;
2468
+ });
2464
2469
}
2465
2470
2466
2471
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)
2617
2622
2618
2623
for (EnumeratorVarAppearance* const a : *(ev->m_appearances ))
2619
2624
{
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))
2621
2627
{
2622
2628
JITDUMP (" %sV%02u %s in " FMT_BB " not dominated by def " FMT_BB " \n " , ev->m_isUseTemp ? " Use temp" : " " ,
2623
2629
lclNum, a->m_isDef ? " def" : " use" , a->m_block ->bbNum , defBlock->bbNum );
2624
2630
return false ;
2625
2631
}
2626
2632
2627
- toVisit.Push (a->m_block );
2633
+ if (BitVecOps::TryAddElemD (&traits, visitedBlocks, aBlock->bbID ))
2634
+ {
2635
+ toVisit.Push (aBlock);
2636
+ }
2628
2637
}
2629
2638
}
2630
2639
@@ -2637,23 +2646,19 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info)
2637
2646
//
2638
2647
while (toVisit.Height () > 0 )
2639
2648
{
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);
2646
2651
2647
2652
// If we see try region entries here, we will handle them below.
2648
2653
//
2649
- if (comp->bbIsTryBeg (visitBlock ))
2654
+ if (comp->bbIsTryBeg (block ))
2650
2655
{
2651
- toVisitTryEntry->push_back (visitBlock );
2656
+ toVisitTryEntry->push_back (block );
2652
2657
}
2653
2658
2654
- JITDUMP (" walking back through " FMT_BB " \n " , visitBlock ->bbNum );
2659
+ JITDUMP (" walking back through " FMT_BB " \n " , block ->bbNum );
2655
2660
2656
- for (FlowEdge* predEdge = comp->BlockPredsWithEH (visitBlock ); predEdge != nullptr ;
2661
+ for (FlowEdge* predEdge = comp->BlockPredsWithEH (block ); predEdge != nullptr ;
2657
2662
predEdge = predEdge->getNextPredEdge ())
2658
2663
{
2659
2664
BasicBlock* const predBlock = predEdge->getSourceBlock ();
@@ -2662,11 +2667,10 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info)
2662
2667
// (consider eh paths?)
2663
2668
//
2664
2669
assert (comp->m_domTree ->Dominates (defBlock, predBlock));
2665
- if (BitVecOps::IsMember (&traits, visitedBlocks, predBlock->bbID ))
2670
+ if (BitVecOps::TryAddElemD (&traits, visitedBlocks, predBlock->bbID ))
2666
2671
{
2667
- continue ;
2672
+ toVisit. Push (predBlock) ;
2668
2673
}
2669
- toVisit.Push (predBlock);
2670
2674
}
2671
2675
}
2672
2676
@@ -2754,8 +2758,6 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info)
2754
2758
2755
2759
// Save off blocks that we need to clone
2756
2760
//
2757
- // TODO: use postorder nums to keeping the vector and bitvec?
2758
- //
2759
2761
info->m_blocksToClone = visited;
2760
2762
info->m_blocks = visitedBlocks;
2761
2763
info->m_canClone = true ;
0 commit comments