LLVM  8.0.1
LoopVectorizationPlanner.h
Go to the documentation of this file.
1 //===- LoopVectorizationPlanner.h - Planner for LoopVectorization ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
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.
19 ///
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 //===----------------------------------------------------------------------===//
24 
25 #ifndef LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
26 #define LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
27 
28 #include "VPlan.h"
29 #include "llvm/Analysis/LoopInfo.h"
32 
33 namespace llvm {
34 
35 /// VPlan-based builder utility analogous to IRBuilder.
36 class VPBuilder {
37 private:
38  VPBasicBlock *BB = nullptr;
40 
41  VPInstruction *createInstruction(unsigned Opcode,
42  ArrayRef<VPValue *> Operands) {
43  VPInstruction *Instr = new VPInstruction(Opcode, Operands);
44  if (BB)
45  BB->insert(Instr, InsertPt);
46  return Instr;
47  }
48 
49  VPInstruction *createInstruction(unsigned Opcode,
50  std::initializer_list<VPValue *> Operands) {
51  return createInstruction(Opcode, ArrayRef<VPValue *>(Operands));
52  }
53 
54 public:
55  VPBuilder() {}
56 
57  /// Clear the insertion point: created instructions will not be inserted into
58  /// a block.
60  BB = nullptr;
61  InsertPt = VPBasicBlock::iterator();
62  }
63 
64  VPBasicBlock *getInsertBlock() const { return BB; }
65  VPBasicBlock::iterator getInsertPoint() const { return InsertPt; }
66 
67  /// InsertPoint - A saved insertion point.
68  class VPInsertPoint {
69  VPBasicBlock *Block = nullptr;
71 
72  public:
73  /// Creates a new insertion point which doesn't point to anything.
74  VPInsertPoint() = default;
75 
76  /// Creates a new insertion point at the given location.
78  : Block(InsertBlock), Point(InsertPoint) {}
79 
80  /// Returns true if this insert point is set.
81  bool isSet() const { return Block != nullptr; }
82 
83  VPBasicBlock *getBlock() const { return Block; }
84  VPBasicBlock::iterator getPoint() const { return Point; }
85  };
86 
87  /// Sets the current insert point to a previously-saved location.
89  if (IP.isSet())
90  setInsertPoint(IP.getBlock(), IP.getPoint());
91  else
93  }
94 
95  /// This specifies that created VPInstructions should be appended to the end
96  /// of the specified block.
98  assert(TheBB && "Attempting to set a null insert point");
99  BB = TheBB;
100  InsertPt = BB->end();
101  }
102 
103  /// This specifies that created instructions should be inserted at the
104  /// specified point.
106  BB = TheBB;
107  InsertPt = IP;
108  }
109 
110  /// Insert and return the specified instruction.
112  BB->insert(I, InsertPt);
113  return I;
114  }
115 
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);
122  return NewVPInst;
123  }
124  VPValue *createNaryOp(unsigned Opcode,
125  std::initializer_list<VPValue *> Operands,
126  Instruction *Inst = nullptr) {
127  return createNaryOp(Opcode, ArrayRef<VPValue *>(Operands), Inst);
128  }
129 
130  VPValue *createNot(VPValue *Operand) {
131  return createInstruction(VPInstruction::Not, {Operand});
132  }
133 
135  return createInstruction(Instruction::BinaryOps::And, {LHS, RHS});
136  }
137 
139  return createInstruction(Instruction::BinaryOps::Or, {LHS, RHS});
140  }
141 
142  //===--------------------------------------------------------------------===//
143  // RAII helpers.
144  //===--------------------------------------------------------------------===//
145 
146  /// RAII object that stores the current insertion point and restores it when
147  /// the object is destroyed.
149  VPBuilder &Builder;
150  VPBasicBlock *Block;
152 
153  public:
155  : Builder(B), Block(B.getInsertBlock()), Point(B.getInsertPoint()) {}
156 
157  InsertPointGuard(const InsertPointGuard &) = delete;
158  InsertPointGuard &operator=(const InsertPointGuard &) = delete;
159 
160  ~InsertPointGuard() { Builder.restoreIP(VPInsertPoint(Block, Point)); }
161  };
162 };
163 
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.
168 
169 /// Information about vectorization costs
171  // Vector width with best cost
172  unsigned Width;
173  // Cost of the loop with that width
174  unsigned Cost;
175 };
176 
177 /// Planner drives the vectorization process after having passed
178 /// Legality checks.
180  /// The loop that we evaluate.
181  Loop *OrigLoop;
182 
183  /// Loop Info analysis.
184  LoopInfo *LI;
185 
186  /// Target Library Info.
187  const TargetLibraryInfo *TLI;
188 
189  /// Target Transform Info.
190  const TargetTransformInfo *TTI;
191 
192  /// The legality analysis.
194 
195  /// The profitablity analysis.
197 
198  using VPlanPtr = std::unique_ptr<VPlan>;
199 
201 
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;
206 
207  VPCallbackILV(InnerLoopVectorizer &ILV) : ILV(ILV) {}
208 
209  Value *getOrCreateVectorValues(Value *V, unsigned Part) override;
210  };
211 
212  /// A builder used to construct the current plan.
213  VPBuilder Builder;
214 
215  unsigned BestVF = 0;
216  unsigned BestUF = 0;
217 
218 public:
220  const TargetTransformInfo *TTI,
223  : OrigLoop(L), LI(LI), TLI(TLI), TTI(TTI), Legal(Legal), CM(CM) {}
224 
225  /// Plan how to best vectorize, return the best VF and its cost.
226  VectorizationFactor plan(bool OptForSize, unsigned UserVF);
227 
228  /// Use the VPlan-native path to plan how to best vectorize, return the best
229  /// VF and its cost.
230  VectorizationFactor planInVPlanNativePath(bool OptForSize, unsigned UserVF);
231 
232  /// Finalize the best decision and dispose of all other VPlans.
233  void setBestPlan(unsigned VF, unsigned UF);
234 
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);
238 
240  for (const auto &Plan : VPlans)
241  O << *Plan;
242  }
243 
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.
247  static bool
248  getDecisionAndClampRange(const std::function<bool(unsigned)> &Predicate,
249  VFRange &Range);
250 
251 protected:
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);
256 
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);
261 
262 private:
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);
267 
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.
270  VPlanPtr
271  buildVPlanWithVPRecipes(VFRange &Range, SmallPtrSetImpl<Value *> &NeedDef,
272  SmallPtrSetImpl<Instruction *> &DeadInstructions);
273 
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);
278 };
279 
280 } // namespace llvm
281 
282 #endif // LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
RAII object that stores the current insertion point and restores it when the object is destroyed...
bool isSet() const
Returns true if this insert point is set.
This class represents lattice values for constants.
Definition: AllocatorList.h:24
InnerLoopVectorizer vectorizes loops which contain only one basic block to a specified vectorization ...
TODO: The following VectorizationFactor was pulled out of LoopVectorizationCostModel class...
void setUnderlyingValue(Value *Val)
Definition: VPlanValue.h:68
LoopVectorizationLegality checks if it is legal to vectorize a loop, and to what vectorization factor...
VPInsertPoint()=default
Creates a new insertion point which doesn&#39;t point to anything.
VPValue * createNot(VPValue *Operand)
LoopVectorizationPlanner(Loop *L, LoopInfo *LI, const TargetLibraryInfo *TLI, const TargetTransformInfo *TTI, LoopVectorizationLegality *Legal, LoopVectorizationCostModel &CM)
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition: VPlan.h:1021
VPValue * createNaryOp(unsigned Opcode, std::initializer_list< VPValue *> Operands, Instruction *Inst=nullptr)
RecipeListTy::iterator iterator
Instruction iterators...
Definition: VPlan.h:983
This class is used to enable the VPlan to invoke a method of ILV.
Definition: VPlan.h:227
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Definition: Dominators.h:145
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
VPlan-based builder utility analogous to IRBuilder.
This file contains the declarations of the Vectorization Plan base classes:
VPValue * createNaryOp(unsigned Opcode, ArrayRef< VPValue *> Operands, Instruction *Inst=nullptr)
Create an N-ary operation with Opcode, Operands and set Inst as its underlying Instruction.
InsertPoint - A saved insertion point.
VPBasicBlock::iterator getPoint() const
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition: VPlan.h:965
Planner drives the vectorization process after having passed Legality checks.
Iterator for intrusive lists based on ilist_node.
A range of powers-of-2 vectorization factors with fixed start and adjustable end. ...
Definition: VPlan.h:68
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Provides information about what library functions are available for the current target.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
Definition: PPCPredicates.h:27
void setInsertPoint(VPBasicBlock *TheBB, VPBasicBlock::iterator IP)
This specifies that created instructions should be inserted at the specified point.
VPValue * createOr(VPValue *LHS, VPValue *RHS)
void clearInsertionPoint()
Clear the insertion point: created instructions will not be inserted into a block.
VPInstruction * insert(VPInstruction *I) const
Insert and return the specified instruction.
VPBasicBlock::iterator getInsertPoint() const
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:465
#define I(x, y, z)
Definition: MD5.cpp:58
VPBasicBlock * getInsertBlock() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
iterator end()
Definition: VPlan.h:993
LoopVectorizationCostModel - estimates the expected speedups due to vectorization.
LLVM Value Representation.
Definition: Value.h:73
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
print Print MemDeps of function
VPValue * createAnd(VPValue *LHS, VPValue *RHS)
void restoreIP(VPInsertPoint IP)
Sets the current insert point to a previously-saved location.
void setInsertPoint(VPBasicBlock *TheBB)
This specifies that created VPInstructions should be appended to the end of the specified block...
This pass exposes codegen information to IR-level passes.
VPInsertPoint(VPBasicBlock *InsertBlock, VPBasicBlock::iterator InsertPoint)
Creates a new insertion point at the given location.
This is a concrete Recipe that models a single VPlan-level instruction.
Definition: VPlan.h:611
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition: LegalizerInfo.h:48