summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Transforms/Scalar/SimplifyCFG.h21
-rw-r--r--llvm/include/llvm/Transforms/Utils/Local.h35
-rw-r--r--llvm/lib/CodeGen/DwarfEHPrepare.cpp2
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp2
-rw-r--r--llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp48
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp91
-rw-r--r--llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll6
-rw-r--r--llvm/tools/bugpoint/CrashDebugger.cpp2
8 files changed, 106 insertions, 101 deletions
diff --git a/llvm/include/llvm/Transforms/Scalar/SimplifyCFG.h b/llvm/include/llvm/Transforms/Scalar/SimplifyCFG.h
index 54b51c405ad..ef47fa8e684 100644
--- a/llvm/include/llvm/Transforms/Scalar/SimplifyCFG.h
+++ b/llvm/include/llvm/Transforms/Scalar/SimplifyCFG.h
@@ -17,26 +17,25 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Utils/Local.h"
namespace llvm {
-/// \brief A pass to simplify and canonicalize the CFG of a function.
+/// A pass to simplify and canonicalize the CFG of a function.
///
-/// This pass iteratively simplifies the entire CFG of a function, removing
-/// unnecessary control flows and bringing it into the canonical form expected
-/// by the rest of the mid-level optimizer.
+/// This pass iteratively simplifies the entire CFG of a function. It may change
+/// or remove control flow to put the CFG into a canonical form expected by
+/// other passes of the mid-level optimizer. Depending on the specified options,
+/// it may further optimize control-flow to create non-canonical forms.
class SimplifyCFGPass : public PassInfoMixin<SimplifyCFGPass> {
- int BonusInstThreshold;
- bool LateSimplifyCFG;
+ SimplifyCFGOptions Options;
public:
- /// \brief Construct a pass with the default thresholds
- /// and switch optimizations.
+ /// Construct a pass with default options.
SimplifyCFGPass();
- /// \brief Construct a pass with a specific bonus threshold
- /// and optional switch optimizations.
- SimplifyCFGPass(int BonusInstThreshold, bool LateSimplifyCFG);
+ /// Construct a pass with optional optimizations.
+ SimplifyCFGPass(const SimplifyCFGOptions &PassOptions);
/// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h
index 9816e7fecf2..b445bbd4966 100644
--- a/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/llvm/include/llvm/Transforms/Utils/Local.h
@@ -51,6 +51,22 @@ class LazyValueInfo;
template<typename T> class SmallVectorImpl;
+/// A set of parameters used to control the transforms in the SimplifyCFG pass.
+/// Options may change depending on the position in the optimization pipeline.
+/// For example, canonical form that includes switches and branches may later be
+/// replaced by lookup tables and selects.
+struct SimplifyCFGOptions {
+ int BonusInstThreshold;
+ bool ConvertSwitchToLookupTable;
+ bool NeedCanonicalLoop;
+
+ SimplifyCFGOptions(int BonusThreshold = 1, bool SwitchToLookup = false,
+ bool CanonicalLoops = true)
+ : BonusInstThreshold(BonusThreshold),
+ ConvertSwitchToLookupTable(SwitchToLookup),
+ NeedCanonicalLoop(CanonicalLoops) {}
+};
+
//===----------------------------------------------------------------------===//
// Local constant propagation.
//
@@ -135,17 +151,16 @@ bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB);
/// values, but instcombine orders them so it usually won't matter.
bool EliminateDuplicatePHINodes(BasicBlock *BB);
-/// This function is used to do simplification of a CFG. For
-/// example, it adjusts branches to branches to eliminate the extra hop, it
-/// eliminates unreachable basic blocks, and does other "peephole" optimization
-/// of the CFG. It returns true if a modification was made, possibly deleting
-/// the basic block that was pointed to. LoopHeaders is an optional input
-/// parameter, providing the set of loop header that SimplifyCFG should not
-/// eliminate.
+/// This function is used to do simplification of a CFG. For example, it
+/// adjusts branches to branches to eliminate the extra hop, it eliminates
+/// unreachable basic blocks, and does other peephole optimization of the CFG.
+/// It returns true if a modification was made, possibly deleting the basic
+/// block that was pointed to. LoopHeaders is an optional input parameter
+/// providing the set of loop headers that SimplifyCFG should not eliminate.
bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
- unsigned BonusInstThreshold, AssumptionCache *AC = nullptr,
- SmallPtrSetImpl<BasicBlock *> *LoopHeaders = nullptr,
- bool LateSimplifyCFG = false);
+ AssumptionCache *AC = nullptr,
+ const SimplifyCFGOptions &Options = {},
+ SmallPtrSetImpl<BasicBlock *> *LoopHeaders = nullptr);
/// This function is used to flatten a CFG. For example, it uses parallel-and
/// and parallel-or mode to collapse if-conditions and merge if-regions with
diff --git a/llvm/lib/CodeGen/DwarfEHPrepare.cpp b/llvm/lib/CodeGen/DwarfEHPrepare.cpp
index f57e3d6b062..b5f84863b59 100644
--- a/llvm/lib/CodeGen/DwarfEHPrepare.cpp
+++ b/llvm/lib/CodeGen/DwarfEHPrepare.cpp
@@ -172,7 +172,7 @@ size_t DwarfEHPrepare::pruneUnreachableResumes(
BasicBlock *BB = RI->getParent();
new UnreachableInst(Ctx, RI);
RI->eraseFromParent();
- SimplifyCFG(BB, TTI, 1);
+ SimplifyCFG(BB, TTI);
}
}
Resumes.resize(ResumesLeft);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp b/llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp
index 309913f87fb..f0ebfa3ce77 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp
@@ -142,7 +142,7 @@ static BasicBlock *unifyReturnBlockSet(Function &F,
for (BasicBlock *BB : ReturningBlocks) {
// Cleanup possible branch to unconditional branch to the return.
- SimplifyCFG(BB, TTI, 2);
+ SimplifyCFG(BB, TTI, nullptr, {2});
}
return NewRetBlock;
diff --git a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
index 8754c714c5b..3ef119ec05d 100644
--- a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -130,8 +130,7 @@ static bool mergeEmptyReturnBlocks(Function &F) {
/// iterating until no more changes are made.
static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
AssumptionCache *AC,
- unsigned BonusInstThreshold,
- bool LateSimplifyCFG) {
+ const SimplifyCFGOptions &Options) {
bool Changed = false;
bool LocalChange = true;
@@ -146,7 +145,7 @@ static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
// Loop over all of the basic blocks and remove them if they are unneeded.
for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
- if (SimplifyCFG(&*BBIt++, TTI, BonusInstThreshold, AC, &LoopHeaders, LateSimplifyCFG)) {
+ if (SimplifyCFG(&*BBIt++, TTI, AC, Options, &LoopHeaders)) {
LocalChange = true;
++NumSimpl;
}
@@ -157,12 +156,11 @@ static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
}
static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
- AssumptionCache *AC, int BonusInstThreshold,
- bool LateSimplifyCFG) {
+ AssumptionCache *AC,
+ const SimplifyCFGOptions &Options) {
bool EverChanged = removeUnreachableBlocks(F);
EverChanged |= mergeEmptyReturnBlocks(F);
- EverChanged |= iterativelySimplifyCFG(F, TTI, AC, BonusInstThreshold,
- LateSimplifyCFG);
+ EverChanged |= iterativelySimplifyCFG(F, TTI, AC, Options);
// If neither pass changed anything, we're done.
if (!EverChanged) return false;
@@ -176,8 +174,7 @@ static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
return true;
do {
- EverChanged = iterativelySimplifyCFG(F, TTI, AC, BonusInstThreshold,
- LateSimplifyCFG);
+ EverChanged = iterativelySimplifyCFG(F, TTI, AC, Options);
EverChanged |= removeUnreachableBlocks(F);
} while (EverChanged);
@@ -185,19 +182,17 @@ static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
}
SimplifyCFGPass::SimplifyCFGPass()
- : BonusInstThreshold(UserBonusInstThreshold),
- LateSimplifyCFG(true) {}
+ : Options(UserBonusInstThreshold, true, false) {}
-SimplifyCFGPass::SimplifyCFGPass(int BonusInstThreshold, bool LateSimplifyCFG)
- : BonusInstThreshold(BonusInstThreshold),
- LateSimplifyCFG(LateSimplifyCFG) {}
+SimplifyCFGPass::SimplifyCFGPass(const SimplifyCFGOptions &PassOptions)
+ : Options(PassOptions) {}
PreservedAnalyses SimplifyCFGPass::run(Function &F,
FunctionAnalysisManager &AM) {
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
auto &AC = AM.getResult<AssumptionAnalysis>(F);
- if (!simplifyFunctionCFG(F, TTI, &AC, BonusInstThreshold, LateSimplifyCFG))
+ if (!simplifyFunctionCFG(F, TTI, &AC, Options))
return PreservedAnalyses::all();
PreservedAnalyses PA;
PA.preserve<GlobalsAA>();
@@ -206,16 +201,17 @@ PreservedAnalyses SimplifyCFGPass::run(Function &F,
namespace {
struct BaseCFGSimplifyPass : public FunctionPass {
- unsigned BonusInstThreshold;
std::function<bool(const Function &)> PredicateFtor;
- bool LateSimplifyCFG;
+ int BonusInstThreshold;
+ bool ConvertSwitchToLookupTable;
+ bool KeepCanonicalLoops;
- BaseCFGSimplifyPass(int T, bool LateSimplifyCFG,
- std::function<bool(const Function &)> Ftor,
- char &ID)
+ BaseCFGSimplifyPass(int T, bool ConvertSwitch, bool KeepLoops,
+ std::function<bool(const Function &)> Ftor, char &ID)
: FunctionPass(ID), PredicateFtor(std::move(Ftor)),
- LateSimplifyCFG(LateSimplifyCFG) {
- BonusInstThreshold = (T == -1) ? UserBonusInstThreshold : unsigned(T);
+ ConvertSwitchToLookupTable(ConvertSwitch),
+ KeepCanonicalLoops(KeepLoops) {
+ BonusInstThreshold = (T == -1) ? UserBonusInstThreshold : T;
}
bool runOnFunction(Function &F) override {
if (skipFunction(F) || (PredicateFtor && !PredicateFtor(F)))
@@ -225,7 +221,9 @@ struct BaseCFGSimplifyPass : public FunctionPass {
&getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
const TargetTransformInfo &TTI =
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- return simplifyFunctionCFG(F, TTI, AC, BonusInstThreshold, LateSimplifyCFG);
+ return simplifyFunctionCFG(
+ F, TTI, AC,
+ {BonusInstThreshold, ConvertSwitchToLookupTable, KeepCanonicalLoops});
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -240,7 +238,7 @@ struct CFGSimplifyPass : public BaseCFGSimplifyPass {
CFGSimplifyPass(int T = -1,
std::function<bool(const Function &)> Ftor = nullptr)
- : BaseCFGSimplifyPass(T, false, Ftor, ID) {
+ : BaseCFGSimplifyPass(T, false, true, Ftor, ID) {
initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
}
};
@@ -250,7 +248,7 @@ struct LateCFGSimplifyPass : public BaseCFGSimplifyPass {
LateCFGSimplifyPass(int T = -1,
std::function<bool(const Function &)> Ftor = nullptr)
- : BaseCFGSimplifyPass(T, true, Ftor, ID) {
+ : BaseCFGSimplifyPass(T, true, false, Ftor, ID) {
initializeLateCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
}
};
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 290f4151c0a..d3e7d70b1a9 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -167,11 +167,10 @@ struct ValueEqualityComparisonCase {
class SimplifyCFGOpt {
const TargetTransformInfo &TTI;
const DataLayout &DL;
- unsigned BonusInstThreshold;
AssumptionCache *AC;
SmallPtrSetImpl<BasicBlock *> *LoopHeaders;
- // See comments in SimplifyCFGOpt::SimplifySwitch.
- bool LateSimplifyCFG;
+ const SimplifyCFGOptions &Options;
+
Value *isValueEqualityComparison(TerminatorInst *TI);
BasicBlock *GetValueEqualityComparisonCases(
TerminatorInst *TI, std::vector<ValueEqualityComparisonCase> &Cases);
@@ -194,11 +193,10 @@ class SimplifyCFGOpt {
public:
SimplifyCFGOpt(const TargetTransformInfo &TTI, const DataLayout &DL,
- unsigned BonusInstThreshold, AssumptionCache *AC,
+ AssumptionCache *AC,
SmallPtrSetImpl<BasicBlock *> *LoopHeaders,
- bool LateSimplifyCFG)
- : TTI(TTI), DL(DL), BonusInstThreshold(BonusInstThreshold), AC(AC),
- LoopHeaders(LoopHeaders), LateSimplifyCFG(LateSimplifyCFG) {}
+ const SimplifyCFGOptions &Opts)
+ : TTI(TTI), DL(DL), AC(AC), LoopHeaders(LoopHeaders), Options(Opts) {}
bool run(BasicBlock *BB);
};
@@ -3491,8 +3489,8 @@ static bool SimplifyIndirectBrOnSelect(IndirectBrInst *IBI, SelectInst *SI) {
/// the PHI, merging the third icmp into the switch.
static bool TryToSimplifyUncondBranchWithICmpInIt(
ICmpInst *ICI, IRBuilder<> &Builder, const DataLayout &DL,
- const TargetTransformInfo &TTI, unsigned BonusInstThreshold,
- AssumptionCache *AC) {
+ const TargetTransformInfo &TTI, AssumptionCache *AC,
+ const SimplifyCFGOptions &Options) {
BasicBlock *BB = ICI->getParent();
// If the block has any PHIs in it or the icmp has multiple uses, it is too
@@ -3527,7 +3525,7 @@ static bool TryToSimplifyUncondBranchWithICmpInIt(
ICI->eraseFromParent();
}
// BB is now empty, so it is likely to simplify away.
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
}
// Ok, the block is reachable from the default dest. If the constant we're
@@ -3543,7 +3541,7 @@ static bool TryToSimplifyUncondBranchWithICmpInIt(
ICI->replaceAllUsesWith(V);
ICI->eraseFromParent();
// BB is now empty, so it is likely to simplify away.
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
}
// The use of the icmp has to be in the 'end' block, by the only PHI node in
@@ -5522,12 +5520,12 @@ 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, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
Value *Cond = SI->getCondition();
if (SelectInst *Select = dyn_cast<SelectInst>(Cond))
if (SimplifySwitchOnSelect(SI, Select))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
// If the block only contains the switch, see if we can fold the block
// away into any preds.
@@ -5537,33 +5535,34 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
++BBI;
if (SI == &*BBI)
if (FoldValueComparisonIntoPredecessors(SI, Builder))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
}
// Try to transform the switch into an icmp and a branch.
if (TurnSwitchRangeIntoICmp(SI, Builder))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
// Remove unreachable cases.
if (EliminateDeadSwitchCases(SI, AC, DL))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
if (SwitchToSelect(SI, Builder, AC, DL, TTI))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
if (ForwardSwitchConditionToPHI(SI))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
// 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
// switch expression itself can still be restricted as a result of inlining or
// CVP. Therefore, only apply this transformation during late stages of the
// optimisation pipeline.
- if (LateSimplifyCFG && SwitchToLookupTable(SI, Builder, DL, TTI))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ if (Options.ConvertSwitchToLookupTable &&
+ SwitchToLookupTable(SI, Builder, DL, TTI))
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
if (ReduceSwitchRange(SI, Builder, DL, TTI))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
return false;
}
@@ -5601,7 +5600,7 @@ bool SimplifyCFGOpt::SimplifyIndirectBr(IndirectBrInst *IBI) {
if (SelectInst *SI = dyn_cast<SelectInst>(IBI->getAddress())) {
if (SimplifyIndirectBrOnSelect(IBI, SI))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
}
return Changed;
}
@@ -5697,7 +5696,7 @@ bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI,
// vectorization to keep canonical loop forms for nested loops. These blocks
// can be eliminated when the pass is invoked later in the back-end.)
bool NeedCanonicalLoop =
- !LateSimplifyCFG &&
+ Options.NeedCanonicalLoop &&
(LoopHeaders && (LoopHeaders->count(BB) || LoopHeaders->count(Succ)));
BasicBlock::iterator I = BB->getFirstNonPHIOrDbg()->getIterator();
if (I->isTerminator() && BB != &BB->getParent()->getEntryBlock() &&
@@ -5711,8 +5710,8 @@ bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI,
for (++I; isa<DbgInfoIntrinsic>(I); ++I)
;
if (I->isTerminator() &&
- TryToSimplifyUncondBranchWithICmpInIt(ICI, Builder, DL, TTI,
- BonusInstThreshold, AC))
+ TryToSimplifyUncondBranchWithICmpInIt(ICI, Builder, DL, TTI, AC,
+ Options))
return true;
}
@@ -5729,8 +5728,8 @@ bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI,
// branches to us and our successor, fold the comparison into the
// predecessor and use logical operations to update the incoming value
// for PHI nodes in common successor.
- if (FoldBranchToCommonDest(BI, BonusInstThreshold))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ if (FoldBranchToCommonDest(BI, Options.BonusInstThreshold))
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
return false;
}
@@ -5755,7 +5754,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
// switch.
if (BasicBlock *OnlyPred = BB->getSinglePredecessor())
if (SimplifyEqualityComparisonWithOnlyPredecessor(BI, OnlyPred, Builder))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
// This block must be empty, except for the setcond inst, if it exists.
// Ignore dbg intrinsics.
@@ -5765,14 +5764,14 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
++I;
if (&*I == BI) {
if (FoldValueComparisonIntoPredecessors(BI, Builder))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
} else if (&*I == cast<Instruction>(BI->getCondition())) {
++I;
// Ignore dbg intrinsics.
while (isa<DbgInfoIntrinsic>(I))
++I;
if (&*I == BI && FoldValueComparisonIntoPredecessors(BI, Builder))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
}
}
@@ -5799,7 +5798,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
: ConstantInt::getFalse(BB->getContext());
BI->setCondition(CI);
RecursivelyDeleteTriviallyDeadInstructions(OldCond);
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
}
}
}
@@ -5807,8 +5806,8 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
// If this basic block is ONLY a compare and a branch, and if a predecessor
// 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, BonusInstThreshold))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ if (FoldBranchToCommonDest(BI, Options.BonusInstThreshold))
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
// 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
@@ -5817,7 +5816,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, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
} else {
// If Successor #1 has multiple preds, we may be able to conditionally
// execute Successor #0 if it branches to Successor #1.
@@ -5825,7 +5824,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, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
}
} else if (BI->getSuccessor(1)->getSinglePredecessor()) {
// If Successor #0 has multiple preds, we may be able to conditionally
@@ -5834,7 +5833,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, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
}
// If this is a branch on a phi node in the current block, thread control
@@ -5842,14 +5841,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, AC))
- return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
// 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, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
// Look for diamond patterns.
if (MergeCondStores)
@@ -5857,7 +5856,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, BonusInstThreshold, AC) | true;
+ return SimplifyCFG(BB, TTI, AC, Options) | true;
return false;
}
@@ -6013,16 +6012,10 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {
return Changed;
}
-/// This function is used to do simplification of a CFG.
-/// For example, it adjusts branches to branches to eliminate the extra hop,
-/// eliminates unreachable basic blocks, and does other "peephole" optimization
-/// of the CFG. It returns true if a modification was made.
-///
bool llvm::SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
- unsigned BonusInstThreshold, AssumptionCache *AC,
- SmallPtrSetImpl<BasicBlock *> *LoopHeaders,
- bool LateSimplifyCFG) {
- return SimplifyCFGOpt(TTI, BB->getModule()->getDataLayout(),
- BonusInstThreshold, AC, LoopHeaders, LateSimplifyCFG)
+ AssumptionCache *AC, const SimplifyCFGOptions &Options,
+ SmallPtrSetImpl<BasicBlock *> *LoopHeaders) {
+ return SimplifyCFGOpt(TTI, BB->getModule()->getDataLayout(), AC, LoopHeaders,
+ Options)
.run(BB);
}
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
index e8896b10fa7..e61e9153b79 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
@@ -1173,10 +1173,10 @@ return:
ret i32 %retval.0
; CHECK-LABEL: @reuse_cmp2(
; CHECK: entry:
-; CHECK-NEXT: %switch = icmp ult i32 %x, 4
-; CHECK-NEXT: %x. = select i1 %switch, i32 %x, i32 4
+; CHECK-NEXT: %0 = icmp ult i32 %x, 4
+; CHECK-NEXT: %x. = select i1 %0, i32 %x, i32 4
; CHECK-NEXT: [[C:%.+]] = icmp ne i32 %x., 4
-; CHECK: [[R:%.+]] = select i1 [[C]], i32 {{.*}}, i32 100
+; CHECK: [[R:%.+]] = select i1 %0, i32 {{.*}}, i32 100
; CHECK-NEXT: ret i32 [[R]]
}
diff --git a/llvm/tools/bugpoint/CrashDebugger.cpp b/llvm/tools/bugpoint/CrashDebugger.cpp
index 2fd8699c5fc..2cd19bdccbd 100644
--- a/llvm/tools/bugpoint/CrashDebugger.cpp
+++ b/llvm/tools/bugpoint/CrashDebugger.cpp
@@ -648,7 +648,7 @@ bool ReduceSimplifyCFG::TestBlocks(std::vector<const BasicBlock *> &BBs) {
++BBIt;
continue;
}
- SimplifyCFG(&*BBIt++, TTI, 1);
+ SimplifyCFG(&*BBIt++, TTI);
}
// Verify we didn't break anything
std::vector<std::string> Passes;
OpenPOWER on IntegriCloud