LLVM 19.0.0git
Macros | Enumerations | Functions | Variables
SimplifyCFG.cpp File Reference
#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/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>

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "simplifycfg"
 

Enumerations

enum  SkipFlags { SkipReadMem = 1 , SkipSideEffect = 2 , SkipImplicitControlFlow = 4 }
 

Functions

 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")
 
static bool IncomingValuesAreCompatible (BasicBlock *BB, ArrayRef< BasicBlock * > IncomingBlocks, SmallPtrSetImpl< Value * > *EquivalenceSet=nullptr)
 Return true if all the PHI nodes in the basic block BB receive compatible (identical) incoming values when coming from all of the predecessor blocks that are specified in IncomingBlocks.
 
static bool SafeToMergeTerminators (Instruction *SI1, Instruction *SI2, SmallSetVector< BasicBlock *, 4 > *FailBlocks=nullptr)
 Return true if it is safe to merge these two terminator instructions together.
 
static void AddPredecessorToBlock (BasicBlock *Succ, BasicBlock *NewPred, BasicBlock *ExistPred, MemorySSAUpdater *MSSAU=nullptr)
 Update PHI nodes in Succ to indicate that there will now be entries in it from the 'NewPred' block.
 
static InstructionCost computeSpeculationCost (const User *I, const TargetTransformInfo &TTI)
 Compute an abstract "cost" of speculating the given instruction, which is assumed to be safe to speculate.
 
static bool dominatesMergePoint (Value *V, BasicBlock *BB, SmallPtrSetImpl< Instruction * > &AggressiveInsts, InstructionCost &Cost, InstructionCost Budget, const TargetTransformInfo &TTI, unsigned Depth=0)
 If we have a merge point of an "if condition" as accepted above, return true if the specified value dominates the block.
 
static ConstantIntGetConstantInt (Value *V, const DataLayout &DL)
 Extract ConstantInt from value, looking through IntToPtr and PointerNullValue.
 
static void EraseTerminatorAndDCECond (Instruction *TI, MemorySSAUpdater *MSSAU=nullptr)
 
static void EliminateBlockCases (BasicBlock *BB, std::vector< ValueEqualityComparisonCase > &Cases)
 Given a vector of bb/value pairs, remove any entries in the list that match the specified block.
 
static bool ValuesOverlap (std::vector< ValueEqualityComparisonCase > &C1, std::vector< ValueEqualityComparisonCase > &C2)
 Return true if there are any keys in C1 that exist in C2 as well.
 
static void setBranchWeights (SwitchInst *SI, ArrayRef< uint32_t > Weights)
 
static void setBranchWeights (Instruction *I, uint32_t TrueWeight, uint32_t FalseWeight)
 
static int ConstantIntSortPredicate (ConstantInt *const *P1, ConstantInt *const *P2)
 
static void GetBranchWeights (Instruction *TI, SmallVectorImpl< uint64_t > &Weights)
 Get Weights of a given terminator, the default weight is at the front of the vector.
 
static void FitWeights (MutableArrayRef< uint64_t > Weights)
 Keep halving the weights until all can fit in uint32_t.
 
static void CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses (BasicBlock *BB, BasicBlock *PredBlock, ValueToValueMapTy &VMap)
 
static bool isSafeToHoistInvoke (BasicBlock *BB1, BasicBlock *BB2, Instruction *I1, Instruction *I2)
 
static unsigned skippedInstrFlags (Instruction *I)
 
static bool isSafeToHoistInstr (Instruction *I, unsigned Flags)
 
static bool passingValueIsAlwaysUndefined (Value *V, Instruction *I, bool PtrValueMayBeModified)
 Check if passing a value to an instruction will cause undefined behavior.
 
static bool shouldHoistCommonInstructions (Instruction *I1, Instruction *I2, const TargetTransformInfo &TTI)
 Helper function for hoistCommonCodeFromSuccessors.
 
static void hoistLockstepIdenticalDbgVariableRecords (Instruction *TI, Instruction *I1, SmallVectorImpl< Instruction * > &OtherInsts)
 Hoists DbgVariableRecords from I1 and OtherInstrs that are identical in lock-step to TI.
 
static bool isLifeTimeMarker (const Instruction *I)
 
static bool replacingOperandWithVariableIsCheap (const Instruction *I, int OpIdx)
 
static bool canSinkInstructions (ArrayRef< Instruction * > Insts, DenseMap< Instruction *, SmallVector< Value *, 4 > > &PHIOperands)
 
static bool sinkLastInstruction (ArrayRef< BasicBlock * > Blocks)
 
static bool SinkCommonCodeFromPredecessors (BasicBlock *BB, DomTreeUpdater *DTU)
 Check whether BB's predecessors end with unconditional branches.
 
static void MergeCompatibleInvokesImpl (ArrayRef< InvokeInst * > Invokes, DomTreeUpdater *DTU)
 
static bool MergeCompatibleInvokes (BasicBlock *BB, DomTreeUpdater *DTU)
 If this block is a landingpad exception handling block, categorize all the predecessor invokes into sets, with all invokes in each set being "mergeable" together, and then merge invokes in each set together.
 
static ValueisSafeToSpeculateStore (Instruction *I, BasicBlock *BrBB, BasicBlock *StoreBB, BasicBlock *EndBB)
 Determine if we can hoist sink a sole store instruction out of a conditional block.
 
static bool validateAndCostRequiredSelects (BasicBlock *BB, BasicBlock *ThenBB, BasicBlock *EndBB, unsigned &SpeculatedInstructions, InstructionCost &Cost, const TargetTransformInfo &TTI)
 Estimate the cost of the insertion(s) and check that the PHI nodes can be converted to selects.
 
static bool BlockIsSimpleEnoughToThreadThrough (BasicBlock *BB)
 Return true if we can thread a branch across this block.
 
static ConstantIntgetKnownValueOnEdge (Value *V, BasicBlock *From, BasicBlock *To)
 
static std::optional< boolFoldCondBranchOnValueKnownInPredecessorImpl (BranchInst *BI, DomTreeUpdater *DTU, const DataLayout &DL, AssumptionCache *AC)
 If we have a conditional branch on something for which we know the constant value in predecessors (e.g.
 
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)
 Given a BB that starts with the specified two-entry PHI node, see if we can eliminate it.
 
static ValuecreateLogicalOp (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)
 Return true if either PBI or BI has branch weight available, and store the weights in {Pred|Succ}{True|False}Weight.
 
static std::optional< std::tuple< BasicBlock *, Instruction::BinaryOps, bool > > shouldFoldCondBranchesToCommonDestination (BranchInst *BI, BranchInst *PBI, const TargetTransformInfo *TTI)
 Determine if the two branches share a common destination and deduce a glue that joins the branches' conditions to arrive at the common destination if that would be profitable.
 
static bool performBranchToCommonDestFolding (BranchInst *BI, BranchInst *PBI, DomTreeUpdater *DTU, MemorySSAUpdater *MSSAU, const TargetTransformInfo *TTI)
 
static bool isVectorOp (Instruction &I)
 Return if an instruction's type or any of its operands' types are a vector type.
 
static StoreInstfindUniqueStoreInBlocks (BasicBlock *BB1, BasicBlock *BB2)
 
static ValueensureValueAvailableInSuccessor (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)
 If the previous block ended with a widenable branch, determine if reusing the target block is profitable and legal.
 
