LLVM 20.0.0git
|
#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>
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 ConstantInt * | getConstantInt (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, bool IsExpected) |
static void | setBranchWeights (Instruction *I, uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected) |
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 | areIdenticalUpToCommutativity (const Instruction *I1, const Instruction *I2) |
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) |
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 invoke s into sets, with all invoke s in each set being "mergeable" together, and then merge invokes in each set together. | |
static Value * | isSafeToSpeculateStore (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 | isProfitableToSpeculate (const BranchInst *BI, bool Invert, const TargetTransformInfo &TTI) |
static bool | blockIsSimpleEnoughToThreadThrough (BasicBlock *BB) |
Return true if we can thread a branch across this block. | |
static ConstantInt * | getKnownValueOnEdge (Value *V, BasicBlock *From, BasicBlock *To) |
static std::optional< bool > | foldCondBranchOnValueKnownInPredecessorImpl (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, bool SpeculateUnpredictables) |
Given a BB that starts with the specified two-entry PHI node, see if we can eliminate it. | |
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) |
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 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) |
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, bool RemoveOrigDefaultBlock=true) |
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 PHINode * | findPHIForConditionForwarding (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 Constant * | lookupConstant (Value *V, const SmallDenseMap< Value *, Constant * > &ConstantPool) |
If V is a Constant, return it. | |
static Constant * | constantFold (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 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) |
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 BasicBlock * | allPredecessorsComeFromSameSource (BasicBlock *BB) |
static bool | mergeNestedCondBranch (BranchInst *BI, DomTreeUpdater *DTU) |
Fold the following pattern: bb0: br i1 cond1, label bb1, label bb2 bb1: br i1 cond2, label bb3, label bb4 bb2: br i1 cond2, label bb4, label bb3 bb3: ... bb4: ... into bb0: cond = xor i1 cond1, cond2 br i1 cond, label bb4, label bb3 bb3: ... bb4: ... NOTE: cond2 always dominates the terminator of bb0. | |
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< 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< 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")) |
#define DEBUG_TYPE "simplifycfg" |
Definition at line 93 of file SimplifyCFG.cpp.
enum SkipFlags |
Enumerator | |
---|---|
SkipReadMem | |
SkipSideEffect | |
SkipImplicitControlFlow |
Definition at line 1441 of file SimplifyCFG.cpp.
|
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 373 of file SimplifyCFG.cpp.
References llvm::BasicBlock::phis().
Referenced by foldCondBranchOnValueKnownInPredecessorImpl(), performBranchToCommonDestFolding(), SimplifyCondBranchToCondBranch(), and switchToLookupTable().
|
static |
Definition at line 7382 of file SimplifyCFG.cpp.
References P, and llvm::predecessors().
|
static |
Definition at line 1586 of file SimplifyCFG.cpp.
References llvm::drop_begin(), llvm::equal(), llvm::User::getOperand(), and llvm::User::operands().
|
static |
Return true if we can thread a branch across this block.
Definition at line 3274 of file SimplifyCFG.cpp.
References llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), I, llvm::BasicBlock::instructionsWithoutDebug(), MaxSmallBlockSize, llvm::reverse(), and Size.
Referenced by foldCondBranchOnValueKnownInPredecessorImpl().
|
static |
Definition at line 1953 of file SimplifyCFG.cpp.
References llvm::all_of(), llvm::any_of(), assert(), llvm::CallingConv::C, llvm::canReplaceOperandWithVariable(), llvm::equal(), llvm::ArrayRef< T >::front(), llvm::User::getNumOperands(), llvm::User::getOperand(), llvm::User::getOperandUse(), I, isLifeTimeMarker(), replacingOperandWithVariableIsCheap(), and llvm::Value::uses().
Referenced by sinkCommonCodeFromPredecessors().
|
static |
Definition at line 5507 of file SimplifyCFG.cpp.
References llvm::array_pod_sort(), assert(), llvm::SmallVectorTemplateCommon< T, typename >::begin(), constantIntSortPredicate(), llvm::SmallVectorTemplateCommon< T, typename >::end(), I, and llvm::SmallVectorBase< Size_T >::size().
|
static |
Definition at line 1095 of file SimplifyCFG.cpp.
References assert(), llvm::Instruction::clone(), llvm::Instruction::cloneDebugInfoFrom(), llvm::Instruction::dropUBImplyingAttrsAndMetadata(), llvm::Instruction::getDebugLoc(), llvm::ilist_node_impl< OptionsT >::getIterator(), llvm::Instruction::getModule(), llvm::Value::getName(), llvm::BasicBlock::getTerminator(), llvm::Instruction::insertInto(), llvm::make_early_inc_range(), Range, llvm::RemapDbgRecordRange(), llvm::RemapInstruction(), llvm::RF_IgnoreMissingLocals, llvm::RF_NoModuleLevelChanges, llvm::Instruction::setDebugLoc(), and llvm::Value::takeName().
Referenced by performBranchToCommonDestFolding().
|
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 387 of file SimplifyCFG.cpp.
References assert(), llvm::TargetTransformInfo::getInstructionCost(), I, llvm::isSafeToSpeculativelyExecute(), and llvm::TargetTransformInfo::TCK_SizeAndLatency.
Referenced by dominatesMergePoint(), and validateAndCostRequiredSelects().
|
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 5904 of file SimplifyCFG.cpp.
References A, llvm::ConstantFoldInstOperands(), DL, I, lookupConstant(), N, llvm::SmallVectorTemplateBase< T, bool >::push_back(), and Select.
Referenced by getCaseResults().
|
static |
Definition at line 1056 of file SimplifyCFG.cpp.
Referenced by casesAreContiguous().
|
static |
Definition at line 3701 of file SimplifyCFG.cpp.
References llvm::IRBuilderBase::CreateBinOp(), llvm::IRBuilderBase::CreateLogicalAnd(), llvm::IRBuilderBase::CreateLogicalOr(), llvm::impliesPoison(), LHS, llvm_unreachable, Name, and RHS.
Referenced by performBranchToCommonDestFolding(), and SimplifyCondBranchToCondBranch().
|
static |
Definition at line 5518 of file SimplifyCFG.cpp.
References llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::applyUpdates(), llvm::BasicBlock::Create(), llvm::dbgs(), llvm::BasicBlock::getContext(), llvm::Value::getName(), llvm::BasicBlock::getParent(), llvm::is_contained(), LLVM_DEBUG, llvm::SmallVectorTemplateBase< T, bool >::push_back(), and llvm::successors().
Referenced by eliminateDeadSwitchCases().
|
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 412 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().
|
static |
Given a vector of bb/value pairs, remove any entries in the list that match the specified block.
Definition at line 823 of file SimplifyCFG.cpp.
References llvm::erase().
|
static |
Compute masked bits for the condition of a switch and use it to remove dead cases.
Definition at line 5673 of file SimplifyCFG.cpp.
References llvm::SwitchInstProfUpdateWrapper::addCase(), llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::applyUpdates(), assert(), llvm::computeKnownBits(), llvm::ComputeMaxSignificantBits(), Cond, llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::count(), createUnreachableSwitchDefault(), llvm::dbgs(), DL, llvm::SmallVectorBase< Size_T >::empty(), llvm::KnownBits::getBitWidth(), llvm::Type::getIntegerBitWidth(), llvm::APInt::getSignificantBits(), llvm::SwitchInstProfUpdateWrapper::getSuccessorWeight(), llvm::APInt::intersects(), llvm::APInt::isSubsetOf(), LLVM_DEBUG, llvm::KnownBits::One, llvm::popcount(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::SwitchInstProfUpdateWrapper::removeCase(), llvm::SwitchInstProfUpdateWrapper::setSuccessorWeight(), llvm::Successor, and llvm::KnownBits::Zero.
|
static |
Definition at line 4047 of file SimplifyCFG.cpp.
References assert(), llvm::BasicBlock::begin(), llvm::PHINode::Create(), llvm::PoisonValue::get(), getParent(), llvm::BasicBlock::getSingleSuccessor(), llvm::BasicBlock::hasNPredecessors(), I, PHI, llvm::pred_begin(), and llvm::predecessors().
Referenced by mergeConditionalStoreToAddress().
|
static |
Definition at line 756 of file SimplifyCFG.cpp.
References Cond, llvm::Instruction::eraseFromParent(), and llvm::RecursivelyDeleteTriviallyDeadInstructions().
|
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 3717 of file SimplifyCFG.cpp.
References llvm::extractBranchWeights().
Referenced by performBranchToCommonDestFolding(), and SimplifyCondBranchToCondBranch().
|
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 5775 of file SimplifyCFG.cpp.
References assert(), llvm::BasicBlock::getFirstNonPHIOrDbg(), llvm::BasicBlock::getSinglePredecessor(), llvm::BasicBlock::getTerminator(), Idx, PHI, and llvm::BasicBlock::phis().
Referenced by forwardSwitchConditionToPHI().
|
static |
Definition at line 4030 of file SimplifyCFG.cpp.
References I.
Referenced by mergeConditionalStoreToAddress().
|
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 mergeNestedCondBranch(), performBranchToCommonDestFolding(), and SimplifyCondBranchToCondBranch().
|
static |
Definition at line 3487 of file SimplifyCFG.cpp.
References DL, and foldCondBranchOnValueKnownInPredecessorImpl().
|
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 3330 of file SimplifyCFG.cpp.
References addPredecessorToBlock(), llvm::any_of(), llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::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::ilist_detail::node_parent_access< NodeTy, ParentTy >::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().
|
static |
Definition at line 6079 of file SimplifyCFG.cpp.
References llvm::And, llvm::IRBuilderBase::CreateAnd(), llvm::IRBuilderBase::CreateICmpEQ(), llvm::IRBuilderBase::CreateOr(), llvm::IRBuilderBase::CreateSelect(), llvm::IRBuilderBase::CreateSub(), llvm::ConstantInt::getBitWidth(), llvm::Constant::getNullValue(), llvm::ConstantInt::getValue(), llvm::APInt::getZero(), llvm::Constant::isNullValue(), llvm::isPowerOf2_32(), llvm::Log2_32(), llvm::APInt::popcount(), and llvm::ArrayRef< T >::size().
Referenced by trySwitchToSelect().
|
static |
Given a BB that starts with the specified two-entry PHI node, see if we can eliminate it.
Definition at line 3503 of file SimplifyCFG.cpp.
References llvm::any_of(), llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::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::TargetTransformInfo::getBranchMispredictPenalty(), 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::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::TargetTransformInfo::getPredictableBranchThreshold(), llvm::BranchInst::getSuccessor(), llvm::Value::getType(), llvm::BasicBlock::hasAddressTaken(), llvm::hoistAllInstructionsInto(), I, II, 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.
|
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 5806 of file SimplifyCFG.cpp.
References llvm::count(), findPHIForConditionForwarding(), llvm::is_contained(), llvm::BasicBlock::phis(), and llvm::SmallVectorBase< Size_T >::size().
|
static |
Get Weights of a given terminator, the default weight is at the front of the vector.
If TI is a conditional eq, we need to swap the branch-weight metadata.
Definition at line 1068 of file SimplifyCFG.cpp.
References assert(), llvm::SmallVectorTemplateCommon< T, typename >::back(), llvm::extractFromBranchWeightMD64(), llvm::SmallVectorTemplateCommon< T, typename >::front(), llvm::BranchInst::getCondition(), llvm::Instruction::getMetadata(), llvm::CmpInst::getPredicate(), llvm::SmallVectorBase< Size_T >::size(), and std::swap().
|
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 5933 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().
|
static |
Extract ConstantInt from value, looking through IntToPtr and PointerNullValue.
Return NULL if value is not a constant int.
Definition at line 481 of file SimplifyCFG.cpp.
References llvm::ConstantFoldIntegerCast(), DL, and llvm::Value::getType().
|
static |
Definition at line 3308 of file SimplifyCFG.cpp.
References From, llvm::BranchInst::getCondition(), llvm::Value::getContext(), llvm::ConstantInt::getFalse(), llvm::BranchInst::getSuccessor(), llvm::ConstantInt::getTrue(), I, and llvm::BranchInst::isConditional().
Referenced by foldCondBranchOnValueKnownInPredecessorImpl().
|
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 1535 of file SimplifyCFG.cpp.
References llvm::all_of(), llvm::ilist_node_impl< OptionsT >::getIterator(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), I, 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().
|
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 317 of file SimplifyCFG.cpp.
References llvm::all_of(), assert(), llvm::BasicBlock::phis(), and llvm::ArrayRef< T >::size().
Referenced by safeToMergeTerminators().
|
static |
Definition at line 6022 of file SimplifyCFG.cpp.
References llvm::SmallVectorTemplateCommon< T, typename >::begin(), llvm::Function::begin(), DL, getCaseResults(), llvm::BasicBlock::getFirstNonPHIOrDbg(), I, mapCaseToResult(), MaxSwitchCasesPerResult, PHI, Results, llvm::SmallVectorBase< Size_T >::size(), and llvm::Function::size().
Referenced by trySwitchToSelect().
|
static |
Definition at line 5044 of file SimplifyCFG.cpp.
Referenced by removeEmptyCleanup().
|
static |
Definition at line 1928 of file SimplifyCFG.cpp.
Referenced by canSinkInstructions().
|
static |
Definition at line 2982 of file SimplifyCFG.cpp.
References llvm::extractBranchWeights(), llvm::BranchProbability::getBranchProbability(), llvm::Instruction::getMetadata(), and llvm::TargetTransformInfo::getPredictableBranchThreshold().
|
static |
Definition at line 1462 of file SimplifyCFG.cpp.
References I, llvm::isSafeToSpeculativelyExecute(), SkipImplicitControlFlow, SkipReadMem, and SkipSideEffect.
|
static |
Definition at line 1424 of file SimplifyCFG.cpp.
References llvm::BasicBlock::phis(), and llvm::successors().
|
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 ...
Definition at line 2868 of file SimplifyCFG.cpp.
References llvm::StoreInst::getAlign(), llvm::StoreInst::getPointerOperand(), llvm::Value::getType(), llvm::getUnderlyingObject(), llvm::StoreInst::getValueOperand(), I, llvm::BasicBlock::instructionsWithoutDebug(), llvm::StoreInst::isSimple(), llvm::PointerMayBeCaptured(), and llvm::reverse().
Definition at line 6514 of file SimplifyCFG.cpp.
References llvm::ArrayRef< T >::back(), llvm::ArrayRef< T >::front(), isSwitchDense(), Range, and llvm::ArrayRef< T >::size().
Definition at line 6502 of file SimplifyCFG.cpp.
References UINT64_MAX.
Referenced by isSwitchDense(), reduceSwitchRange(), shouldBuildLookupTable(), and simplifySwitchOfPowersOfTwo().
|
static |
Definition at line 6481 of file SimplifyCFG.cpp.
References llvm::BitWidth, DL, llvm::isPowerOf2_32(), llvm::TargetTransformInfo::isTypeLegal(), and IT.
Referenced by shouldBuildLookupTable().
|
static |
Return if an instruction's type or any of its operands' types are a vector type.
Definition at line 3894 of file SimplifyCFG.cpp.
References llvm::any_of(), and I.
Referenced by llvm::foldBranchToCommonDest().
|
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 5892 of file SimplifyCFG.cpp.
References llvm::CallingConv::C.
Referenced by constantFold(), and getCaseResults().
|
static |
Definition at line 6004 of file SimplifyCFG.cpp.
References I.
Referenced by initializeUniqueCases().
|
static |
Definition at line 5275 of file SimplifyCFG.cpp.
References llvm::BranchInst::Create(), llvm::Instruction::eraseFromParent(), llvm::BasicBlock::front(), llvm::CleanupReturnInst::getCleanupPad(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::BasicBlock::getSinglePredecessor(), llvm::CleanupReturnInst::getUnwindDest(), and llvm::Value::replaceAllUsesWith().
|
static |
If this block is a landingpad
exception handling block, categorize all the predecessor invoke
s into sets, with all invoke
s 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 2785 of file SimplifyCFG.cpp.
References EnableMergeCompatibleInvokes, llvm::BasicBlock::isLandingPad(), mergeCompatibleInvokesImpl(), llvm::predecessors(), and llvm::ArrayRef< T >::size().
|
static |
Definition at line 2640 of file SimplifyCFG.cpp.
References assert(), llvm::Instruction::clone(), llvm::BasicBlock::Create(), llvm::BasicBlock::end(), llvm::ArrayRef< T >::front(), llvm::Value::getContext(), llvm::Value::getName(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::BasicBlock::getParent(), II, llvm::Instruction::insertInto(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::SmallVectorImpl< T >::reserve(), llvm::InvokeInst::setNormalDest(), llvm::ArrayRef< T >::size(), and llvm::successors().
Referenced by mergeCompatibleInvokes().
|
static |
Definition at line 4245 of file SimplifyCFG.cpp.
References DL, llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::BasicBlock::getSinglePredecessor(), llvm::BasicBlock::getSingleSuccessor(), llvm::BranchInst::getSuccessor(), I, llvm::SmallPtrSetImpl< PtrType >::insert(), mergeConditionalStoreToAddress(), P, llvm::set_intersect(), and std::swap().
Referenced by SimplifyCondBranchToCondBranch().
|
static |
Definition at line 4097 of file SimplifyCFG.cpp.
References assert(), llvm::IRBuilderBase::CreateNot(), llvm::IRBuilderBase::CreateOr(), llvm::IRBuilderBase::CreateStore(), ensureValueAvailableInSuccessor(), llvm::Instruction::eraseFromParent(), llvm::find(), findUniqueStoreInBlocks(), llvm::Instruction::getAAMetadata(), llvm::StoreInst::getAlign(), llvm::BasicBlock::getFirstInsertionPt(), llvm::IRBuilderBase::GetInsertPoint(), llvm::TargetTransformInfo::getInstructionCost(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::BasicBlock::getSinglePredecessor(), llvm::BasicBlock::getTerminator(), llvm::Value::getType(), llvm::StoreInst::getValueOperand(), I, llvm::BasicBlock::instructionsWithoutDebug(), llvm::StoreInst::isUnordered(), llvm::AAMDNodes::merge(), MergeCondStoresAggressively, PHINodeFoldingThreshold, llvm::pred_begin(), llvm::pred_end(), llvm::IRBuilderBase::SetCurrentDebugLocation(), llvm::IRBuilderBase::SetInsertPoint(), llvm::SplitBlockAndInsertIfThen(), llvm::SplitBlockPredecessors(), llvm::TargetTransformInfo::TCC_Basic, and llvm::TargetTransformInfo::TCK_SizeAndLatency.
Referenced by mergeConditionalStores().
|
static |
Fold the following pattern: bb0: br i1 cond1, label bb1, label bb2 bb1: br i1 cond2, label bb3, label bb4 bb2: br i1 cond2, label bb4, label bb3 bb3: ... bb4: ... into bb0: cond = xor i1 cond1, cond2 br i1 cond, label bb4, label bb3 bb3: ... bb4: ... NOTE: cond2 always dominates the terminator of bb0.
Definition at line 7413 of file SimplifyCFG.cpp.
References llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::applyUpdates(), llvm::IRBuilderBase::CreateXor(), llvm::extractBranchWeights(), fitWeights(), llvm::BasicBlock::front(), llvm::BranchInst::getCondition(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::BranchInst::getSuccessor(), llvm::BasicBlock::getTerminator(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::BasicBlock::removePredecessor(), setBranchWeights(), llvm::BranchInst::setCondition(), and llvm::BranchInst::setSuccessor().
|
static |
Check if passing a value to an instruction will cause undefined behavior.
Definition at line 7597 of file SimplifyCFG.cpp.
References llvm::any_of(), llvm::CallingConv::C, llvm::find_if(), GEP, I, llvm::isGuaranteedToTransferExecutionToSuccessor(), llvm::make_range(), llvm::NullPointerIsDefined(), and passingValueIsAlwaysUndefined().
Referenced by passingValueIsAlwaysUndefined(), removeUndefIntroducingPredecessor(), and validateAndCostRequiredSelects().
|
static |
Definition at line 3780 of file SimplifyCFG.cpp.
References addPredecessorToBlock(), llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::applyUpdates(), llvm::SmallVectorTemplateCommon< T, typename >::begin(), llvm::Instruction::cloneDebugInfoFrom(), cloneInstructionsIntoPredecessorBlockAndUpdateSSAUses(), llvm::IRBuilderBase::CollectMetadataToCopy(), createLogicalOp(), llvm::dbgs(), llvm::SmallVectorTemplateCommon< T, typename >::end(), extractPredSuccWeights(), llvm::filterDbgVars(), fitWeights(), llvm::BranchInst::getCondition(), llvm::Instruction::getDbgRecordRange(), llvm::Instruction::getMetadata(), llvm::BasicBlock::getModule(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::BranchInst::getSuccessor(), llvm::BasicBlock::getTerminator(), llvm::InvertBranch(), llvm::BasicBlock::IsNewDbgInfoFormat, LLVM_DEBUG, llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::RemapDbgRecord(), llvm::RF_IgnoreMissingLocals, llvm::RF_NoModuleLevelChanges, setBranchWeights(), llvm::BranchInst::setCondition(), llvm::Instruction::setMetadata(), llvm::BranchInst::setSuccessor(), and shouldFoldCondBranchesToCommonDestination().
Referenced by llvm::foldBranchToCommonDest().
|
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 6981 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().
|
static |
Definition at line 5157 of file SimplifyCFG.cpp.
References llvm::PHINode::addIncoming(), llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::applyUpdates(), assert(), llvm::DeleteDeadBlock(), llvm::PoisonValue::get(), llvm::CleanupReturnInst::getCleanupPad(), llvm::BasicBlock::getFirstNonPHI(), llvm::PHINode::getIncomingValueForBlock(), llvm::ilist_node_with_parent< NodeTy, ParentTy, Options >::getNextNode(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::Value::getType(), llvm::CleanupReturnInst::getUnwindDest(), llvm::Value::hasOneUse(), Idx, isCleanupBlockEmpty(), llvm::Instruction::isUsedOutsideOfBlock(), llvm::make_early_inc_range(), llvm::Instruction::moveBefore(), llvm::BasicBlock::phis(), pred, llvm::predecessors(), llvm::BasicBlock::removePredecessor(), llvm::removeUnwindEdge(), llvm::User::replaceUsesOfWith(), and llvm::Value::use_empty().
|
static |
Definition at line 6155 of file SimplifyCFG.cpp.
References llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::applyUpdates(), llvm::IRBuilderBase::CreateBr(), Idx, llvm::SmallPtrSetImpl< PtrType >::insert(), llvm::is_contained(), PHI, llvm::predecessors(), and llvm::BasicBlock::removePredecessor().
Referenced by trySwitchToSelect().
|
static |
If BB has an incoming value that will always trigger undefined behavior (eg.
null pointer dereference), remove the branch leading here.
Definition at line 7729 of file SimplifyCFG.cpp.
References llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::applyUpdates(), Cond, llvm::BasicBlock::Create(), llvm::IRBuilderBase::CreateAssumption(), llvm::IRBuilderBase::CreateBr(), llvm::IRBuilderBase::CreateNot(), llvm::IRBuilderBase::CreateUnreachable(), llvm::Instruction::eraseFromParent(), llvm::BranchInst::getCondition(), llvm::BasicBlock::getContext(), llvm::BasicBlock::getParent(), llvm::BranchInst::getSuccessor(), llvm::BasicBlock::getTerminator(), llvm::BranchInst::isUnconditional(), passingValueIsAlwaysUndefined(), PHI, llvm::BasicBlock::phis(), llvm::AssumptionCache::registerAssumption(), llvm::BasicBlock::removePredecessor(), and llvm::IRBuilderBase::SetInsertPoint().
|
static |
|
static |
Try to reuse the switch table index compare.
Following pattern:
Is optimized to:
Jump threading will then eliminate the second if(cond).
Definition at line 6603 of file SimplifyCFG.cpp.
References llvm::ConstantFoldCompareInstOperands(), DL, llvm::BranchInst::getCondition(), llvm::BasicBlock::getDataLayout(), llvm::ConstantInt::getFalse(), llvm::ilist_node_impl< OptionsT >::getIterator(), llvm::User::getOperand(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::CmpInst::getPredicate(), llvm::ConstantInt::getTrue(), llvm::Value::getType(), llvm::BasicBlock::getUniquePredecessor(), llvm::predecessors(), and llvm::Value::replaceAllUsesWith().
Referenced by switchToLookupTable().
|
static |
Return true if it is safe to merge these two terminator instructions together.
Definition at line 341 of file SimplifyCFG.cpp.
References llvm::SmallPtrSetImpl< PtrType >::count(), Fail, llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), incomingValuesAreCompatible(), llvm::succ_begin(), llvm::succ_end(), and llvm::successors().
Referenced by llvm::foldBranchToCommonDest().
|
static |
Definition at line 877 of file SimplifyCFG.cpp.
References assert(), llvm::MDBuilder::createBranchWeights(), I, and N.
|
static |
Definition at line 864 of file SimplifyCFG.cpp.
References llvm::any_of(), llvm::MDBuilder::createBranchWeights(), and N.
Referenced by mergeNestedCondBranch(), performBranchToCommonDestFolding(), and SimplifyCondBranchToCondBranch().
|
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 6529 of file SimplifyCFG.cpp.
References DL, I, isSwitchDense(), and isTypeLegalForLookupTable().
Referenced by switchToLookupTable().
|
static |
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.
Definition at line 3741 of file SimplifyCFG.cpp.
References assert(), llvm::extractBranchWeights(), llvm::BranchProbability::getBranchProbability(), llvm::BranchProbability::getCompl(), llvm::Instruction::getMetadata(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::TargetTransformInfo::getPredictableBranchThreshold(), llvm::BranchInst::getSuccessor(), llvm::is_contained(), llvm::BranchInst::isConditional(), llvm::BranchProbability::isUnknown(), and llvm::predecessors().
Referenced by llvm::foldBranchToCommonDest(), and performBranchToCommonDestFolding().
|
static |
Helper function for hoistCommonCodeFromSuccessors.
Return true if identical instructions I1
and I2
can and should be hoisted.
Definition at line 1500 of file SimplifyCFG.cpp.
References llvm::TargetTransformInfo::isProfitableToHoist().
|
static |
Definition at line 6566 of file SimplifyCFG.cpp.
References llvm::all_of(), DL, llvm::ConstantInt::getLimitedValue(), llvm::ConstantInt::isNegative(), and llvm::Constant::isNullValue().
Referenced by switchToLookupTable().
|
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 4414 of file SimplifyCFG.cpp.
References addPredecessorToBlock(), llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::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::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::BasicBlock::getParent(), llvm::TargetTransformInfo::getPredictableBranchThreshold(), llvm::BasicBlock::getSinglePredecessor(), llvm::BranchInst::getSuccessor(), II, 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().
|
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 7068 of file SimplifyCFG.cpp.
References llvm::SmallVectorTemplateCommon< T, typename >::back(), 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.
|
static |
Check whether BB's predecessors end with unconditional branches.
If it is true, sink any common code from the predecessors to BB.
Definition at line 2255 of file SimplifyCFG.cpp.
References llvm::all_of(), assert(), canSinkInstructions(), llvm::dbgs(), llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::end(), llvm::SmallPtrSetImpl< PtrType >::erase(), llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::find(), I, Idx, llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::insert(), llvm::SmallPtrSetImpl< PtrType >::insert(), llvm::IsBlockFollowedByDeoptOrUnreachable(), llvm::isSafeToSpeculativelyExecute(), LLVM_DEBUG, llvm::BasicBlock::phis(), llvm::predecessors(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), sinkLastInstruction(), llvm::SmallVectorBase< Size_T >::size(), and llvm::SplitBlockPredecessors().
|
static |
Definition at line 2090 of file SimplifyCFG.cpp.
References llvm::Instruction::andIRFlags(), llvm::any_of(), llvm::Instruction::applyMergedLocation(), assert(), Blocks, llvm::combineMetadataForCSE(), llvm::PHINode::Create(), llvm::SmallVectorTemplateCommon< T, typename >::front(), llvm::BasicBlock::front(), llvm::Instruction::getDebugLoc(), llvm::User::getNumOperands(), llvm::User::getOperand(), llvm::User::getOperandUse(), llvm::BasicBlock::getTerminator(), I, llvm::make_early_inc_range(), llvm::Instruction::moveBefore(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::Use::set(), llvm::SmallVectorBase< Size_T >::size(), and llvm::Value::users().
Referenced by sinkCommonCodeFromPredecessors().
|
static |
Definition at line 1447 of file SimplifyCFG.cpp.
References I, llvm::isGuaranteedToTransferExecutionToSuccessor(), SkipImplicitControlFlow, SkipReadMem, and SkipSideEffect.
STATISTIC | ( | NumBitMaps | , |
"Number of switch instructions turned into bitmaps" | |||
) |
STATISTIC | ( | NumFoldBranchToCommonDest | , |
"Number of branches folded into predecessor basic block" | |||
) |
STATISTIC | ( | NumFoldValueComparisonIntoPredecessors | , |
"Number of value comparisons folded into predecessor basic blocks" | |||
) |
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 | ( | NumInvokes | , |
"Number of invokes with empty resume blocks simplified into calls" | |||
) |
STATISTIC | ( | NumInvokeSetsFormed | , |
"Number of invoke sets that were formed" | |||
) |
STATISTIC | ( | NumInvokesMerged | , |
"Number of invokes that were merged together" | |||
) |
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 | ( | 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 | ( | NumTableCmpReuses | , |
"Number of reused switch table lookup compares" | |||
) |
|
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 6668 of file SimplifyCFG.cpp.
References addPredecessorToBlock(), llvm::all_of(), llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::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::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.
|
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 6192 of file SimplifyCFG.cpp.
References assert(), Cond, DL, foldSwitchToSelect(), initializeUniqueCases(), PHI, removeSwitchAfterSelectFold(), and llvm::IRBuilderBase::SetInsertPoint().
|
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 7264 of file SimplifyCFG.cpp.
References llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::applyUpdates(), assert(), llvm::BasicBlock::begin(), llvm::IRBuilderBase::CreateUnreachable(), llvm::Instruction::eraseFromParent(), llvm::BasicBlock::getTerminator(), llvm::BasicBlock::getUniqueSuccessor(), I, II, llvm::Instruction::isIdenticalTo(), llvm::make_early_inc_range(), llvm::pred_begin(), llvm::pred_end(), llvm::predecessors(), llvm::BasicBlock::removePredecessor(), llvm::succ_begin(), and llvm::succ_end().
|
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 4357 of file SimplifyCFG.cpp.
References llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::applyUpdates(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), 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().
|
static |
Estimate the cost of the insertion(s) and check that the PHI nodes can be converted to selects.
Definition at line 2929 of file SimplifyCFG.cpp.
References llvm::CmpInst::BAD_ICMP_PREDICATE, computeSpeculationCost(), CostKind, llvm::TargetTransformInfo::getCmpSelInstrCost(), llvm::PHINode::getIncomingValueForBlock(), llvm::BasicBlock::getParent(), llvm::Value::getType(), llvm::Function::hasMinSize(), passingValueIsAlwaysUndefined(), PHINodeFoldingThreshold, llvm::BasicBlock::phis(), llvm::TargetTransformInfo::TCC_Basic, llvm::TargetTransformInfo::TCK_CodeSize, and llvm::TargetTransformInfo::TCK_SizeAndLatency.
|
static |
Return true if the backend will be able to handle initializing an array of constants like C.
Definition at line 5864 of file SimplifyCFG.cpp.
References llvm::CallingConv::C, llvm::TargetTransformInfo::shouldBuildLookupTablesForConstant(), and validLookupTableConstant().
Referenced by getCaseResults(), and validLookupTableConstant().
|
static |
Return true if there are any keys in C1 that exist in C2 as well.
Definition at line 829 of file SimplifyCFG.cpp.
References llvm::array_pod_sort(), std::swap(), and llvm::Value::Value().
|
static |
Referenced by llvm::foldBranchToCommonDest().
|
static |
Referenced by llvm::foldBranchToCommonDest().
|
static |
Referenced by mergeCompatibleInvokes().
|
static |
|
static |
|
static |
|
static |
Referenced by blockIsSimpleEnoughToThreadThrough().
|
static |
Referenced by dominatesMergePoint().
|
static |
Referenced by initializeUniqueCases().
|
static |
Referenced by SimplifyCondBranchToCondBranch().
|
static |
Referenced by mergeConditionalStoreToAddress().
|
static |
Referenced by mergeConditionalStoreToAddress(), and validateAndCostRequiredSelects().
|
static |
|
static |
Referenced by dominatesMergePoint().
|
static |
Referenced by foldTwoEntryPHINode().