LLVM 24.0.0git
SLPVectorizer.cpp File Reference
#include "llvm/Transforms/Vectorize/SLPVectorizer.h"
#include "SLPVectorizer/SLPCostAnalysis.h"
#include "SLPVectorizer/SLPUtils.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/PriorityQueue.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVectorExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CodeMetrics.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/DemandedBits.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/IVDescriptors.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.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/Intrinsics.h"
#include "llvm/IR/Module.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/IR/VectorTypeUtils.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DOTGraphTraits.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/DebugCounter.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/InstructionCost.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/InjectTLIMappings.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <tuple>
#include <utility>

Go to the source code of this file.

Classes

class  slpvectorizer::BoUpSLP
 Bottom Up SLP Vectorizer. More...
struct  slpvectorizer::BoUpSLP::StridedPtrInfo
 If we decide to generate strided load / store, this struct contains all the necessary info. More...
struct  slpvectorizer::BoUpSLP::EdgeInfo
 This structure holds any data we need about the edges being traversed during buildTreeRec(). More...
class  slpvectorizer::BoUpSLP::LookAheadHeuristics
 A helper class used for scoring candidates for two consecutive lanes. More...
class  slpvectorizer::BoUpSLP::VLOperands
 A helper data structure to hold the operands of a vector of instructions. More...
struct  llvm::DenseMapInfo< BoUpSLP::EdgeInfo >
struct  llvm::GraphTraits< BoUpSLP * >
struct  llvm::GraphTraits< BoUpSLP * >::ChildIteratorType
 Add the VectorizableTree to the index iterator to be able to return TreeEntry pointers. More...
class  llvm::GraphTraits< BoUpSLP * >::nodes_iterator
 For the node iterator we just need to turn the TreeEntry iterator into a TreeEntry* iterator so that it dereferences to NodeRef. More...
struct  llvm::DOTGraphTraits< BoUpSLP * >
class  slpvectorizer::BoUpSLP::ShuffleCostEstimator
 Merges shuffle masks and emits final shuffle instruction, if required. More...
class  slpvectorizer::BoUpSLP::ShuffleInstructionBuilder
 Merges shuffle masks and emits final shuffle instruction, if required. More...

Macros

#define SV_NAME   "slp-vectorizer"
#define DEBUG_TYPE   "SLP"

Functions

 STATISTIC (NumVectorInstructions, "Number of vector instructions generated")
 STATISTIC (NumStridedStoreChains, "Number of vectorized stride stores")
 STATISTIC (NumStoreChains, "Number of vector stores created")
 STATISTIC (NumVectorizedStores, "Number of vectorized stores")
 DEBUG_COUNTER (VectorizedGraphs, "slp-vectorized", "Controls which SLP graphs should be vectorized.")
