#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/GuardUtils.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/ProfDataUtils.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <algorithm>
#include <cassert>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <map>
#include <optional>
#include <set>
#include <tuple>
#include <utility>
#include <vector>
usingnamespacellvm;
usingnamespacePatternMatch;
#define DEBUG_TYPE …
cl::opt<bool> llvm::RequireAndPreserveDomTree(
"simplifycfg-require-and-preserve-domtree", cl::Hidden,
cl::desc("Temorary development switch used to gradually uplift SimplifyCFG "
"into preserving DomTree,"));
static cl::opt<unsigned> PHINodeFoldingThreshold(
"phi-node-folding-threshold", cl::Hidden, cl::init(2),
cl::desc(
"Control the amount of phi node folding to perform (default = 2)"));
static cl::opt<unsigned> TwoEntryPHINodeFoldingThreshold(
"two-entry-phi-node-folding-threshold", cl::Hidden, cl::init(4),
cl::desc("Control the maximal total instruction cost that we are willing "
"to speculatively execute to fold a 2-entry PHI node into a "
"select (default = 4)"));
static cl::opt<bool>
HoistCommon("simplifycfg-hoist-common", cl::Hidden, cl::init(true),
cl::desc("Hoist common instructions up to the parent block"));
static cl::opt<bool> HoistLoadsStoresWithCondFaulting(
"simplifycfg-hoist-loads-stores-with-cond-faulting", cl::Hidden,
cl::init(true),
cl::desc("Hoist loads/stores if the target supports "
"conditional faulting"));
static cl::opt<unsigned> HoistLoadsStoresWithCondFaultingThreshold(
"hoist-loads-stores-with-cond-faulting-threshold", cl::Hidden, cl::init(6),
cl::desc("Control the maximal conditonal load/store that we are willing "
"to speculatively execute to eliminate conditional branch "
"(default = 6)"));
static cl::opt<unsigned>
HoistCommonSkipLimit("simplifycfg-hoist-common-skip-limit", cl::Hidden,
cl::init(20),
cl::desc("Allow reordering across at most this many "
"instructions when hoisting"));
static cl::opt<bool>
SinkCommon("simplifycfg-sink-common", cl::Hidden, cl::init(true),
cl::desc("Sink common instructions down to the end block"));
static cl::opt<bool> HoistCondStores(
"simplifycfg-hoist-cond-stores", cl::Hidden, cl::init(true),
cl::desc("Hoist conditional stores if an unconditional store precedes"));
static cl::opt<bool> MergeCondStores(
"simplifycfg-merge-cond-stores", cl::Hidden, cl::init(true),
cl::desc("Hoist conditional stores even if an unconditional store does not "
"precede - hoist multiple conditional stores into a single "
"predicated store"));
static cl::opt<bool> MergeCondStoresAggressively(
"simplifycfg-merge-cond-stores-aggressively", cl::Hidden, cl::init(false),
cl::desc("When merging conditional stores, do so even if the resultant "
"basic blocks are unlikely to be if-converted as a result"));
static cl::opt<bool> SpeculateOneExpensiveInst(
"speculate-one-expensive-inst", cl::Hidden, cl::init(true),
cl::desc("Allow exactly one expensive instruction to be speculatively "
"executed"));
static cl::opt<unsigned> MaxSpeculationDepth(
"max-speculation-depth", cl::Hidden, cl::init(10),
cl::desc("Limit maximum recursion depth when calculating costs of "
"speculatively executed instructions"));
static cl::opt<int>
MaxSmallBlockSize("simplifycfg-max-small-block-size", cl::Hidden,
cl::init(10),
cl::desc("Max size of a block which is still considered "
"small enough to thread through"));
static cl::opt<unsigned>
BranchFoldThreshold("simplifycfg-branch-fold-threshold", cl::Hidden,
cl::init(2),
cl::desc("Maximum cost of combining conditions when "
"folding branches"));
static cl::opt<unsigned> BranchFoldToCommonDestVectorMultiplier(
"simplifycfg-branch-fold-common-dest-vector-multiplier", cl::Hidden,
cl::init(2),
cl::desc("Multiplier to apply to threshold when determining whether or not "
"to fold branch to common destination when vector operations are "
"present"));
static cl::opt<bool> EnableMergeCompatibleInvokes(
"simplifycfg-merge-compatible-invokes", cl::Hidden, cl::init(true),
cl::desc("Allow SimplifyCFG to merge invokes together when appropriate"));
static cl::opt<unsigned> MaxSwitchCasesPerResult(
"max-switch-cases-per-result", cl::Hidden, cl::init(16),
cl::desc("Limit cases to analyze when converting a switch to select"));
STATISTIC(NumBitMaps, "Number of switch instructions turned into bitmaps");
STATISTIC(NumLinearMaps,
"Number of switch instructions turned into linear mapping");
STATISTIC(NumLookupTables,
"Number of switch instructions turned into lookup tables");
STATISTIC(
NumLookupTablesHoles,
"Number of switch instructions turned into lookup tables (holes checked)");
STATISTIC(NumTableCmpReuses, "Number of reused switch table lookup compares");
STATISTIC(NumFoldValueComparisonIntoPredecessors,
"Number of value comparisons folded into predecessor basic blocks");
STATISTIC(NumFoldBranchToCommonDest,
"Number of branches folded into predecessor basic block");
STATISTIC(
NumHoistCommonCode,
"Number of common instruction 'blocks' hoisted up to the begin block");
STATISTIC(NumHoistCommonInstrs,
"Number of common instructions hoisted up to the begin block");
STATISTIC(NumSinkCommonCode,
"Number of common instruction 'blocks' sunk down to the end block");
STATISTIC(NumSinkCommonInstrs,
"Number of common instructions sunk down to the end block");
STATISTIC(NumSpeculations, "Number of speculative executed instructions");
STATISTIC(NumInvokes,
"Number of invokes with empty resume blocks simplified into calls");
STATISTIC(NumInvokesMerged, "Number of invokes that were merged together");
STATISTIC(NumInvokeSetsFormed, "Number of invoke sets that were formed");
namespace {
SwitchCaseResultVectorTy;
SwitchCaseResultsTy;
struct ValueEqualityComparisonCase { … };
class SimplifyCFGOpt { … };
}
static bool incomingValuesAreCompatible(
BasicBlock *BB, ArrayRef<BasicBlock *> IncomingBlocks,
SmallPtrSetImpl<Value *> *EquivalenceSet = nullptr) { … }
static bool
safeToMergeTerminators(Instruction *SI1, Instruction *SI2,
SmallSetVector<BasicBlock *, 4> *FailBlocks = nullptr) { … }
static void addPredecessorToBlock(BasicBlock *Succ, BasicBlock *NewPred,
BasicBlock *ExistPred,
MemorySSAUpdater *MSSAU = nullptr) { … }
static InstructionCost computeSpeculationCost(const User *I,
const TargetTransformInfo &TTI) { … }
static bool dominatesMergePoint(Value *V, BasicBlock *BB,
SmallPtrSetImpl<Instruction *> &AggressiveInsts,
InstructionCost &Cost,
InstructionCost Budget,
const TargetTransformInfo &TTI,
unsigned Depth = 0) { … }
static ConstantInt *getConstantInt(Value *V, const DataLayout &DL) { … }
namespace {
struct ConstantComparesGatherer { … };
}
static void eraseTerminatorAndDCECond(Instruction *TI,
MemorySSAUpdater *MSSAU = nullptr) { … }
Value *SimplifyCFGOpt::isValueEqualityComparison(Instruction *TI) { … }
BasicBlock *SimplifyCFGOpt::getValueEqualityComparisonCases(
Instruction *TI, std::vector<ValueEqualityComparisonCase> &Cases) { … }
static void
eliminateBlockCases(BasicBlock *BB,
std::vector<ValueEqualityComparisonCase> &Cases) { … }
static bool valuesOverlap(std::vector<ValueEqualityComparisonCase> &C1,
std::vector<ValueEqualityComparisonCase> &C2) { … }
static void setBranchWeights(SwitchInst *SI, ArrayRef<uint32_t> Weights,
bool IsExpected) { … }
static void setBranchWeights(Instruction *I, uint32_t TrueWeight,
uint32_t FalseWeight, bool IsExpected) { … }
bool SimplifyCFGOpt::simplifyEqualityComparisonWithOnlyPredecessor(
Instruction *TI, BasicBlock *Pred, IRBuilder<> &Builder) { … }
namespace {
struct ConstantIntOrdering { … };
}
static int constantIntSortPredicate(ConstantInt *const *P1,
ConstantInt *const *P2) { … }
static void getBranchWeights(Instruction *TI,
SmallVectorImpl<uint64_t> &Weights) { … }
static void fitWeights(MutableArrayRef<uint64_t> Weights) { … }
static void cloneInstructionsIntoPredecessorBlockAndUpdateSSAUses(
BasicBlock *BB, BasicBlock *PredBlock, ValueToValueMapTy &VMap) { … }
bool SimplifyCFGOpt::performValueComparisonIntoPredecessorFolding(
Instruction *TI, Value *&CV, Instruction *PTI, IRBuilder<> &Builder) { … }
bool SimplifyCFGOpt::foldValueComparisonIntoPredecessors(Instruction *TI,
IRBuilder<> &Builder) { … }
static bool isSafeToHoistInvoke(BasicBlock *BB1, BasicBlock *BB2,
Instruction *I1, Instruction *I2) { … }
enum SkipFlags { … };
static unsigned skippedInstrFlags(Instruction *I) { … }
static bool isSafeToHoistInstr(Instruction *I, unsigned Flags) { … }
static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValueMayBeModified = false);
static bool shouldHoistCommonInstructions(Instruction *I1, Instruction *I2,
const TargetTransformInfo &TTI) { … }
static void hoistLockstepIdenticalDbgVariableRecords(
Instruction *TI, Instruction *I1,
SmallVectorImpl<Instruction *> &OtherInsts) { … }
static bool areIdenticalUpToCommutativity(const Instruction *I1,
const Instruction *I2) { … }
bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
bool EqTermsOnly) { … }
bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
Instruction *TI, Instruction *I1,
SmallVectorImpl<Instruction *> &OtherSuccTIs) { … }
static bool isLifeTimeMarker(const Instruction *I) { … }
static bool replacingOperandWithVariableIsCheap(const Instruction *I,
int OpIdx) { … }
static bool canSinkInstructions(
ArrayRef<Instruction *> Insts,
DenseMap<const Use *, SmallVector<Value *, 4>> &PHIOperands) { … }
static void sinkLastInstruction(ArrayRef<BasicBlock*> Blocks) { … }
namespace {
class LockstepReverseIterator { … };
}
static bool sinkCommonCodeFromPredecessors(BasicBlock *BB,
DomTreeUpdater *DTU) { … }
namespace {
struct CompatibleSets { … };
CompatibleSets::SetTy &CompatibleSets::getCompatibleSet(InvokeInst *II) { … }
void CompatibleSets::insert(InvokeInst *II) { … }
bool CompatibleSets::shouldBelongToSameSet(ArrayRef<InvokeInst *> Invokes) { … }
}
static void mergeCompatibleInvokesImpl(ArrayRef<InvokeInst *> Invokes,
DomTreeUpdater *DTU) { … }
static bool mergeCompatibleInvokes(BasicBlock *BB, DomTreeUpdater *DTU) { … }
namespace {
class EphemeralValueTracker { … };
}
static Value *isSafeToSpeculateStore(Instruction *I, BasicBlock *BrBB,
BasicBlock *StoreBB, BasicBlock *EndBB) { … }
static bool validateAndCostRequiredSelects(BasicBlock *BB, BasicBlock *ThenBB,
BasicBlock *EndBB,
unsigned &SpeculatedInstructions,
InstructionCost &Cost,
const TargetTransformInfo &TTI) { … }
static bool isProfitableToSpeculate(const BranchInst *BI, bool Invert,
const TargetTransformInfo &TTI) { … }
static bool isSafeCheapLoadStore(const Instruction *I,
const TargetTransformInfo &TTI) { … }
bool SimplifyCFGOpt::speculativelyExecuteBB(BranchInst *BI,
BasicBlock *ThenBB) { … }
static bool blockIsSimpleEnoughToThreadThrough(BasicBlock *BB) { … }
static ConstantInt *getKnownValueOnEdge(Value *V, BasicBlock *From,
BasicBlock *To) { … }
static std::optional<bool>
foldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU,
const DataLayout &DL,
AssumptionCache *AC) { … }
static bool foldCondBranchOnValueKnownInPredecessor(BranchInst *BI,
DomTreeUpdater *DTU,
const DataLayout &DL,
AssumptionCache *AC) { … }
static bool foldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
DomTreeUpdater *DTU, const DataLayout &DL,
bool SpeculateUnpredictables) { … }
static Value *createLogicalOp(IRBuilderBase &Builder,
Instruction::BinaryOps Opc, Value *LHS,
Value *RHS, const Twine &Name = "") { … }
static bool extractPredSuccWeights(BranchInst *PBI, BranchInst *BI,
uint64_t &PredTrueWeight,
uint64_t &PredFalseWeight,
uint64_t &SuccTrueWeight,
uint64_t &SuccFalseWeight) { … }
static std::optional<std::tuple<BasicBlock *, Instruction::BinaryOps, bool>>
shouldFoldCondBranchesToCommonDestination(BranchInst *BI, BranchInst *PBI,
const TargetTransformInfo *TTI) { … }
static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI,
DomTreeUpdater *DTU,
MemorySSAUpdater *MSSAU,
const TargetTransformInfo *TTI) { … }
static bool isVectorOp(Instruction &I) { … }
bool llvm::foldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU,
MemorySSAUpdater *MSSAU,
const TargetTransformInfo *TTI,
unsigned BonusInstThreshold) { … }
static StoreInst *findUniqueStoreInBlocks(BasicBlock *BB1, BasicBlock *BB2) { … }
static Value *ensureValueAvailableInSuccessor(Value *V, BasicBlock *BB,
Value *AlternativeV = nullptr) { … }
static bool mergeConditionalStoreToAddress(
BasicBlock *PTB, BasicBlock *PFB, BasicBlock *QTB, BasicBlock *QFB,
BasicBlock *PostBB, Value *Address, bool InvertPCond, bool InvertQCond,
DomTreeUpdater *DTU, const DataLayout &DL, const TargetTransformInfo &TTI) { … }
static bool mergeConditionalStores(BranchInst *PBI, BranchInst *QBI,
DomTreeUpdater *DTU, const DataLayout &DL,
const TargetTransformInfo &TTI) { … }
static bool tryWidenCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
DomTreeUpdater *DTU) { … }
static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
DomTreeUpdater *DTU,
const DataLayout &DL,
const TargetTransformInfo &TTI) { … }
bool SimplifyCFGOpt::simplifyTerminatorOnSelect(Instruction *OldTerm,
Value *Cond, BasicBlock *TrueBB,
BasicBlock *FalseBB,
uint32_t TrueWeight,
uint32_t FalseWeight) { … }
bool SimplifyCFGOpt::simplifySwitchOnSelect(SwitchInst *SI,
SelectInst *Select) { … }
bool SimplifyCFGOpt::simplifyIndirectBrOnSelect(IndirectBrInst *IBI,
SelectInst *SI) { … }
bool SimplifyCFGOpt::tryToSimplifyUncondBranchWithICmpInIt(
ICmpInst *ICI, IRBuilder<> &Builder) { … }
bool SimplifyCFGOpt::simplifyBranchOnICmpChain(BranchInst *BI,
IRBuilder<> &Builder,
const DataLayout &DL) { … }
bool SimplifyCFGOpt::simplifyResume(ResumeInst *RI, IRBuilder<> &Builder) { … }
static bool isCleanupBlockEmpty(iterator_range<BasicBlock::iterator> R) { … }
bool SimplifyCFGOpt::simplifyCommonResume(ResumeInst *RI) { … }
bool SimplifyCFGOpt::simplifySingleResume(ResumeInst *RI) { … }
static bool removeEmptyCleanup(CleanupReturnInst *RI, DomTreeUpdater *DTU) { … }
static bool mergeCleanupPad(CleanupReturnInst *RI) { … }
bool SimplifyCFGOpt::simplifyCleanupReturn(CleanupReturnInst *RI) { … }
bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) { … }
static bool casesAreContiguous(SmallVectorImpl<ConstantInt *> &Cases) { … }
static void createUnreachableSwitchDefault(SwitchInst *Switch,
DomTreeUpdater *DTU,
bool RemoveOrigDefaultBlock = true) { … }
bool SimplifyCFGOpt::turnSwitchRangeIntoICmp(SwitchInst *SI,
IRBuilder<> &Builder) { … }
static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
AssumptionCache *AC,
const DataLayout &DL) { … }
static PHINode *findPHIForConditionForwarding(ConstantInt *CaseValue,
BasicBlock *BB, int *PhiIndex) { … }
static bool forwardSwitchConditionToPHI(SwitchInst *SI) { … }
static bool validLookupTableConstant(Constant *C, const TargetTransformInfo &TTI) { … }
static Constant *
lookupConstant(Value *V,
const SmallDenseMap<Value *, Constant *> &ConstantPool) { … }
static Constant *
constantFold(Instruction *I, const DataLayout &DL,
const SmallDenseMap<Value *, Constant *> &ConstantPool) { … }
static bool
getCaseResults(SwitchInst *SI, ConstantInt *CaseVal, BasicBlock *CaseDest,
BasicBlock **CommonDest,
SmallVectorImpl<std::pair<PHINode *, Constant *>> &Res,
const DataLayout &DL, const TargetTransformInfo &TTI) { … }
static size_t mapCaseToResult(ConstantInt *CaseVal,
SwitchCaseResultVectorTy &UniqueResults,
Constant *Result) { … }
static bool initializeUniqueCases(SwitchInst *SI, PHINode *&PHI,
BasicBlock *&CommonDest,
SwitchCaseResultVectorTy &UniqueResults,
Constant *&DefaultResult,
const DataLayout &DL,
const TargetTransformInfo &TTI,
uintptr_t MaxUniqueResults) { … }
static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
Constant *DefaultResult, Value *Condition,
IRBuilder<> &Builder) { … }
static void removeSwitchAfterSelectFold(SwitchInst *SI, PHINode *PHI,
Value *SelectValue,
IRBuilder<> &Builder,
DomTreeUpdater *DTU) { … }
static bool trySwitchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
DomTreeUpdater *DTU, const DataLayout &DL,
const TargetTransformInfo &TTI) { … }
namespace {
class SwitchLookupTable { … };
}
SwitchLookupTable::SwitchLookupTable(
Module &M, uint64_t TableSize, ConstantInt *Offset,
const SmallVectorImpl<std::pair<ConstantInt *, Constant *>> &Values,
Constant *DefaultValue, const DataLayout &DL, const StringRef &FuncName) { … }
Value *SwitchLookupTable::buildLookup(Value *Index, IRBuilder<> &Builder) { … }
bool SwitchLookupTable::wouldFitInRegister(const DataLayout &DL,
uint64_t TableSize,
Type *ElementType) { … }
static bool isTypeLegalForLookupTable(Type *Ty, const TargetTransformInfo &TTI,
const DataLayout &DL) { … }
static bool isSwitchDense(uint64_t NumCases, uint64_t CaseRange) { … }
static bool isSwitchDense(ArrayRef<int64_t> Values) { … }
static bool
shouldBuildLookupTable(SwitchInst *SI, uint64_t TableSize,
const TargetTransformInfo &TTI, const DataLayout &DL,
const SmallDenseMap<PHINode *, Type *> &ResultTypes) { … }
static bool shouldUseSwitchConditionAsTableIndex(
ConstantInt &MinCaseVal, const ConstantInt &MaxCaseVal,
bool HasDefaultResults, const SmallDenseMap<PHINode *, Type *> &ResultTypes,
const DataLayout &DL, const TargetTransformInfo &TTI) { … }
static void reuseTableCompare(
User *PhiUser, BasicBlock *PhiBlock, BranchInst *RangeCheckBranch,
Constant *DefaultValue,
const SmallVectorImpl<std::pair<ConstantInt *, Constant *>> &Values) { … }
static bool switchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
DomTreeUpdater *DTU, const DataLayout &DL,
const TargetTransformInfo &TTI) { … }
static bool reduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
const DataLayout &DL,
const TargetTransformInfo &TTI) { … }
static bool simplifySwitchOfPowersOfTwo(SwitchInst *SI, IRBuilder<> &Builder,
const DataLayout &DL,
const TargetTransformInfo &TTI) { … }
static bool simplifySwitchOfCmpIntrinsic(SwitchInst *SI, IRBuilderBase &Builder,
DomTreeUpdater *DTU) { … }
bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) { … }
bool SimplifyCFGOpt::simplifyIndirectBr(IndirectBrInst *IBI) { … }
static bool tryToMergeLandingPad(LandingPadInst *LPad, BranchInst *BI,
BasicBlock *BB, DomTreeUpdater *DTU) { … }
bool SimplifyCFGOpt::simplifyBranch(BranchInst *Branch, IRBuilder<> &Builder) { … }
bool SimplifyCFGOpt::simplifyUncondBranch(BranchInst *BI,
IRBuilder<> &Builder) { … }
static BasicBlock *allPredecessorsComeFromSameSource(BasicBlock *BB) { … }
static bool mergeNestedCondBranch(BranchInst *BI, DomTreeUpdater *DTU) { … }
bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) { … }
static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValueMayBeModified) { … }
static bool removeUndefIntroducingPredecessor(BasicBlock *BB,
DomTreeUpdater *DTU,
AssumptionCache *AC) { … }
bool SimplifyCFGOpt::simplifyOnce(BasicBlock *BB) { … }
bool SimplifyCFGOpt::run(BasicBlock *BB) { … }
bool llvm::simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
DomTreeUpdater *DTU, const SimplifyCFGOptions &Options,
ArrayRef<WeakVH> LoopHeaders) { … }