diff options
-rw-r--r-- | llvm/include/llvm/Transforms/Scalar/SimplifyCFG.h | 21 | ||||
-rw-r--r-- | llvm/include/llvm/Transforms/Utils/Local.h | 35 | ||||
-rw-r--r-- | llvm/lib/CodeGen/DwarfEHPrepare.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp | 48 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 91 | ||||
-rw-r--r-- | llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll | 6 | ||||
-rw-r--r-- | llvm/tools/bugpoint/CrashDebugger.cpp | 2 |
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; |