static bool SimplifyCondBranchToCondBranch (BranchInst *PBI, BranchInst *BI, DomTreeUpdater *DTU, const DataLayout &DL, const TargetTransformInfo &TTI)
 If we have a conditional branch as a predecessor of another block, this function tries to simplify it.
 
static bool isCleanupBlockEmpty (iterator_range< BasicBlock::iterator > R)
 
static bool removeEmptyCleanup (CleanupReturnInst *RI, DomTreeUpdater *DTU)
 
static bool mergeCleanupPad (CleanupReturnInst *RI)
 
static bool CasesAreContiguous (SmallVectorImpl< ConstantInt * > &Cases)
 
static void createUnreachableSwitchDefault (SwitchInst *Switch, DomTreeUpdater *DTU)
 
static bool eliminateDeadSwitchCases (SwitchInst *SI, DomTreeUpdater *DTU, AssumptionCache *AC, const DataLayout &DL)
 Compute masked bits for the condition of a switch and use it to remove dead cases.
 
static PHINodeFindPHIForConditionForwarding (ConstantInt *CaseValue, BasicBlock *BB, int *PhiIndex)
 If BB would be eligible for simplification by TryToSimplifyUncondBranchFromEmptyBlock (i.e.
 
static bool ForwardSwitchConditionToPHI (SwitchInst *SI)
 Try to forward the condition of a switch instruction to a phi node dominated by the switch, if that would mean that some of the destination blocks of the switch can be folded away.
 
static bool ValidLookupTableConstant (Constant *C, const TargetTransformInfo &TTI)
 Return true if the backend will be able to handle initializing an array of constants like C.
 
static ConstantLookupConstant (Value *V, const SmallDenseMap< Value *, Constant * > &ConstantPool)
 If V is a Constant, return it.
 
static ConstantConstantFold (Instruction *I, const DataLayout &DL, const SmallDenseMap< Value *, Constant * > &ConstantPool)
 Try to fold instruction I into a constant.
 
static bool getCaseResults (SwitchInst *SI, ConstantInt *CaseVal, BasicBlock *CaseDest, BasicBlock **CommonDest, SmallVectorImpl< std::pair< PHINode *, Constant * > > &Res, const DataLayout &DL, const TargetTransformInfo &TTI)
 Try to determine the resulting constant values in phi nodes at the common destination basic block, *CommonDest, for one of the case destionations CaseDest corresponding to value CaseVal (0 for the default case), of a switch instruction SI.
 
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 ValuefoldSwitchToSelect (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)
 If a switch is only used to initialize one or more phi nodes in a common successor block with only two different constant values, try to replace the switch with a select.
 
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)
 Determine whether a lookup table should be built for this switch, based on the number of cases, size of the table, and the types of the results.
 
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)
 Try to reuse the switch table index compare.
 
static bool SwitchToLookupTable (SwitchInst *SI, IRBuilder<> &Builder, DomTreeUpdater *DTU, const DataLayout &DL, const TargetTransformInfo &TTI)
 If the switch is only used to initialize one or more phi nodes in a common successor block with different constant values, replace the switch with lookup tables.
 
static bool ReduceSwitchRange (SwitchInst *SI, IRBuilder<> &Builder, const DataLayout &DL, const TargetTransformInfo &TTI)
 Try to transform a switch that has "holes" in it to a contiguous sequence of cases.
 
static bool simplifySwitchOfPowersOfTwo (SwitchInst *SI, IRBuilder<> &Builder, const DataLayout &DL, const TargetTransformInfo &TTI)
 Tries to transform switch of powers of two to reduce switch range.
 
static bool TryToMergeLandingPad (LandingPadInst *LPad, BranchInst *BI, BasicBlock *BB, DomTreeUpdater *DTU)
 Given an block with only a single landing pad and a unconditional branch try to find another basic block which this one can be merged with.
 
static BasicBlockallPredecessorsComeFromSameSource (BasicBlock *BB)
 
