Skip to content

Commit d6e7c16

Browse files
committed
[NFC][GuardUtils] Add util to extract widenable conditions
This is the next preparation patch to support widenable conditions widening instead of branches widening. We've added parseWidenableGuard util which parses guard condition and collects all checks existing in the expression tree: D157276 Here we are adding util which walks similar way through the expression tree but looks up for widenable condition without collecting the checks. Therefore llvm::extractWidenableCondition could parse widenable branches with arbitrary position of widenable condition in the expression tree. llvm::parseWidenableBranch which is we are going to get rid of is being replaced by llvm::extractWidenableCondition where it's possible. Reviewed By: anna Differential Revision: https://reviews.llvm.org/D157529
1 parent 686aef8 commit d6e7c16

File tree

5 files changed

+53
-39
lines changed

5 files changed

+53
-39
lines changed

llvm/include/llvm/Analysis/GuardUtils.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ bool isGuard(const User *U);
2828
/// call
2929
bool isWidenableCondition(const Value *V);
3030

31-
/// Returns true iff \p U is a widenable branch (that is, parseWidenableBranch
32-
/// returns true).
31+
/// Returns true iff \p U is a widenable branch (that is,
32+
/// extractWidenableCondition returns widenable condition).
3333
bool isWidenableBranch(const User *U);
3434

3535
/// Returns true iff \p U has semantics of a guard expressed in a form of a
@@ -60,6 +60,10 @@ bool parseWidenableBranch(User *U, Use *&Cond, Use *&WC, BasicBlock *&IfTrueBB,
6060
// cond1 && cond2 && cond3 && widenable_contidion ...
6161
// Method collects the list of checks, but skips widenable_condition.
6262
void parseWidenableGuard(const User *U, llvm::SmallVectorImpl<Value *> &Checks);
63+
64+
// Returns widenable_condition if it exists in the expression tree rooting from
65+
// \p U and has only one use.
66+
Value *extractWidenableCondition(const User *U);
6367
} // llvm
6468

6569
#endif // LLVM_ANALYSIS_GUARDUTILS_H

llvm/lib/Analysis/GuardUtils.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,13 @@ bool llvm::isWidenableCondition(const Value *V) {
2424
}
2525

2626
bool llvm::isWidenableBranch(const User *U) {
27-
Value *Condition, *WidenableCondition;
28-
BasicBlock *GuardedBB, *DeoptBB;
29-
return parseWidenableBranch(U, Condition, WidenableCondition, GuardedBB,
30-
DeoptBB);
27+
return extractWidenableCondition(U) != nullptr;
3128
}
3229

