@@ -2127,9 +2127,10 @@ static void unswitchNontrivialInvariants(
2127
2127
Loop &L, Instruction &TI, ArrayRef<Value *> Invariants,
2128
2128
IVConditionInfo &PartialIVInfo, DominatorTree &DT, LoopInfo &LI,
2129
2129
AssumptionCache &AC,
2130
- function_ref<void (bool , bool , ArrayRef<Loop *>)> UnswitchCB,
2130
+ function_ref<void (bool , bool , bool , ArrayRef<Loop *>)> UnswitchCB,
2131
2131
ScalarEvolution *SE, MemorySSAUpdater *MSSAU,
2132
- function_ref<void(Loop &, StringRef)> DestroyLoopCB, bool InsertFreeze) {
2132
+ function_ref<void(Loop &, StringRef)> DestroyLoopCB, bool InsertFreeze,
2133
+ bool InjectedCondition) {
2133
2134
auto *ParentBB = TI.getParent ();
2134
2135
BranchInst *BI = dyn_cast<BranchInst>(&TI);
2135
2136
SwitchInst *SI = BI ? nullptr : cast<SwitchInst>(&TI);
@@ -2582,7 +2583,7 @@ static void unswitchNontrivialInvariants(
2582
2583
for (Loop *UpdatedL : llvm::concat<Loop *>(NonChildClonedLoops, HoistedLoops))
2583
2584
if (UpdatedL->getParentLoop () == ParentL)
2584
2585
SibLoops.push_back (UpdatedL);
2585
- UnswitchCB (IsStillLoop, PartiallyInvariant, SibLoops);
2586
+ UnswitchCB (IsStillLoop, PartiallyInvariant, InjectedCondition, SibLoops);
2586
2587
2587
2588
if (MSSAU && VerifyMemorySSA)
2588
2589
MSSAU->getMemorySSA ()->verifyMemorySSA ();
@@ -2980,13 +2981,6 @@ static bool shouldTryInjectInvariantCondition(
2980
2981
// / the metadata.
2981
2982
bool shouldTryInjectBasingOnMetadata (const BranchInst *BI,
2982
2983
const BasicBlock *TakenSucc) {
2983
- // Skip branches that have already been unswithed this way. After successful
2984
- // unswitching of injected condition, we will still have a copy of this loop
2985
- // which looks exactly the same as original one. To prevent the 2nd attempt
2986
- // of unswitching it in the same pass, mark this branch as "nothing to do
2987
- // here".
2988
- if (BI->hasMetadata (" llvm.invariant.condition.injection.disabled" ))
2989
- return false ;
2990
2984
SmallVector<uint32_t > Weights;
2991
2985
if (!extractBranchWeights (*BI, Weights))
2992
2986
return false ;
@@ -3069,13 +3063,9 @@ injectPendingInvariantConditions(NonTrivialUnswitchCandidate Candidate, Loop &L,
3069
3063
Builder.CreateCondBr (InjectedCond, InLoopSucc, CheckBlock);
3070
3064
3071
3065
Builder.SetInsertPoint (CheckBlock);
3072
- auto *NewTerm = Builder.CreateCondBr (TI->getCondition (), TI->getSuccessor (0 ),
3073
- TI->getSuccessor (1 ));
3074
-
3066
+ Builder.CreateCondBr (TI->getCondition (), TI->getSuccessor (0 ),
3067
+ TI->getSuccessor (1 ));
3075
3068
TI->eraseFromParent ();
3076
- // Prevent infinite unswitching.
3077
- NewTerm->setMetadata (" llvm.invariant.condition.injection.disabled" ,
3078
- MDNode::get (BB->getContext (), {}));
3079
3069
3080
3070
// Fixup phis.
3081
3071
for (auto &I : *InLoopSucc) {
@@ -3443,7 +3433,7 @@ static bool shouldInsertFreeze(Loop &L, Instruction &TI, DominatorTree &DT,
3443
3433
static bool unswitchBestCondition (
3444
3434
Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC,
3445
3435
AAResults &AA, TargetTransformInfo &TTI,
3446
- function_ref<void (bool , bool , ArrayRef<Loop *>)> UnswitchCB,
3436
+ function_ref<void (bool , bool , bool , ArrayRef<Loop *>)> UnswitchCB,
3447
3437
ScalarEvolution *SE, MemorySSAUpdater *MSSAU,
3448
3438
function_ref<void(Loop &, StringRef)> DestroyLoopCB) {
3449
3439
// Collect all invariant conditions within this loop (as opposed to an inner
@@ -3453,9 +3443,10 @@ static bool unswitchBestCondition(
3453
3443
Instruction *PartialIVCondBranch = nullptr ;
3454
3444
collectUnswitchCandidates (UnswitchCandidates, PartialIVInfo,
3455
3445
PartialIVCondBranch, L, LI, AA, MSSAU);
3456
- collectUnswitchCandidatesWithInjections (UnswitchCandidates, PartialIVInfo,
3457
- PartialIVCondBranch, L, DT, LI, AA,
3458
- MSSAU);
3446
+ if (!findOptionMDForLoop (&L, " llvm.loop.unswitch.injection.disable" ))
3447
+ collectUnswitchCandidatesWithInjections (UnswitchCandidates, PartialIVInfo,
3448
+ PartialIVCondBranch, L, DT, LI, AA,
3449
+ MSSAU);
3459
3450
// If we didn't find any candidates, we're done.
3460
3451
if (UnswitchCandidates.empty ())
3461
3452
return false ;
@@ -3476,8 +3467,11 @@ static bool unswitchBestCondition(
3476
3467
return false ;
3477
3468
}
3478
3469
3479
- if (Best.hasPendingInjection ())
3470
+ bool InjectedCondition = false ;
3471
+ if (Best.hasPendingInjection ()) {
3480
3472
Best = injectPendingInvariantConditions (Best, L, DT, LI, AC, MSSAU);
3473
+ InjectedCondition = true ;
3474
+ }
3481
3475
assert (!Best.hasPendingInjection () &&
3482
3476
" All injections should have been done by now!" );
3483
3477
@@ -3505,7 +3499,7 @@ static bool unswitchBestCondition(
3505
3499
<< " ) terminator: " << *Best.TI << " \n " );
3506
3500
unswitchNontrivialInvariants (L, *Best.TI , Best.Invariants , PartialIVInfo, DT,
3507
3501
LI, AC, UnswitchCB, SE, MSSAU, DestroyLoopCB,
3508
- InsertFreeze);
3502
+ InsertFreeze, InjectedCondition );
3509
3503
return true ;
3510
3504
}
3511
3505
@@ -3534,7 +3528,7 @@ static bool
3534
3528
unswitchLoop (Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC,
3535
3529
AAResults &AA, TargetTransformInfo &TTI, bool Trivial,
3536
3530
bool NonTrivial,
3537
- function_ref<void (bool , bool , ArrayRef<Loop *>)> UnswitchCB,
3531
+ function_ref<void (bool , bool , bool , ArrayRef<Loop *>)> UnswitchCB,
3538
3532
ScalarEvolution *SE, MemorySSAUpdater *MSSAU,
3539
3533
ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
3540
3534
function_ref<void(Loop &, StringRef)> DestroyLoopCB) {
@@ -3549,7 +3543,8 @@ unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC,
3549
3543
if (Trivial && unswitchAllTrivialConditions (L, DT, LI, SE, MSSAU)) {
3550
3544
// If we unswitched successfully we will want to clean up the loop before
3551
3545
// processing it further so just mark it as unswitched and return.
3552
- UnswitchCB (/* CurrentLoopValid*/ true , false , {});
3546
+ UnswitchCB (/* CurrentLoopValid*/ true , /* PartiallyInvariant*/ false ,
3547
+ /* InjectedCondition*/ false , {});
3553
3548
return true ;
3554
3549
}
3555
3550
@@ -3645,6 +3640,7 @@ PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM,
3645
3640
3646
3641
auto UnswitchCB = [&L, &U, &LoopName](bool CurrentLoopValid,
3647
3642
bool PartiallyInvariant,
3643
+ bool InjectedCondition,
3648
3644
ArrayRef<Loop *> NewLoops) {
3649
3645
// If we did a non-trivial unswitch, we have added new (cloned) loops.
3650
3646
if (!NewLoops.empty ())
@@ -3664,6 +3660,16 @@ PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM,
3664
3660
Context, L.getLoopID (), {" llvm.loop.unswitch.partial" },
3665
3661
{DisableUnswitchMD});
3666
3662
L.setLoopID (NewLoopID);
3663
+ } else if (InjectedCondition) {
3664
+ // Do the same for injection of invariant conditions.
3665
+ auto &Context = L.getHeader ()->getContext ();
3666
+ MDNode *DisableUnswitchMD = MDNode::get (
3667
+ Context,
3668
+ MDString::get (Context, " llvm.loop.unswitch.injection.disable" ));
3669
+ MDNode *NewLoopID = makePostTransformationMetadata (
3670
+ Context, L.getLoopID (), {" llvm.loop.unswitch.injection" },
3671
+ {DisableUnswitchMD});
3672
+ L.setLoopID (NewLoopID);
3667
3673
} else
3668
3674
U.revisitCurrentLoop ();
3669
3675
} else
@@ -3756,6 +3762,7 @@ bool SimpleLoopUnswitchLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
3756
3762
auto *SE = SEWP ? &SEWP->getSE () : nullptr ;
3757
3763
3758
3764
auto UnswitchCB = [&L, &LPM](bool CurrentLoopValid, bool PartiallyInvariant,
3765
+ bool InjectedCondition,
3759
3766
ArrayRef<Loop *> NewLoops) {
3760
3767
// If we did a non-trivial unswitch, we have added new (cloned) loops.
3761
3768
for (auto *NewL : NewLoops)
@@ -3766,9 +3773,9 @@ bool SimpleLoopUnswitchLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
3766
3773
// but it is the best we can do in the old PM.
3767
3774
if (CurrentLoopValid) {
3768
3775
// If the current loop has been unswitched using a partially invariant
3769
- // condition, we should not re-add the current loop to avoid unswitching
3770
- // on the same condition again.
3771
- if (!PartiallyInvariant)
3776
+ // condition or injected invariant condition , we should not re-add the
3777
+ // current loop to avoid unswitching on the same condition again.
3778
+ if (!PartiallyInvariant && !InjectedCondition )
3772
3779
LPM.addLoop (*L);
3773
3780
} else
3774
3781
LPM.markLoopAsDeleted (*L);
0 commit comments