10f1314c5SHal Finkel //===- LoopVectorizationPlanner.h - Planner for LoopVectorization ---------===// 20f1314c5SHal Finkel // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60f1314c5SHal Finkel // 70f1314c5SHal Finkel //===----------------------------------------------------------------------===// 80f1314c5SHal Finkel /// 90f1314c5SHal Finkel /// \file 100f1314c5SHal Finkel /// This file provides a LoopVectorizationPlanner class. 110f1314c5SHal Finkel /// InnerLoopVectorizer vectorizes loops which contain only one basic 120f1314c5SHal Finkel /// LoopVectorizationPlanner - drives the vectorization process after having 130f1314c5SHal Finkel /// passed Legality checks. 140f1314c5SHal Finkel /// The planner builds and optimizes the Vectorization Plans which record the 150f1314c5SHal Finkel /// decisions how to vectorize the given loop. In particular, represent the 160f1314c5SHal Finkel /// control-flow of the vectorized version, the replication of instructions that 170f1314c5SHal Finkel /// are to be scalarized, and interleave access groups. 180f1314c5SHal Finkel /// 190f1314c5SHal Finkel /// Also provides a VPlan-based builder utility analogous to IRBuilder. 200f1314c5SHal Finkel /// It provides an instruction-level API for generating VPInstructions while 210f1314c5SHal Finkel /// abstracting away the Recipe manipulation details. 220f1314c5SHal Finkel //===----------------------------------------------------------------------===// 230f1314c5SHal Finkel 240f1314c5SHal Finkel #ifndef LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H 250f1314c5SHal Finkel #define LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H 260f1314c5SHal Finkel 270f1314c5SHal Finkel #include "VPlan.h" 281b89c832Sserge-sans-paille #include "llvm/Support/InstructionCost.h" 290f1314c5SHal Finkel 300f1314c5SHal Finkel namespace llvm { 310f1314c5SHal Finkel 3249999d43SFlorian Hahn class LoopInfo; 33b108a457SSimon Pilgrim class LoopVectorizationLegality; 34b108a457SSimon Pilgrim class LoopVectorizationCostModel; 3518138e02SFlorian Hahn class PredicatedScalarEvolution; 36c773d0f9SFlorian Hahn class LoopVectorizeHints; 37c773d0f9SFlorian Hahn class OptimizationRemarkEmitter; 3849999d43SFlorian Hahn class TargetTransformInfo; 3949999d43SFlorian Hahn class TargetLibraryInfo; 40745bf6cfSDavid Green class VPRecipeBuilder; 4118138e02SFlorian Hahn 420f1314c5SHal Finkel /// VPlan-based builder utility analogous to IRBuilder. 430f1314c5SHal Finkel class VPBuilder { 440f1314c5SHal Finkel VPBasicBlock *BB = nullptr; 450f1314c5SHal Finkel VPBasicBlock::iterator InsertPt = VPBasicBlock::iterator(); 460f1314c5SHal Finkel 470f1314c5SHal Finkel VPInstruction *createInstruction(unsigned Opcode, 48*02d6950dSDavid Sherwood ArrayRef<VPValue *> Operands, DebugLoc DL, 49*02d6950dSDavid Sherwood const Twine &Name = "") { 50*02d6950dSDavid Sherwood VPInstruction *Instr = new VPInstruction(Opcode, Operands, DL, Name); 51168d04d5SDiego Caballero if (BB) 520f1314c5SHal Finkel BB->insert(Instr, InsertPt); 530f1314c5SHal Finkel return Instr; 540f1314c5SHal Finkel } 550f1314c5SHal Finkel 56168d04d5SDiego Caballero VPInstruction *createInstruction(unsigned Opcode, 575b362e4cSFlorian Hahn std::initializer_list<VPValue *> Operands, 58*02d6950dSDavid Sherwood DebugLoc DL, const Twine &Name = "") { 59*02d6950dSDavid Sherwood return createInstruction(Opcode, ArrayRef<VPValue *>(Operands), DL, Name); 60168d04d5SDiego Caballero } 61168d04d5SDiego Caballero 620f1314c5SHal Finkel public: 633a3cb929SKazu Hirata VPBuilder() = default; 640f1314c5SHal Finkel 65168d04d5SDiego Caballero /// Clear the insertion point: created instructions will not be inserted into 66168d04d5SDiego Caballero /// a block. clearInsertionPoint()67168d04d5SDiego Caballero void clearInsertionPoint() { 68168d04d5SDiego Caballero BB = nullptr; 69168d04d5SDiego Caballero InsertPt = VPBasicBlock::iterator(); 70168d04d5SDiego Caballero } 71168d04d5SDiego Caballero getInsertBlock()72168d04d5SDiego Caballero VPBasicBlock *getInsertBlock() const { return BB; } getInsertPoint()73168d04d5SDiego Caballero VPBasicBlock::iterator getInsertPoint() const { return InsertPt; } 74168d04d5SDiego Caballero 75168d04d5SDiego Caballero /// InsertPoint - A saved insertion point. 76168d04d5SDiego Caballero class VPInsertPoint { 77168d04d5SDiego Caballero VPBasicBlock *Block = nullptr; 78168d04d5SDiego Caballero VPBasicBlock::iterator Point; 79168d04d5SDiego Caballero 80168d04d5SDiego Caballero public: 81168d04d5SDiego Caballero /// Creates a new insertion point which doesn't point to anything. 82168d04d5SDiego Caballero VPInsertPoint() = default; 83168d04d5SDiego Caballero 84168d04d5SDiego Caballero /// Creates a new insertion point at the given location. VPInsertPoint(VPBasicBlock * InsertBlock,VPBasicBlock::iterator InsertPoint)85168d04d5SDiego Caballero VPInsertPoint(VPBasicBlock *InsertBlock, VPBasicBlock::iterator InsertPoint) 86168d04d5SDiego Caballero : Block(InsertBlock), Point(InsertPoint) {} 87168d04d5SDiego Caballero 88168d04d5SDiego Caballero /// Returns true if this insert point is set. isSet()89168d04d5SDiego Caballero bool isSet() const { return Block != nullptr; } 90168d04d5SDiego Caballero getBlock()91168d04d5SDiego Caballero VPBasicBlock *getBlock() const { return Block; } getPoint()92168d04d5SDiego Caballero VPBasicBlock::iterator getPoint() const { return Point; } 93168d04d5SDiego Caballero }; 94168d04d5SDiego Caballero 95168d04d5SDiego Caballero /// Sets the current insert point to a previously-saved location. restoreIP(VPInsertPoint IP)96168d04d5SDiego Caballero void restoreIP(VPInsertPoint IP) { 97168d04d5SDiego Caballero if (IP.isSet()) 98168d04d5SDiego Caballero setInsertPoint(IP.getBlock(), IP.getPoint()); 99168d04d5SDiego Caballero else 100168d04d5SDiego Caballero clearInsertionPoint(); 101168d04d5SDiego Caballero } 102168d04d5SDiego Caballero 103168d04d5SDiego Caballero /// This specifies that created VPInstructions should be appended to the end 104168d04d5SDiego Caballero /// of the specified block. setInsertPoint(VPBasicBlock * TheBB)1050f1314c5SHal Finkel void setInsertPoint(VPBasicBlock *TheBB) { 1060f1314c5SHal Finkel assert(TheBB && "Attempting to set a null insert point"); 1070f1314c5SHal Finkel BB = TheBB; 1080f1314c5SHal Finkel InsertPt = BB->end(); 1090f1314c5SHal Finkel } 1100f1314c5SHal Finkel 111168d04d5SDiego Caballero /// This specifies that created instructions should be inserted at the 112168d04d5SDiego Caballero /// specified point. setInsertPoint(VPBasicBlock * TheBB,VPBasicBlock::iterator IP)113168d04d5SDiego Caballero void setInsertPoint(VPBasicBlock *TheBB, VPBasicBlock::iterator IP) { 114168d04d5SDiego Caballero BB = TheBB; 115168d04d5SDiego Caballero InsertPt = IP; 116168d04d5SDiego Caballero } 117168d04d5SDiego Caballero 118168d04d5SDiego Caballero /// Insert and return the specified instruction. insert(VPInstruction * I)119168d04d5SDiego Caballero VPInstruction *insert(VPInstruction *I) const { 120168d04d5SDiego Caballero BB->insert(I, InsertPt); 121168d04d5SDiego Caballero return I; 122168d04d5SDiego Caballero } 123168d04d5SDiego Caballero 124168d04d5SDiego Caballero /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as 125168d04d5SDiego Caballero /// its underlying Instruction. 126168d04d5SDiego Caballero VPValue *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands, 127*02d6950dSDavid Sherwood Instruction *Inst = nullptr, const Twine &Name = "") { 1285b362e4cSFlorian Hahn DebugLoc DL; 1295b362e4cSFlorian Hahn if (Inst) 1305b362e4cSFlorian Hahn DL = Inst->getDebugLoc(); 131*02d6950dSDavid Sherwood VPInstruction *NewVPInst = createInstruction(Opcode, Operands, DL, Name); 132168d04d5SDiego Caballero NewVPInst->setUnderlyingValue(Inst); 133168d04d5SDiego Caballero return NewVPInst; 134168d04d5SDiego Caballero } 1355b362e4cSFlorian Hahn VPValue *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands, 136*02d6950dSDavid Sherwood DebugLoc DL, const Twine &Name = "") { 137*02d6950dSDavid Sherwood return createInstruction(Opcode, Operands, DL, Name); 1380f1314c5SHal Finkel } 1390f1314c5SHal Finkel 140*02d6950dSDavid Sherwood VPValue *createNot(VPValue *Operand, DebugLoc DL, const Twine &Name = "") { 141*02d6950dSDavid Sherwood return createInstruction(VPInstruction::Not, {Operand}, DL, Name); 1420f1314c5SHal Finkel } 1430f1314c5SHal Finkel 144*02d6950dSDavid Sherwood VPValue *createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL, 145*02d6950dSDavid Sherwood const Twine &Name = "") { 146*02d6950dSDavid Sherwood return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}, DL, Name); 1470f1314c5SHal Finkel } 148083ea389SGalina Kistanova 149*02d6950dSDavid Sherwood VPValue *createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL, 150*02d6950dSDavid Sherwood const Twine &Name = "") { 151*02d6950dSDavid Sherwood return createInstruction(Instruction::BinaryOps::Or, {LHS, RHS}, DL, Name); 1525b362e4cSFlorian Hahn } 1535b362e4cSFlorian Hahn 1545b362e4cSFlorian Hahn VPValue *createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, 155*02d6950dSDavid Sherwood DebugLoc DL, const Twine &Name = "") { 156*02d6950dSDavid Sherwood return createNaryOp(Instruction::Select, {Cond, TrueVal, FalseVal}, DL, 157*02d6950dSDavid Sherwood Name); 158ed253ef7SJuneyoung Lee } 159ed253ef7SJuneyoung Lee 160168d04d5SDiego Caballero //===--------------------------------------------------------------------===// 161168d04d5SDiego Caballero // RAII helpers. 162168d04d5SDiego Caballero //===--------------------------------------------------------------------===// 163168d04d5SDiego Caballero 164168d04d5SDiego Caballero /// RAII object that stores the current insertion point and restores it when 165168d04d5SDiego Caballero /// the object is destroyed. 166168d04d5SDiego Caballero class InsertPointGuard { 167168d04d5SDiego Caballero VPBuilder &Builder; 168168d04d5SDiego Caballero VPBasicBlock *Block; 169168d04d5SDiego Caballero VPBasicBlock::iterator Point; 170168d04d5SDiego Caballero 171168d04d5SDiego Caballero public: InsertPointGuard(VPBuilder & B)172168d04d5SDiego Caballero InsertPointGuard(VPBuilder &B) 173168d04d5SDiego Caballero : Builder(B), Block(B.getInsertBlock()), Point(B.getInsertPoint()) {} 174168d04d5SDiego Caballero 175168d04d5SDiego Caballero InsertPointGuard(const InsertPointGuard &) = delete; 176168d04d5SDiego Caballero InsertPointGuard &operator=(const InsertPointGuard &) = delete; 177168d04d5SDiego Caballero ~InsertPointGuard()178168d04d5SDiego Caballero ~InsertPointGuard() { Builder.restoreIP(VPInsertPoint(Block, Point)); } 179168d04d5SDiego Caballero }; 180168d04d5SDiego Caballero }; 1810f1314c5SHal Finkel 1820f1314c5SHal Finkel /// TODO: The following VectorizationFactor was pulled out of 1830f1314c5SHal Finkel /// LoopVectorizationCostModel class. LV also deals with 1840f1314c5SHal Finkel /// VectorizerParams::VectorizationFactor and VectorizationCostTy. 1850f1314c5SHal Finkel /// We need to streamline them. 1860f1314c5SHal Finkel 187cc5ee857SFlorian Hahn /// Information about vectorization costs. 1880f1314c5SHal Finkel struct VectorizationFactor { 189cc5ee857SFlorian Hahn /// Vector width with best cost. 1905a34b3abSFrancesco Petrogalli ElementCount Width; 191cc5ee857SFlorian Hahn /// Cost of the loop with that width. 19286729538SSander de Smalen InstructionCost Cost; 19386729538SSander de Smalen 194cb69ba4fSFlorian Hahn /// Cost of the scalar loop. 195cb69ba4fSFlorian Hahn InstructionCost ScalarCost; 196cb69ba4fSFlorian Hahn 197644a965cSFlorian Hahn /// The minimum trip count required to make vectorization profitable, e.g. due 198644a965cSFlorian Hahn /// to runtime checks. 199644a965cSFlorian Hahn ElementCount MinProfitableTripCount; 200644a965cSFlorian Hahn VectorizationFactorVectorizationFactor201cb69ba4fSFlorian Hahn VectorizationFactor(ElementCount Width, InstructionCost Cost, 202cb69ba4fSFlorian Hahn InstructionCost ScalarCost) 203cb69ba4fSFlorian Hahn : Width(Width), Cost(Cost), ScalarCost(ScalarCost) {} 204ba5acbc4SFlorian Hahn 205cc5ee857SFlorian Hahn /// Width 1 means no vectorization, cost 0 means uncomputed cost. DisabledVectorizationFactor2065a34b3abSFrancesco Petrogalli static VectorizationFactor Disabled() { 207cb69ba4fSFlorian Hahn return {ElementCount::getFixed(1), 0, 0}; 2085a34b3abSFrancesco Petrogalli } 209e21ed594SFlorian Hahn 210e21ed594SFlorian Hahn bool operator==(const VectorizationFactor &rhs) const { 211e21ed594SFlorian Hahn return Width == rhs.Width && Cost == rhs.Cost; 212e21ed594SFlorian Hahn } 213a7e2c269SBardia Mahjour 214a7e2c269SBardia Mahjour bool operator!=(const VectorizationFactor &rhs) const { 215a7e2c269SBardia Mahjour return !(*this == rhs); 216a7e2c269SBardia Mahjour } 2170f1314c5SHal Finkel }; 2180f1314c5SHal Finkel 21981fdc73eSSander de Smalen /// A class that represents two vectorization factors (initialized with 0 by 22081fdc73eSSander de Smalen /// default). One for fixed-width vectorization and one for scalable 22181fdc73eSSander de Smalen /// vectorization. This can be used by the vectorizer to choose from a range of 22281fdc73eSSander de Smalen /// fixed and/or scalable VFs in order to find the most cost-effective VF to 22381fdc73eSSander de Smalen /// vectorize with. 22481fdc73eSSander de Smalen struct FixedScalableVFPair { 22581fdc73eSSander de Smalen ElementCount FixedVF; 22681fdc73eSSander de Smalen ElementCount ScalableVF; 22781fdc73eSSander de Smalen FixedScalableVFPairFixedScalableVFPair22881fdc73eSSander de Smalen FixedScalableVFPair() 22981fdc73eSSander de Smalen : FixedVF(ElementCount::getFixed(0)), 23081fdc73eSSander de Smalen ScalableVF(ElementCount::getScalable(0)) {} FixedScalableVFPairFixedScalableVFPair23181fdc73eSSander de Smalen FixedScalableVFPair(const ElementCount &Max) : FixedScalableVFPair() { 23281fdc73eSSander de Smalen *(Max.isScalable() ? &ScalableVF : &FixedVF) = Max; 23381fdc73eSSander de Smalen } FixedScalableVFPairFixedScalableVFPair23481fdc73eSSander de Smalen FixedScalableVFPair(const ElementCount &FixedVF, 23581fdc73eSSander de Smalen const ElementCount &ScalableVF) 23681fdc73eSSander de Smalen : FixedVF(FixedVF), ScalableVF(ScalableVF) { 23781fdc73eSSander de Smalen assert(!FixedVF.isScalable() && ScalableVF.isScalable() && 23881fdc73eSSander de Smalen "Invalid scalable properties"); 23981fdc73eSSander de Smalen } 24081fdc73eSSander de Smalen getNoneFixedScalableVFPair24181fdc73eSSander de Smalen static FixedScalableVFPair getNone() { return FixedScalableVFPair(); } 24281fdc73eSSander de Smalen 24381fdc73eSSander de Smalen /// \return true if either fixed- or scalable VF is non-zero. 24481fdc73eSSander de Smalen explicit operator bool() const { return FixedVF || ScalableVF; } 24581fdc73eSSander de Smalen 24681fdc73eSSander de Smalen /// \return true if either fixed- or scalable VF is a valid vector VF. hasVectorFixedScalableVFPair24781fdc73eSSander de Smalen bool hasVector() const { return FixedVF.isVector() || ScalableVF.isVector(); } 24881fdc73eSSander de Smalen }; 24981fdc73eSSander de Smalen 2500f1314c5SHal Finkel /// Planner drives the vectorization process after having passed 2510f1314c5SHal Finkel /// Legality checks. 2520f1314c5SHal Finkel class LoopVectorizationPlanner { 2530f1314c5SHal Finkel /// The loop that we evaluate. 2540f1314c5SHal Finkel Loop *OrigLoop; 2550f1314c5SHal Finkel 2560f1314c5SHal Finkel /// Loop Info analysis. 2570f1314c5SHal Finkel LoopInfo *LI; 2580f1314c5SHal Finkel 2590f1314c5SHal Finkel /// Target Library Info. 2600f1314c5SHal Finkel const TargetLibraryInfo *TLI; 2610f1314c5SHal Finkel 2620f1314c5SHal Finkel /// Target Transform Info. 2630f1314c5SHal Finkel const TargetTransformInfo *TTI; 2640f1314c5SHal Finkel 2650f1314c5SHal Finkel /// The legality analysis. 2660f1314c5SHal Finkel LoopVectorizationLegality *Legal; 2670f1314c5SHal Finkel 2689bbdde25SFlorian Hahn /// The profitability analysis. 2690f1314c5SHal Finkel LoopVectorizationCostModel &CM; 2700f1314c5SHal Finkel 2717f152543SGil Rapaport /// The interleaved access analysis. 2727f152543SGil Rapaport InterleavedAccessInfo &IAI; 2737f152543SGil Rapaport 27418138e02SFlorian Hahn PredicatedScalarEvolution &PSE; 27518138e02SFlorian Hahn 276c773d0f9SFlorian Hahn const LoopVectorizeHints &Hints; 277c773d0f9SFlorian Hahn 278c773d0f9SFlorian Hahn OptimizationRemarkEmitter *ORE; 279c773d0f9SFlorian Hahn 2800f1314c5SHal Finkel SmallVector<VPlanPtr, 4> VPlans; 2810f1314c5SHal Finkel 2820f1314c5SHal Finkel /// A builder used to construct the current plan. 2830f1314c5SHal Finkel VPBuilder Builder; 2840f1314c5SHal Finkel 2850f1314c5SHal Finkel public: LoopVectorizationPlanner(Loop * L,LoopInfo * LI,const TargetLibraryInfo * TLI,const TargetTransformInfo * TTI,LoopVectorizationLegality * Legal,LoopVectorizationCostModel & CM,InterleavedAccessInfo & IAI,PredicatedScalarEvolution & PSE,const LoopVectorizeHints & Hints,OptimizationRemarkEmitter * ORE)2860f1314c5SHal Finkel LoopVectorizationPlanner(Loop *L, LoopInfo *LI, const TargetLibraryInfo *TLI, 2870f1314c5SHal Finkel const TargetTransformInfo *TTI, 2880f1314c5SHal Finkel LoopVectorizationLegality *Legal, 2897f152543SGil Rapaport LoopVectorizationCostModel &CM, 29018138e02SFlorian Hahn InterleavedAccessInfo &IAI, 291c773d0f9SFlorian Hahn PredicatedScalarEvolution &PSE, 292c773d0f9SFlorian Hahn const LoopVectorizeHints &Hints, 293c773d0f9SFlorian Hahn OptimizationRemarkEmitter *ORE) 29418138e02SFlorian Hahn : OrigLoop(L), LI(LI), TLI(TLI), TTI(TTI), Legal(Legal), CM(CM), IAI(IAI), 295644a965cSFlorian Hahn PSE(PSE), Hints(Hints), ORE(ORE) {} 2960f1314c5SHal Finkel 297ba5acbc4SFlorian Hahn /// Plan how to best vectorize, return the best VF and its cost, or None if 298ba5acbc4SFlorian Hahn /// vectorization and interleaving should be avoided up front. 2995a34b3abSFrancesco Petrogalli Optional<VectorizationFactor> plan(ElementCount UserVF, unsigned UserIC); 3000f1314c5SHal Finkel 30160f2776bSDiego Caballero /// Use the VPlan-native path to plan how to best vectorize, return the best 30260f2776bSDiego Caballero /// VF and its cost. 3035a34b3abSFrancesco Petrogalli VectorizationFactor planInVPlanNativePath(ElementCount UserVF); 30460f2776bSDiego Caballero 3053d706c20SDavid Sherwood /// Return the best VPlan for \p VF. 3063d706c20SDavid Sherwood VPlan &getBestPlanFor(ElementCount VF) const; 3070f1314c5SHal Finkel 3080f1314c5SHal Finkel /// Generate the IR code for the body of the vectorized loop according to the 3093d706c20SDavid Sherwood /// best selected \p VF, \p UF and VPlan \p BestPlan. 3100dddf04cSFlorian Hahn /// TODO: \p IsEpilogueVectorization is needed to avoid issues due to epilogue 3110dddf04cSFlorian Hahn /// vectorization re-using plans for both the main and epilogue vector loops. 3120dddf04cSFlorian Hahn /// It should be removed once the re-use issue has been fixed. 3133d706c20SDavid Sherwood void executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan, 3140dddf04cSFlorian Hahn InnerLoopVectorizer &LB, DominatorTree *DT, 3150dddf04cSFlorian Hahn bool IsEpilogueVectorization); 3160f1314c5SHal Finkel 31792205cb2SAndrei Elovikov #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 31893a9d2deSAndrei Elovikov void printPlans(raw_ostream &O); 31992205cb2SAndrei Elovikov #endif 3200f1314c5SHal Finkel 321a7e2c269SBardia Mahjour /// Look through the existing plans and return true if we have one with all 322a7e2c269SBardia Mahjour /// the vectorization factors in question. hasPlanWithVF(ElementCount VF)323c42bb30bSDavid Sherwood bool hasPlanWithVF(ElementCount VF) const { 324c42bb30bSDavid Sherwood return any_of(VPlans, 325c42bb30bSDavid Sherwood [&](const VPlanPtr &Plan) { return Plan->hasVF(VF); }); 326a7e2c269SBardia Mahjour } 327a7e2c269SBardia Mahjour 32845e5d5b4SFlorian Hahn /// Test a \p Predicate on a \p Range of VF's. Return the value of applying 32945e5d5b4SFlorian Hahn /// \p Predicate on Range.Start, possibly decreasing Range.End such that the 33045e5d5b4SFlorian Hahn /// returned value holds for the entire \p Range. 33145e5d5b4SFlorian Hahn static bool 3325a34b3abSFrancesco Petrogalli getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate, 33345e5d5b4SFlorian Hahn VFRange &Range); 33445e5d5b4SFlorian Hahn 3353ed9f603STiehu Zhang /// Check if the number of runtime checks exceeds the threshold. 3363ed9f603STiehu Zhang bool requiresTooManyRuntimeChecks() const; 3373ed9f603STiehu Zhang 3380f1314c5SHal Finkel protected: 3390f1314c5SHal Finkel /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive, 3400f1314c5SHal Finkel /// according to the information gathered by Legal when it checked if it is 3410f1314c5SHal Finkel /// legal to vectorize the loop. 342f47573f9SSander de Smalen void buildVPlans(ElementCount MinVF, ElementCount MaxVF); 3430f1314c5SHal Finkel 3440f1314c5SHal Finkel private: 3450f1314c5SHal Finkel /// Build a VPlan according to the information gathered by Legal. \return a 3460f1314c5SHal Finkel /// VPlan for vectorization factors \p Range.Start and up to \p Range.End 3470f1314c5SHal Finkel /// exclusive, possibly decreasing \p Range.End. 348b3c6f07dSFlorian Hahn VPlanPtr buildVPlan(VFRange &Range); 349b3c6f07dSFlorian Hahn 350b3c6f07dSFlorian Hahn /// Build a VPlan using VPRecipes according to the information gather by 351b3c6f07dSFlorian Hahn /// Legal. This method is only used for the legacy inner loop vectorizer. 352a911fef3SFlorian Hahn VPlanPtr buildVPlanWithVPRecipes( 353e0c479cdSDavid Green VFRange &Range, SmallPtrSetImpl<Instruction *> &DeadInstructions, 354aa00b1d7SFlorian Hahn const MapVector<Instruction *, Instruction *> &SinkAfter); 355b3c6f07dSFlorian Hahn 356b3c6f07dSFlorian Hahn /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive, 357b3c6f07dSFlorian Hahn /// according to the information gathered by Legal when it checked if it is 358b3c6f07dSFlorian Hahn /// legal to vectorize the loop. This method creates VPlans using VPRecipes. 359f47573f9SSander de Smalen void buildVPlansWithVPRecipes(ElementCount MinVF, ElementCount MaxVF); 360745bf6cfSDavid Green 361a00aafc3SFlorian Hahn // Adjust the recipes for reductions. For in-loop reductions the chain of 362a00aafc3SFlorian Hahn // instructions leading from the loop exit instr to the phi need to be 363a00aafc3SFlorian Hahn // converted to reductions, with one operand being vector and the other being 364a00aafc3SFlorian Hahn // the scalar reduction chain. For other reductions, a select is introduced 365a00aafc3SFlorian Hahn // between the phi and live-out recipes when folding the tail. 366a00aafc3SFlorian Hahn void adjustRecipesForReductions(VPBasicBlock *LatchVPBB, VPlanPtr &Plan, 367f9967256SKerry McLaughlin VPRecipeBuilder &RecipeBuilder, 368f9967256SKerry McLaughlin ElementCount MinVF); 3690f1314c5SHal Finkel }; 3700f1314c5SHal Finkel 3710f1314c5SHal Finkel } // namespace llvm 3720f1314c5SHal Finkel 3730f1314c5SHal Finkel #endif // LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H 374