3330
bool llvm::isGuardAsWidenableBranch(const User *U) {
34-
Value *Condition, *WidenableCondition;
35-
BasicBlock *GuardedBB, *DeoptBB;
36-
if (!parseWidenableBranch(U, Condition, WidenableCondition, GuardedBB,
37-
DeoptBB))
31+
if (!isWidenableBranch(U))
3832
return false;
33+
BasicBlock *DeoptBB = cast<BranchInst>(U)->getSuccessor(1);
3934
SmallPtrSet<const BasicBlock *, 2> Visited;
4035
Visited.insert(DeoptBB);
4136
do {
@@ -117,7 +112,8 @@ bool llvm::parseWidenableBranch(User *U, Use *&C,Use *&WC,
117112
}
118113

119114
template <typename CallbackType>
120-
static void parseCondition(Value *Condition, CallbackType Callback) {
115+
static void parseCondition(Value *Condition,
116+
CallbackType RecordCheckOrWidenableCond) {
121117
SmallVector<Value *, 4> Worklist(1, Condition);
122118
SmallPtrSet<Value *, 4> Visited;
123119
Visited.insert(Condition);
@@ -131,7 +127,8 @@ static void parseCondition(Value *Condition, CallbackType Callback) {
131127
Worklist.push_back(RHS);
132128
continue;
133129
}
134-
Callback(Check);
130+
if (!RecordCheckOrWidenableCond(Check))
131+
break;
135132
} while (!Worklist.empty());
136133
}
137134

@@ -144,5 +141,28 @@ void llvm::parseWidenableGuard(const User *U,
144141
parseCondition(Condition, [&](Value *Check) {
145142
if (!isWidenableCondition(Check))
146143
Checks.push_back(Check);
144+
return true;
145+
});
146+
}
147+
148+
Value *llvm::extractWidenableCondition(const User *U) {
149+
auto *BI = dyn_cast<BranchInst>(U);
150+
if (!BI || !BI->isConditional())
151+
return nullptr;
152+
153+
auto Condition = BI->getCondition();
154+
if (!Condition->hasOneUse())
155+
return nullptr;
156+
157+
Value *WidenableCondition = nullptr;
158+
parseCondition(Condition, [&](Value *Check) {
159+
// We require widenable_condition has only one use, otherwise we don't
160+
// consider appropriate branch as widenable.
161+
if (isWidenableCondition(Check) && Check->hasOneUse()) {
162+
WidenableCondition = Check;
163+
return false;
164+
}
165+
return true;
147166
});
167+
return WidenableCondition;
148168
}

llvm/lib/Transforms/Scalar/GuardWidening.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,7 @@ static void eliminateGuard(Instruction *GuardInst, MemorySSAUpdater *MSSAU) {
124124
/// the one described at https://github.com/llvm/llvm-project/issues/60234. The
125125
/// safest way to do it is to expand the new condition at WC's block.
126126
static Instruction *findInsertionPointForWideCondition(Instruction *Guard) {
127-
Value *Condition, *WC;
128-
BasicBlock *IfTrue, *IfFalse;
129-
if (parseWidenableBranch(Guard, Condition, WC, IfTrue, IfFalse))
127+
if (auto WC = extractWidenableCondition(Guard))
130128
return cast<Instruction>(WC);
131129
return Guard;
132130
}

llvm/lib/Transforms/Scalar/LoopPredication.cpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -802,18 +802,13 @@ bool LoopPredication::widenWidenableBranchGuardConditions(
802802
LLVM_DEBUG(dbgs() << "Processing guard:\n");
803803
LLVM_DEBUG(BI->dump());
804804

805-
Value *Cond, *WC;
806-
BasicBlock *IfTrueBB, *IfFalseBB;
807-
bool Parsed = parseWidenableBranch(BI, Cond, WC, IfTrueBB, IfFalseBB);
808-
assert(Parsed && "Must be able to parse widenable branch");
809-
(void)Parsed;
810-
811805
TotalConsidered++;
812806
SmallVector<Value *, 4> Checks;
813807
SmallVector<Value *> WidenedChecks;
814808
parseWidenableGuard(BI, Checks);
815809
// At the moment, our matching logic for wideable conditions implicitly
816810
// assumes we preserve the form: (br (and Cond, WC())). FIXME
811+
auto WC = extractWidenableCondition(BI);
817812
Checks.push_back(WC);
818813
widenChecks(Checks, WidenedChecks, Expander, BI);
819814
if (WidenedChecks.empty())
@@ -827,6 +822,7 @@ bool LoopPredication::widenWidenableBranchGuardConditions(
827822
auto *OldCond = BI->getCondition();
828823
BI->setCondition(AllChecks);
829824
if (InsertAssumesOfPredicatedGuardsConditions) {
825+
BasicBlock *IfTrueBB = BI->getSuccessor(0);
830826
Builder.SetInsertPoint(IfTrueBB, IfTrueBB->getFirstInsertionPt());
831827
// If this block has other predecessors, we might not be able to use Cond.
832828
// In this case, create a Phi where every other input is `true` and input
@@ -1033,13 +1029,9 @@ static BranchInst *FindWidenableTerminatorAboveLoop(Loop *L, LoopInfo &LI) {
10331029
} while (true);
10341030

10351031
if (BasicBlock *Pred = BB->getSinglePredecessor()) {
1036-
auto *Term = Pred->getTerminator();
1037-
1038-
Value *Cond, *WC;
1039-
BasicBlock *IfTrueBB, *IfFalseBB;
1040-
if (parseWidenableBranch(Term, Cond, WC, IfTrueBB, IfFalseBB) &&
1041-
IfTrueBB == BB)
1042-
return cast<BranchInst>(Term);
1032+
if (auto *BI = dyn_cast<BranchInst>(Pred->getTerminator()))
1033+
if (BI->getSuccessor(0) == BB && isWidenableBranch(BI))
1034+
return BI;
10431035
}
10441036
return nullptr;
10451037
}
@@ -1127,13 +1119,13 @@ bool LoopPredication::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) {
11271119
if (!BI)
11281120
continue;
11291121

1130-
Use *Cond, *WC;
1131-
BasicBlock *IfTrueBB, *IfFalseBB;
1132-
if (parseWidenableBranch(BI, Cond, WC, IfTrueBB, IfFalseBB) &&
1133-
L->contains(IfTrueBB)) {
1134-
WC->set(ConstantInt::getTrue(IfTrueBB->getContext()));
1135-
ChangedLoop = true;
1136-
}
1122+
if (auto WC = extractWidenableCondition(BI))
1123+
if (L->contains(BI->getSuccessor(0))) {
1124+
assert(WC->hasOneUse() && "Not appropriate widenable branch!");
1125+
WC->user_back()->replaceUsesOfWith(
1126+
WC, ConstantInt::getTrue(BI->getContext()));
1127+
ChangedLoop = true;
1128+
}
11371129
}
11381130
if (ChangedLoop)
11391131
SE->forgetLoop(L);

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4149,10 +4149,10 @@ static bool tryWidenCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
41494149
// 2) We can sink side effecting instructions into BI's fallthrough
41504150
// successor provided they doesn't contribute to computation of
41514151
// BI's condition.
4152-
Value *CondWB, *WC;
4153-
BasicBlock *IfTrueBB, *IfFalseBB;
4154-
if (!parseWidenableBranch(PBI, CondWB, WC, IfTrueBB, IfFalseBB) ||
4155-
IfTrueBB != BI->getParent() || !BI->getParent()->getSinglePredecessor())
4152+
BasicBlock *IfTrueBB = PBI->getSuccessor(0);
4153+
BasicBlock *IfFalseBB = PBI->getSuccessor(1);
4154+
if (!isWidenableBranch(PBI) || IfTrueBB != BI->getParent() ||
4155+
!BI->getParent()->getSinglePredecessor())
41564156
return false;
41574157
if (!IfFalseBB->phis().empty())
41584158
return false; // TODO

0 commit comments

Comments
 (0)