@@ -221,6 +221,12 @@ static cl::opt<float> LatchExitProbabilityScale(
221
221
cl::desc(" scale factor for the latch probability. Value should be greater "
222
222
" than 1. Lower values are ignored" ));
223
223
224
+ static cl::opt<bool > PredicateWidenableBranchGuards (
225
+ " loop-predication-predicate-widenable-branches-to-deopt" , cl::Hidden,
226
+ cl::desc (" Whether or not we should predicate guards "
227
+ " expressed as widenable branches to deoptimize blocks" ),
228
+ cl::init(true ));
229
+
224
230
namespace {
225
231
class LoopPredication {
226
232
// / Represents an induction variable check:
@@ -275,7 +281,7 @@ class LoopPredication {
275
281
unsigned collectChecks (SmallVectorImpl<Value *> &Checks, Value *Condition,
276
282
SCEVExpander &Expander, IRBuilder<> &Builder);
277
283
bool widenGuardConditions (IntrinsicInst *II, SCEVExpander &Expander);
278
-
284
+ bool widenWidenableBranchGuardConditions (BranchInst *Guard, SCEVExpander &Expander);
279
285
// If the loop always exits through another block in the loop, we should not
280
286
// predicate based on the latch check. For example, the latch check can be a
281
287
// very coarse grained check and there can be more fine grained exit checks
@@ -643,6 +649,43 @@ bool LoopPredication::widenGuardConditions(IntrinsicInst *Guard,
643
649
return true ;
644
650
}
645
651
652
+ bool LoopPredication::widenWidenableBranchGuardConditions (
653
+ BranchInst *Guard, SCEVExpander &Expander) {
654
+ assert (isGuardAsWidenableBranch (Guard) && " Must be!" );
655
+ LLVM_DEBUG (dbgs () << " Processing guard:\n " );
656
+ LLVM_DEBUG (Guard->dump ());
657
+
658
+ TotalConsidered++;
659
+ SmallVector<Value *, 4 > Checks;
660
+ IRBuilder<> Builder (cast<Instruction>(Preheader->getTerminator ()));
661
+ Value *Condition = nullptr , *WidenableCondition = nullptr ;
662
+ BasicBlock *GBB = nullptr , *DBB = nullptr ;
663
+ parseWidenableBranch (Guard, Condition, WidenableCondition, GBB, DBB);
664
+ unsigned NumWidened = collectChecks (Checks, Condition, Expander, Builder);
665
+ if (NumWidened == 0 )
666
+ return false ;
667
+
668
+ TotalWidened += NumWidened;
669
+
670
+ // Emit the new guard condition
671
+ Builder.SetInsertPoint (Guard);
672
+ Value *LastCheck = nullptr ;
673
+ for (auto *Check : Checks)
674
+ if (!LastCheck)
675
+ LastCheck = Check;
676
+ else
677
+ LastCheck = Builder.CreateAnd (LastCheck, Check);
678
+ // Make sure that the check contains widenable condition and therefore can be
679
+ // further widened.
680
+ LastCheck = Builder.CreateAnd (LastCheck, WidenableCondition);
681
+ Guard->setOperand (0 , LastCheck);
682
+ assert (isGuardAsWidenableBranch (Guard) &&
683
+ " Stopped being a guard after transform?" );
684
+
685
+ LLVM_DEBUG (dbgs () << " Widened checks = " << NumWidened << " \n " );
686
+ return true ;
687
+ }
688
+
646
689
Optional<LoopPredication::LoopICmp> LoopPredication::parseLoopLatchICmp () {
647
690
using namespace PatternMatch ;
648
691
@@ -800,7 +843,12 @@ bool LoopPredication::runOnLoop(Loop *Loop) {
800
843
// There is nothing to do if the module doesn't use guards
801
844
auto *GuardDecl =
802
845
M->getFunction (Intrinsic::getName (Intrinsic::experimental_guard));
803
- if (!GuardDecl || GuardDecl->use_empty ())
846
+ bool HasIntrinsicGuards = GuardDecl && !GuardDecl->use_empty ();
847
+ auto *WCDecl = M->getFunction (
848
+ Intrinsic::getName (Intrinsic::experimental_widenable_condition));
849
+ bool HasWidenableConditions =
850
+ PredicateWidenableBranchGuards && WCDecl && !WCDecl->use_empty ();
851
+ if (!HasIntrinsicGuards && !HasWidenableConditions)
804
852
return false ;
805
853
806
854
DL = &M->getDataLayout ();
@@ -824,19 +872,27 @@ bool LoopPredication::runOnLoop(Loop *Loop) {
824
872
// Collect all the guards into a vector and process later, so as not
825
873
// to invalidate the instruction iterator.
826
874
SmallVector<IntrinsicInst *, 4 > Guards;
827
- for (const auto BB : L->blocks ())
875
+ SmallVector<BranchInst *, 4 > GuardsAsWidenableBranches;
876
+ for (const auto BB : L->blocks ()) {
828
877
for (auto &I : *BB)
829
878
if (isGuard (&I))
830
879
Guards.push_back (cast<IntrinsicInst>(&I));
880
+ if (PredicateWidenableBranchGuards &&
881
+ isGuardAsWidenableBranch (BB->getTerminator ()))
882
+ GuardsAsWidenableBranches.push_back (
883
+ cast<BranchInst>(BB->getTerminator ()));
884
+ }
831
885
832
- if (Guards.empty ())
886
+ if (Guards.empty () && GuardsAsWidenableBranches. empty () )
833
887
return false ;
834
888
835
889
SCEVExpander Expander (*SE, *DL, " loop-predication" );
836
890
837
891
bool Changed = false ;
838
892
for (auto *Guard : Guards)
839
893
Changed |= widenGuardConditions (Guard, Expander);
894
+ for (auto *Guard : GuardsAsWidenableBranches)
895
+ Changed |= widenWidenableBranchGuardConditions (Guard, Expander);
840
896
841
897
return Changed;
842
898
}
0 commit comments