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