1 //===- LoopVectorizationPlanner.h - Planner for LoopVectorization ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This file provides a LoopVectorizationPlanner class.
12 /// InnerLoopVectorizer vectorizes loops which contain only one basic
13 /// LoopVectorizationPlanner - drives the vectorization process after having
14 /// passed Legality checks.
15 /// The planner builds and optimizes the Vectorization Plans which record the
16 /// decisions how to vectorize the given loop. In particular, represent the
17 /// control-flow of the vectorized version, the replication of instructions that
18 /// are to be scalarized, and interleave access groups.
20 /// Also provides a VPlan-based builder utility analogous to IRBuilder.
21 /// It provides an instruction-level API for generating VPInstructions while
22 /// abstracting away the Recipe manipulation details.
23 //===----------------------------------------------------------------------===//
25 #ifndef LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
26 #define LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
29 #include "llvm/Analysis/LoopInfo.h"
30 #include "llvm/Analysis/TargetLibraryInfo.h"
31 #include "llvm/Analysis/TargetTransformInfo.h"
35 /// VPlan-based builder utility analogous to IRBuilder.
38 VPBasicBlock *BB = nullptr;
39 VPBasicBlock::iterator InsertPt = VPBasicBlock::iterator();
41 VPInstruction *createInstruction(unsigned Opcode,
42 ArrayRef<VPValue *> Operands) {
43 VPInstruction *Instr = new VPInstruction(Opcode, Operands);
45 BB->insert(Instr, InsertPt);
49 VPInstruction *createInstruction(unsigned Opcode,
50 std::initializer_list<VPValue *> Operands) {
51 return createInstruction(Opcode, ArrayRef<VPValue *>(Operands));
57 /// Clear the insertion point: created instructions will not be inserted into
59 void clearInsertionPoint() {
61 InsertPt = VPBasicBlock::iterator();
64 VPBasicBlock *getInsertBlock() const { return BB; }
65 VPBasicBlock::iterator getInsertPoint() const { return InsertPt; }
67 /// InsertPoint - A saved insertion point.
69 VPBasicBlock *Block = nullptr;
70 VPBasicBlock::iterator Point;
73 /// Creates a new insertion point which doesn't point to anything.
74 VPInsertPoint() = default;
76 /// Creates a new insertion point at the given location.
77 VPInsertPoint(VPBasicBlock *InsertBlock, VPBasicBlock::iterator InsertPoint)
78 : Block(InsertBlock), Point(InsertPoint) {}
80 /// Returns true if this insert point is set.
81 bool isSet() const { return Block != nullptr; }
83 VPBasicBlock *getBlock() const { return Block; }
84 VPBasicBlock::iterator getPoint() const { return Point; }
87 /// Sets the current insert point to a previously-saved location.
88 void restoreIP(VPInsertPoint IP) {
90 setInsertPoint(IP.getBlock(), IP.getPoint());
92 clearInsertionPoint();
95 /// This specifies that created VPInstructions should be appended to the end
96 /// of the specified block.
97 void setInsertPoint(VPBasicBlock *TheBB) {
98 assert(TheBB && "Attempting to set a null insert point");
100 InsertPt = BB->end();
103 /// This specifies that created instructions should be inserted at the
105 void setInsertPoint(VPBasicBlock *TheBB, VPBasicBlock::iterator IP) {
110 /// Insert and return the specified instruction.
111 VPInstruction *insert(VPInstruction *I) const {
112 BB->insert(I, InsertPt);
116 /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as
117 /// its underlying Instruction.
118 VPValue *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands,
119 Instruction *Inst = nullptr) {
120 VPInstruction *NewVPInst = createInstruction(Opcode, Operands);
121 NewVPInst->setUnderlyingValue(Inst);
124 VPValue *createNaryOp(unsigned Opcode,
125 std::initializer_list<VPValue *> Operands,
126 Instruction *Inst = nullptr) {
127 return createNaryOp(Opcode, ArrayRef<VPValue *>(Operands), Inst);
130 VPValue *createNot(VPValue *Operand) {
131 return createInstruction(VPInstruction::Not, {Operand});
134 VPValue *createAnd(VPValue *LHS, VPValue *RHS) {
135 return createInstruction(Instruction::BinaryOps::And, {LHS, RHS});
138 VPValue *createOr(VPValue *LHS, VPValue *RHS) {
139 return createInstruction(Instruction::BinaryOps::Or, {LHS, RHS});
142 //===--------------------------------------------------------------------===//
144 //===--------------------------------------------------------------------===//
146 /// RAII object that stores the current insertion point and restores it when
147 /// the object is destroyed.
148 class InsertPointGuard {
151 VPBasicBlock::iterator Point;
154 InsertPointGuard(VPBuilder &B)
155 : Builder(B), Block(B.getInsertBlock()), Point(B.getInsertPoint()) {}
157 InsertPointGuard(const InsertPointGuard &) = delete;
158 InsertPointGuard &operator=(const InsertPointGuard &) = delete;
160 ~InsertPointGuard() { Builder.restoreIP(VPInsertPoint(Block, Point)); }
164 /// TODO: The following VectorizationFactor was pulled out of
165 /// LoopVectorizationCostModel class. LV also deals with
166 /// VectorizerParams::VectorizationFactor and VectorizationCostTy.
167 /// We need to streamline them.
169 /// Information about vectorization costs
170 struct VectorizationFactor {
171 // Vector width with best cost
173 // Cost of the loop with that width
177 /// Planner drives the vectorization process after having passed
179 class LoopVectorizationPlanner {
180 /// The loop that we evaluate.
183 /// Loop Info analysis.
186 /// Target Library Info.
187 const TargetLibraryInfo *TLI;
189 /// Target Transform Info.
190 const TargetTransformInfo *TTI;
192 /// The legality analysis.
193 LoopVectorizationLegality *Legal;
195 /// The profitablity analysis.
196 LoopVectorizationCostModel &CM;
198 using VPlanPtr = std::unique_ptr<VPlan>;
200 SmallVector<VPlanPtr, 4> VPlans;
202 /// This class is used to enable the VPlan to invoke a method of ILV. This is
203 /// needed until the method is refactored out of ILV and becomes reusable.
204 struct VPCallbackILV : public VPCallback {
205 InnerLoopVectorizer &ILV;
207 VPCallbackILV(InnerLoopVectorizer &ILV) : ILV(ILV) {}
209 Value *getOrCreateVectorValues(Value *V, unsigned Part) override;
212 /// A builder used to construct the current plan.
219 LoopVectorizationPlanner(Loop *L, LoopInfo *LI, const TargetLibraryInfo *TLI,
220 const TargetTransformInfo *TTI,
221 LoopVectorizationLegality *Legal,
222 LoopVectorizationCostModel &CM)
223 : OrigLoop(L), LI(LI), TLI(TLI), TTI(TTI), Legal(Legal), CM(CM) {}
225 /// Plan how to best vectorize, return the best VF and its cost.
226 VectorizationFactor plan(bool OptForSize, unsigned UserVF);
228 /// Use the VPlan-native path to plan how to best vectorize, return the best
230 VectorizationFactor planInVPlanNativePath(bool OptForSize, unsigned UserVF);
232 /// Finalize the best decision and dispose of all other VPlans.
233 void setBestPlan(unsigned VF, unsigned UF);
235 /// Generate the IR code for the body of the vectorized loop according to the
236 /// best selected VPlan.
237 void executePlan(InnerLoopVectorizer &LB, DominatorTree *DT);
239 void printPlans(raw_ostream &O) {
240 for (const auto &Plan : VPlans)
244 /// Test a \p Predicate on a \p Range of VF's. Return the value of applying
245 /// \p Predicate on Range.Start, possibly decreasing Range.End such that the
246 /// returned value holds for the entire \p Range.
248 getDecisionAndClampRange(const std::function<bool(unsigned)> &Predicate,
252 /// Collect the instructions from the original loop that would be trivially
253 /// dead in the vectorized loop if generated.
254 void collectTriviallyDeadInstructions(
255 SmallPtrSetImpl<Instruction *> &DeadInstructions);
257 /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
258 /// according to the information gathered by Legal when it checked if it is
259 /// legal to vectorize the loop.
260 void buildVPlans(unsigned MinVF, unsigned MaxVF);
263 /// Build a VPlan according to the information gathered by Legal. \return a
264 /// VPlan for vectorization factors \p Range.Start and up to \p Range.End
265 /// exclusive, possibly decreasing \p Range.End.
266 VPlanPtr buildVPlan(VFRange &Range);
268 /// Build a VPlan using VPRecipes according to the information gather by
269 /// Legal. This method is only used for the legacy inner loop vectorizer.
271 buildVPlanWithVPRecipes(VFRange &Range, SmallPtrSetImpl<Value *> &NeedDef,
272 SmallPtrSetImpl<Instruction *> &DeadInstructions);
274 /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
275 /// according to the information gathered by Legal when it checked if it is
276 /// legal to vectorize the loop. This method creates VPlans using VPRecipes.
277 void buildVPlansWithVPRecipes(unsigned MinVF, unsigned MaxVF);
282 #endif // LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H