summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp83
1 files changed, 54 insertions, 29 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 458413d2f8a..5e972b16e28 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -173,6 +173,7 @@ class SimplifyCFGOpt {
const DataLayout &DL;
SmallPtrSetImpl<BasicBlock *> *LoopHeaders;
const SimplifyCFGOptions &Options;
+ bool Resimplify;
Value *isValueEqualityComparison(TerminatorInst *TI);
BasicBlock *GetValueEqualityComparisonCases(
@@ -194,6 +195,9 @@ class SimplifyCFGOpt {
bool SimplifyUncondBranch(BranchInst *BI, IRBuilder<> &Builder);
bool SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder);
+ bool tryToSimplifyUncondBranchWithICmpInIt(ICmpInst *ICI,
+ IRBuilder<> &Builder);
+
public:
SimplifyCFGOpt(const TargetTransformInfo &TTI, const DataLayout &DL,
SmallPtrSetImpl<BasicBlock *> *LoopHeaders,
@@ -201,6 +205,13 @@ public:
: TTI(TTI), DL(DL), LoopHeaders(LoopHeaders), Options(Opts) {}
bool run(BasicBlock *BB);
+ bool simplifyOnce(BasicBlock *BB);
+
+ // Helper to set Resimplify and return change indication.
+ bool requestResimplify() {
+ Resimplify = true;
+ return true;
+ }
};
} // end anonymous namespace
@@ -3543,9 +3554,8 @@ static bool SimplifyIndirectBrOnSelect(IndirectBrInst *IBI, SelectInst *SI) {
///
/// We prefer to split the edge to 'end' so that there is a true/false entry to
/// the PHI, merging the third icmp into the switch.
-static bool tryToSimplifyUncondBranchWithICmpInIt(
- ICmpInst *ICI, IRBuilder<> &Builder, const DataLayout &DL,
- const TargetTransformInfo &TTI, const SimplifyCFGOptions &Options) {
+bool SimplifyCFGOpt::tryToSimplifyUncondBranchWithICmpInIt(
+ ICmpInst *ICI, IRBuilder<> &Builder) {
BasicBlock *BB = ICI->getParent();
// If the block has any PHIs in it or the icmp has multiple uses, it is too
@@ -3580,7 +3590,7 @@ static bool tryToSimplifyUncondBranchWithICmpInIt(
ICI->eraseFromParent();
}
// BB is now empty, so it is likely to simplify away.
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
}
// Ok, the block is reachable from the default dest. If the constant we're
@@ -3596,7 +3606,7 @@ static bool tryToSimplifyUncondBranchWithICmpInIt(
ICI->replaceAllUsesWith(V);
ICI->eraseFromParent();
// BB is now empty, so it is likely to simplify away.
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
}
// The use of the icmp has to be in the 'end' block, by the only PHI node in
@@ -5595,33 +5605,33 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
// see if that predecessor totally determines the outcome of this switch.
if (BasicBlock *OnlyPred = BB->getSinglePredecessor())
if (SimplifyEqualityComparisonWithOnlyPredecessor(SI, OnlyPred, Builder))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
Value *Cond = SI->getCondition();
if (SelectInst *Select = dyn_cast<SelectInst>(Cond))
if (SimplifySwitchOnSelect(SI, Select))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
// If the block only contains the switch, see if we can fold the block
// away into any preds.
if (SI == &*BB->instructionsWithoutDebug().begin())
if (FoldValueComparisonIntoPredecessors(SI, Builder))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
}
// Try to transform the switch into an icmp and a branch.
if (TurnSwitchRangeIntoICmp(SI, Builder))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
// Remove unreachable cases.
if (eliminateDeadSwitchCases(SI, Options.AC, DL))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
if (switchToSelect(SI, Builder, DL, TTI))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
if (Options.ForwardSwitchCondToPhi && ForwardSwitchConditionToPHI(SI))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
// The conversion from switch to lookup tables results in difficult-to-analyze
// code and makes pruning branches much harder. This is a problem if the
@@ -5630,10 +5640,10 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
// optimisation pipeline.
if (Options.ConvertSwitchToLookupTable &&
SwitchToLookupTable(SI, Builder, DL, TTI))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
if (ReduceSwitchRange(SI, Builder, DL, TTI))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
return false;
}
@@ -5671,7 +5681,7 @@ bool SimplifyCFGOpt::SimplifyIndirectBr(IndirectBrInst *IBI) {
if (SelectInst *SI = dyn_cast<SelectInst>(IBI->getAddress())) {
if (SimplifyIndirectBrOnSelect(IBI, SI))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
}
return Changed;
}
@@ -5781,7 +5791,7 @@ bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI,
for (++I; isa<DbgInfoIntrinsic>(I); ++I)
;
if (I->isTerminator() &&
- tryToSimplifyUncondBranchWithICmpInIt(ICI, Builder, DL, TTI, Options))
+ tryToSimplifyUncondBranchWithICmpInIt(ICI, Builder))
return true;
}
@@ -5799,7 +5809,7 @@ bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI,
// predecessor and use logical operations to update the incoming value
// for PHI nodes in common successor.
if (FoldBranchToCommonDest(BI, Options.BonusInstThreshold))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
return false;
}
@@ -5827,18 +5837,18 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
// switch.
if (BasicBlock *OnlyPred = BB->getSinglePredecessor())
if (SimplifyEqualityComparisonWithOnlyPredecessor(BI, OnlyPred, Builder))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
// This block must be empty, except for the setcond inst, if it exists.
// Ignore dbg intrinsics.
auto I = BB->instructionsWithoutDebug().begin();
if (&*I == BI) {
if (FoldValueComparisonIntoPredecessors(BI, Builder))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
} else if (&*I == cast<Instruction>(BI->getCondition())) {
++I;
if (&*I == BI && FoldValueComparisonIntoPredecessors(BI, Builder))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
}
}
@@ -5865,7 +5875,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
: ConstantInt::getFalse(BB->getContext());
BI->setCondition(CI);
RecursivelyDeleteTriviallyDeadInstructions(OldCond);
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
}
}
}
@@ -5874,7 +5884,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
// branches to us and one of our successors, fold the comparison into the
// predecessor and use logical operations to pick the right destination.
if (FoldBranchToCommonDest(BI, Options.BonusInstThreshold))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
// We have a conditional branch to two blocks that are only reachable
// from BI. We know that the condbr dominates the two blocks, so see if
@@ -5883,7 +5893,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
if (BI->getSuccessor(0)->getSinglePredecessor()) {
if (BI->getSuccessor(1)->getSinglePredecessor()) {
if (HoistThenElseCodeToIf(BI, TTI))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
} else {
// If Successor #1 has multiple preds, we may be able to conditionally
// execute Successor #0 if it branches to Successor #1.
@@ -5891,7 +5901,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
if (Succ0TI->getNumSuccessors() == 1 &&
Succ0TI->getSuccessor(0) == BI->getSuccessor(1))
if (SpeculativelyExecuteBB(BI, BI->getSuccessor(0), TTI))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
}
} else if (BI->getSuccessor(1)->getSinglePredecessor()) {
// If Successor #0 has multiple preds, we may be able to conditionally
@@ -5900,7 +5910,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
if (Succ1TI->getNumSuccessors() == 1 &&
Succ1TI->getSuccessor(0) == BI->getSuccessor(0))
if (SpeculativelyExecuteBB(BI, BI->getSuccessor(1), TTI))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
}
// If this is a branch on a phi node in the current block, thread control
@@ -5908,14 +5918,14 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
if (PHINode *PN = dyn_cast<PHINode>(BI->getCondition()))
if (PN->getParent() == BI->getParent())
if (FoldCondBranchOnPHI(BI, DL, Options.AC))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
// Scan predecessor blocks for conditional branches.
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
if (BranchInst *PBI = dyn_cast<BranchInst>((*PI)->getTerminator()))
if (PBI != BI && PBI->isConditional())
if (SimplifyCondBranchToCondBranch(PBI, BI, DL))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
// Look for diamond patterns.
if (MergeCondStores)
@@ -5923,7 +5933,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
if (BranchInst *PBI = dyn_cast<BranchInst>(PrevBB->getTerminator()))
if (PBI != BI && PBI->isConditional())
if (mergeConditionalStores(PBI, BI, DL))
- return simplifyCFG(BB, TTI, Options) || true;
+ return requestResimplify();
return false;
}
@@ -6006,7 +6016,7 @@ static bool removeUndefIntroducingPredecessor(BasicBlock *BB) {
return false;
}
-bool SimplifyCFGOpt::run(BasicBlock *BB) {
+bool SimplifyCFGOpt::simplifyOnce(BasicBlock *BB) {
bool Changed = false;
assert(BB && BB->getParent() && "Block not embedded in function!");
@@ -6080,6 +6090,21 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {
return Changed;
}
+bool SimplifyCFGOpt::run(BasicBlock *BB) {
+ bool Changed = false;
+
+ // Repeated simplify BB as long as resimplification is requested.
+ do {
+ Resimplify = false;
+
+ // Perform one round of simplifcation. Resimplify flag will be set if
+ // another iteration is requested.
+ Changed |= simplifyOnce(BB);
+ } while (Resimplify);
+
+ return Changed;
+}
+
bool llvm::simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
const SimplifyCFGOptions &Options,
SmallPtrSetImpl<BasicBlock *> *LoopHeaders) {