Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit 5b032bb

Browse files
author
Max Kazantsev
committed
[LoopPredication] Support guards expressed as branches by widenable condition
This patch adds support of guards expressed as branches by widenable conditions in Loop Predication. Differential Revision: https://reviews.llvm.org/D56081 Reviewed By: reames git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351805 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 3cab73d commit 5b032bb

File tree

2 files changed

+1546
-4
lines changed

2 files changed

+1546
-4
lines changed

lib/Transforms/Scalar/LoopPredication.cpp

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,12 @@ static cl::opt<float> LatchExitProbabilityScale(
221221
cl::desc("scale factor for the latch probability. Value should be greater "
222222
"than 1. Lower values are ignored"));
223223

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+
224230
namespace {
225231
class LoopPredication {
226232
/// Represents an induction variable check:
@@ -275,7 +281,7 @@ class LoopPredication {
275281
unsigned collectChecks(SmallVectorImpl<Value *> &Checks, Value *Condition,
276282
SCEVExpander &Expander, IRBuilder<> &Builder);
277283
bool widenGuardConditions(IntrinsicInst *II, SCEVExpander &Expander);
278-
284+
bool widenWidenableBranchGuardConditions(BranchInst *Guard, SCEVExpander &Expander);
279285
// If the loop always exits through another block in the loop, we should not
280286
// predicate based on the latch check. For example, the latch check can be a
281287
// very coarse grained check and there can be more fine grained exit checks
@@ -643,6 +649,43 @@ bool LoopPredication::widenGuardConditions(IntrinsicInst *Guard,
643649
return true;
644650
}
645651

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+
646689
Optional<LoopPredication::LoopICmp> LoopPredication::parseLoopLatchICmp() {
647690
using namespace PatternMatch;
648691

@@ -800,7 +843,12 @@ bool LoopPredication::runOnLoop(Loop *Loop) {
800843
// There is nothing to do if the module doesn't use guards
801844
auto *GuardDecl =
802845
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)
804852
return false;
805853

806854
DL = &M->getDataLayout();
@@ -824,19 +872,27 @@ bool LoopPredication::runOnLoop(Loop *Loop) {
824872
// Collect all the guards into a vector and process later, so as not
825873
// to invalidate the instruction iterator.
826874
SmallVector<IntrinsicInst *, 4> Guards;
827-
for (const auto BB : L->blocks())
875+
SmallVector<BranchInst *, 4> GuardsAsWidenableBranches;
876+
for (const auto BB : L->blocks()) {
828877
for (auto &I : *BB)
829878
if (isGuard(&I))
830879
Guards.push_back(cast<IntrinsicInst>(&I));
880+
if (PredicateWidenableBranchGuards &&
881+
isGuardAsWidenableBranch(BB->getTerminator()))
882+
GuardsAsWidenableBranches.push_back(
883+
cast<BranchInst>(BB->getTerminator()));
884+
}
831885

832-
if (Guards.empty())
886+
if (Guards.empty() && GuardsAsWidenableBranches.empty())
833887
return false;
834888

835889
SCEVExpander Expander(*SE, *DL, "loop-predication");
836890

837891
bool Changed = false;
838892
for (auto *Guard : Guards)
839893
Changed |= widenGuardConditions(Guard, Expander);
894+
for (auto *Guard : GuardsAsWidenableBranches)
895+
Changed |= widenWidenableBranchGuardConditions(Guard, Expander);
840896

841897
return Changed;
842898
}

0 commit comments

Comments
 (0)