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