@@ -70,6 +70,7 @@ using namespace llvm::PatternMatch;
70
70
71
71
STATISTIC (NumBranches, " Number of branches unswitched" );
72
72
STATISTIC (NumSwitches, " Number of switches unswitched" );
73
+ STATISTIC (NumSelects, " Number of selects turned into branches for unswitching" );
73
74
STATISTIC (NumGuards, " Number of guards turned into branches for unswitching" );
74
75
STATISTIC (NumTrivial, " Number of unswitches that are trivial" );
75
76
STATISTIC (
@@ -2552,6 +2553,59 @@ static InstructionCost computeDomSubtreeCost(
2552
2553
return Cost;
2553
2554
}
2554
2555
2556
+ // / Turns a select instruction into implicit control flow branch,
2557
+ // / making the following replacement:
2558
+ // /
2559
+ // / head:
2560
+ // / --code before select--
2561
+ // / select %cond, %trueval, %falseval
2562
+ // / --code after select--
2563
+ // /
2564
+ // / into
2565
+ // /
2566
+ // / head:
2567
+ // / --code before select--
2568
+ // / br i1 %cond, label %then, label %tail
2569
+ // /
2570
+ // / then:
2571
+ // / br %tail
2572
+ // /
2573
+ // / tail:
2574
+ // / phi [ %trueval, %then ], [ %falseval, %head]
2575
+ // / unreachable
2576
+ // /
2577
+ // / It also makes all relevant DT and LI updates, so that all structures are in
2578
+ // / valid state after this transform.
2579
+ static BranchInst *turnSelectIntoBranch (SelectInst *SI, DominatorTree &DT,
2580
+ LoopInfo &LI, MemorySSAUpdater *MSSAU,
2581
+ AssumptionCache *AC) {
2582
+ LLVM_DEBUG (dbgs () << " Turning " << *SI << " into a branch.\n " );
2583
+ BasicBlock *HeadBB = SI->getParent ();
2584
+
2585
+ Value *Cond = SI->getCondition ();
2586
+ if (!isGuaranteedNotToBeUndefOrPoison (Cond, AC, SI, &DT))
2587
+ Cond = new FreezeInst (Cond, Cond->getName () + " .fr" , SI);
2588
+ SplitBlockAndInsertIfThen (SI->getCondition (), SI, false ,
2589
+ SI->getMetadata (LLVMContext::MD_prof), &DT, &LI);
2590
+ auto *CondBr = cast<BranchInst>(HeadBB->getTerminator ());
2591
+ BasicBlock *ThenBB = CondBr->getSuccessor (0 ),
2592
+ *TailBB = CondBr->getSuccessor (1 );
2593
+ if (MSSAU)
2594
+ MSSAU->moveAllAfterSpliceBlocks (HeadBB, TailBB, SI);
2595
+
2596
+ PHINode *Phi = PHINode::Create (SI->getType (), 2 , " unswitched.select" , SI);
2597
+ Phi->addIncoming (SI->getTrueValue (), ThenBB);
2598
+ Phi->addIncoming (SI->getFalseValue (), HeadBB);
2599
+ SI->replaceAllUsesWith (Phi);
2600
+ SI->eraseFromParent ();
2601
+
2602
+ if (MSSAU && VerifyMemorySSA)
2603
+ MSSAU->getMemorySSA ()->verifyMemorySSA ();
2604
+
2605
+ ++NumSelects;
2606
+ return CondBr;
2607
+ }
2608
+
2555
2609
// / Turns a llvm.experimental.guard intrinsic into implicit control flow branch,
2556
2610
// / making the following replacement:
2557
2611
// /
@@ -2663,9 +2717,10 @@ static int CalculateUnswitchCostMultiplier(
2663
2717
BasicBlock *CondBlock = TI.getParent ();
2664
2718
if (DT.dominates (CondBlock, Latch) &&
2665
2719
(isGuard (&TI) ||
2666
- llvm::count_if (successors (&TI), [&L](BasicBlock *SuccBB) {
2667
- return L.contains (SuccBB);
2668
- }) <= 1 )) {
2720
+ (TI.isTerminator () &&
2721
+ llvm::count_if (successors (&TI), [&L](BasicBlock *SuccBB) {
2722
+ return L.contains (SuccBB);
2723
+ }) <= 1 ))) {
2669
2724
NumCostMultiplierSkipped++;
2670
2725
return 1 ;
2671
2726
}
@@ -2674,12 +2729,17 @@ static int CalculateUnswitchCostMultiplier(
2674
2729
int SiblingsCount = (ParentL ? ParentL->getSubLoopsVector ().size ()
2675
2730
: std::distance (LI.begin (), LI.end ()));
2676
2731
// Count amount of clones that all the candidates might cause during
2677
- // unswitching. Branch/guard counts as 1, switch counts as log2 of its cases.
2732
+ // unswitching. Branch/guard/select counts as 1, switch counts as log2 of its
2733
+ // cases.
2678
2734
int UnswitchedClones = 0 ;
2679
2735
for (auto Candidate : UnswitchCandidates) {
2680
2736
Instruction *CI = Candidate.first ;
2681
2737
BasicBlock *CondBlock = CI->getParent ();
2682
2738
bool SkipExitingSuccessors = DT.dominates (CondBlock, Latch);
2739
+ if (isa<SelectInst>(CI)) {
2740
+ UnswitchedClones++;
2741
+ continue ;
2742
+ }
2683
2743
if (isGuard (CI)) {
2684
2744
if (!SkipExitingSuccessors)
2685
2745
UnswitchedClones++;
@@ -2747,14 +2807,19 @@ static bool unswitchBestCondition(
2747
2807
if (LI.getLoopFor (BB) != &L)
2748
2808
continue ;
2749
2809
2750
- if (CollectGuards)
2751
- for (auto &I : *BB)
2752
- if (isGuard (&I)) {
2753
- auto *Cond = cast<IntrinsicInst>(&I)->getArgOperand (0 );
2754
- // TODO: Support AND, OR conditions and partial unswitching.
2755
- if (!isa<Constant>(Cond) && L.isLoopInvariant (Cond))
2756
- UnswitchCandidates.push_back ({&I, {Cond}});
2757
- }
2810
+ for (auto &I : *BB) {
2811
+ if (auto *SI = dyn_cast<SelectInst>(&I)) {
2812
+ auto *Cond = SI->getCondition ();
2813
+ if (!isa<Constant>(Cond) && L.isLoopInvariant (Cond))
2814
+ UnswitchCandidates.push_back ({&I, {Cond}});
2815
+ } else if (CollectGuards && isGuard (&I)) {
2816
+ auto *Cond =
2817
+ skipTrivialSelect (cast<IntrinsicInst>(&I)->getArgOperand (0 ));
2818
+ // TODO: Support AND, OR conditions and partial unswitching.
2819
+ if (!isa<Constant>(Cond) && L.isLoopInvariant (Cond))
2820
+ UnswitchCandidates.push_back ({&I, {Cond}});
2821
+ }
2822
+ }
2758
2823
2759
2824
if (auto *SI = dyn_cast<SwitchInst>(BB->getTerminator ())) {
2760
2825
// We can only consider fully loop-invariant switch conditions as we need
@@ -2953,7 +3018,8 @@ static bool unswitchBestCondition(
2953
3018
// loop. This is computing the new cost of unswitching a condition.
2954
3019
// Note that guards always have 2 unique successors that are implicit and
2955
3020
// will be materialized if we decide to unswitch it.
2956
- int SuccessorsCount = isGuard (&TI) ? 2 : Visited.size ();
3021
+ int SuccessorsCount =
3022
+ isGuard (&TI) || isa<SelectInst>(TI) ? 2 : Visited.size ();
2957
3023
assert (SuccessorsCount > 1 &&
2958
3024
" Cannot unswitch a condition without multiple distinct successors!" );
2959
3025
return (LoopCost - Cost) * (SuccessorsCount - 1 );
@@ -3004,7 +3070,9 @@ static bool unswitchBestCondition(
3004
3070
PartialIVInfo.InstToDuplicate .clear ();
3005
3071
3006
3072
// If the best candidate is a guard, turn it into a branch.
3007
- if (isGuard (BestUnswitchTI))
3073
+ if (auto *SI = dyn_cast<SelectInst>(BestUnswitchTI))
3074
+ BestUnswitchTI = turnSelectIntoBranch (SI, DT, LI, MSSAU, &AC);
3075
+ else if (isGuard (BestUnswitchTI))
3008
3076
BestUnswitchTI = turnGuardIntoBranch (cast<IntrinsicInst>(BestUnswitchTI), L,
3009
3077
ExitBlocks, DT, LI, MSSAU);
3010
3078
0 commit comments