static bool removeUndefIntroducingPredecessor (BasicBlock *BB, DomTreeUpdater *DTU, AssumptionCache *AC)
 If BB has an incoming value that will always trigger undefined behavior (eg.
 

Variables

static cl::opt< unsignedPHINodeFoldingThreshold ("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< unsignedTwoEntryPHINodeFoldingThreshold ("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< boolHoistCommon ("simplifycfg-hoist-common", cl::Hidden, cl::init(true), cl::desc("Hoist common instructions up to the parent block"))
 
static cl::opt< unsignedHoistCommonSkipLimit ("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< boolSinkCommon ("simplifycfg-sink-common", cl::Hidden, cl::init(true), cl::desc("Sink common instructions down to the end block"))
 
static cl::opt< boolHoistCondStores ("simplifycfg-hoist-cond-stores", cl::Hidden, cl::init(true), cl::desc("Hoist conditional stores if an unconditional store precedes"))
 
static cl::opt< boolMergeCondStores ("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< boolMergeCondStoresAggressively ("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< boolSpeculateOneExpensiveInst ("speculate-one-expensive-inst", cl::Hidden, cl::init(true), cl::desc("Allow exactly one expensive instruction to be speculatively " "executed"))
 
static cl::opt< unsignedMaxSpeculationDepth ("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< unsignedBranchFoldThreshold ("simplifycfg-branch-fold-threshold", cl::Hidden, cl::init(2), cl::desc("Maximum cost of combining conditions when " "folding branches"))
 
static cl::opt< unsignedBranchFoldToCommonDestVectorMultiplier ("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< boolEnableMergeCompatibleInvokes ("simplifycfg-merge-compatible-invokes", cl::Hidden, cl::init(true), cl::desc("Allow SimplifyCFG to merge invokes together when appropriate"))
 
static cl::opt< unsignedMaxSwitchCasesPerResult ("max-switch-cases-per-result", cl::Hidden, cl::init(16), cl::desc("Limit cases to analyze when converting a switch to select"))
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "simplifycfg"

Definition at line 92 of file SimplifyCFG.cpp.

Enumeration Type Documentation

◆ SkipFlags

enum SkipFlags
Enumerator
SkipReadMem 
SkipSideEffect 
SkipImplicitControlFlow 

Definition at line 1442 of file SimplifyCFG.cpp.

Function Documentation

◆ AddPredecessorToBlock()

static void AddPredecessorToBlock ( BasicBlock Succ,
BasicBlock NewPred,
BasicBlock ExistPred,
MemorySSAUpdater MSSAU = nullptr 
)
static

Update PHI nodes in Succ to indicate that there will now be entries in it from the 'NewPred' block.

The values that will be flowing into the PHI nodes will be the same as those coming in from ExistPred, an existing predecessor of Succ.

Definition at line 372 of file SimplifyCFG.cpp.

References llvm::BasicBlock::phis().

Referenced by FoldCondBranchOnValueKnownInPredecessorImpl(), performBranchToCommonDestFolding(), SimplifyCondBranchToCondBranch(), and SwitchToLookupTable().

◆ allPredecessorsComeFromSameSource()

static BasicBlock * allPredecessorsComeFromSameSource ( BasicBlock BB)
static

Definition at line 7320 of file SimplifyCFG.cpp.

References P, and llvm::predecessors().

◆ BlockIsSimpleEnoughToThreadThrough()

static bool BlockIsSimpleEnoughToThreadThrough ( BasicBlock BB)
static

Return true if we can thread a branch across this block.

Definition at line 3259 of file SimplifyCFG.cpp.

References llvm::Instruction::getParent(), I, llvm::BasicBlock::instructionsWithoutDebug(), MaxSmallBlockSize, llvm::reverse(), and Size.

Referenced by FoldCondBranchOnValueKnownInPredecessorImpl().

◆ canSinkInstructions()

static bool canSinkInstructions ( ArrayRef< Instruction * >  Insts,
DenseMap< Instruction *, SmallVector< Value *, 4 > > &  PHIOperands 
)
static

◆ CasesAreContiguous()

static bool CasesAreContiguous ( SmallVectorImpl< ConstantInt * > &  Cases)
static

◆ CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses()

static void CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses ( BasicBlock BB,
BasicBlock PredBlock,
ValueToValueMapTy VMap 
)
static

◆ computeSpeculationCost()

static InstructionCost computeSpeculationCost ( const User I,
const TargetTransformInfo TTI 
)
static

Compute an abstract "cost" of speculating the given instruction, which is assumed to be safe to speculate.

TCC_Free means cheap, TCC_Basic means less cheap, and TCC_Expensive means prohibitively expensive.

Definition at line 386 of file SimplifyCFG.cpp.

References assert(), llvm::TargetTransformInfo::getInstructionCost(), I, llvm::isSafeToSpeculativelyExecute(), and llvm::TargetTransformInfo::TCK_SizeAndLatency.

Referenced by dominatesMergePoint(), and validateAndCostRequiredSelects().

◆ ConstantFold()

static Constant * ConstantFold ( Instruction I,
const DataLayout DL,
const SmallDenseMap< Value *, Constant * > &  ConstantPool 
)
static

Try to fold instruction I into a constant.

This works for simple instructions such as binary operations where both operands are constant or can be replaced by constants from the ConstantPool. Returns the resulting constant on success, 0 otherwise.

Definition at line 5857 of file SimplifyCFG.cpp.

References A, llvm::ConstantFoldInstOperands(), DL, I, LookupConstant(), N, llvm::SmallVectorTemplateBase< T, bool >::push_back(), and Select.

Referenced by getCaseResults(), and llvm::SelectionDAG::getVScale().

◆ ConstantIntSortPredicate()

static int ConstantIntSortPredicate ( ConstantInt *const P1,
ConstantInt *const P2 
)
static

Definition at line 1053 of file SimplifyCFG.cpp.

References LHS, and RHS.

Referenced by CasesAreContiguous().

◆ createLogicalOp()

static Value * createLogicalOp ( IRBuilderBase Builder,
Instruction::BinaryOps  Opc,
Value LHS,
Value RHS,
const Twine Name = "" 
)
static

◆ createUnreachableSwitchDefault()

static void createUnreachableSwitchDefault ( SwitchInst Switch,
DomTreeUpdater DTU 
)
static

◆ dominatesMergePoint()

static bool dominatesMergePoint ( Value V,
BasicBlock BB,
SmallPtrSetImpl< Instruction * > &  AggressiveInsts,
InstructionCost Cost,
InstructionCost  Budget,
const TargetTransformInfo TTI,
unsigned  Depth = 0 
)
static

If we have a merge point of an "if condition" as accepted above, return true if the specified value dominates the block.

We don't handle the true generality of domination here, just a special case which works well enough for us.

If AggressiveInsts is non-null, and if V does not dominate BB, we check to see if V (which must be an instruction) and its recursive operands that do not dominate BB have a combined cost lower than Budget and are non-trapping. If both are true, the instruction is inserted into the set and true is returned.

The cost for most non-trapping instructions is defined as 1 except for Select whose cost is 2.

After this function returns, Cost is increased by the cost of V plus its non-dominating operands. If that cost is greater than Budget, false is returned and Cost is undefined.

Definition at line 411 of file SimplifyCFG.cpp.

References computeSpeculationCost(), llvm::SmallPtrSetImpl< PtrType >::count(), llvm::Depth, dominatesMergePoint(), llvm::SmallPtrSetImplBase::empty(), llvm::BranchInst::getSuccessor(), llvm::BasicBlock::getTerminator(), I, llvm::SmallPtrSetImpl< PtrType >::insert(), llvm::BranchInst::isConditional(), llvm::isSafeToSpeculativelyExecute(), llvm::InstructionCost::isValid(), MaxSpeculationDepth, and SpeculateOneExpensiveInst.

Referenced by dominatesMergePoint(), and FoldTwoEntryPHINode().

◆ EliminateBlockCases()

static void EliminateBlockCases ( BasicBlock BB,
std::vector< ValueEqualityComparisonCase > &  Cases 
)
static

Given a vector of bb/value pairs, remove any entries in the list that match the specified block.

Definition at line 822 of file SimplifyCFG.cpp.

References llvm::erase().

◆ eliminateDeadSwitchCases()

static bool eliminateDeadSwitchCases ( SwitchInst SI,
DomTreeUpdater DTU,
AssumptionCache AC,
const DataLayout DL 
)
static

◆ ensureValueAvailableInSuccessor()

static Value * ensureValueAvailableInSuccessor ( Value V,
BasicBlock BB,
Value AlternativeV = nullptr 
)
static

◆ EraseTerminatorAndDCECond()

static void EraseTerminatorAndDCECond ( Instruction TI,
MemorySSAUpdater MSSAU = nullptr 
)
static

◆ extractPredSuccWeights()

static bool extractPredSuccWeights ( BranchInst PBI,
BranchInst BI,
uint64_t PredTrueWeight,
uint64_t PredFalseWeight,
uint64_t SuccTrueWeight,
uint64_t SuccFalseWeight 
)
static

Return true if either PBI or BI has branch weight available, and store the weights in {Pred|Succ}{True|False}Weight.

If one of PBI and BI does not have branch weight, use 1:1 as its weight.

Definition at line 3697 of file SimplifyCFG.cpp.

References llvm::extractBranchWeights().

Referenced by performBranchToCommonDestFolding(), and SimplifyCondBranchToCondBranch().

◆ FindPHIForConditionForwarding()

static PHINode * FindPHIForConditionForwarding ( ConstantInt CaseValue,
BasicBlock BB,
int *  PhiIndex 
)
static

If BB would be eligible for simplification by TryToSimplifyUncondBranchFromEmptyBlock (i.e.

it is empty and terminated by an unconditional branch), look at the phi node for BB in the successor block and see if the incoming value is equal to CaseValue. If so, return the phi node, and set PhiIndex to BB's index in the phi node.

Definition at line 5729 of file SimplifyCFG.cpp.

References assert(), llvm::BasicBlock::getFirstNonPHIOrDbg(), llvm::BasicBlock::getSinglePredecessor(), llvm::BasicBlock::getTerminator(), Idx, PHI, and llvm::BasicBlock::phis().

Referenced by ForwardSwitchConditionToPHI().

◆ findUniqueStoreInBlocks()

static StoreInst * findUniqueStoreInBlocks ( BasicBlock BB1,
BasicBlock BB2 
)
static

Definition at line 4010 of file SimplifyCFG.cpp.

References I.

Referenced by mergeConditionalStoreToAddress().

◆ FitWeights()

static void FitWeights ( MutableArrayRef< uint64_t Weights)
static

Keep halving the weights until all can fit in uint32_t.

Definition at line 1086 of file SimplifyCFG.cpp.

References llvm::countl_zero(), I, llvm::max_element(), and llvm::Offset.

Referenced by performBranchToCommonDestFolding(), and SimplifyCondBranchToCondBranch().

◆ FoldCondBranchOnValueKnownInPredecessor()

static bool FoldCondBranchOnValueKnownInPredecessor ( BranchInst BI,
DomTreeUpdater DTU,
const DataLayout DL,
AssumptionCache AC 
)
static

Definition at line 3472 of file SimplifyCFG.cpp.

References DL, and FoldCondBranchOnValueKnownInPredecessorImpl().

◆ FoldCondBranchOnValueKnownInPredecessorImpl()

static std::optional< bool > FoldCondBranchOnValueKnownInPredecessorImpl ( BranchInst BI,
DomTreeUpdater DTU,
const DataLayout DL,
AssumptionCache AC 
)
static

If we have a conditional branch on something for which we know the constant value in predecessors (e.g.

a phi node in the current block), thread edges from the predecessor to their ultimate destination.

Definition at line 3315 of file SimplifyCFG.cpp.

References AddPredecessorToBlock(), llvm::any_of(), llvm::DomTreeUpdater::applyUpdates(), llvm::BasicBlock::begin(), BlockIsSimpleEnoughToThreadThrough(), Cond, llvm::dbgs(), DL, llvm::MapVector< KeyT, ValueT, MapType, VectorType >::empty(), llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::end(), llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::find(), llvm::FoldSingleEntryPHINodes(), llvm::BranchInst::getCondition(), llvm::Instruction::getDebugLoc(), llvm::PHINode::getIncomingBlock(), llvm::PHINode::getIncomingValueForBlock(), getKnownValueOnEdge(), llvm::Value::getName(), llvm::PHINode::getNumIncomingValues(), llvm::Instruction::getParent(), llvm::BranchInst::getSuccessor(), llvm::BasicBlock::getTerminator(), llvm::ConstantInt::getZExtValue(), llvm::PHINode::incoming_values(), llvm::MapVector< KeyT, ValueT, MapType, VectorType >::insert(), LLVM_DEBUG, llvm::MergeBlockIntoPredecessor(), N, llvm::predecessors(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::AssumptionCache::registerAssumption(), llvm::BasicBlock::removePredecessor(), llvm::Instruction::setDebugLoc(), llvm::BranchInst::setSuccessor(), llvm::simplifyInstruction(), and llvm::SplitBlockPredecessors().

Referenced by FoldCondBranchOnValueKnownInPredecessor().

◆ foldSwitchToSelect()

static Value * foldSwitchToSelect ( const SwitchCaseResultVectorTy &  ResultVector,
Constant DefaultResult,
Value Condition,
IRBuilder<> &  Builder 
)
static

◆ FoldTwoEntryPHINode()

static bool FoldTwoEntryPHINode ( PHINode PN,
const TargetTransformInfo TTI,
DomTreeUpdater DTU,
const DataLayout DL 
)
static

Given a BB that starts with the specified two-entry PHI node, see if we can eliminate it.

Definition at line 3488 of file SimplifyCFG.cpp.

References llvm::any_of(), llvm::DomTreeUpdater::applyUpdates(), assert(), llvm::BasicBlock::begin(), llvm::PHINode::blocks(), llvm::copy_if(), llvm::SmallPtrSetImpl< PtrType >::count(), llvm::IRBuilderBase::CreateBr(), llvm::IRBuilderBase::CreateSelect(), llvm::dbgs(), DL, dominatesMergePoint(), llvm::Instruction::eraseFromParent(), llvm::extractBranchWeights(), llvm::BranchProbability::getBranchProbability(), llvm::BranchProbability::getCompl(), llvm::BranchInst::getCondition(), llvm::Instruction::getFastMathFlags(), llvm::GetIfCondition(), llvm::PHINode::getIncomingValue(), llvm::PHINode::getIncomingValueForBlock(), llvm::Instruction::getMetadata(), llvm::Value::getName(), llvm::Instruction::getParent(), llvm::TargetTransformInfo::getPredictableBranchThreshold(), llvm::BranchInst::getSuccessor(), llvm::Value::getType(), llvm::BasicBlock::hasAddressTaken(), llvm::hoistAllInstructionsInto(), I, llvm::Type::isIntegerTy(), LLVM_DEBUG, llvm::PatternMatch::m_AnyIntegralConstant(), llvm::PatternMatch::m_BinOp(), llvm::PatternMatch::m_CombineOr(), llvm::PatternMatch::m_ImmConstant(), llvm::PatternMatch::m_Not(), llvm::PatternMatch::m_Select(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::Value::replaceAllUsesWith(), llvm::IRBuilderBase::setFastMathFlags(), llvm::simplifyInstruction(), llvm::SmallVectorBase< Size_T >::size(), llvm::Successor, llvm::successors(), std::swap(), llvm::Value::takeName(), llvm::TargetTransformInfo::TCC_Basic, and TwoEntryPHINodeFoldingThreshold.

◆ ForwardSwitchConditionToPHI()

static bool ForwardSwitchConditionToPHI ( SwitchInst SI)
static

Try to forward the condition of a switch instruction to a phi node dominated by the switch, if that would mean that some of the destination blocks of the switch can be folded away.

Return true if a change is made.

Definition at line 5760 of file SimplifyCFG.cpp.

References llvm::count(), FindPHIForConditionForwarding(), llvm::BasicBlock::phis(), and llvm::SmallVectorBase< Size_T >::size().

◆ GetBranchWeights()

static void GetBranchWeights ( Instruction TI,
SmallVectorImpl< uint64_t > &  Weights 
)
static

◆ getCaseResults()

static bool getCaseResults ( SwitchInst SI,
ConstantInt CaseVal,
BasicBlock CaseDest,
BasicBlock **  CommonDest,
SmallVectorImpl< std::pair< PHINode *, Constant * > > &  Res,
const DataLayout DL,
const TargetTransformInfo TTI 
)
static

Try to determine the resulting constant values in phi nodes at the common destination basic block, *CommonDest, for one of the case destionations CaseDest corresponding to value CaseVal (0 for the default case), of a switch instruction SI.

Definition at line 5886 of file SimplifyCFG.cpp.

References llvm::CallingConv::C, ConstantFold(), DL, llvm::Use::getUser(), I, Idx, llvm::BasicBlock::instructionsWithoutDebug(), LookupConstant(), PHI, and ValidLookupTableConstant().

Referenced by initializeUniqueCases(), and SwitchToLookupTable().

◆ GetConstantInt()

static ConstantInt * GetConstantInt ( Value V,
const DataLayout DL 
)
static

Extract ConstantInt from value, looking through IntToPtr and PointerNullValue.

Return NULL if value is not a constant int.

Definition at line 480 of file SimplifyCFG.cpp.

References llvm::ConstantFoldIntegerCast(), DL, and llvm::Value::getType().

◆ getKnownValueOnEdge()

static ConstantInt * getKnownValueOnEdge ( Value V,
BasicBlock From,
BasicBlock To 
)
static

◆ hoistLockstepIdenticalDbgVariableRecords()

static void hoistLockstepIdenticalDbgVariableRecords ( Instruction TI,
Instruction I1,
SmallVectorImpl< Instruction * > &  OtherInsts 
)
static

Hoists DbgVariableRecords from I1 and OtherInstrs that are identical in lock-step to TI.

This matches how dbg.* intrinsics are hoisting in hoistCommonCodeFromSuccessors. e.g. The input: I1 DVRs: { x, z }, OtherInsts: { I2 DVRs: { x, y, z } } would result in hoisting only DbgVariableRecord x.

Definition at line 1536 of file SimplifyCFG.cpp.

References llvm::all_of(), llvm::ilist_node_impl< OptionsT >::getIterator(), llvm::Instruction::getParent(), I, llvm::BasicBlock::insertDbgRecordBefore(), llvm::make_first_range(), llvm::none_of(), Other, llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::DbgRecord::removeFromParent(), llvm::SmallVectorImpl< T >::reserve(), and llvm::SmallVectorBase< Size_T >::size().

◆ IncomingValuesAreCompatible()

static bool IncomingValuesAreCompatible ( BasicBlock BB,
ArrayRef< BasicBlock * >  IncomingBlocks,
SmallPtrSetImpl< Value * > *  EquivalenceSet = nullptr 
)
static

Return true if all the PHI nodes in the basic block BB receive compatible (identical) incoming values when coming from all of the predecessor blocks that are specified in IncomingBlocks.

Note that if the values aren't exactly identical, but EquivalenceSet is provided, and both of the values are present in the set, then they are considered equal.

Definition at line 316 of file SimplifyCFG.cpp.

References llvm::all_of(), assert(), llvm::BasicBlock::phis(), and llvm::ArrayRef< T >::size().

Referenced by SafeToMergeTerminators().

◆ initializeUniqueCases()

static bool initializeUniqueCases ( SwitchInst SI,
PHINode *&  PHI,
BasicBlock *&  CommonDest,
SwitchCaseResultVectorTy &  UniqueResults,
Constant *&  DefaultResult,
const DataLayout DL,
const TargetTransformInfo TTI,
uintptr_t  MaxUniqueResults 
)
static

◆ isCleanupBlockEmpty()

static bool isCleanupBlockEmpty ( iterator_range< BasicBlock::iterator R)
static

Definition at line 5023 of file SimplifyCFG.cpp.

References llvm::CallBase::getIntrinsicID(), and I.

Referenced by removeEmptyCleanup().

◆ isLifeTimeMarker()

static bool isLifeTimeMarker ( const Instruction I)
static

Definition at line 1908 of file SimplifyCFG.cpp.

References I.

Referenced by canSinkInstructions().

◆ isSafeToHoistInstr()

static bool isSafeToHoistInstr ( Instruction I,
unsigned  Flags 
)
static

◆ isSafeToHoistInvoke()

static bool isSafeToHoistInvoke ( BasicBlock BB1,
BasicBlock BB2,
Instruction I1,
Instruction I2 
)
static

Definition at line 1425 of file SimplifyCFG.cpp.

References llvm::BasicBlock::phis(), and llvm::successors().

◆ isSafeToSpeculateStore()

static Value * isSafeToSpeculateStore ( Instruction I,
BasicBlock BrBB,
BasicBlock StoreBB,
BasicBlock EndBB 
)
static

Determine if we can hoist sink a sole store instruction out of a conditional block.

We are looking for code like the following: BrBB: store i32 add, i32* arrayidx2 ... // No other stores or function calls (we could be calling a memory ... // function). cmp = icmp ult x, y br i1 cmp, label EndBB, label ThenBB ThenBB: store i32 add5, i32* arrayidx2 br label EndBB EndBB: ... We are going to transform this into: BrBB: store i32 add, i32* arrayidx2 ... // cmp = icmp ult x, y add.add5 = select i1 cmp, i32 add, add5 store i32 add.add5, i32* arrayidx2 ...

Returns
The pointer to the value of the previous store if the store can be hoisted into the predecessor block. 0 otherwise.

Definition at line 2860 of file SimplifyCFG.cpp.

References llvm::StoreInst::getPointerOperand(), llvm::Value::getType(), llvm::getUnderlyingObject(), llvm::StoreInst::getValueOperand(), I, llvm::BasicBlock::instructionsWithoutDebug(), llvm::StoreInst::isSimple(), llvm::PointerMayBeCaptured(), and llvm::reverse().

◆ isSwitchDense() [1/2]

static bool isSwitchDense ( ArrayRef< int64_t >  Values)
static

◆ isSwitchDense() [2/2]

static bool isSwitchDense ( uint64_t  NumCases,
uint64_t  CaseRange 
)
static

◆ isTypeLegalForLookupTable()

static bool isTypeLegalForLookupTable ( Type Ty,
const TargetTransformInfo TTI,
const DataLayout DL 
)
static

◆ isVectorOp()

static bool isVectorOp ( Instruction I)
static

Return if an instruction's type or any of its operands' types are a vector type.

Definition at line 3874 of file SimplifyCFG.cpp.

References llvm::any_of(), and I.

Referenced by llvm::FoldBranchToCommonDest().

◆ LookupConstant()

static Constant * LookupConstant ( Value V,
const SmallDenseMap< Value *, Constant * > &  ConstantPool 
)
static

If V is a Constant, return it.

Otherwise, try to look up its constant value in ConstantPool, returning 0 if it's not there.

Definition at line 5845 of file SimplifyCFG.cpp.

References llvm::CallingConv::C.

Referenced by ConstantFold(), and getCaseResults().

◆ mapCaseToResult()

static size_t mapCaseToResult ( ConstantInt CaseVal,
SwitchCaseResultVectorTy &  UniqueResults,
Constant Result 
)
static

Definition at line 5957 of file SimplifyCFG.cpp.

References I.

Referenced by initializeUniqueCases().

◆ mergeCleanupPad()

static bool mergeCleanupPad ( CleanupReturnInst RI)
static

◆ MergeCompatibleInvokes()

static bool MergeCompatibleInvokes ( BasicBlock BB,
DomTreeUpdater DTU 
)
static

If this block is a landingpad exception handling block, categorize all the predecessor invokes into sets, with all invokes in each set being "mergeable" together, and then merge invokes in each set together.

This is a weird mix of hoisting and sinking. Visually, it goes from: [...] [...] | | [invoke0] [invoke1] / \ / \ [cont0] [landingpad] [cont1] to: [...] [...] \ / [invoke] / \ [cont] [landingpad]

But of course we can only do that if the invokes share the landingpad, edges invoke0->cont0 and invoke1->cont1 are "compatible", and the invoked functions are "compatible".

Definition at line 2777 of file SimplifyCFG.cpp.

References EnableMergeCompatibleInvokes, llvm::BasicBlock::isLandingPad(), MergeCompatibleInvokesImpl(), llvm::predecessors(), and llvm::ArrayRef< T >::size().

◆ MergeCompatibleInvokesImpl()

static void MergeCompatibleInvokesImpl ( ArrayRef< InvokeInst * >  Invokes,
DomTreeUpdater DTU 
)
static

◆ mergeConditionalStores()

static bool mergeConditionalStores ( BranchInst PBI,
BranchInst QBI,
DomTreeUpdater DTU,
const DataLayout DL,
const TargetTransformInfo TTI 
)
static

◆ mergeConditionalStoreToAddress()

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

◆ passingValueIsAlwaysUndefined()

static bool passingValueIsAlwaysUndefined ( Value V,
Instruction I,
bool  PtrValueMayBeModified = false 
)
static

◆ performBranchToCommonDestFolding()

static bool performBranchToCommonDestFolding ( BranchInst BI,
BranchInst PBI,
DomTreeUpdater DTU,
MemorySSAUpdater MSSAU,
const TargetTransformInfo TTI 
)
static

◆ ReduceSwitchRange()

static bool ReduceSwitchRange ( SwitchInst SI,
IRBuilder<> &  Builder,
const DataLayout DL,
const TargetTransformInfo TTI 
)
static

Try to transform a switch that has "holes" in it to a contiguous sequence of cases.

A switch such as: switch(i) {case 5: case 9: case 13: case 17:} can be range-reduced to: switch ((i-5) / 4) {case 0: case 1: case 2: case 3:}.

This converts a sparse switch into a dense switch which allows better lowering and could also allow transforming into a lookup table.

Definition at line 6919 of file SimplifyCFG.cpp.

References assert(), llvm::sampleprof::Base, llvm::CallingConv::C, llvm::countr_zero(), llvm::IRBuilderBase::CreateIntrinsic(), llvm::IRBuilderBase::CreateSub(), DL, isSwitchDense(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::IRBuilderBase::SetInsertPoint(), and llvm::sort().

◆ removeEmptyCleanup()

static bool removeEmptyCleanup ( CleanupReturnInst RI,
DomTreeUpdater DTU 
)
static

◆ removeSwitchAfterSelectFold()

static void removeSwitchAfterSelectFold ( SwitchInst SI,
PHINode PHI,
Value SelectValue,
IRBuilder<> &  Builder,
DomTreeUpdater DTU 
)
static

◆ removeUndefIntroducingPredecessor()

static bool removeUndefIntroducingPredecessor ( BasicBlock BB,
DomTreeUpdater DTU,
AssumptionCache AC 
)
static

◆ replacingOperandWithVariableIsCheap()

static bool replacingOperandWithVariableIsCheap ( const Instruction I,
int  OpIdx 
)
static

Definition at line 1923 of file SimplifyCFG.cpp.

References I.

Referenced by canSinkInstructions().

◆ reuseTableCompare()

static void reuseTableCompare ( User PhiUser,
BasicBlock PhiBlock,
BranchInst RangeCheckBranch,
Constant DefaultValue,
const SmallVectorImpl< std::pair< ConstantInt *, Constant * > > &  Values 
)
static

Try to reuse the switch table index compare.

Following pattern:

if (idx < tablesize)
r = table[idx]; // table does not contain default_value
else
r = default_value;
if (r != default_value)
...

Is optimized to:

cond = idx < tablesize;
if (cond)
r = table[idx];
else
r = default_value;
if (cond)
...

Jump threading will then eliminate the second if(cond).

Definition at line 6556 of file SimplifyCFG.cpp.

References llvm::BranchInst::getCondition(), llvm::ConstantInt::getFalse(), llvm::ConstantExpr::getICmp(), llvm::ilist_node_impl< OptionsT >::getIterator(), llvm::User::getOperand(), llvm::Instruction::getParent(), llvm::CmpInst::getPredicate(), llvm::ConstantInt::getTrue(), llvm::Value::getType(), llvm::BasicBlock::getUniquePredecessor(), llvm::predecessors(), and llvm::Value::replaceAllUsesWith().

Referenced by SwitchToLookupTable().

◆ SafeToMergeTerminators()

static bool SafeToMergeTerminators ( Instruction SI1,
Instruction SI2,
SmallSetVector< BasicBlock *, 4 > *  FailBlocks = nullptr 
)
static

Return true if it is safe to merge these two terminator instructions together.

Definition at line 340 of file SimplifyCFG.cpp.

References llvm::SmallPtrSetImpl< PtrType >::count(), Fail, llvm::Instruction::getParent(), IncomingValuesAreCompatible(), llvm::succ_begin(), llvm::succ_end(), and llvm::successors().

Referenced by llvm::FoldBranchToCommonDest().

◆ setBranchWeights() [1/2]

static void setBranchWeights ( Instruction I,
uint32_t  TrueWeight,
uint32_t  FalseWeight 
)
static

Definition at line 874 of file SimplifyCFG.cpp.

References assert(), llvm::MDBuilder::createBranchWeights(), I, and N.

◆ setBranchWeights() [2/2]

static void setBranchWeights ( SwitchInst SI,
ArrayRef< uint32_t Weights 
)
static

◆ ShouldBuildLookupTable()

static bool ShouldBuildLookupTable ( SwitchInst SI,
uint64_t  TableSize,
const TargetTransformInfo TTI,
const DataLayout DL,
const SmallDenseMap< PHINode *, Type * > &  ResultTypes 
)
static

Determine whether a lookup table should be built for this switch, based on the number of cases, size of the table, and the types of the results.

Definition at line 6482 of file SimplifyCFG.cpp.

References DL, I, isSwitchDense(), and isTypeLegalForLookupTable().

Referenced by SwitchToLookupTable().

◆ shouldFoldCondBranchesToCommonDestination()

static std::optional< std::tuple< BasicBlock *, Instruction::BinaryOps, bool > > shouldFoldCondBranchesToCommonDestination ( BranchInst BI,
BranchInst PBI,
const TargetTransformInfo TTI 
)
static

◆ shouldHoistCommonInstructions()

static bool shouldHoistCommonInstructions ( Instruction I1,
Instruction I2,
const TargetTransformInfo TTI 
)
static

Helper function for hoistCommonCodeFromSuccessors.

Return true if identical instructions I1 and I2 can and should be hoisted.

Definition at line 1501 of file SimplifyCFG.cpp.

References llvm::TargetTransformInfo::isProfitableToHoist().

◆ ShouldUseSwitchConditionAsTableIndex()

static bool ShouldUseSwitchConditionAsTableIndex ( ConstantInt MinCaseVal,
const ConstantInt MaxCaseVal,
bool  HasDefaultResults,
const SmallDenseMap< PHINode *, Type * > &  ResultTypes,
const DataLayout DL,
const TargetTransformInfo TTI 
)
static

◆ SimplifyCondBranchToCondBranch()

static bool SimplifyCondBranchToCondBranch ( BranchInst PBI,
BranchInst BI,
DomTreeUpdater DTU,
const DataLayout DL,
const TargetTransformInfo TTI 
)
static

If we have a conditional branch as a predecessor of another block, this function tries to simplify it.

We know that PBI and BI are both conditional branches, and BI is in one of the successor blocks of PBI - PBI branches to BI.

Definition at line 4394 of file SimplifyCFG.cpp.

References AddPredecessorToBlock(), llvm::DomTreeUpdater::applyUpdates(), assert(), llvm::BasicBlock::begin(), Cond, llvm::BranchInst::Create(), llvm::BasicBlock::Create(), createLogicalOp(), llvm::IRBuilderBase::CreateNot(), llvm::IRBuilderBase::CreateSelect(), llvm::dbgs(), DL, llvm::extractBranchWeights(), extractPredSuccWeights(), FitWeights(), llvm::PHINode::getBasicBlockIndex(), llvm::BranchProbability::getBranchProbability(), llvm::BranchInst::getCondition(), llvm::BasicBlock::getContext(), llvm::PHINode::getIncomingValue(), llvm::PHINode::getIncomingValueForBlock(), llvm::Type::getInt1Ty(), llvm::Instruction::getMetadata(), llvm::Value::getName(), llvm::BasicBlock::getParent(), llvm::Instruction::getParent(), llvm::TargetTransformInfo::getPredictableBranchThreshold(), llvm::BasicBlock::getSinglePredecessor(), llvm::BranchInst::getSuccessor(), llvm::BasicBlock::instructionsWithoutDebug(), llvm::BranchInst::isConditional(), LLVM_DEBUG, mergeConditionalStores(), MergeCondStores, llvm::BasicBlock::phis(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), setBranchWeights(), llvm::BranchInst::setCondition(), llvm::PHINode::setIncomingValue(), llvm::BranchInst::setSuccessor(), and tryWidenCondBranchToCondBranch().

◆ simplifySwitchOfPowersOfTwo()

static bool simplifySwitchOfPowersOfTwo ( SwitchInst SI,
IRBuilder<> &  Builder,
const DataLayout DL,
const TargetTransformInfo TTI 
)
static

Tries to transform switch of powers of two to reduce switch range.

For example, switch like: switch (C) { case 1: case 2: case 64: case 128: } will be transformed to: switch (count_trailing_zeros(C)) { case 0: case 1: case 6: case 7: }

This transformation allows better lowering and could allow transforming into a lookup table.

Definition at line 7006 of file SimplifyCFG.cpp.

References llvm::SmallVectorTemplateCommon< T, typename >::back(), Context, llvm::countr_zero(), llvm::IRBuilderBase::CreateIntrinsic(), DL, llvm::SmallVectorTemplateCommon< T, typename >::front(), llvm::TargetTransformInfo::getIntrinsicInstrCost(), llvm::ConstantInt::getTrue(), llvm::Value::getType(), llvm::has_single_bit(), isSwitchDense(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::IRBuilderBase::SetInsertPoint(), llvm::SmallVectorBase< Size_T >::size(), llvm::sort(), llvm::TargetTransformInfo::TCC_Basic, and llvm::TargetTransformInfo::TCK_SizeAndLatency.

◆ SinkCommonCodeFromPredecessors()

static bool SinkCommonCodeFromPredecessors ( BasicBlock BB,
DomTreeUpdater DTU 
)
static

◆ sinkLastInstruction()

static bool sinkLastInstruction ( ArrayRef< BasicBlock * >  Blocks)
static

◆ skippedInstrFlags()

static unsigned skippedInstrFlags ( Instruction I)
static

◆ STATISTIC() [1/15]

STATISTIC ( NumBitMaps  ,
"Number of switch instructions turned into bitmaps"   
)

◆ STATISTIC() [2/15]

STATISTIC ( NumFoldBranchToCommonDest  ,
"Number of branches folded into predecessor basic block"   
)

◆ STATISTIC() [3/15]

STATISTIC ( NumFoldValueComparisonIntoPredecessors  ,
"Number of value comparisons folded into predecessor basic blocks"   
)

◆ STATISTIC() [4/15]

STATISTIC ( NumHoistCommonCode  ,
"Number of common instruction 'blocks' hoisted up to the begin block"   
)

◆ STATISTIC() [5/15]

STATISTIC ( NumHoistCommonInstrs  ,
"Number of common instructions hoisted up to the begin block"   
)

◆ STATISTIC() [6/15]

STATISTIC ( NumInvokes  ,
"Number of invokes with empty resume blocks simplified into calls"   
)

◆ STATISTIC() [7/15]

STATISTIC ( NumInvokeSetsFormed  ,
"Number of invoke sets that were formed"   
)

◆ STATISTIC() [8/15]

STATISTIC ( NumInvokesMerged  ,
"Number of invokes that were merged together"   
)

◆ STATISTIC() [9/15]

STATISTIC ( NumLinearMaps  ,
"Number of switch instructions turned into linear mapping"   
)

◆ STATISTIC() [10/15]

STATISTIC ( NumLookupTables  ,
"Number of switch instructions turned into lookup tables"   
)

◆ STATISTIC() [11/15]

STATISTIC ( NumLookupTablesHoles  ,
"Number of switch instructions turned into lookup tables (holes checked)"   
)

◆ STATISTIC() [12/15]

STATISTIC ( NumSinkCommonCode  ,
"Number of common instruction 'blocks' sunk down to the end block"   
)

◆ STATISTIC() [13/15]

STATISTIC ( NumSinkCommonInstrs  ,
"Number of common instructions sunk down to the end block"   
)

◆ STATISTIC() [14/15]

STATISTIC ( NumSpeculations  ,
"Number of speculative executed instructions"   
)

◆ STATISTIC() [15/15]

STATISTIC ( NumTableCmpReuses  ,
"Number of reused switch table lookup compares"   
)

◆ SwitchToLookupTable()

static bool SwitchToLookupTable ( SwitchInst SI,
IRBuilder<> &  Builder,
DomTreeUpdater DTU,
const DataLayout DL,
const TargetTransformInfo TTI 
)
static

If the switch is only used to initialize one or more phi nodes in a common successor block with different constant values, replace the switch with lookup tables.

Definition at line 6620 of file SimplifyCFG.cpp.

References AddPredecessorToBlock(), llvm::all_of(), llvm::DomTreeUpdater::applyUpdates(), assert(), llvm::computeConstantRange(), llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::count(), llvm::BasicBlock::Create(), llvm::IRBuilderBase::CreateBr(), llvm::IRBuilderBase::CreateCondBr(), llvm::IRBuilderBase::CreateICmpULT(), llvm::IRBuilderBase::CreateLShr(), llvm::IRBuilderBase::CreateSub(), llvm::IRBuilderBase::CreateTrunc(), llvm::IRBuilderBase::CreateZExtOrTrunc(), DL, getCaseResults(), llvm::Module::getContext(), llvm::Function::getFnAttribute(), llvm::Type::getInt1Ty(), llvm::ConstantInt::getIntegerType(), llvm::APInt::getLimitedValue(), llvm::ConstantInt::getLimitedValue(), llvm::Value::getName(), llvm::GlobalValue::getParent(), llvm::BasicBlock::getParent(), llvm::Type::getPrimitiveSizeInBits(), llvm::Value::getType(), llvm::ConstantRange::getUpper(), llvm::ConstantInt::getValue(), llvm::Attribute::getValueAsBool(), I, Idx, llvm::SmallPtrSetImpl< PtrType >::insert(), llvm::ConstantRange::isUpperWrapped(), Mod, llvm::NextPowerOf2(), PHI, llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::BasicBlock::removePredecessor(), Results, reuseTableCompare(), llvm::IRBuilderBase::SetInsertPoint(), llvm::Value::setName(), llvm::APInt::sgt(), ShouldBuildLookupTable(), llvm::TargetTransformInfo::shouldBuildLookupTables(), ShouldUseSwitchConditionAsTableIndex(), llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::size(), llvm::APInt::slt(), llvm::APInt::ssub_ov(), and UINT64_MAX.

◆ trySwitchToSelect()

static bool trySwitchToSelect ( SwitchInst SI,
IRBuilder<> &  Builder,
DomTreeUpdater DTU,
const DataLayout DL,
const TargetTransformInfo TTI 
)
static

If a switch is only used to initialize one or more phi nodes in a common successor block with only two different constant values, try to replace the switch with a select.

Returns true if the fold was made.

Definition at line 6145 of file SimplifyCFG.cpp.

References assert(), Cond, DL, foldSwitchToSelect(), initializeUniqueCases(), PHI, removeSwitchAfterSelectFold(), and llvm::IRBuilderBase::SetInsertPoint().

◆ TryToMergeLandingPad()

static bool TryToMergeLandingPad ( LandingPadInst LPad,
BranchInst BI,
BasicBlock BB,
DomTreeUpdater DTU 
)
static

Given an block with only a single landing pad and a unconditional branch try to find another basic block which this one can be merged with.

This handles cases where we have multiple invokes with unique landing pads, but a shared handler.

We specifically choose to not worry about merging non-empty blocks here. That is a PRE/scheduling problem and is best solved elsewhere. In practice, the optimizer produces empty landing pad blocks quite frequently when dealing with exception dense code. (see: instcombine, gvn, if-else sinking in this file)

This is primarily a code size optimization. We need to avoid performing any transform which might inhibit optimization (such as our ability to specialize a particular handler via tail commoning). We do this by not merging any blocks which require us to introduce a phi. Since the same values are flowing through both blocks, we don't lose any ability to specialize. If anything, we make such specialization more likely.

TODO - This transformation could remove entries from a phi in the target block when the inputs in the phi are the same for the two blocks being merged. In some cases, this could result in removal of the PHI entirely.

Definition at line 7202 of file SimplifyCFG.cpp.

References llvm::DomTreeUpdater::applyUpdates(), assert(), llvm::BasicBlock::begin(), llvm::IRBuilderBase::CreateUnreachable(), llvm::Instruction::eraseFromParent(), llvm::InvokeInst::getNormalDest(), llvm::BasicBlock::getTerminator(), llvm::BasicBlock::getUniqueSuccessor(), llvm::InvokeInst::getUnwindDest(), I, llvm::Instruction::isIdenticalTo(), llvm::make_early_inc_range(), llvm::pred_begin(), llvm::pred_end(), llvm::predecessors(), llvm::BasicBlock::removePredecessor(), llvm::InvokeInst::setUnwindDest(), llvm::succ_begin(), and llvm::succ_end().

◆ tryWidenCondBranchToCondBranch()

static bool tryWidenCondBranchToCondBranch ( BranchInst PBI,
BranchInst BI,
DomTreeUpdater DTU 
)
static

If the previous block ended with a widenable branch, determine if reusing the target block is profitable and legal.

This will have the effect of "widening" PBI, but doesn't require us to reason about hosting safety.

Definition at line 4337 of file SimplifyCFG.cpp.

References llvm::DomTreeUpdater::applyUpdates(), llvm::Instruction::getParent(), llvm::BasicBlock::getSinglePredecessor(), llvm::BranchInst::getSuccessor(), llvm::BasicBlock::getTerminatingDeoptimizeCall(), I, llvm::isWidenableBranch(), llvm::none_of(), llvm::BasicBlock::phis(), llvm::BasicBlock::removePredecessor(), llvm::BranchInst::setSuccessor(), and llvm::succ_empty().

Referenced by SimplifyCondBranchToCondBranch().

◆ validateAndCostRequiredSelects()

static bool validateAndCostRequiredSelects ( BasicBlock BB,
BasicBlock ThenBB,
BasicBlock EndBB,
unsigned SpeculatedInstructions,
InstructionCost Cost,
const TargetTransformInfo TTI 
)
static

◆ ValidLookupTableConstant()

static bool ValidLookupTableConstant ( Constant C,
const TargetTransformInfo TTI 
)
static

Return true if the backend will be able to handle initializing an array of constants like C.

Definition at line 5817 of file SimplifyCFG.cpp.

References llvm::CallingConv::C, llvm::TargetTransformInfo::shouldBuildLookupTablesForConstant(), and ValidLookupTableConstant().

Referenced by getCaseResults(), and ValidLookupTableConstant().

◆ ValuesOverlap()

static bool ValuesOverlap ( std::vector< ValueEqualityComparisonCase > &  C1,
std::vector< ValueEqualityComparisonCase > &  C2 
)
static

Return true if there are any keys in C1 that exist in C2 as well.

Definition at line 828 of file SimplifyCFG.cpp.

References llvm::array_pod_sort(), std::swap(), and llvm::Value::Value().

Variable Documentation

◆ BranchFoldThreshold

cl::opt< unsigned > BranchFoldThreshold("simplifycfg-branch-fold-threshold", cl::Hidden, cl::init(2), cl::desc("Maximum cost of combining conditions when " "folding branches")) ( "simplifycfg-branch-fold-threshold"  ,
cl::Hidden  ,
cl::init(2)  ,
cl::desc("Maximum cost of combining conditions when " "folding branches")   
)
static

◆ BranchFoldToCommonDestVectorMultiplier

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")) ( "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

◆ EnableMergeCompatibleInvokes

cl::opt< bool > EnableMergeCompatibleInvokes("simplifycfg-merge-compatible-invokes", cl::Hidden, cl::init(true), cl::desc("Allow SimplifyCFG to merge invokes together when appropriate")) ( "simplifycfg-merge-compatible-invokes"  ,
cl::Hidden  ,
cl::init(true ,
cl::desc("Allow SimplifyCFG to merge invokes together when appropriate")   
)
static

Referenced by MergeCompatibleInvokes().

◆ HoistCommon

cl::opt< bool > HoistCommon("simplifycfg-hoist-common", cl::Hidden, cl::init(true), cl::desc("Hoist common instructions up to the parent block")) ( "simplifycfg-hoist-common"  ,
cl::Hidden  ,
cl::init(true ,
cl::desc("Hoist common instructions up to the parent block")   
)
static

◆ HoistCommonSkipLimit

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")) ( "simplifycfg-hoist-common-skip-limit"  ,
cl::Hidden  ,
cl::init(20)  ,
cl::desc("Allow reordering across at most this many " "instructions when hoisting")   
)
static

◆ HoistCondStores

cl::opt< bool > HoistCondStores("simplifycfg-hoist-cond-stores", cl::Hidden, cl::init(true), cl::desc("Hoist conditional stores if an unconditional store precedes")) ( "simplifycfg-hoist-cond-stores"  ,
cl::Hidden  ,
cl::init(true ,
cl::desc("Hoist conditional stores if an unconditional store precedes")   
)
static

◆ MaxSmallBlockSize

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")) ( "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

◆ MaxSpeculationDepth

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")) ( "max-speculation-depth"  ,
cl::Hidden  ,
cl::init(10)  ,
cl::desc("Limit maximum recursion depth when calculating costs of " "speculatively executed instructions")   
)
static

Referenced by dominatesMergePoint().

◆ MaxSwitchCasesPerResult

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")) ( "max-switch-cases-per-result"  ,
cl::Hidden  ,
cl::init(16)  ,
cl::desc("Limit cases to analyze when converting a switch to select")   
)
static

Referenced by initializeUniqueCases().

◆ MergeCondStores

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")) ( "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

◆ MergeCondStoresAggressively

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")) ( "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

◆ PHINodeFoldingThreshold

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)")) ( "phi-node-folding-threshold"  ,
cl::Hidden  ,
cl::init(2)  ,
cl::desc( "Control the amount of phi node folding to perform (default = 2)")   
)
static

◆ SinkCommon

cl::opt< bool > SinkCommon("simplifycfg-sink-common", cl::Hidden, cl::init(true), cl::desc("Sink common instructions down to the end block")) ( "simplifycfg-sink-common"  ,
cl::Hidden  ,
cl::init(true ,
cl::desc("Sink common instructions down to the end block")   
)
static

◆ SpeculateOneExpensiveInst

cl::opt< bool > SpeculateOneExpensiveInst("speculate-one-expensive-inst", cl::Hidden, cl::init(true), cl::desc("Allow exactly one expensive instruction to be speculatively " "executed")) ( "speculate-one-expensive-inst"  ,
cl::Hidden  ,
cl::init(true ,
cl::desc("Allow exactly one expensive instruction to be speculatively " "executed")   
)
static

Referenced by dominatesMergePoint().

◆ TwoEntryPHINodeFoldingThreshold

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)")) ( "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

Referenced by FoldTwoEntryPHINode().