static bool isAllowedNonPowerOf2VF (unsigned NumElts)
 True when slp-vectorize-non-power-of-2 is enabled and NumElts is a supported non-power-of-2 width: NumElts + 1 must be a power of two (e.g.
static bool isValidElementType (Type *Ty)
 Predicate for the element types that the SLP vectorizer supports.
static TypegetValueType (Value *V, bool LookThroughCmp=false)
 Returns the "element type" of the given value/instruction V.
static TypegetWidenedType (Type *ScalarTy, unsigned VF)
static unsigned getFullVectorNumberOfElements (const TargetTransformInfo &TTI, Type *Ty, unsigned Sz)
 Returns the number of elements of the given type Ty, not less than Sz, which forms type, which splits by TTI into whole vector types during legalization.
static unsigned getFloorFullVectorNumberOfElements (const TargetTransformInfo &TTI, Type *Ty, unsigned Sz)
 Returns the number of elements of the given type Ty, not greater than Sz, which forms type, which splits by TTI into whole vector types during legalization.
static std::optional< TargetTransformInfo::ShuffleKindisFixedVectorShuffle (ArrayRef< Value * > VL, SmallVectorImpl< int > &Mask, AssumptionCache *AC)
 Checks if the vector of instructions can be represented as a shuffle, like: x0 = extractelement <4 x i8> x, i32 0 x3 = extractelement <4 x i8> x, i32 3 y1 = extractelement <4 x i8> y, i32 1 y2 = extractelement <4 x i8> y, i32 2 x0x0 = mul i8 x0, x0 x3x3 = mul i8 x3, x3 y1y1 = mul i8 y1, y1 y2y2 = mul i8 y2, y2 ins1 = insertelement <4 x i8> poison, i8 x0x0, i32 0 ins2 = insertelement <4 x i8> ins1, i8 x3x3, i32 1 ins3 = insertelement <4 x i8> ins2, i8 y1y1, i32 2 ins4 = insertelement <4 x i8> ins3, i8 y2y2, i32 3 ret <4 x i8> ins4 can be transformed into: %1 = shufflevector <4 x i8> x, <4 x i8> y, <4 x i32> <i32 0, i32 3, i32 5, i32 6> %2 = mul <4 x i8> %1, %1 ret <4 x i8> %2 Mask will return the Shuffle Mask equivalent to the extracted elements.
static bool isValidForAlternation (unsigned Opcode)
static InstructionsState getSameOpcode (ArrayRef< Value * > VL, const TargetLibraryInfo &TLI)
static InstructionfindInstructionWithOpcode (ArrayRef< Value * > VL, unsigned Opcode)
 Find an instruction with a specific opcode in VL.
static bool areCompatibleCmpOps (Value *BaseOp0, Value *BaseOp1, Value *Op0, Value *Op1, const TargetLibraryInfo &TLI)
 Checks if the provided operands of 2 cmp instructions are compatible, i.e.
static bool isCmpSameOrSwapped (const CmpInst *BaseCI, const CmpInst *CI, const TargetLibraryInfo &TLI)
static bool hasFullVectorsOrPowerOf2 (const TargetTransformInfo &TTI, Type *Ty, unsigned Sz)
 Returns true if widened type of Ty elements with size Sz represents full vector type, i.e.
static unsigned getNumberOfParts (const TargetTransformInfo &TTI, Type *VecTy, Type *ScalarTy, const unsigned Limit=std::numeric_limits< unsigned >::max())
 Returns number of parts, the type VecTy will be split at the codegen phase.
static void reorderReuses (SmallVectorImpl< int > &Reuses, ArrayRef< int > Mask)
 Reorders the given Reuses mask according to the given Mask.
static void reorderOrder (SmallVectorImpl< unsigned > &Order, ArrayRef< int > Mask, bool BottomOrder=false)
 Reorders the given Order according to the given Mask.
static bool arePointersCompatible (Value *Ptr1, Value *Ptr2, const TargetLibraryInfo &TLI, bool CompareOpcodes=true)
template<typename T>
static Align computeCommonAlignment (ArrayRef< Value * > VL)
 Calculates minimal alignment as a common alignment.
static bool isReverseOrder (ArrayRef< unsigned > Order)
 Check if Order represents reverse order.
static const SCEVcalculateRtStride (ArrayRef< Value * > PointerOps, Type *ElemTy, const DataLayout &DL, ScalarEvolution &SE, SmallVectorImpl< unsigned > &SortedIndices)
 Checks if the provided list of pointers Pointers represents the strided pointers for type ElemTy.
static InstructionCost getScalarizationOverhead (const TargetTransformInfo &TTI, Type *ScalarTy, VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None)
 This is similar to TargetTransformInfo::getScalarizationOverhead, but if ScalarTy is a FixedVectorType, a vector will be inserted or extracted instead of a scalar.
static InstructionCost getVectorInstrCost (const TargetTransformInfo &TTI, Type *ScalarTy, unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, Value *Scalar, ArrayRef< std::tuple< Value *, User *, int > > ScalarUserAndIdx)
 This is similar to TargetTransformInfo::getVectorInstrCost, but if ScalarTy is a FixedVectorType, a vector will be extracted instead of a scalar.
static InstructionCost getExtractWithExtendCost (const TargetTransformInfo &TTI, unsigned Opcode, Type *Dst, VectorType *VecTy, unsigned Index, TTI::TargetCostKind CostKind=TTI::TCK_RecipThroughput)
 This is similar to TargetTransformInfo::getExtractWithExtendCost, but if Dst is a FixedVectorType, a vector will be extracted instead of a scalar.
static ValuecreateInsertVector (IRBuilderBase &Builder, Value *Vec, Value *V, unsigned Index, function_ref< Value *(Value *, Value *, ArrayRef< int >)> Generator={})
 Creates subvector insert.
static ValuecreateExtractVector (IRBuilderBase &Builder, Value *Vec, unsigned SubVecVF, unsigned Index)
 Generates subvector extract using Generator or using default shuffle.
static bool buildCompressMask (ArrayRef< Value * > PointerOps, ArrayRef< unsigned > Order, Type *ScalarTy, const DataLayout &DL, ScalarEvolution &SE, SmallVectorImpl< int > &CompressMask)
 Builds compress-like mask for shuffles for the given PointerOps, ordered with Order.
static bool isMaskedLoadCompress (ArrayRef< Value * > VL, ArrayRef< Value * > PointerOps, ArrayRef< unsigned > Order, const TargetTransformInfo &TTI, const DataLayout &DL, ScalarEvolution &SE, AssumptionCache &AC, const DominatorTree &DT, const TargetLibraryInfo &TLI, const function_ref< bool(Value *)> AreAllUsersVectorized, bool &IsMasked, unsigned &InterleaveFactor, SmallVectorImpl< int > &CompressMask, VectorType *&LoadVecTy)
 Checks if the VL can be transformed to a (masked)load + compress or (masked) interleaved load.
static bool isMaskedLoadCompress (ArrayRef< Value * > VL, ArrayRef< Value * > PointerOps, ArrayRef< unsigned > Order, const TargetTransformInfo &TTI, const DataLayout &DL, ScalarEvolution &SE, AssumptionCache &AC, const DominatorTree &DT, const TargetLibraryInfo &TLI, const function_ref< bool(Value *)> AreAllUsersVectorized)
 Checks if the VL can be transformed to a (masked)load + compress or (masked) interleaved load.
static bool isMaskedStoreCompress (ArrayRef< Value * > VL, ArrayRef< Value * > PointerOps, ArrayRef< unsigned > Order, const TargetTransformInfo &TTI, const DataLayout &DL, ScalarEvolution &SE, Align CommonAlignment, SmallVectorImpl< int > &ReuseShuffleIndices, FixedVectorType *&StoreVecTy)
 Checks if the stores VL with pointers PointerOps can be lowered as a single masked store.
static bool clusterSortPtrAccesses (ArrayRef< Value * > VL, ArrayRef< BasicBlock * > BBs, Type *ElemTy, const DataLayout &DL, ScalarEvolution &SE, SmallVectorImpl< unsigned > &SortedIndices)
static bool areTwoInsertFromSameBuildVector (InsertElementInst *VU, InsertElementInst *V, function_ref< Value *(InsertElementInst *)> GetBaseOperand)
 Check if two insertelement instructions are from the same buildvector.
static bool isAlternateInstruction (Instruction *I, Instruction *MainOp, Instruction *AltOp, const TargetLibraryInfo &TLI)
 Checks if the specified instruction I is an alternate operation for the given MainOp and AltOp instructions.
static bool isRepeatedNonIdentityClusteredMask (ArrayRef< int > Mask, unsigned Sz)
 Checks if the given mask is a "clustered" mask with the same clusters of size Sz, which are not identity submasks.
static void combineOrders (MutableArrayRef< unsigned > Order, ArrayRef< unsigned > SecondaryOrder)
static LLVM_DUMP_METHOD void dumpOrder (const BoUpSLP::OrdersType &Order)
static void gatherPossiblyVectorizableLoads (const BoUpSLP &R, ArrayRef< Value * > VL, const DataLayout &DL, ScalarEvolution &SE, const TargetTransformInfo &TTI, SmallVectorImpl< SmallVector< std::pair< LoadInst *, int64_t > > > &GatheredLoads, bool AddNew=true)
 Tries to find subvector of loads and builds new vector of only loads if can be profitable.
static std::pair< size_t, size_tgenerateKeySubkey (Value *V, const TargetLibraryInfo *TLI, function_ref< hash_code(size_t, LoadInst *)> LoadsSubkeyGenerator, bool AllowAlternate)
 Generates key/subkey pair for the given value to provide effective sorting of the values and better detection of the vectorizable values sequences.
static bool isMainInstruction (Instruction *I, Instruction *MainOp, Instruction *AltOp, const TargetLibraryInfo &TLI)
 Checks if the specified instruction I is an main operation for the given MainOp and AltOp instructions.
static SmallVector< Type * > buildIntrinsicArgTypes (const CallInst *CI, const Intrinsic::ID ID, const unsigned VF, unsigned MinBW, const TargetTransformInfo *TTI)
 Builds the arguments types vector for the given call instruction with the given ID for the specified vector factor.
static std::pair< InstructionCost, InstructionCostgetVectorCallCosts (CallInst *CI, Type *VecTy, const TargetTransformInfo *TTI, const TargetLibraryInfo *TLI, ArrayRef< Type * > ArgTys)
 Calculates the costs of vectorized intrinsic (if possible) and vectorized function (if possible) calls.
static InstructionCost getVectorOpCost (Instruction *I, unsigned VF, const TargetTransformInfo &TTI, const TargetLibraryInfo &TLI)
static unsigned getPoorThroughputTypeKey (Type *Ty)
 Packs a type's kind and scalar width into one key, so an opcode/intrinsic id reused across scalar widths (e.g.
static bool isPoorThroughputOp (Instruction *I, const TargetTransformInfo &TTI, const TargetLibraryInfo &TLI, PoorThroughputOpCache &Cache)
 Returns true if I is an expensive scalar op whose vector form is cheaper per lane (e.g.
static const LoopfindInnermostNonInvariantLoop (const Loop *L, ArrayRef< Value * > VL)
 Find the innermost loop starting from L, for which at least a single value in VL is not invariant.
static bool checkEVsForVecCalls (ArrayRef< Value * > VL, const InstructionsState &S, const TargetLibraryInfo &TLI, SmallVectorImpl< unsigned > &Indices, SmallVectorImpl< Value * > &Calls)
 Detects an extractvalue bundle that can be widened by vectorizing the underlying struct-returning calls.
static bool allStructUsersAreExtractValueInsts (ArrayRef< Value * > VL)
static std::pair< Instruction *, Instruction * > getMainAltOpsNoStateVL (ArrayRef< Value * > VL)
 Returns main/alternate instructions for the given VL.
static bool tryToFindDuplicates (SmallVectorImpl< Value * > &VL, SmallVectorImpl< int > &ReuseShuffleIndices, const TargetTransformInfo &TTI, const TargetLibraryInfo &TLI, const InstructionsState &S, const BoUpSLP::EdgeInfo &UserTreeIdx, const BoUpSLP &R, bool BuildGatherOnly=true)
 Checks that every instruction appears once in the list and if not, packs them, building ReuseShuffleIndices mask and mutating VL.
static InstructionCost canConvertToFMA (ArrayRef< Value * > VL, const InstructionsState &S, DominatorTree &DT, const DataLayout &DL, TargetTransformInfo &TTI, const TargetLibraryInfo &TLI)
 Check if we can convert fadd/fsub sequence to FMAD.
static unsigned getLoopTripCount (const Loop *L, ScalarEvolution &SE)
 Get the assumed loop trip count for the loop L.
static TTI::VectorInstrContext getVectorInstrContextHint (ArrayRef< Value * > VL, const APInt &DemandedElts)
 Calculates a VectorInstrContext from the values in VL at indices in DemandedElts.
static bool isFirstInsertElement (const InsertElementInst *IE1, const InsertElementInst *IE2)
 Checks if the IE1 instructions is followed by IE2 instruction in the buildvector sequence.
template<typename T>
static TperformExtractsShuffleAction (MutableArrayRef< std::pair< T *, SmallVector< int > > > ShuffleMask, Value *Base, function_ref< unsigned(T *)> GetVF, function_ref< std::pair< T *, bool >(T *, ArrayRef< int >, bool)> ResizeAction, function_ref< T *(ArrayRef< int >, ArrayRef< T * >)> Action)
 Does the analysis of the provided shuffle masks and performs the requested actions on the vectors with the given shuffle masks.
static InstructionpropagateMetadata (Instruction *Inst, ArrayRef< Value * > VL)
static DebugLoc getDebugLocFromPHI (PHINode &PN)
static bool blockBodyHasVectorInstructions (BasicBlock *BB)
 Returns true if BB's body already contains vector instructions, e.g.
static RecurKind getRdxKind (Value *V)
 Gets recurrence kind from the specified value.
static std::optional< unsignedgetAggregateSize (Instruction *InsertInst)
static void findBuildAggregateRec (Instruction *LastInsertInst, TargetTransformInfo *TTI, SmallVectorImpl< Value * > &BuildVectorOpds, SmallVectorImpl< Value * > &InsertElts, unsigned OperandOffset, const BoUpSLP &R)
static bool findBuildAggregate (Instruction *LastInsertInst, TargetTransformInfo *TTI, SmallVectorImpl< Value * > &BuildVectorOpds, SmallVectorImpl< Value * > &InsertElts, const BoUpSLP &R)
 Recognize construction of vectors like ra = insertelement <4 x float> poison, float s0, i32 0 rb = insertelement <4 x float> ra, float s1, i32 1 rc = insertelement <4 x float> rb, float s2, i32 2 rd = insertelement <4 x float> rc, float s3, i32 3 starting from the last insertelement or insertvalue instruction.
static InstructiongetReductionInstr (const DominatorTree *DT, PHINode *P, BasicBlock *ParentBB, LoopInfo *LI)
 Try and get a reduction instruction from a phi node.
static bool matchRdxBop (Instruction *I, Value *&V0, Value *&V1)
static InstructiontryGetSecondaryReductionRoot (PHINode *Phi, Instruction *Root)
 We could have an initial reduction that is not an add.
static InstructiongetNonPhiOperand (Instruction *I, PHINode *Phi)
 Returns the first operand of I that does not match Phi.
static bool isReductionCandidate (Instruction *I)
 \Returns true if I is a candidate instruction for reduction vectorization.
template<typename T>
static bool tryToVectorizeSequence (SmallVectorImpl< T * > &Incoming, function_ref< bool(T *, T *)> Comparator, function_ref< bool(ArrayRef< T * >, T *)> AreCompatible, function_ref< bool(ArrayRef< T * >, bool)> TryToVectorizeHelper, bool MaxVFOnly, BoUpSLP &R)
template<bool IsCompatibility>
static bool compareCmp (Value *V, Value *V2, TargetLibraryInfo &TLI, const DominatorTree &DT)
 Compare two cmp instructions.
static bool isNonVectorizableInst (const Instruction *I, const TargetLibraryInfo *TLI)
 Returns true if I is an instruction whose result the SLP vectorizer cannot turn into a vector instruction directly, but whose operand chains may still be worth vectorizing as bundle seeds.
template<typename Func>
static void forEachOperandChainCandidate (Instruction *I, Func F, bool ForReduction)
 Visits the value operands of I that are candidates for operand-chain vectorization.

Variables

static cl::opt< boolRunSLPVectorization ("vectorize-slp", cl::init(true), cl::Hidden, cl::desc("Run the SLP vectorization passes"))
static cl::opt< boolSLPReVec ("slp-revec", cl::init(false), cl::Hidden, cl::desc("Enable vectorization for wider vector utilization"))
static cl::opt< int > SLPCostThreshold ("slp-threshold", cl::init(0), cl::Hidden, cl::desc("Only vectorize if you gain more than this " "number "))
static cl::opt< boolShouldVectorizeHor ("slp-vectorize-hor", cl::init(true), cl::Hidden, cl::desc("Attempt to vectorize horizontal reductions"))
static cl::opt< boolShouldStartVectorizeHorAtStore ("slp-vectorize-hor-store", cl::init(false), cl::Hidden, cl::desc("Attempt to vectorize horizontal reductions feeding into a store"))
static cl::opt< boolSplitAlternateInstructions ("slp-split-alternate-instructions", cl::init(true), cl::Hidden, cl::desc("Improve the code quality by splitting alternate instructions"))
static cl::opt< boolSLPInstCountCheck ("slp-inst-count-check", cl::init(true), cl::Hidden, cl::desc("Reject vectorization if vector instruction count exceeds " "scalar instruction count"))
static cl::opt< int > MaxVectorRegSizeOption ("slp-max-reg-size", cl::init(128), cl::Hidden, cl::desc("Attempt to vectorize for this register size in bits"))
static cl::opt< unsignedMaxVFOption ("slp-max-vf", cl::init(0), cl::Hidden, cl::desc("Maximum SLP vectorization factor (0=unlimited)"))
static cl::opt< int > ScheduleRegionSizeBudget ("slp-schedule-budget", cl::init(100000), cl::Hidden, cl::desc("Limit the size of the SLP scheduling region per block"))
 Limits the size of scheduling regions in a block.
static cl::opt< int > MinVectorRegSizeOption ("slp-min-reg-size", cl::init(128), cl::Hidden, cl::desc("Attempt to vectorize for this register size in bits"))
static cl::opt< unsignedRecursionMaxDepth ("slp-recursion-max-depth", cl::init(12), cl::Hidden, cl::desc("Limit the recursion depth when building a vectorizable tree"))
static cl::opt< unsignedMinTreeSize ("slp-min-tree-size", cl::init(3), cl::Hidden, cl::desc("Only vectorize small trees if they are fully vectorizable"))
static cl::opt< unsignedPHINodeVectorizationBudget ("slp-phi-vectorization-budget", cl::init(1024), cl::Hidden, cl::desc("Do not vectorize a bundle of PHI nodes if the product of the " "bundle size and the number of incoming values exceeds this " "value, to limit the compile time spent on wide PHIs"))
static cl::opt< int > LookAheadMaxDepth ("slp-max-look-ahead-depth", cl::init(2), cl::Hidden, cl::desc("The maximum look-ahead depth for operand reordering scores"))
static cl::opt< int > RootLookAheadMaxDepth ("slp-max-root-look-ahead-depth", cl::init(2), cl::Hidden, cl::desc("The maximum look-ahead depth for searching best rooting option"))
static cl::opt< unsignedMinProfitableStridedLoads ("slp-min-strided-loads", cl::init(2), cl::Hidden, cl::desc("The minimum number of loads, which should be considered strided, " "if the stride is > 1 or is runtime value"))
static cl::opt< unsignedMinProfitableStridedStores ("slp-min-strided-stores", cl::init(2), cl::Hidden, cl::desc("The minimum number of stores, which should be considered strided, " "if the stride is > 1 or is runtime value"))
static cl::opt< unsignedMaxProfitableStride ("slp-max-stride", cl::init(8), cl::Hidden, cl::desc("The maximum stride, considered to be profitable."))
static cl::opt< boolEnableStridedStores ("slp-enable-strided-stores", cl::init(false), cl::Hidden, cl::desc("Enable SLP trees to be built from strided " "store chains."))
static cl::opt< boolEnableMaskedStores ("slp-enable-masked-stores", cl::init(true), cl::Hidden, cl::desc("Enable vectorization of non-consecutive stores as a single " "masked store, when the target supports masked stores."))
static cl::opt< boolDisableTreeReorder ("slp-disable-tree-reorder", cl::init(false), cl::Hidden, cl::desc("Disable tree reordering even if it is " "profitable. Used for testing only."))
static cl::opt< boolForceStridedLoads ("slp-force-strided-loads", cl::init(false), cl::Hidden, cl::desc("Generate strided loads even if they are not " "profitable. Used for testing only."))
static cl::opt< boolViewSLPTree ("view-slp-tree", cl::Hidden, cl::desc("Display the SLP trees with Graphviz"))
static cl::opt< boolVectorizeNonPowerOf2 ("slp-vectorize-non-power-of-2", cl::init(false), cl::Hidden, cl::desc("Try to vectorize with non-power-of-2 number of elements."))
static cl::opt< boolForcePostProcessStoresOperands ("slp-postprocess-stores-operands", cl::init(false), cl::Hidden, cl::desc("Force vectorization of non-vectorizable stores operands."))
static cl::opt< boolNonVectReductions ("slp-non-vectorizables-as-reductions", cl::init(false), cl::Hidden, cl::desc("Use non-vectorizable instructions as potential reduction roots."))
static cl::opt< boolVectorizePoorThroughput ("slp-vectorize-poor-throughput", cl::init(true), cl::Hidden, cl::desc("Use poor-throughput instructions (e.g. fdiv, frem, fsqrt) as " "standalone vectorization seeds."))
static cl::opt< boolVectorizeCopyableElements ("slp-copyable-elements", cl::init(true), cl::Hidden, cl::desc("Try to replace values with the idempotent instructions for " "better vectorization."))
 Enables vectorization of copyable elements.
static cl::opt< unsignedLoopAwareTripCount ("slp-cost-loop-trip-count", cl::init(2), cl::Hidden, cl::desc("Loop trip count, considered by the cost model during " "modeling (0=loops are ignored and considered flat code)"))
static cl::opt< boolPerLaneGatherScale ("slp-per-lane-gather-scale", cl::init(true), cl::Hidden, cl::desc("Use per-lane execution scale for gather/buildvector tree " "entries to model LICM-hoistable buildvector sequences."))
 Refine the loop-aware cost scaling of gather/buildvector tree entries by using the per-lane execution scale of the operand that feeds each lane, instead of a single whole-entry scale.
static cl::opt< boolSLPEnableRuntimeAliasChecks ("slp-vectorize-with-runtime-alias-checks", cl::init(true), cl::Hidden, cl::desc("Allow SLP to version a block with runtime alias checks to " "vectorize trees blocked by may-alias memory dependencies."))
 Enable versioning of a basic block with runtime alias checks.
static cl::opt< unsignedSLPMaxRuntimeAliasChecks ("slp-max-runtime-alias-checks", cl::init(8), cl::Hidden, cl::desc("The maximum number of runtime alias checks generated to guard a " "single SLP-vectorized region."))
 Maximum number of runtime alias checks (one per pair of base objects) that may guard a single versioned region.
static cl::opt< unsignedSLPRuntimeAliasChecksMaxScalarCostPercent ("slp-runtime-alias-checks-max-scalar-cost-percent", cl::init(25), cl::Hidden, cl::desc("Maximum SLP runtime alias check cost, as a percentage of the " "guarded scalar region cost, before versioning is rejected to " "avoid pessimizing the scalar fallback path."))
 The runtime checks and the guard branch execute on both the vector and the scalar fallback path, so they add overhead to the scalar code.
static const unsigned AliasedCheckLimit = 10
static const unsigned MaxMemDepDistance = 160
static const int MinScheduleRegionSize = 16
 If the ScheduleRegionSizeBudget is exhausted, we allow small scheduling regions to be handled.
static const unsigned MaxPHINumOperands = 128
 Maximum allowed number of operands in the PHI nodes.

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "SLP"

Definition at line 118 of file SLPVectorizer.cpp.

◆ SV_NAME

#define SV_NAME   "slp-vectorizer"

Definition at line 117 of file SLPVectorizer.cpp.

Function Documentation

◆ allStructUsersAreExtractValueInsts()

bool allStructUsersAreExtractValueInsts ( ArrayRef< Value * > VL)
static

Definition at line 10546 of file SLPVectorizer.cpp.

References llvm::all_of(), llvm::isa(), and llvm::IsaPred.

◆ areCompatibleCmpOps()

bool areCompatibleCmpOps ( Value * BaseOp0,
Value * BaseOp1,
Value * Op0,
Value * Op1,
const TargetLibraryInfo & TLI )
static

Checks if the provided operands of 2 cmp instructions are compatible, i.e.

compatible instructions or constants, or just some other regular values.

Definition at line 1190 of file SLPVectorizer.cpp.

References getSameOpcode(), llvm::isa(), and llvm::slpvectorizer::isConstant().

Referenced by isCmpSameOrSwapped().

◆ arePointersCompatible()

bool arePointersCompatible ( Value * Ptr1,
Value * Ptr2,
const TargetLibraryInfo & TLI,
bool CompareOpcodes = true )
static

◆ areTwoInsertFromSameBuildVector()

◆ blockBodyHasVectorInstructions()

bool blockBodyHasVectorInstructions ( BasicBlock * BB)
static

Returns true if BB's body already contains vector instructions, e.g.

from an earlier SLP vectorization in the same pass.

Definition at line 24302 of file SLPVectorizer.cpp.

References getValueType(), I, and llvm::isa().

Referenced by slpvectorizer::BoUpSLP::canVersionBlockForRuntimeChecks().

◆ buildCompressMask()

bool buildCompressMask ( ArrayRef< Value * > PointerOps,
ArrayRef< unsigned > Order,
Type * ScalarTy,
const DataLayout & DL,
ScalarEvolution & SE,
SmallVectorImpl< int > & CompressMask )
static

Builds compress-like mask for shuffles for the given PointerOps, ordered with Order.

Returns
true if the mask represents strided access, false - otherwise.

Definition at line 6802 of file SLPVectorizer.cpp.

References llvm::SmallVectorImpl< T >::assign(), DL, llvm::ArrayRef< T >::empty(), llvm::ArrayRef< T >::front(), llvm::getPointersDiff(), I, llvm::PoisonMaskElem, llvm::seq(), and llvm::ArrayRef< T >::size().

Referenced by isMaskedLoadCompress().

◆ buildIntrinsicArgTypes()

SmallVector< Type * > buildIntrinsicArgTypes ( const CallInst * CI,
const Intrinsic::ID ID,
const unsigned VF,
unsigned MinBW,
const TargetTransformInfo * TTI )
static

Builds the arguments types vector for the given call instruction with the given ID for the specified vector factor.

Definition at line 10262 of file SLPVectorizer.cpp.

References llvm::CallBase::args(), llvm::enumerate(), llvm::IntegerType::get(), llvm::Value::getContext(), getWidenedType(), llvm::isVectorIntrinsicWithScalarOpAtArg(), llvm::Intrinsic::not_intrinsic, and llvm::SmallVectorTemplateBase< T, bool >::push_back().

Referenced by getVectorOpCost().

◆ calculateRtStride()

const SCEV * calculateRtStride ( ArrayRef< Value * > PointerOps,
Type * ElemTy,
const DataLayout & DL,
ScalarEvolution & SE,
SmallVectorImpl< unsigned > & SortedIndices )
static

Checks if the provided list of pointers Pointers represents the strided pointers for type ElemTy.

If they are not, nullptr is returned. Otherwise, SCEV* of the stride value is returned. If PointerOps can be rearanged into the following sequence:

%x + c_0 * stride,
%x + c_1 * stride,
%x + c_2 * stride
...

where each c_i is constant. The SCEV of the stride will be returned.

Definition at line 6586 of file SLPVectorizer.cpp.

References llvm::SmallVectorImpl< T >::clear(), DL, llvm::dyn_cast(), llvm::enumerate(), llvm::ScalarEvolution::getAddExpr(), llvm::ScalarEvolution::getConstant(), llvm::ScalarEvolution::getMinusSCEV(), llvm::ScalarEvolution::getMulExpr(), llvm::ScalarEvolution::getSCEV(), llvm::SCEV::getType(), llvm::ScalarEvolution::getUDivExactExpr(), llvm::isa(), llvm::SCEV::isNonConstantNegative(), llvm::SCEV::isZero(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::SmallVectorImpl< T >::resize(), Size, llvm::ArrayRef< T >::size(), and llvm::SmallVectorTemplateCommon< T, typename >::size().

Referenced by slpvectorizer::BoUpSLP::analyzeRtStrideCandidate().

◆ canConvertToFMA()

◆ checkEVsForVecCalls()

bool checkEVsForVecCalls ( ArrayRef< Value * > VL,
const InstructionsState & S,
const TargetLibraryInfo & TLI,
SmallVectorImpl< unsigned > & Indices,
SmallVectorImpl< Value * > & Calls )
static

Detects an extractvalue bundle that can be widened by vectorizing the underlying struct-returning calls.

VL is a bundle whose state S is Instruction::ExtractValue. The bundle is acceptable for widening into one struct-of-vectors call only when:

  • every element of VL is an ExtractValueInst,
  • every ExtractValueInst extracts the same struct field (its getIndices() matches the main op's indices),
  • the aggregate operands form a uniform set of CallInsts (per getSameOpcode) that is not an alt-shuffle and whose return type is a literal struct, and
  • every user of every such call is itself an ExtractValueInst, so the external-use extraction code can rebuild scalars via extractvalue + extractelement without needing an insertvalue chain.

On success returns true and fills Indices with the common field index path and Calls with the per-lane aggregate calls (in VL order), for the caller to feed as the operand of the new tree entry. Otherwise returns false and leaves the output parameters untouched.

Definition at line 10502 of file SLPVectorizer.cpp.

References Aggregates, llvm::all_of(), llvm::slpvectorizer::allSameBlock(), assert(), llvm::SmallVectorImpl< T >::assign(), llvm::ArrayRef< T >::begin(), llvm::cast(), llvm::ArrayRef< T >::end(), getSameOpcode(), llvm::isa(), llvm::IsaPred, IV, and llvm::SmallVectorImpl< T >::swap().

◆ clusterSortPtrAccesses()

◆ combineOrders()

◆ compareCmp()

template<bool IsCompatibility>
bool compareCmp ( Value * V,
Value * V2,
TargetLibraryInfo & TLI,
const DominatorTree & DT )
static

Compare two cmp instructions.

If IsCompatibility is true, function returns true if 2 cmps have same/swapped predicates and mos compatible corresponding operands. If IsCompatibility is false, function implements strict weak ordering relation between two cmp instructions, returning true if the first instruction is "less" than the second, i.e. its predicate is less than the predicate of the second or the operands IDs are less than the operands IDs of the second cmp instruction.

Definition at line 32357 of file SLPVectorizer.cpp.

References assert(), llvm::cast(), llvm::dyn_cast(), E(), llvm::DomTreeNodeBase< NodeT >::getDFSNumIn(), llvm::DominatorTreeBase< NodeT, IsPostDom >::getNode(), llvm::User::getOperand(), getSameOpcode(), llvm::Type::getScalarSizeInBits(), llvm::CmpInst::getSwappedPredicate(), llvm::Value::getType(), llvm::Type::getTypeID(), I, and isValidElementType().

Referenced by llvm::SLPVectorizerPass::vectorizeCmpInsts().

◆ computeCommonAlignment()

template<typename T>
Align computeCommonAlignment ( ArrayRef< Value * > VL)
static

Calculates minimal alignment as a common alignment.

Definition at line 6558 of file SLPVectorizer.cpp.

References llvm::cast(), llvm::ArrayRef< T >::consume_front(), and getAlign().

Referenced by slpvectorizer::BoUpSLP::canVectorizeLoads().

◆ createExtractVector()

Value * createExtractVector ( IRBuilderBase & Builder,
Value * Vec,
unsigned SubVecVF,
unsigned Index )
static

Generates subvector extract using Generator or using default shuffle.

Definition at line 6792 of file SLPVectorizer.cpp.

References llvm::PoisonMaskElem.

Referenced by slpvectorizer::BoUpSLP::vectorizeTree().

◆ createInsertVector()

Value * createInsertVector ( IRBuilderBase & Builder,
Value * Vec,
Value * V,
unsigned Index,
function_ref< Value *(Value *, Value *, ArrayRef< int >)> Generator = {} )
static

Creates subvector insert.

Generates shuffle using Generator or using default shuffle.

Definition at line 6762 of file SLPVectorizer.cpp.

◆ DEBUG_COUNTER()

DEBUG_COUNTER ( VectorizedGraphs ,
"slp-vectorized" ,
"Controls which SLP graphs should be vectorized."  )

◆ dumpOrder()

LLVM_DUMP_METHOD void dumpOrder ( const BoUpSLP::OrdersType & Order)
static

Definition at line 9490 of file SLPVectorizer.cpp.

References llvm::dbgs(), and LLVM_DUMP_METHOD.

◆ findBuildAggregate()

bool findBuildAggregate ( Instruction * LastInsertInst,
TargetTransformInfo * TTI,
SmallVectorImpl< Value * > & BuildVectorOpds,
SmallVectorImpl< Value * > & InsertElts,
const BoUpSLP & R )
static

Recognize construction of vectors like ra = insertelement <4 x float> poison, float s0, i32 0 rb = insertelement <4 x float> ra, float s1, i32 1 rc = insertelement <4 x float> rb, float s2, i32 2 rd = insertelement <4 x float> rc, float s3, i32 3 starting from the last insertelement or insertvalue instruction.

Also recognize homogeneous aggregates like {<2 x float>, <2 x float>}, {{float, float}, {float, float}}, [2 x {float, float}] and so on. See llvm/test/Transforms/SLPVectorizer/X86/pr42022.ll for examples.

Assume LastInsertInst is of InsertElementInst or InsertValueInst type.

Returns
true if it matches.

Definition at line 31789 of file SLPVectorizer.cpp.

References assert(), llvm::SmallVectorTemplateCommon< T, typename >::empty(), llvm::erase(), findBuildAggregateRec(), getAggregateSize(), llvm::isa(), llvm::SmallVectorImpl< T >::resize(), and llvm::SmallVectorTemplateCommon< T, typename >::size().

◆ findBuildAggregateRec()

void findBuildAggregateRec ( Instruction * LastInsertInst,
TargetTransformInfo * TTI,
SmallVectorImpl< Value * > & BuildVectorOpds,
SmallVectorImpl< Value * > & InsertElts,
unsigned OperandOffset,
const BoUpSLP & R )
static

◆ findInnermostNonInvariantLoop()

const Loop * findInnermostNonInvariantLoop ( const Loop * L,
ArrayRef< Value * > VL )
static

Find the innermost loop starting from L, for which at least a single value in VL is not invariant.

Definition at line 10451 of file SLPVectorizer.cpp.

References llvm::all_of(), assert(), and llvm::isa().

Referenced by slpvectorizer::BoUpSLP::getTreeCost().

◆ findInstructionWithOpcode()

Instruction * findInstructionWithOpcode ( ArrayRef< Value * > VL,
unsigned Opcode )
static

Find an instruction with a specific opcode in VL.

Parameters
VLArray of values to search through. Must contain only Instructions and PoisonValues.
OpcodeThe instruction opcode to search for
Returns
  • The first instruction found with matching opcode
  • nullptr if no matching instruction is found

Definition at line 1175 of file SLPVectorizer.cpp.

References assert(), llvm::cast(), and llvm::isa().

Referenced by getSameOpcode().

◆ forEachOperandChainCandidate()

template<typename Func>
void forEachOperandChainCandidate ( Instruction * I,
Func F,
bool ForReduction )
static

Visits the value operands of I that are candidates for operand-chain vectorization.

Definition at line 32550 of file SLPVectorizer.cpp.

References llvm::dyn_cast(), llvm::enumerate(), F, I, llvm_unreachable, and NonVectReductions.

Referenced by llvm::SLPVectorizerPass::vectorizeNonVectorizableInsts().

◆ gatherPossiblyVectorizableLoads()

◆ generateKeySubkey()

std::pair< size_t, size_t > generateKeySubkey ( Value * V,
const TargetLibraryInfo * TLI,
function_ref< hash_code(size_t, LoadInst *)> LoadsSubkeyGenerator,
bool AllowAlternate )
static

◆ getAggregateSize()

std::optional< unsigned > getAggregateSize ( Instruction * InsertInst)
static

Definition at line 31722 of file SLPVectorizer.cpp.

References llvm::cast(), llvm::dyn_cast(), llvm::Type::isSingleValueType(), and IV.

Referenced by findBuildAggregate().

◆ getDebugLocFromPHI()

DebugLoc getDebugLocFromPHI ( PHINode & PN)
static

◆ getExtractWithExtendCost()

◆ getFloorFullVectorNumberOfElements()

unsigned getFloorFullVectorNumberOfElements ( const TargetTransformInfo & TTI,
Type * Ty,
unsigned Sz )
static

Returns the number of elements of the given type Ty, not greater than Sz, which forms type, which splits by TTI into whole vector types during legalization.

Definition at line 411 of file SLPVectorizer.cpp.

References llvm::bit_ceil(), llvm::bit_floor(), llvm::divideCeil(), getWidenedType(), llvm::isa(), and isValidElementType().

Referenced by slpvectorizer::BoUpSLP::canVectorizeLoads().

◆ getFullVectorNumberOfElements()

unsigned getFullVectorNumberOfElements ( const TargetTransformInfo & TTI,
Type * Ty,
unsigned Sz )
static

Returns the number of elements of the given type Ty, not less than Sz, which forms type, which splits by TTI into whole vector types during legalization.

Definition at line 396 of file SLPVectorizer.cpp.

References llvm::bit_ceil(), llvm::divideCeil(), getWidenedType(), llvm::isa(), and isValidElementType().

Referenced by getNumberOfParts(), and isMaskedLoadCompress().

◆ getLoopTripCount()

unsigned getLoopTripCount ( const Loop * L,
ScalarEvolution & SE )
static

Get the assumed loop trip count for the loop L.

Definition at line 16313 of file SLPVectorizer.cpp.

References llvm::getLoopEstimatedTripCount(), llvm::ScalarEvolution::getSmallConstantTripCount(), and LoopAwareTripCount.

◆ getMainAltOpsNoStateVL()

std::pair< Instruction *, Instruction * > getMainAltOpsNoStateVL ( ArrayRef< Value * > VL)
static

Returns main/alternate instructions for the given VL.

Unlike getSameOpcode supports non-compatible instructions for better SplitVectorize node support.

Returns
first main/alt instructions, if only poisons and instruction with only 2 opcodes exists. Returns pair of nullptr otherwise.

Definition at line 11126 of file SLPVectorizer.cpp.

References assert(), llvm::dyn_cast(), llvm::Instruction::getOpcode(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), I, and llvm::isa().

◆ getNonPhiOperand()

Instruction * getNonPhiOperand ( Instruction * I,
PHINode * Phi )
static

Returns the first operand of I that does not match Phi.

If operand is not an instruction it returns nullptr.

Definition at line 31912 of file SLPVectorizer.cpp.

References llvm::dyn_cast(), I, and matchRdxBop().

◆ getNumberOfParts()

◆ getPoorThroughputTypeKey()

unsigned getPoorThroughputTypeKey ( Type * Ty)
static

Packs a type's kind and scalar width into one key, so an opcode/intrinsic id reused across scalar widths (e.g.

fdiv float vs. fdiv double) is cached per width instead of sharing one verdict.

Definition at line 10353 of file SLPVectorizer.cpp.

Referenced by isPoorThroughputOp().

◆ getRdxKind()

RecurKind getRdxKind ( Value * V)
static

Gets recurrence kind from the specified value.

Definition at line 31719 of file SLPVectorizer.cpp.

◆ getReductionInstr()

Instruction * getReductionInstr ( const DominatorTree * DT,
PHINode * P,
BasicBlock * ParentBB,
LoopInfo * LI )
static

Try and get a reduction instruction from a phi node.

Given a phi node P in a block ParentBB, consider possible reductions if they come from either ParentBB or a containing loop latch.

Returns
A candidate reduction value if possible, or
nullptr
if not possible.

Definition at line 31824 of file SLPVectorizer.cpp.

References llvm::cast(), llvm::DominatorTree::dominates(), llvm::dyn_cast(), llvm::LoopInfoBase< BlockT, LoopT >::getLoopFor(), llvm::LoopBase< BlockT, LoopT >::getLoopLatch(), llvm::isa(), and P.

◆ getSameOpcode()

InstructionsState getSameOpcode ( ArrayRef< Value * > VL,
const TargetLibraryInfo & TLI )
static
Returns
analysis of the Instructions in VL described in InstructionsState, the Opcode that we suppose the whole list could be vectorized even if its structure is diverse.

Definition at line 1226 of file SLPVectorizer.cpp.

References llvm::all_of(), llvm::slpvectorizer::allSameOpcode(), assert(), llvm::CmpInst::BAD_ICMP_PREDICATE, Call, llvm::cast(), llvm::SetVector< T, Vector, Set, N >::contains(), llvm::dyn_cast(), llvm::SmallVectorTemplateCommon< T, typename >::empty(), llvm::ArrayRef< T >::end(), llvm::find_if(), findInstructionWithOpcode(), llvm::SmallVectorTemplateCommon< T, typename >::front(), llvm::CallBase::getBundleOperandsStartIndex(), llvm::CallBase::getCalledFunction(), llvm::VFDatabase::getMappings(), llvm::Instruction::getOpcode(), llvm::User::getOperand(), llvm::CmpInst::getSwappedPredicate(), llvm::Value::getType(), llvm::getVectorIntrinsicIDForCall(), llvm::CallBase::hasOperandBundles(), I, llvm::SetVector< T, Vector, Set, N >::insert(), llvm::isa(), llvm::IsaPred, isCmpSameOrSwapped(), llvm::isTriviallyVectorizable(), isValidForAlternation(), llvm::slpvectorizer::isVectorLikeInstWithConstOps(), llvm::iterator_range(), llvm::User::op_begin(), llvm::ArrayRef< T >::size(), llvm::SetVector< T, Vector, Set, N >::size(), and llvm::SmallVectorTemplateCommon< T, typename >::size().

Referenced by areCompatibleCmpOps(), arePointersCompatible(), canConvertToFMA(), checkEVsForVecCalls(), compareCmp(), slpvectorizer::BoUpSLP::LookAheadHeuristics::getShallowScore(), slpvectorizer::BoUpSLP::isTreeNotExtendable(), and slpvectorizer::BoUpSLP::VLOperands::reorder().

◆ getScalarizationOverhead()

InstructionCost getScalarizationOverhead ( const TargetTransformInfo & TTI,
Type * ScalarTy,
VectorType * Ty,
const APInt & DemandedElts,
bool Insert,
bool Extract,
TTI::TargetCostKind CostKind,
bool ForPoisonSrc = true,
ArrayRef< Value * > VL = {},
TTI::VectorInstrContext VIC = TTI::VectorInstrContext::None )
static

◆ getValueType()

Type * getValueType ( Value * V,
bool LookThroughCmp = false )
static

Returns the "element type" of the given value/instruction V.

For stores, returns the stored value type; for insertelement (when ReVec is off), the inserted operand type. For compares, the default is to return the result type (i1); when LookThroughCmp is true, returns the type of the compared operands instead, which is needed for vector width calculations (the width is determined by the operand type, not the i1 result).

Definition at line 355 of file SLPVectorizer.cpp.

References llvm::dyn_cast(), IV, and SLPReVec.

Referenced by blockBodyHasVectorInstructions(), slpvectorizer::BoUpSLP::canBuildSplitNode(), CollectOpsToWiden(), combineArithReduction(), combineBitcastvxi1(), combineMulToPMULDQ(), combineSetCC(), combineToHorizontalAddSub(), CompactSwizzlableVector(), detectPMADDUBSW(), FoldBUILD_VECTOR(), foldCONCAT_VECTORS(), gatherPossiblyVectorizableLoads(), llvm::TargetLoweringBase::getAsmOperandValueType(), llvm::Function::getFunctionType(), slpvectorizer::BoUpSLP::getInsertBuildVectorSrcTy(), llvm::RISCVTTIImpl::getIntImmCostInst(), llvm::BasicTTIImplBase< BasicTTIImpl >::getIntrinsicInstrCost(), llvm::TargetLoweringBase::getMemValueType(), slpvectorizer::BoUpSLP::getReorderingData(), llvm::TargetLoweringBase::getSimpleValueType(), getTestBitOperand(), slpvectorizer::BoUpSLP::getTreeCost(), llvm::TargetLoweringBase::isExtLoad(), LLVMGlobalGetValueType(), matchPMADDWD(), matchPMADDWD_2(), mayFoldIntoVector(), narrowVectorSelect(), performCONCAT_VECTORSCombine(), slpvectorizer::BoUpSLP::reorderBottomToTop(), slpvectorizer::BoUpSLP::reorderTopToBottom(), llvm::SelectionDAGISel::SelectInlineAsmMemoryOperands(), tryToFindDuplicates(), tryToVectorizeSequence(), and llvm::SLPVectorizerPass::vectorizeCmpInsts().

◆ getVectorCallCosts()

std::pair< InstructionCost, InstructionCost > getVectorCallCosts ( CallInst * CI,
Type * VecTy,
const TargetTransformInfo * TTI,
const TargetLibraryInfo * TLI,
ArrayRef< Type * > ArgTys )
static

Calculates the costs of vectorized intrinsic (if possible) and vectorized function (if possible) calls.

Returns invalid cost for the corresponding calls, if they cannot be vectorized/will be scalarized.

Definition at line 10287 of file SLPVectorizer.cpp.

References llvm::CallBase::args(), llvm::dyn_cast(), llvm::VFShape::get(), llvm::ElementCount::getFixed(), llvm::CallBase::getFunctionType(), llvm::InstructionCost::getInvalid(), llvm::slpvectorizer::getNumElements(), llvm::getVectorIntrinsicIDForCall(), llvm::VFDatabase::getVectorizedFunction(), IntrinsicCost, llvm::CallBase::isNoBuiltin(), and llvm::TargetTransformInfo::TCK_RecipThroughput.

Referenced by getVectorOpCost().

◆ getVectorInstrContextHint()

TTI::VectorInstrContext getVectorInstrContextHint ( ArrayRef< Value * > VL,
const APInt & DemandedElts )
static

◆ getVectorInstrCost()

InstructionCost getVectorInstrCost ( const TargetTransformInfo & TTI,
Type * ScalarTy,
unsigned Opcode,
Type * Val,
TTI::TargetCostKind CostKind,
unsigned Index,
Value * Scalar,
ArrayRef< std::tuple< Value *, User *, int > > ScalarUserAndIdx )
static

◆ getVectorOpCost()

InstructionCost getVectorOpCost ( Instruction * I,
unsigned VF,
const TargetTransformInfo & TTI,
const TargetLibraryInfo & TLI )
static
Returns
the reciprocal-throughput cost of I widened to VF lanes (an arithmetic op or a vectorizable call).

Definition at line 10333 of file SLPVectorizer.cpp.

References assert(), buildIntrinsicArgTypes(), CostKind, llvm::dyn_cast(), getVectorCallCosts(), llvm::getVectorIntrinsicIDForCall(), getWidenedType(), I, llvm::isa(), and llvm::TargetTransformInfo::TCK_RecipThroughput.

Referenced by isPoorThroughputOp().

◆ getWidenedType()

Type * getWidenedType ( Type * ScalarTy,
unsigned VF )
static
Returns
the vector type of ScalarTy based on vectorization factor.

Definition at line 370 of file SLPVectorizer.cpp.

References llvm::all_of(), assert(), llvm::dyn_cast(), llvm::FixedVectorType::get(), llvm::StructType::get(), llvm::ElementCount::getFixed(), llvm::slpvectorizer::getNumElements(), llvm::isUnpackedStructLiteral(), llvm::VectorType::isValidElementType(), llvm::isVectorizedTy(), llvm::map_to_vector(), llvm::toScalarizedTy(), and llvm::toVectorizedTy().

Referenced by slpvectorizer::BoUpSLP::ShuffleCostEstimator::add(), slpvectorizer::BoUpSLP::ShuffleCostEstimator::add(), slpvectorizer::BoUpSLP::analyzeConstantStrideCandidate(), slpvectorizer::BoUpSLP::analyzeRtStrideCandidate(), buildIntrinsicArgTypes(), slpvectorizer::BoUpSLP::canBuildSplitNode(), slpvectorizer::BoUpSLP::canMapToVector(), slpvectorizer::BoUpSLP::canVectorizeLoads(), slpvectorizer::BoUpSLP::computeMinimumValueSizes(), slpvectorizer::BoUpSLP::findReusedOrderedScalars(), getExtractWithExtendCost(), getFloorFullVectorNumberOfElements(), getFullVectorNumberOfElements(), slpvectorizer::BoUpSLP::getInsertBuildVectorSrcTy(), slpvectorizer::BoUpSLP::getReductionType(), slpvectorizer::BoUpSLP::getReorderingData(), slpvectorizer::BoUpSLP::LookAheadHeuristics::getShallowScore(), slpvectorizer::BoUpSLP::getSpillCost(), slpvectorizer::BoUpSLP::getTreeCost(), getVectorOpCost(), hasFullVectorsOrPowerOf2(), isMaskedLoadCompress(), isMaskedStoreCompress(), slpvectorizer::BoUpSLP::isStridedLoad(), slpvectorizer::BoUpSLP::isTreeTinyAndNotFullyVectorizable(), slpvectorizer::BoUpSLP::ShuffleInstructionBuilder::needToDelay(), slpvectorizer::BoUpSLP::optimizeGatherSequence(), slpvectorizer::BoUpSLP::processBuildVector(), slpvectorizer::BoUpSLP::reorderTopToBottom(), tryToFindDuplicates(), and slpvectorizer::BoUpSLP::vectorizeTree().

◆ hasFullVectorsOrPowerOf2()

bool hasFullVectorsOrPowerOf2 ( const TargetTransformInfo & TTI,
Type * Ty,
unsigned Sz )
static

Returns true if widened type of Ty elements with size Sz represents full vector type, i.e.

adding extra element results in extra parts upon type legalization.

Definition at line 1424 of file SLPVectorizer.cpp.

References getWidenedType(), llvm::has_single_bit(), llvm::isa(), and isValidElementType().

Referenced by slpvectorizer::BoUpSLP::canBuildSplitNode(), and getNumberOfParts().

◆ isAllowedNonPowerOf2VF()

bool isAllowedNonPowerOf2VF ( unsigned NumElts)
static

True when slp-vectorize-non-power-of-2 is enabled and NumElts is a supported non-power-of-2 width: NumElts + 1 must be a power of two (e.g.

3 or 7 lanes, i.e. almost a full power-of-2 register).

Definition at line 269 of file SLPVectorizer.cpp.

References llvm::has_single_bit(), and VectorizeNonPowerOf2.

◆ isAlternateInstruction()

bool isAlternateInstruction ( Instruction * I,
Instruction * MainOp,
Instruction * AltOp,
const TargetLibraryInfo & TLI )
static

Checks if the specified instruction I is an alternate operation for the given MainOp and AltOp instructions.

Definition at line 13738 of file SLPVectorizer.cpp.

References assert(), llvm::cast(), llvm::dyn_cast(), llvm::CmpInst::getSwappedPredicate(), I, isCmpSameOrSwapped(), and P.

Referenced by slpvectorizer::BoUpSLP::canBuildSplitNode(), and slpvectorizer::BoUpSLP::getReorderingData().

◆ isCmpSameOrSwapped()

bool isCmpSameOrSwapped ( const CmpInst * BaseCI,
const CmpInst * CI,
const TargetLibraryInfo & TLI )
static
Returns
true if a compare instruction CI has similar "look" and same predicate as BaseCI, "as is" or with its operands and predicate swapped, false otherwise.

Definition at line 1204 of file SLPVectorizer.cpp.

References areCompatibleCmpOps(), assert(), llvm::User::getOperand(), llvm::CmpInst::getPredicate(), llvm::CmpInst::getSwappedPredicate(), and llvm::Value::getType().

Referenced by getSameOpcode(), and isAlternateInstruction().

◆ isFirstInsertElement()

bool isFirstInsertElement ( const InsertElementInst * IE1,
const InsertElementInst * IE2 )
static

Checks if the IE1 instructions is followed by IE2 instruction in the buildvector sequence.

Definition at line 18751 of file SLPVectorizer.cpp.

References llvm::dyn_cast(), getElementIndex(), llvm::Value::hasOneUse(), and llvm_unreachable.

Referenced by slpvectorizer::BoUpSLP::getTreeCost().

◆ isFixedVectorShuffle()

std::optional< TargetTransformInfo::ShuffleKind > isFixedVectorShuffle ( ArrayRef< Value * > VL,
SmallVectorImpl< int > & Mask,
AssumptionCache * AC )
static

Checks if the vector of instructions can be represented as a shuffle, like: x0 = extractelement <4 x i8> x, i32 0 x3 = extractelement <4 x i8> x, i32 3 y1 = extractelement <4 x i8> y, i32 1 y2 = extractelement <4 x i8> y, i32 2 x0x0 = mul i8 x0, x0 x3x3 = mul i8 x3, x3 y1y1 = mul i8 y1, y1 y2y2 = mul i8 y2, y2 ins1 = insertelement <4 x i8> poison, i8 x0x0, i32 0 ins2 = insertelement <4 x i8> ins1, i8 x3x3, i32 1 ins3 = insertelement <4 x i8> ins2, i8 y1y1, i32 2 ins4 = insertelement <4 x i8> ins3, i8 y2y2, i32 3 ret <4 x i8> ins4 can be transformed into: %1 = shufflevector <4 x i8> x, <4 x i8> y, <4 x i32> <i32 0, i32 3, i32 5, i32 6> %2 = mul <4 x i8> %1, %1 ret <4 x i8> %2 Mask will return the Shuffle Mask equivalent to the extracted elements.

TODO: Can we split off and reuse the shuffle mask detection from ShuffleVectorInst/getShuffleCost?

Definition at line 448 of file SLPVectorizer.cpp.

References llvm::accumulate(), llvm::any_of(), llvm::cast(), llvm::dyn_cast(), E(), llvm::ArrayRef< T >::end(), llvm::find_if(), I, llvm::isa(), llvm::IsaPred, llvm::isGuaranteedNotToBePoison(), llvm::slpvectorizer::isUndefVector(), llvm::PoisonMaskElem, Select, Size, llvm::ArrayRef< T >::size(), llvm::TargetTransformInfo::SK_PermuteSingleSrc, llvm::TargetTransformInfo::SK_PermuteTwoSrc, llvm::TargetTransformInfo::SK_Select, and Unknown.

◆ isMainInstruction()

bool isMainInstruction ( Instruction * I,
Instruction * MainOp,
Instruction * AltOp,
const TargetLibraryInfo & TLI )
static

Checks if the specified instruction I is an main operation for the given MainOp and AltOp instructions.

Definition at line 13732 of file SLPVectorizer.cpp.

References I.

Referenced by slpvectorizer::BoUpSLP::canBuildSplitNode().

◆ isMaskedLoadCompress() [1/2]

bool isMaskedLoadCompress ( ArrayRef< Value * > VL,
ArrayRef< Value * > PointerOps,
ArrayRef< unsigned > Order,
const TargetTransformInfo & TTI,
const DataLayout & DL,
ScalarEvolution & SE,
AssumptionCache & AC,
const DominatorTree & DT,
const TargetLibraryInfo & TLI,
const function_ref< bool(Value *)> AreAllUsersVectorized )
static

Checks if the VL can be transformed to a (masked)load + compress or (masked) interleaved load.

Definition at line 6976 of file SLPVectorizer.cpp.

References DL, and isMaskedLoadCompress().

◆ isMaskedLoadCompress() [2/2]

bool isMaskedLoadCompress ( ArrayRef< Value * > VL,
ArrayRef< Value * > PointerOps,
ArrayRef< unsigned > Order,
const TargetTransformInfo & TTI,
const DataLayout & DL,
ScalarEvolution & SE,
AssumptionCache & AC,
const DominatorTree & DT,
const TargetLibraryInfo & TLI,
const function_ref< bool(Value *)> AreAllUsersVectorized,
bool & IsMasked,
unsigned & InterleaveFactor,
SmallVectorImpl< int > & CompressMask,
VectorType *& LoadVecTy )
static

◆ isMaskedStoreCompress()

bool isMaskedStoreCompress ( ArrayRef< Value * > VL,
ArrayRef< Value * > PointerOps,
ArrayRef< unsigned > Order,
const TargetTransformInfo & TTI,
const DataLayout & DL,
ScalarEvolution & SE,
Align CommonAlignment,
SmallVectorImpl< int > & ReuseShuffleIndices,
FixedVectorType *& StoreVecTy )
static

Checks if the stores VL with pointers PointerOps can be lowered as a single masked store.

On success StoreVecTy is the widened store type and ReuseShuffleIndices is the expand mask that places each stored value at its element offset from the base (poison in the gaps).

Definition at line 6995 of file SLPVectorizer.cpp.

References llvm::SmallVectorImpl< T >::assign(), llvm::ArrayRef< T >::back(), llvm::cast(), llvm::TargetTransformInfo::ConstantMask, DL, llvm::ArrayRef< T >::empty(), llvm::ArrayRef< T >::front(), llvm::getPointersDiff(), getWidenedType(), I, llvm::Type::isFloatingPointTy(), llvm::Type::isIntOrPtrTy(), llvm::PoisonMaskElem, llvm::TargetTransformInfo::RGK_FixedWidthVector, llvm::seq(), and llvm::ArrayRef< T >::size().

◆ isNonVectorizableInst()

bool isNonVectorizableInst ( const Instruction * I,
const TargetLibraryInfo * TLI )
static

Returns true if I is an instruction whose result the SLP vectorizer cannot turn into a vector instruction directly, but whose operand chains may still be worth vectorizing as bundle seeds.

Definition at line 32497 of file SLPVectorizer.cpp.

References llvm::all_of(), llvm::any_of(), llvm::CallBase::args(), llvm::dyn_cast(), llvm::VFDatabase::getMappings(), getType(), llvm::getVectorIntrinsicIDForCall(), I, II, llvm::isa(), llvm::isTriviallyVectorizable(), and SLPReVec.

◆ isPoorThroughputOp()

◆ isReductionCandidate()

bool isReductionCandidate ( Instruction * I)
static

\Returns true if I is a candidate instruction for reduction vectorization.

Definition at line 31921 of file SLPVectorizer.cpp.

References I, IsSelect(), llvm::PatternMatch::m_Select(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), and matchRdxBop().

◆ isRepeatedNonIdentityClusteredMask()

bool isRepeatedNonIdentityClusteredMask ( ArrayRef< int > Mask,
unsigned Sz )
static

Checks if the given mask is a "clustered" mask with the same clusters of size Sz, which are not identity submasks.

Definition at line 8268 of file SLPVectorizer.cpp.

References E(), I, and llvm::ShuffleVectorInst::isIdentityMask().

◆ isReverseOrder()

bool isReverseOrder ( ArrayRef< unsigned > Order)
static

◆ isValidElementType()

bool isValidElementType ( Type * Ty)
static

Predicate for the element types that the SLP vectorizer supports.

The most important thing to filter here are types which are invalid in LLVM vectors. We also filter target specific types which have absolutely no meaningful vectorization path such as x86_fp80 and ppc_f128. This just avoids spending time checking the cost model and realizing that they will be inevitably scalarized.

Definition at line 341 of file SLPVectorizer.cpp.

References llvm::canVectorizeTy(), llvm::getVectorizedTypeVF(), llvm::isVectorizedTy(), SLPReVec, and llvm::toScalarizedTy().

Referenced by slpvectorizer::BoUpSLP::canMapToVector(), compareCmp(), slpvectorizer::BoUpSLP::findReusedOrderedScalars(), gatherPossiblyVectorizableLoads(), getFloorFullVectorNumberOfElements(), getFullVectorNumberOfElements(), slpvectorizer::BoUpSLP::LookAheadHeuristics::getShallowScore(), hasFullVectorsOrPowerOf2(), isPoorThroughputOp(), tryToVectorizeSequence(), llvm::SLPVectorizerPass::vectorizeCmpInsts(), and llvm::SLPVectorizerPass::vectorizeNonVectorizableInsts().

◆ isValidForAlternation()

bool isValidForAlternation ( unsigned Opcode)
static
Returns
true if Opcode is allowed as part of the main/alternate instruction for SLP vectorization.

Example of unsupported opcode is SDIV that can potentially cause UB if the "shuffled out" lane would result in division by zero.

Definition at line 539 of file SLPVectorizer.cpp.

References llvm::Instruction::isIntDivRem().

Referenced by generateKeySubkey(), and getSameOpcode().

◆ matchRdxBop()

◆ performExtractsShuffleAction()

template<typename T>
T * performExtractsShuffleAction ( MutableArrayRef< std::pair< T *, SmallVector< int > > > ShuffleMask,
Value * Base,
function_ref< unsigned(T *)> GetVF,
function_ref< std::pair< T *, bool >(T *, ArrayRef< int >, bool)> ResizeAction,
function_ref< T *(ArrayRef< int >, ArrayRef< T * >)> Action )
static

Does the analysis of the provided shuffle masks and performs the requested actions on the vectors with the given shuffle masks.

It tries to do it in several steps.

  1. If the Base vector is not undef vector, resizing the very first mask to have common VF and perform action for 2 input vectors (including non-undef Base). Other shuffle masks are combined with the resulting after the 1 stage and processed as a shuffle of 2 elements.
  2. If the Base is undef vector and have only 1 shuffle mask, perform the action only for 1 vector with the given mask, if it is not the identity mask.
  3. If > 2 masks are used, perform the remaining shuffle actions for 2 vectors, combing the masks properly between the steps.

Definition at line 18806 of file SLPVectorizer.cpp.

References llvm::SmallBitVector::all(), assert(), llvm::sampleprof::Base, llvm::slpvectorizer::buildUseMask(), E(), I, llvm::slpvectorizer::isUndefVector(), llvm::slpvectorizer::isUndefVector< true >(), llvm::PoisonMaskElem, T, and llvm::SmallBitVector::test().

Referenced by slpvectorizer::BoUpSLP::getTreeCost().

◆ propagateMetadata()

Instruction * propagateMetadata ( Instruction * Inst,
ArrayRef< Value * > VL )
static
Returns
I after propagating metadata from VL only for instructions in VL.

Definition at line 22866 of file SLPVectorizer.cpp.

References llvm::isa(), llvm::propagateMetadata(), and llvm::SmallVectorTemplateBase< T, bool >::push_back().

◆ reorderOrder()

◆ reorderReuses()

void reorderReuses ( SmallVectorImpl< int > & Reuses,
ArrayRef< int > Mask )
static

Reorders the given Reuses mask according to the given Mask.

Reuses contains original mask for the scalars reused in the node. Procedure transform this mask in accordance with the given Mask.

Definition at line 6286 of file SLPVectorizer.cpp.

References assert(), llvm::SmallVectorTemplateCommon< T, typename >::begin(), E(), llvm::SmallVectorTemplateCommon< T, typename >::end(), I, llvm::PoisonMaskElem, llvm::SmallVectorTemplateCommon< T, typename >::size(), and llvm::SmallVectorImpl< T >::swap().

Referenced by slpvectorizer::BoUpSLP::reorderBottomToTop(), and reorderOrder().

◆ STATISTIC() [1/4]

STATISTIC ( NumStoreChains ,
"Number of vector stores created"  )

◆ STATISTIC() [2/4]

STATISTIC ( NumStridedStoreChains ,
"Number of vectorized stride stores"  )

◆ STATISTIC() [3/4]

STATISTIC ( NumVectorInstructions ,
"Number of vector instructions generated"  )

◆ STATISTIC() [4/4]

STATISTIC ( NumVectorizedStores ,
"Number of vectorized stores"  )

◆ tryGetSecondaryReductionRoot()

Instruction * tryGetSecondaryReductionRoot ( PHINode * Phi,
Instruction * Root )
static

We could have an initial reduction that is not an add.

r *= v1 + v2 + v3 + v4 In such a case start looking for a tree rooted in the first '+'. \Returns the new root if found, which may be nullptr if not an instruction.

Definition at line 31894 of file SLPVectorizer.cpp.

References assert(), llvm::dyn_cast(), llvm::User::getOperand(), llvm::isa(), LHS, and RHS.

◆ tryToFindDuplicates()

bool tryToFindDuplicates ( SmallVectorImpl< Value * > & VL,
SmallVectorImpl< int > & ReuseShuffleIndices,
const TargetTransformInfo & TTI,
const TargetLibraryInfo & TLI,
const InstructionsState & S,
const BoUpSLP::EdgeInfo & UserTreeIdx,
const BoUpSLP & R,
bool BuildGatherOnly = true )
static

Checks that every instruction appears once in the list and if not, packs them, building ReuseShuffleIndices mask and mutating VL.

The list of unique scalars is extended by poison values to the whole register size.

Returns
false if VL could not be uniquified, in which case VL is unchanged and ReuseShuffleIndices is empty.

Definition at line 11168 of file SLPVectorizer.cpp.

References llvm::all_of(), assert(), llvm::cast(), llvm::SmallVectorImpl< T >::clear(), llvm::APInt::clearBit(), slpvectorizer::BoUpSLP::CompressVectorize, llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::contains(), CostKind, llvm::CostThreshold, llvm::dbgs(), llvm::slpvectorizer::doesNotNeedToSchedule(), llvm::SmallVectorImpl< T >::emplace_back(), llvm::SmallVectorTemplateCommon< T, typename >::end(), llvm::enumerate(), llvm::SmallVectorImpl< T >::erase(), llvm::find_if_not(), llvm::SmallVectorTemplateCommon< T, typename >::front(), slpvectorizer::BoUpSLP::Gather, llvm::APInt::getAllOnes(), getNumberOfParts(), getScalarizationOverhead(), llvm::slpvectorizer::getShuffleCost(), getValueType(), getWidenedType(), llvm::APInt::getZero(), llvm::has_single_bit(), InstructionCost, llvm::isa(), llvm::IsaPred, isConstant(), llvm::ShuffleVectorInst::isIdentityMask(), llvm::slpvectorizer::isVectorLikeInstWithConstOps(), LLVM_DEBUG, llvm::make_range(), llvm::PoisonMaskElem, llvm::SmallVectorTemplateCommon< T, typename >::rbegin(), llvm::SmallVectorTemplateCommon< T, typename >::rend(), slpvectorizer::BoUpSLP::ScatterVectorize, llvm::APInt::setBit(), llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::size(), llvm::SmallVectorTemplateCommon< T, typename >::size(), llvm::TargetTransformInfo::SK_PermuteSingleSrc, slpvectorizer::BoUpSLP::StridedVectorize, llvm::TargetTransformInfo::TCC_Expensive, llvm::TargetTransformInfo::TCC_Free, llvm::TargetTransformInfo::TCK_RecipThroughput, llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::try_emplace(), and slpvectorizer::BoUpSLP::EdgeInfo::UserTE.

◆ tryToVectorizeSequence()

Variable Documentation

◆ AliasedCheckLimit

const unsigned AliasedCheckLimit = 10
static

Definition at line 320 of file SLPVectorizer.cpp.

◆ DisableTreeReorder

cl::opt< bool > DisableTreeReorder("slp-disable-tree-reorder", cl::init(false), cl::Hidden, cl::desc("Disable tree reordering even if it is " "profitable. Used for testing only.")) ( "slp-disable-tree-reorder" ,
cl::init(false) ,
cl::Hidden ,
cl::desc("Disable tree reordering even if it is " "profitable. Used for testing only.")  )
static

◆ EnableMaskedStores

cl::opt< bool > EnableMaskedStores("slp-enable-masked-stores", cl::init(true), cl::Hidden, cl::desc("Enable vectorization of non-consecutive stores as a single " "masked store, when the target supports masked stores.")) ( "slp-enable-masked-stores" ,
cl::init(true) ,
cl::Hidden ,
cl::desc("Enable vectorization of non-consecutive stores as a single " "masked store, when the target supports masked stores.")  )
static

◆ EnableStridedStores

cl::opt< bool > EnableStridedStores("slp-enable-strided-stores", cl::init(false), cl::Hidden, cl::desc("Enable SLP trees to be built from strided " "store chains.")) ( "slp-enable-strided-stores" ,
cl::init(false) ,
cl::Hidden ,
cl::desc("Enable SLP trees to be built from strided " "store chains.")  )
static

◆ ForcePostProcessStoresOperands

cl::opt< bool > ForcePostProcessStoresOperands("slp-postprocess-stores-operands", cl::init(false), cl::Hidden, cl::desc("Force vectorization of non-vectorizable stores operands.")) ( "slp-postprocess-stores-operands" ,
cl::init(false) ,
cl::Hidden ,
cl::desc("Force vectorization of non-vectorizable stores operands.")  )
static

◆ ForceStridedLoads

cl::opt< bool > ForceStridedLoads("slp-force-strided-loads", cl::init(false), cl::Hidden, cl::desc("Generate strided loads even if they are not " "profitable. Used for testing only.")) ( "slp-force-strided-loads" ,
cl::init(false) ,
cl::Hidden ,
cl::desc("Generate strided loads even if they are not " "profitable. Used for testing only.")  )
static

◆ LookAheadMaxDepth

cl::opt< int > LookAheadMaxDepth("slp-max-look-ahead-depth", cl::init(2), cl::Hidden, cl::desc("The maximum look-ahead depth for operand reordering scores")) ( "slp-max-look-ahead-depth" ,
cl::init(2) ,
cl::Hidden ,
cl::desc("The maximum look-ahead depth for operand reordering scores")  )
static

◆ LoopAwareTripCount

cl::opt< unsigned > LoopAwareTripCount("slp-cost-loop-trip-count", cl::init(2), cl::Hidden, cl::desc("Loop trip count, considered by the cost model during " "modeling (0=loops are ignored and considered flat code)")) ( "slp-cost-loop-trip-count" ,
cl::init(2) ,
cl::Hidden ,
cl::desc("Loop trip count, considered by the cost model during " "modeling (0=loops are ignored and considered flat code)")  )
static

◆ MaxMemDepDistance

const unsigned MaxMemDepDistance = 160
static

◆ MaxPHINumOperands

const unsigned MaxPHINumOperands = 128
static

Maximum allowed number of operands in the PHI nodes.

Definition at line 332 of file SLPVectorizer.cpp.

◆ MaxProfitableStride

cl::opt< unsigned > MaxProfitableStride("slp-max-stride", cl::init(8), cl::Hidden, cl::desc("The maximum stride, considered to be profitable.")) ( "slp-max-stride" ,
cl::init(8) ,
cl::Hidden ,
cl::desc("The maximum stride, considered to be profitable.")  )
static

◆ MaxVectorRegSizeOption

cl::opt< int > MaxVectorRegSizeOption("slp-max-reg-size", cl::init(128), cl::Hidden, cl::desc("Attempt to vectorize for this register size in bits")) ( "slp-max-reg-size" ,
cl::init(128) ,
cl::Hidden ,
cl::desc("Attempt to vectorize for this register size in bits")  )
static

◆ MaxVFOption

cl::opt< unsigned > MaxVFOption("slp-max-vf", cl::init(0), cl::Hidden, cl::desc("Maximum SLP vectorization factor (0=unlimited)")) ( "slp-max-vf" ,
cl::init(0) ,
cl::Hidden ,
cl::desc("Maximum SLP vectorization factor (0=unlimited)")  )
static

◆ MinProfitableStridedLoads

cl::opt< unsigned > MinProfitableStridedLoads("slp-min-strided-loads", cl::init(2), cl::Hidden, cl::desc("The minimum number of loads, which should be considered strided, " "if the stride is > 1 or is runtime value")) ( "slp-min-strided-loads" ,
cl::init(2) ,
cl::Hidden ,
cl::desc("The minimum number of loads, which should be considered strided, " "if the stride is > 1 or is runtime value")  )
static

◆ MinProfitableStridedStores

cl::opt< unsigned > MinProfitableStridedStores("slp-min-strided-stores", cl::init(2), cl::Hidden, cl::desc( "The minimum number of stores, which should be considered strided, " "if the stride is > 1 or is runtime value")) ( "slp-min-strided-stores" ,
cl::init(2) ,
cl::Hidden ,
cl::desc( "The minimum number of stores, which should be considered strided, " "if the stride is > 1 or is runtime value")  )
static

◆ MinScheduleRegionSize

const int MinScheduleRegionSize = 16
static

If the ScheduleRegionSizeBudget is exhausted, we allow small scheduling regions to be handled.

Definition at line 329 of file SLPVectorizer.cpp.

◆ MinTreeSize

cl::opt< unsigned > MinTreeSize("slp-min-tree-size", cl::init(3), cl::Hidden, cl::desc("Only vectorize small trees if they are fully vectorizable")) ( "slp-min-tree-size" ,
cl::init(3) ,
cl::Hidden ,
cl::desc("Only vectorize small trees if they are fully vectorizable")  )
static

◆ MinVectorRegSizeOption

cl::opt< int > MinVectorRegSizeOption("slp-min-reg-size", cl::init(128), cl::Hidden, cl::desc("Attempt to vectorize for this register size in bits")) ( "slp-min-reg-size" ,
cl::init(128) ,
cl::Hidden ,
cl::desc("Attempt to vectorize for this register size in bits")  )
static

◆ NonVectReductions

cl::opt< bool > NonVectReductions("slp-non-vectorizables-as-reductions", cl::init(false), cl::Hidden, cl::desc( "Use non-vectorizable instructions as potential reduction roots.")) ( "slp-non-vectorizables-as-reductions" ,
cl::init(false) ,
cl::Hidden ,
cl::desc( "Use non-vectorizable instructions as potential reduction roots.")  )
static

◆ PerLaneGatherScale

cl::opt< bool > PerLaneGatherScale("slp-per-lane-gather-scale", cl::init(true), cl::Hidden, cl::desc("Use per-lane execution scale for gather/buildvector tree " "entries to model LICM-hoistable buildvector sequences.")) ( "slp-per-lane-gather-scale" ,
cl::init(true) ,
cl::Hidden ,
cl::desc("Use per-lane execution scale for gather/buildvector tree " "entries to model LICM-hoistable buildvector sequences.")  )
static

Refine the loop-aware cost scaling of gather/buildvector tree entries by using the per-lane execution scale of the operand that feeds each lane, instead of a single whole-entry scale.

This matches the LICM hoisting performed by optimizeGatherSequence() at codegen time: lanes whose operands are loop-invariant in an inner loop contribute the outer loop's execution scale rather than the inner loop's, which avoids over-costing buildvectors that bridge values from outer loop nests into an inner loop.

◆ PHINodeVectorizationBudget

cl::opt< unsigned > PHINodeVectorizationBudget("slp-phi-vectorization-budget", cl::init(1024), cl::Hidden, cl::desc("Do not vectorize a bundle of PHI nodes if the product of the " "bundle size and the number of incoming values exceeds this " "value, to limit the compile time spent on wide PHIs")) ( "slp-phi-vectorization-budget" ,
cl::init(1024) ,
cl::Hidden ,
cl::desc("Do not vectorize a bundle of PHI nodes if the product of the " "bundle size and the number of incoming values exceeds this " "value, to limit the compile time spent on wide PHIs")  )
static

◆ RecursionMaxDepth

cl::opt< unsigned > RecursionMaxDepth("slp-recursion-max-depth", cl::init(12), cl::Hidden, cl::desc("Limit the recursion depth when building a vectorizable tree")) ( "slp-recursion-max-depth" ,
cl::init(12) ,
cl::Hidden ,
cl::desc("Limit the recursion depth when building a vectorizable tree")  )
static

◆ RootLookAheadMaxDepth

cl::opt< int > RootLookAheadMaxDepth("slp-max-root-look-ahead-depth", cl::init(2), cl::Hidden, cl::desc("The maximum look-ahead depth for searching best rooting option")) ( "slp-max-root-look-ahead-depth" ,
cl::init(2) ,
cl::Hidden ,
cl::desc("The maximum look-ahead depth for searching best rooting option")  )
static

◆ RunSLPVectorization

cl::opt< bool > RunSLPVectorization("vectorize-slp", cl::init(true), cl::Hidden, cl::desc("Run the SLP vectorization passes")) ( "vectorize-slp" ,
cl::init(true) ,
cl::Hidden ,
cl::desc("Run the SLP vectorization passes")  )
static

◆ ScheduleRegionSizeBudget

cl::opt< int > ScheduleRegionSizeBudget("slp-schedule-budget", cl::init(100000), cl::Hidden, cl::desc("Limit the size of the SLP scheduling region per block")) ( "slp-schedule-budget" ,
cl::init(100000) ,
cl::Hidden ,
cl::desc("Limit the size of the SLP scheduling region per block")  )
static

Limits the size of scheduling regions in a block.

It avoid long compile times for very large blocks where vector instructions are spread over a wide range. This limit is way higher than needed by real-world functions.

Referenced by slpvectorizer::BoUpSLP::getSpillCost().

◆ ShouldStartVectorizeHorAtStore

cl::opt< bool > ShouldStartVectorizeHorAtStore("slp-vectorize-hor-store", cl::init(false), cl::Hidden, cl::desc( "Attempt to vectorize horizontal reductions feeding into a store")) ( "slp-vectorize-hor-store" ,
cl::init(false) ,
cl::Hidden ,
cl::desc( "Attempt to vectorize horizontal reductions feeding into a store")  )
static

◆ ShouldVectorizeHor

cl::opt< bool > ShouldVectorizeHor("slp-vectorize-hor", cl::init(true), cl::Hidden, cl::desc("Attempt to vectorize horizontal reductions")) ( "slp-vectorize-hor" ,
cl::init(true) ,
cl::Hidden ,
cl::desc("Attempt to vectorize horizontal reductions")  )
static

◆ SLPCostThreshold

cl::opt< int > SLPCostThreshold("slp-threshold", cl::init(0), cl::Hidden, cl::desc("Only vectorize if you gain more than this " "number ")) ( "slp-threshold" ,
cl::init(0) ,
cl::Hidden ,
cl::desc("Only vectorize if you gain more than this " "number ")  )
static

◆ SLPEnableRuntimeAliasChecks

cl::opt< bool > SLPEnableRuntimeAliasChecks("slp-vectorize-with-runtime-alias-checks", cl::init(true), cl::Hidden, cl::desc("Allow SLP to version a block with runtime alias checks to " "vectorize trees blocked by may-alias memory dependencies.")) ( "slp-vectorize-with-runtime-alias-checks" ,
cl::init(true) ,
cl::Hidden ,
cl::desc("Allow SLP to version a block with runtime alias checks to " "vectorize trees blocked by may-alias memory dependencies.")  )
static

Enable versioning of a basic block with runtime alias checks.

◆ SLPInstCountCheck

cl::opt< bool > SLPInstCountCheck("slp-inst-count-check", cl::init(true), cl::Hidden, cl::desc("Reject vectorization if vector instruction count exceeds " "scalar instruction count")) ( "slp-inst-count-check" ,
cl::init(true) ,
cl::Hidden ,
cl::desc("Reject vectorization if vector instruction count exceeds " "scalar instruction count")  )
static

◆ SLPMaxRuntimeAliasChecks

cl::opt< unsigned > SLPMaxRuntimeAliasChecks("slp-max-runtime-alias-checks", cl::init(8), cl::Hidden, cl::desc("The maximum number of runtime alias checks generated to guard a " "single SLP-vectorized region.")) ( "slp-max-runtime-alias-checks" ,
cl::init(8) ,
cl::Hidden ,
cl::desc("The maximum number of runtime alias checks generated to guard a " "single SLP-vectorized region.")  )
static

Maximum number of runtime alias checks (one per pair of base objects) that may guard a single versioned region.

Referenced by slpvectorizer::BoUpSLP::canVersionForRuntimeChecks().

◆ SLPReVec

◆ SLPRuntimeAliasChecksMaxScalarCostPercent

cl::opt< unsigned > SLPRuntimeAliasChecksMaxScalarCostPercent("slp-runtime-alias-checks-max-scalar-cost-percent", cl::init(25), cl::Hidden, cl::desc("Maximum SLP runtime alias check cost, as a percentage of the " "guarded scalar region cost, before versioning is rejected to " "avoid pessimizing the scalar fallback path.")) ( "slp-runtime-alias-checks-max-scalar-cost-percent" ,
cl::init(25) ,
cl::Hidden ,
cl::desc("Maximum SLP runtime alias check cost, as a percentage of the " "guarded scalar region cost, before versioning is rejected to " "avoid pessimizing the scalar fallback path.")  )
static

The runtime checks and the guard branch execute on both the vector and the scalar fallback path, so they add overhead to the scalar code.

Referenced by slpvectorizer::BoUpSLP::canVersionForRuntimeChecks().

◆ SplitAlternateInstructions

cl::opt< bool > SplitAlternateInstructions("slp-split-alternate-instructions", cl::init(true), cl::Hidden, cl::desc("Improve the code quality by splitting alternate instructions")) ( "slp-split-alternate-instructions" ,
cl::init(true) ,
cl::Hidden ,
cl::desc("Improve the code quality by splitting alternate instructions")  )
static

◆ VectorizeCopyableElements

cl::opt< bool > VectorizeCopyableElements("slp-copyable-elements", cl::init(true), cl::Hidden, cl::desc("Try to replace values with the idempotent instructions for " "better vectorization.")) ( "slp-copyable-elements" ,
cl::init(true) ,
cl::Hidden ,
cl::desc("Try to replace values with the idempotent instructions for " "better vectorization.")  )
static

Enables vectorization of copyable elements.

◆ VectorizeNonPowerOf2

cl::opt< bool > VectorizeNonPowerOf2("slp-vectorize-non-power-of-2", cl::init(false), cl::Hidden, cl::desc("Try to vectorize with non-power-of-2 number of elements.")) ( "slp-vectorize-non-power-of-2" ,
cl::init(false) ,
cl::Hidden ,
cl::desc("Try to vectorize with non-power-of-2 number of elements.")  )
static

Referenced by isAllowedNonPowerOf2VF().

◆ VectorizePoorThroughput

cl::opt< bool > VectorizePoorThroughput("slp-vectorize-poor-throughput", cl::init(true), cl::Hidden, cl::desc("Use poor-throughput instructions (e.g. fdiv, frem, fsqrt) as " "standalone vectorization seeds.")) ( "slp-vectorize-poor-throughput" ,
cl::init(true) ,
cl::Hidden ,
cl::desc("Use poor-throughput instructions (e.g. fdiv, frem, fsqrt) as " "standalone vectorization seeds.")  )
static

◆ ViewSLPTree

cl::opt< bool > ViewSLPTree("view-slp-tree", cl::Hidden, cl::desc("Display the SLP trees with Graphviz")) ( "view-slp-tree" ,
cl::Hidden ,
cl::desc("Display the SLP trees with Graphviz")  )
static