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" 280f1314c5SHal Finkel 290f1314c5SHal Finkel namespace llvm { 300f1314c5SHal Finkel 3149999d43SFlorian Hahn class LoopInfo; 32b108a457SSimon Pilgrim class LoopVectorizationLegality; 33b108a457SSimon Pilgrim class LoopVectorizationCostModel; 3418138e02SFlorian Hahn class PredicatedScalarEvolution; 35c773d0f9SFlorian Hahn class LoopVectorizationRequirements; 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, 48168d04d5SDiego Caballero ArrayRef<VPValue *> Operands) { 490f1314c5SHal Finkel VPInstruction *Instr = new VPInstruction(Opcode, Operands); 50168d04d5SDiego Caballero if (BB) 510f1314c5SHal Finkel BB->insert(Instr, InsertPt); 520f1314c5SHal Finkel return Instr; 530f1314c5SHal Finkel } 540f1314c5SHal Finkel 55168d04d5SDiego Caballero VPInstruction *createInstruction(unsigned Opcode, 56168d04d5SDiego Caballero std::initializer_list<VPValue *> Operands) { 57168d04d5SDiego Caballero return createInstruction(Opcode, ArrayRef<VPValue *>(Operands)); 58168d04d5SDiego Caballero } 59168d04d5SDiego Caballero 600f1314c5SHal Finkel public: 610f1314c5SHal Finkel VPBuilder() {} 620f1314c5SHal Finkel 63168d04d5SDiego Caballero /// Clear the insertion point: created instructions will not be inserted into 64168d04d5SDiego Caballero /// a block. 65168d04d5SDiego Caballero void clearInsertionPoint() { 66168d04d5SDiego Caballero BB = nullptr; 67168d04d5SDiego Caballero InsertPt = VPBasicBlock::iterator(); 68168d04d5SDiego Caballero } 69168d04d5SDiego Caballero 70168d04d5SDiego Caballero VPBasicBlock *getInsertBlock() const { return BB; } 71168d04d5SDiego Caballero VPBasicBlock::iterator getInsertPoint() const { return InsertPt; } 72168d04d5SDiego Caballero 73168d04d5SDiego Caballero /// InsertPoint - A saved insertion point. 74168d04d5SDiego Caballero class VPInsertPoint { 75168d04d5SDiego Caballero VPBasicBlock *Block = nullptr; 76168d04d5SDiego Caballero VPBasicBlock::iterator Point; 77168d04d5SDiego Caballero 78168d04d5SDiego Caballero public: 79168d04d5SDiego Caballero /// Creates a new insertion point which doesn't point to anything. 80168d04d5SDiego Caballero VPInsertPoint() = default; 81168d04d5SDiego Caballero 82168d04d5SDiego Caballero /// Creates a new insertion point at the given location. 83168d04d5SDiego Caballero VPInsertPoint(VPBasicBlock *InsertBlock, VPBasicBlock::iterator InsertPoint) 84168d04d5SDiego Caballero : Block(InsertBlock), Point(InsertPoint) {} 85168d04d5SDiego Caballero 86168d04d5SDiego Caballero /// Returns true if this insert point is set. 87168d04d5SDiego Caballero bool isSet() const { return Block != nullptr; } 88168d04d5SDiego Caballero 89168d04d5SDiego Caballero VPBasicBlock *getBlock() const { return Block; } 90168d04d5SDiego Caballero VPBasicBlock::iterator getPoint() const { return Point; } 91168d04d5SDiego Caballero }; 92168d04d5SDiego Caballero 93168d04d5SDiego Caballero /// Sets the current insert point to a previously-saved location. 94168d04d5SDiego Caballero void restoreIP(VPInsertPoint IP) { 95168d04d5SDiego Caballero if (IP.isSet()) 96168d04d5SDiego Caballero setInsertPoint(IP.getBlock(), IP.getPoint()); 97168d04d5SDiego Caballero else 98168d04d5SDiego Caballero clearInsertionPoint(); 99168d04d5SDiego Caballero } 100168d04d5SDiego Caballero 101168d04d5SDiego Caballero /// This specifies that created VPInstructions should be appended to the end 102168d04d5SDiego Caballero /// of the specified block. 1030f1314c5SHal Finkel void setInsertPoint(VPBasicBlock *TheBB) { 1040f1314c5SHal Finkel assert(TheBB && "Attempting to set a null insert point"); 1050f1314c5SHal Finkel BB = TheBB; 1060f1314c5SHal Finkel InsertPt = BB->end(); 1070f1314c5SHal Finkel } 1080f1314c5SHal Finkel 109168d04d5SDiego Caballero /// This specifies that created instructions should be inserted at the 110168d04d5SDiego Caballero /// specified point. 111168d04d5SDiego Caballero void setInsertPoint(VPBasicBlock *TheBB, VPBasicBlock::iterator IP) { 112168d04d5SDiego Caballero BB = TheBB; 113168d04d5SDiego Caballero InsertPt = IP; 114168d04d5SDiego Caballero } 115168d04d5SDiego Caballero 116168d04d5SDiego Caballero /// Insert and return the specified instruction. 117168d04d5SDiego Caballero VPInstruction *insert(VPInstruction *I) const { 118168d04d5SDiego Caballero BB->insert(I, InsertPt); 119168d04d5SDiego Caballero return I; 120168d04d5SDiego Caballero } 121168d04d5SDiego Caballero 122168d04d5SDiego Caballero /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as 123168d04d5SDiego Caballero /// its underlying Instruction. 124168d04d5SDiego Caballero VPValue *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands, 125168d04d5SDiego Caballero Instruction *Inst = nullptr) { 126168d04d5SDiego Caballero VPInstruction *NewVPInst = createInstruction(Opcode, Operands); 127168d04d5SDiego Caballero NewVPInst->setUnderlyingValue(Inst); 128168d04d5SDiego Caballero return NewVPInst; 129168d04d5SDiego Caballero } 130168d04d5SDiego Caballero VPValue *createNaryOp(unsigned Opcode, 131168d04d5SDiego Caballero std::initializer_list<VPValue *> Operands, 132168d04d5SDiego Caballero Instruction *Inst = nullptr) { 133168d04d5SDiego Caballero return createNaryOp(Opcode, ArrayRef<VPValue *>(Operands), Inst); 134168d04d5SDiego Caballero } 135168d04d5SDiego Caballero 1360f1314c5SHal Finkel VPValue *createNot(VPValue *Operand) { 1370f1314c5SHal Finkel return createInstruction(VPInstruction::Not, {Operand}); 1380f1314c5SHal Finkel } 1390f1314c5SHal Finkel 1400f1314c5SHal Finkel VPValue *createAnd(VPValue *LHS, VPValue *RHS) { 1410f1314c5SHal Finkel return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}); 1420f1314c5SHal Finkel } 1430f1314c5SHal Finkel 1440f1314c5SHal Finkel VPValue *createOr(VPValue *LHS, VPValue *RHS) { 1450f1314c5SHal Finkel return createInstruction(Instruction::BinaryOps::Or, {LHS, RHS}); 1460f1314c5SHal Finkel } 147083ea389SGalina Kistanova 148ed253ef7SJuneyoung Lee VPValue *createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal) { 149ed253ef7SJuneyoung Lee return createNaryOp(Instruction::Select, {Cond, TrueVal, FalseVal}); 150ed253ef7SJuneyoung Lee } 151ed253ef7SJuneyoung Lee 152168d04d5SDiego Caballero //===--------------------------------------------------------------------===// 153168d04d5SDiego Caballero // RAII helpers. 154168d04d5SDiego Caballero //===--------------------------------------------------------------------===// 155168d04d5SDiego Caballero 156168d04d5SDiego Caballero /// RAII object that stores the current insertion point and restores it when 157168d04d5SDiego Caballero /// the object is destroyed. 158168d04d5SDiego Caballero class InsertPointGuard { 159168d04d5SDiego Caballero VPBuilder &Builder; 160168d04d5SDiego Caballero VPBasicBlock *Block; 161168d04d5SDiego Caballero VPBasicBlock::iterator Point; 162168d04d5SDiego Caballero 163168d04d5SDiego Caballero public: 164168d04d5SDiego Caballero InsertPointGuard(VPBuilder &B) 165168d04d5SDiego Caballero : Builder(B), Block(B.getInsertBlock()), Point(B.getInsertPoint()) {} 166168d04d5SDiego Caballero 167168d04d5SDiego Caballero InsertPointGuard(const InsertPointGuard &) = delete; 168168d04d5SDiego Caballero InsertPointGuard &operator=(const InsertPointGuard &) = delete; 169168d04d5SDiego Caballero 170168d04d5SDiego Caballero ~InsertPointGuard() { Builder.restoreIP(VPInsertPoint(Block, Point)); } 171168d04d5SDiego Caballero }; 172168d04d5SDiego Caballero }; 1730f1314c5SHal Finkel 1740f1314c5SHal Finkel /// TODO: The following VectorizationFactor was pulled out of 1750f1314c5SHal Finkel /// LoopVectorizationCostModel class. LV also deals with 1760f1314c5SHal Finkel /// VectorizerParams::VectorizationFactor and VectorizationCostTy. 1770f1314c5SHal Finkel /// We need to streamline them. 1780f1314c5SHal Finkel 179cc5ee857SFlorian Hahn /// Information about vectorization costs. 1800f1314c5SHal Finkel struct VectorizationFactor { 181cc5ee857SFlorian Hahn /// Vector width with best cost. 1825a34b3abSFrancesco Petrogalli ElementCount Width; 183cc5ee857SFlorian Hahn /// Cost of the loop with that width. 18486729538SSander de Smalen InstructionCost Cost; 18586729538SSander de Smalen 18686729538SSander de Smalen VectorizationFactor(ElementCount Width, InstructionCost Cost) 18786729538SSander de Smalen : Width(Width), Cost(Cost) {} 188ba5acbc4SFlorian Hahn 189cc5ee857SFlorian Hahn /// Width 1 means no vectorization, cost 0 means uncomputed cost. 1905a34b3abSFrancesco Petrogalli static VectorizationFactor Disabled() { 1915a34b3abSFrancesco Petrogalli return {ElementCount::getFixed(1), 0}; 1925a34b3abSFrancesco Petrogalli } 193e21ed594SFlorian Hahn 194e21ed594SFlorian Hahn bool operator==(const VectorizationFactor &rhs) const { 195e21ed594SFlorian Hahn return Width == rhs.Width && Cost == rhs.Cost; 196e21ed594SFlorian Hahn } 197a7e2c269SBardia Mahjour 198a7e2c269SBardia Mahjour bool operator!=(const VectorizationFactor &rhs) const { 199a7e2c269SBardia Mahjour return !(*this == rhs); 200a7e2c269SBardia Mahjour } 2010f1314c5SHal Finkel }; 2020f1314c5SHal Finkel 20381fdc73eSSander de Smalen /// A class that represents two vectorization factors (initialized with 0 by 20481fdc73eSSander de Smalen /// default). One for fixed-width vectorization and one for scalable 20581fdc73eSSander de Smalen /// vectorization. This can be used by the vectorizer to choose from a range of 20681fdc73eSSander de Smalen /// fixed and/or scalable VFs in order to find the most cost-effective VF to 20781fdc73eSSander de Smalen /// vectorize with. 20881fdc73eSSander de Smalen struct FixedScalableVFPair { 20981fdc73eSSander de Smalen ElementCount FixedVF; 21081fdc73eSSander de Smalen ElementCount ScalableVF; 21181fdc73eSSander de Smalen 21281fdc73eSSander de Smalen FixedScalableVFPair() 21381fdc73eSSander de Smalen : FixedVF(ElementCount::getFixed(0)), 21481fdc73eSSander de Smalen ScalableVF(ElementCount::getScalable(0)) {} 21581fdc73eSSander de Smalen FixedScalableVFPair(const ElementCount &Max) : FixedScalableVFPair() { 21681fdc73eSSander de Smalen *(Max.isScalable() ? &ScalableVF : &FixedVF) = Max; 21781fdc73eSSander de Smalen } 21881fdc73eSSander de Smalen FixedScalableVFPair(const ElementCount &FixedVF, 21981fdc73eSSander de Smalen const ElementCount &ScalableVF) 22081fdc73eSSander de Smalen : FixedVF(FixedVF), ScalableVF(ScalableVF) { 22181fdc73eSSander de Smalen assert(!FixedVF.isScalable() && ScalableVF.isScalable() && 22281fdc73eSSander de Smalen "Invalid scalable properties"); 22381fdc73eSSander de Smalen } 22481fdc73eSSander de Smalen 22581fdc73eSSander de Smalen static FixedScalableVFPair getNone() { return FixedScalableVFPair(); } 22681fdc73eSSander de Smalen 22781fdc73eSSander de Smalen /// \return true if either fixed- or scalable VF is non-zero. 22881fdc73eSSander de Smalen explicit operator bool() const { return FixedVF || ScalableVF; } 22981fdc73eSSander de Smalen 23081fdc73eSSander de Smalen /// \return true if either fixed- or scalable VF is a valid vector VF. 23181fdc73eSSander de Smalen bool hasVector() const { return FixedVF.isVector() || ScalableVF.isVector(); } 23281fdc73eSSander de Smalen }; 23381fdc73eSSander de Smalen 2340f1314c5SHal Finkel /// Planner drives the vectorization process after having passed 2350f1314c5SHal Finkel /// Legality checks. 2360f1314c5SHal Finkel class LoopVectorizationPlanner { 2370f1314c5SHal Finkel /// The loop that we evaluate. 2380f1314c5SHal Finkel Loop *OrigLoop; 2390f1314c5SHal Finkel 2400f1314c5SHal Finkel /// Loop Info analysis. 2410f1314c5SHal Finkel LoopInfo *LI; 2420f1314c5SHal Finkel 2430f1314c5SHal Finkel /// Target Library Info. 2440f1314c5SHal Finkel const TargetLibraryInfo *TLI; 2450f1314c5SHal Finkel 2460f1314c5SHal Finkel /// Target Transform Info. 2470f1314c5SHal Finkel const TargetTransformInfo *TTI; 2480f1314c5SHal Finkel 2490f1314c5SHal Finkel /// The legality analysis. 2500f1314c5SHal Finkel LoopVectorizationLegality *Legal; 2510f1314c5SHal Finkel 2529bbdde25SFlorian Hahn /// The profitability analysis. 2530f1314c5SHal Finkel LoopVectorizationCostModel &CM; 2540f1314c5SHal Finkel 2557f152543SGil Rapaport /// The interleaved access analysis. 2567f152543SGil Rapaport InterleavedAccessInfo &IAI; 2577f152543SGil Rapaport 25818138e02SFlorian Hahn PredicatedScalarEvolution &PSE; 25918138e02SFlorian Hahn 260c773d0f9SFlorian Hahn const LoopVectorizeHints &Hints; 261c773d0f9SFlorian Hahn 262c773d0f9SFlorian Hahn LoopVectorizationRequirements &Requirements; 263c773d0f9SFlorian Hahn 264c773d0f9SFlorian Hahn OptimizationRemarkEmitter *ORE; 265c773d0f9SFlorian Hahn 2660f1314c5SHal Finkel SmallVector<VPlanPtr, 4> VPlans; 2670f1314c5SHal Finkel 2680f1314c5SHal Finkel /// A builder used to construct the current plan. 2690f1314c5SHal Finkel VPBuilder Builder; 2700f1314c5SHal Finkel 2715a34b3abSFrancesco Petrogalli /// The best number of elements of the vector types used in the 2725a34b3abSFrancesco Petrogalli /// transformed loop. BestVF = None means that vectorization is 2735a34b3abSFrancesco Petrogalli /// disabled. 2745a34b3abSFrancesco Petrogalli Optional<ElementCount> BestVF = None; 2750f1314c5SHal Finkel unsigned BestUF = 0; 2760f1314c5SHal Finkel 2770f1314c5SHal Finkel public: 2780f1314c5SHal Finkel LoopVectorizationPlanner(Loop *L, LoopInfo *LI, const TargetLibraryInfo *TLI, 2790f1314c5SHal Finkel const TargetTransformInfo *TTI, 2800f1314c5SHal Finkel LoopVectorizationLegality *Legal, 2817f152543SGil Rapaport LoopVectorizationCostModel &CM, 28218138e02SFlorian Hahn InterleavedAccessInfo &IAI, 283c773d0f9SFlorian Hahn PredicatedScalarEvolution &PSE, 284c773d0f9SFlorian Hahn const LoopVectorizeHints &Hints, 285c773d0f9SFlorian Hahn LoopVectorizationRequirements &Requirements, 286c773d0f9SFlorian Hahn OptimizationRemarkEmitter *ORE) 28718138e02SFlorian Hahn : OrigLoop(L), LI(LI), TLI(TLI), TTI(TTI), Legal(Legal), CM(CM), IAI(IAI), 288c773d0f9SFlorian Hahn PSE(PSE), Hints(Hints), Requirements(Requirements), ORE(ORE) {} 2890f1314c5SHal Finkel 290ba5acbc4SFlorian Hahn /// Plan how to best vectorize, return the best VF and its cost, or None if 291ba5acbc4SFlorian Hahn /// vectorization and interleaving should be avoided up front. 2925a34b3abSFrancesco Petrogalli Optional<VectorizationFactor> plan(ElementCount UserVF, unsigned UserIC); 2930f1314c5SHal Finkel 29460f2776bSDiego Caballero /// Use the VPlan-native path to plan how to best vectorize, return the best 29560f2776bSDiego Caballero /// VF and its cost. 2965a34b3abSFrancesco Petrogalli VectorizationFactor planInVPlanNativePath(ElementCount UserVF); 29760f2776bSDiego Caballero 2980f1314c5SHal Finkel /// Finalize the best decision and dispose of all other VPlans. 2995a34b3abSFrancesco Petrogalli void setBestPlan(ElementCount VF, unsigned UF); 3000f1314c5SHal Finkel 3010f1314c5SHal Finkel /// Generate the IR code for the body of the vectorized loop according to the 3020f1314c5SHal Finkel /// best selected VPlan. 3030f1314c5SHal Finkel void executePlan(InnerLoopVectorizer &LB, DominatorTree *DT); 3040f1314c5SHal Finkel 30592205cb2SAndrei Elovikov #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 30693a9d2deSAndrei Elovikov void printPlans(raw_ostream &O); 30792205cb2SAndrei Elovikov #endif 3080f1314c5SHal Finkel 309a7e2c269SBardia Mahjour /// Look through the existing plans and return true if we have one with all 310a7e2c269SBardia Mahjour /// the vectorization factors in question. 311a7e2c269SBardia Mahjour bool hasPlanWithVFs(const ArrayRef<ElementCount> VFs) const { 312a7e2c269SBardia Mahjour return any_of(VPlans, [&](const VPlanPtr &Plan) { 313a7e2c269SBardia Mahjour return all_of(VFs, [&](const ElementCount &VF) { 31438c6933dSFlorian Hahn return Plan->hasVF(VF); 315a7e2c269SBardia Mahjour }); 316a7e2c269SBardia Mahjour }); 317a7e2c269SBardia Mahjour } 318a7e2c269SBardia Mahjour 31945e5d5b4SFlorian Hahn /// Test a \p Predicate on a \p Range of VF's. Return the value of applying 32045e5d5b4SFlorian Hahn /// \p Predicate on Range.Start, possibly decreasing Range.End such that the 32145e5d5b4SFlorian Hahn /// returned value holds for the entire \p Range. 32245e5d5b4SFlorian Hahn static bool 3235a34b3abSFrancesco Petrogalli getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate, 32445e5d5b4SFlorian Hahn VFRange &Range); 32545e5d5b4SFlorian Hahn 3260f1314c5SHal Finkel protected: 3270f1314c5SHal Finkel /// Collect the instructions from the original loop that would be trivially 3280f1314c5SHal Finkel /// dead in the vectorized loop if generated. 3290f1314c5SHal Finkel void collectTriviallyDeadInstructions( 3300f1314c5SHal Finkel SmallPtrSetImpl<Instruction *> &DeadInstructions); 3310f1314c5SHal Finkel 3320f1314c5SHal Finkel /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive, 3330f1314c5SHal Finkel /// according to the information gathered by Legal when it checked if it is 3340f1314c5SHal Finkel /// legal to vectorize the loop. 335f47573f9SSander de Smalen void buildVPlans(ElementCount MinVF, ElementCount MaxVF); 3360f1314c5SHal Finkel 3370f1314c5SHal Finkel private: 3380f1314c5SHal Finkel /// Build a VPlan according to the information gathered by Legal. \return a 3390f1314c5SHal Finkel /// VPlan for vectorization factors \p Range.Start and up to \p Range.End 3400f1314c5SHal Finkel /// exclusive, possibly decreasing \p Range.End. 341b3c6f07dSFlorian Hahn VPlanPtr buildVPlan(VFRange &Range); 342b3c6f07dSFlorian Hahn 343b3c6f07dSFlorian Hahn /// Build a VPlan using VPRecipes according to the information gather by 344b3c6f07dSFlorian Hahn /// Legal. This method is only used for the legacy inner loop vectorizer. 345a911fef3SFlorian Hahn VPlanPtr buildVPlanWithVPRecipes( 346e0c479cdSDavid Green VFRange &Range, SmallPtrSetImpl<Instruction *> &DeadInstructions, 347aa00b1d7SFlorian Hahn const MapVector<Instruction *, Instruction *> &SinkAfter); 348b3c6f07dSFlorian Hahn 349b3c6f07dSFlorian Hahn /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive, 350b3c6f07dSFlorian Hahn /// according to the information gathered by Legal when it checked if it is 351b3c6f07dSFlorian Hahn /// legal to vectorize the loop. This method creates VPlans using VPRecipes. 352f47573f9SSander de Smalen void buildVPlansWithVPRecipes(ElementCount MinVF, ElementCount MaxVF); 353745bf6cfSDavid Green 354*a00aafc3SFlorian Hahn // Adjust the recipes for reductions. For in-loop reductions the chain of 355*a00aafc3SFlorian Hahn // instructions leading from the loop exit instr to the phi need to be 356*a00aafc3SFlorian Hahn // converted to reductions, with one operand being vector and the other being 357*a00aafc3SFlorian Hahn // the scalar reduction chain. For other reductions, a select is introduced 358*a00aafc3SFlorian Hahn // between the phi and live-out recipes when folding the tail. 359*a00aafc3SFlorian Hahn void adjustRecipesForReductions(VPBasicBlock *LatchVPBB, VPlanPtr &Plan, 360f9967256SKerry McLaughlin VPRecipeBuilder &RecipeBuilder, 361f9967256SKerry McLaughlin ElementCount MinVF); 3620f1314c5SHal Finkel }; 3630f1314c5SHal Finkel 3640f1314c5SHal Finkel } // namespace llvm 3650f1314c5SHal Finkel 3660f1314c5SHal Finkel #endif // LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H 367