/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/include/polly/CodeGen/IslNodeBuilder.h
Line | Count | Source |
1 | | //=- IslNodeBuilder.cpp - Translate an isl AST into a LLVM-IR AST -*- C++ -*-=// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file contains the IslNodeBuilder, a class to translate an isl AST into |
10 | | // a LLVM-IR AST. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef POLLY_ISLNODEBUILDER_H |
15 | | #define POLLY_ISLNODEBUILDER_H |
16 | | |
17 | | #include "polly/CodeGen/BlockGenerators.h" |
18 | | #include "polly/CodeGen/IslExprBuilder.h" |
19 | | #include "polly/ScopDetectionDiagnostic.h" |
20 | | #include "llvm/ADT/ArrayRef.h" |
21 | | #include "llvm/ADT/SmallSet.h" |
22 | | #include "llvm/IR/InstrTypes.h" |
23 | | #include "isl/ctx.h" |
24 | | #include "isl/isl-noexceptions.h" |
25 | | |
26 | | using namespace llvm; |
27 | | using namespace polly; |
28 | | |
29 | | namespace polly { |
30 | | |
31 | | struct InvariantEquivClassTy; |
32 | | } // namespace polly |
33 | | |
34 | | struct SubtreeReferences { |
35 | | LoopInfo &LI; |
36 | | ScalarEvolution &SE; |
37 | | Scop &S; |
38 | | ValueMapT &GlobalMap; |
39 | | SetVector<Value *> &Values; |
40 | | SetVector<const SCEV *> &SCEVs; |
41 | | BlockGenerator &BlockGen; |
42 | | // In case an (optional) parameter space location is provided, parameter space |
43 | | // information is collected as well. |
44 | | isl::space *ParamSpace; |
45 | | }; |
46 | | |
47 | | /// Extract the out-of-scop values and SCEVs referenced from a ScopStmt. |
48 | | /// |
49 | | /// This includes the SCEVUnknowns referenced by the SCEVs used in the |
50 | | /// statement and the base pointers of the memory accesses. For scalar |
51 | | /// statements we force the generation of alloca memory locations and list |
52 | | /// these locations in the set of out-of-scop values as well. |
53 | | /// |
54 | | /// We also collect an isl::space that includes all parameter dimensions |
55 | | /// used in the statement's memory accesses, in case the ParamSpace pointer |
56 | | /// is non-null. |
57 | | /// |
58 | | /// @param Stmt The statement for which to extract the information. |
59 | | /// @param UserPtr A void pointer that can be casted to a |
60 | | /// SubtreeReferences structure. |
61 | | /// @param CreateScalarRefs Should the result include allocas of scalar |
62 | | /// references? |
63 | | void addReferencesFromStmt(const ScopStmt *Stmt, void *UserPtr, |
64 | | bool CreateScalarRefs = true); |
65 | | |
66 | | class IslNodeBuilder { |
67 | | public: |
68 | | IslNodeBuilder(PollyIRBuilder &Builder, ScopAnnotator &Annotator, |
69 | | const DataLayout &DL, LoopInfo &LI, ScalarEvolution &SE, |
70 | | DominatorTree &DT, Scop &S, BasicBlock *StartBlock) |
71 | | : S(S), Builder(Builder), Annotator(Annotator), |
72 | | ExprBuilder(S, Builder, IDToValue, ValueMap, DL, SE, DT, LI, |
73 | | StartBlock), |
74 | | BlockGen(Builder, LI, SE, DT, ScalarMap, EscapeMap, ValueMap, |
75 | | &ExprBuilder, StartBlock), |
76 | | RegionGen(BlockGen), DL(DL), LI(LI), SE(SE), DT(DT), |
77 | 305 | StartBlock(StartBlock) {} |
78 | | |
79 | 305 | virtual ~IslNodeBuilder() = default; |
80 | | |
81 | | void addParameters(__isl_take isl_set *Context); |
82 | | |
83 | | /// Create Values which hold the sizes of the outermost dimension of all |
84 | | /// Fortran arrays in the current scop. |
85 | | /// |
86 | | /// @returns False, if a problem occurred and a Fortran array was not |
87 | | /// materialized. True otherwise. |
88 | | bool materializeFortranArrayOutermostDimension(); |
89 | | |
90 | | /// Generate code that evaluates @p Condition at run-time. |
91 | | /// |
92 | | /// This function is typically called to generate the LLVM-IR for the |
93 | | /// run-time condition of the scop, that verifies that all the optimistic |
94 | | /// assumptions we have taken during scop modeling and transformation |
95 | | /// hold at run-time. |
96 | | /// |
97 | | /// @param Condition The condition to evaluate |
98 | | /// |
99 | | /// @result An llvm::Value that is true if the condition holds and false |
100 | | /// otherwise. |
101 | | Value *createRTC(isl_ast_expr *Condition); |
102 | | |
103 | | void create(__isl_take isl_ast_node *Node); |
104 | | |
105 | | /// Allocate memory for all new arrays created by Polly. |
106 | | void allocateNewArrays(BBPair StartExitBlocks); |
107 | | |
108 | | /// Preload all memory loads that are invariant. |
109 | | bool preloadInvariantLoads(); |
110 | | |
111 | | /// Finalize code generation. |
112 | | /// |
113 | | /// @see BlockGenerator::finalizeSCoP(Scop &S) |
114 | 301 | virtual void finalize() { BlockGen.finalizeSCoP(S); } |
115 | | |
116 | 301 | IslExprBuilder &getExprBuilder() { return ExprBuilder; } |
117 | | |
118 | | /// Get the associated block generator. |
119 | | /// |
120 | | /// @return A reference to the associated block generator. |
121 | 41 | BlockGenerator &getBlockGenerator() { return BlockGen; } |
122 | | |
123 | | /// Return the parallel subfunctions that have been created. |
124 | 305 | const ArrayRef<Function *> getParallelSubfunctions() const { |
125 | 305 | return ParallelSubfunctions; |
126 | 305 | } |
127 | | |
128 | | protected: |
129 | | Scop &S; |
130 | | PollyIRBuilder &Builder; |
131 | | ScopAnnotator &Annotator; |
132 | | |
133 | | IslExprBuilder ExprBuilder; |
134 | | |
135 | | /// Maps used by the block and region generator to demote scalars. |
136 | | /// |
137 | | ///@{ |
138 | | |
139 | | /// See BlockGenerator::ScalarMap. |
140 | | BlockGenerator::AllocaMapTy ScalarMap; |
141 | | |
142 | | /// See BlockGenerator::EscapeMap. |
143 | | BlockGenerator::EscapeUsersAllocaMapTy EscapeMap; |
144 | | |
145 | | ///@} |
146 | | |
147 | | /// The generator used to copy a basic block. |
148 | | BlockGenerator BlockGen; |
149 | | |
150 | | /// The generator used to copy a non-affine region. |
151 | | RegionGenerator RegionGen; |
152 | | |
153 | | const DataLayout &DL; |
154 | | LoopInfo &LI; |
155 | | ScalarEvolution &SE; |
156 | | DominatorTree &DT; |
157 | | BasicBlock *StartBlock; |
158 | | |
159 | | /// The current iteration of out-of-scop loops |
160 | | /// |
161 | | /// This map provides for a given loop a llvm::Value that contains the current |
162 | | /// loop iteration. |
163 | | MapVector<const Loop *, const SCEV *> OutsideLoopIterations; |
164 | | |
165 | | // This maps an isl_id* to the Value* it has in the generated program. For now |
166 | | // on, the only isl_ids that are stored here are the newly calculated loop |
167 | | // ivs. |
168 | | IslExprBuilder::IDToValueTy IDToValue; |
169 | | |
170 | | /// A collection of all parallel subfunctions that have been created. |
171 | | SmallVector<Function *, 8> ParallelSubfunctions; |
172 | | |
173 | | /// Generate code for a given SCEV* |
174 | | /// |
175 | | /// This function generates code for a given SCEV expression. It generated |
176 | | /// code is emitted at the end of the basic block our Builder currently |
177 | | /// points to and the resulting value is returned. |
178 | | /// |
179 | | /// @param Expr The expression to code generate. |
180 | | Value *generateSCEV(const SCEV *Expr); |
181 | | |
182 | | /// A set of Value -> Value remappings to apply when generating new code. |
183 | | /// |
184 | | /// When generating new code for a ScopStmt this map is used to map certain |
185 | | /// llvm::Values to new llvm::Values. |
186 | | ValueMapT ValueMap; |
187 | | |
188 | | /// Materialize code for @p Id if it was not done before. |
189 | | /// |
190 | | /// @returns False, iff a problem occurred and the value was not materialized. |
191 | | bool materializeValue(__isl_take isl_id *Id); |
192 | | |
193 | | /// Materialize parameters of @p Set. |
194 | | /// |
195 | | /// @returns False, iff a problem occurred and the value was not materialized. |
196 | | bool materializeParameters(__isl_take isl_set *Set); |
197 | | |
198 | | /// Materialize all parameters in the current scop. |
199 | | /// |
200 | | /// @returns False, iff a problem occurred and the value was not materialized. |
201 | | bool materializeParameters(); |
202 | | |
203 | | // Extract the upper bound of this loop |
204 | | // |
205 | | // The isl code generation can generate arbitrary expressions to check if the |
206 | | // upper bound of a loop is reached, but it provides an option to enforce |
207 | | // 'atomic' upper bounds. An 'atomic upper bound is always of the form |
208 | | // iv <= expr, where expr is an (arbitrary) expression not containing iv. |
209 | | // |
210 | | // This function extracts 'atomic' upper bounds. Polly, in general, requires |
211 | | // atomic upper bounds for the following reasons: |
212 | | // |
213 | | // 1. An atomic upper bound is loop invariant |
214 | | // |
215 | | // It must not be calculated at each loop iteration and can often even be |
216 | | // hoisted out further by the loop invariant code motion. |
217 | | // |
218 | | // 2. OpenMP needs a loop invariant upper bound to calculate the number |
219 | | // of loop iterations. |
220 | | // |
221 | | // 3. With the existing code, upper bounds have been easier to implement. |
222 | | isl::ast_expr getUpperBound(isl::ast_node For, CmpInst::Predicate &Predicate); |
223 | | |
224 | | /// Return non-negative number of iterations in case of the following form |
225 | | /// of a loop and -1 otherwise. |
226 | | /// |
227 | | /// for (i = 0; i <= NumIter; i++) { |
228 | | /// loop body; |
229 | | /// } |
230 | | /// |
231 | | /// NumIter is a non-negative integer value. Condition can have |
232 | | /// isl_ast_op_lt type. |
233 | | int getNumberOfIterations(isl::ast_node For); |
234 | | |
235 | | /// Compute the values and loops referenced in this subtree. |
236 | | /// |
237 | | /// This function looks at all ScopStmts scheduled below the provided For node |
238 | | /// and finds the llvm::Value[s] and llvm::Loops[s] which are referenced but |
239 | | /// not locally defined. |
240 | | /// |
241 | | /// Values that can be synthesized or that are available as globals are |
242 | | /// considered locally defined. |
243 | | /// |
244 | | /// Loops that contain the scop or that are part of the scop are considered |
245 | | /// locally defined. Loops that are before the scop, but do not contain the |
246 | | /// scop itself are considered not locally defined. |
247 | | /// |
248 | | /// @param For The node defining the subtree. |
249 | | /// @param Values A vector that will be filled with the Values referenced in |
250 | | /// this subtree. |
251 | | /// @param Loops A vector that will be filled with the Loops referenced in |
252 | | /// this subtree. |
253 | | void getReferencesInSubtree(__isl_keep isl_ast_node *For, |
254 | | SetVector<Value *> &Values, |
255 | | SetVector<const Loop *> &Loops); |
256 | | |
257 | | /// Change the llvm::Value(s) used for code generation. |
258 | | /// |
259 | | /// When generating code certain values (e.g., references to induction |
260 | | /// variables or array base pointers) in the original code may be replaced by |
261 | | /// new values. This function allows to (partially) update the set of values |
262 | | /// used. A typical use case for this function is the case when we continue |
263 | | /// code generation in a subfunction/kernel function and need to explicitly |
264 | | /// pass down certain values. |
265 | | /// |
266 | | /// @param NewValues A map that maps certain llvm::Values to new llvm::Values. |
267 | | void updateValues(ValueMapT &NewValues); |
268 | | |
269 | | /// Return the most up-to-date version of the llvm::Value for code generation. |
270 | | /// @param Original The Value to check for an up to date version. |
271 | | /// @returns A remapped `Value` from ValueMap, or `Original` if no mapping |
272 | | /// exists. |
273 | | /// @see IslNodeBuilder::updateValues |
274 | | /// @see IslNodeBuilder::ValueMap |
275 | | Value *getLatestValue(Value *Original) const; |
276 | | |
277 | | /// Generate code for a marker now. |
278 | | /// |
279 | | /// For mark nodes with an unknown name, we just forward the code generation |
280 | | /// to its child. This is currently the only behavior implemented, as there is |
281 | | /// currently not special handling for marker nodes implemented. |
282 | | /// |
283 | | /// @param Mark The node we generate code for. |
284 | | virtual void createMark(__isl_take isl_ast_node *Marker); |
285 | | |
286 | | virtual void createFor(__isl_take isl_ast_node *For); |
287 | | |
288 | | /// Set to remember materialized invariant loads. |
289 | | /// |
290 | | /// An invariant load is identified by its pointer (the SCEV) and its type. |
291 | | SmallSet<std::pair<const SCEV *, Type *>, 16> PreloadedPtrs; |
292 | | |
293 | | /// Preload the memory access at @p AccessRange with @p Build. |
294 | | /// |
295 | | /// @returns The preloaded value casted to type @p Ty |
296 | | Value *preloadUnconditionally(__isl_take isl_set *AccessRange, |
297 | | isl_ast_build *Build, Instruction *AccInst); |
298 | | |
299 | | /// Preload the memory load access @p MA. |
300 | | /// |
301 | | /// If @p MA is not always executed it will be conditionally loaded and |
302 | | /// merged with undef from the same type. Hence, if @p MA is executed only |
303 | | /// under condition C then the preload code will look like this: |
304 | | /// |
305 | | /// MA_preload = undef; |
306 | | /// if (C) |
307 | | /// MA_preload = load MA; |
308 | | /// use MA_preload |
309 | | Value *preloadInvariantLoad(const MemoryAccess &MA, |
310 | | __isl_take isl_set *Domain); |
311 | | |
312 | | /// Preload the invariant access equivalence class @p IAClass |
313 | | /// |
314 | | /// This function will preload the representing load from @p IAClass and |
315 | | /// map all members of @p IAClass to that preloaded value, potentially casted |
316 | | /// to the required type. |
317 | | /// |
318 | | /// @returns False, iff a problem occurred and the load was not preloaded. |
319 | | bool preloadInvariantEquivClass(InvariantEquivClassTy &IAClass); |
320 | | |
321 | | void createForVector(__isl_take isl_ast_node *For, int VectorWidth); |
322 | | void createForSequential(isl::ast_node For, bool MarkParallel); |
323 | | |
324 | | /// Create LLVM-IR that executes a for node thread parallel. |
325 | | /// |
326 | | /// @param For The FOR isl_ast_node for which code is generated. |
327 | | void createForParallel(__isl_take isl_ast_node *For); |
328 | | |
329 | | /// Create new access functions for modified memory accesses. |
330 | | /// |
331 | | /// In case the access function of one of the memory references in the Stmt |
332 | | /// has been modified, we generate a new isl_ast_expr that reflects the |
333 | | /// newly modified access function and return a map that maps from the |
334 | | /// individual memory references in the statement (identified by their id) |
335 | | /// to these newly generated ast expressions. |
336 | | /// |
337 | | /// @param Stmt The statement for which to (possibly) generate new access |
338 | | /// functions. |
339 | | /// @param Node The ast node corresponding to the statement for us to extract |
340 | | /// the local schedule from. |
341 | | /// @return A new hash table that contains remappings from memory ids to new |
342 | | /// access expressions. |
343 | | __isl_give isl_id_to_ast_expr * |
344 | | createNewAccesses(ScopStmt *Stmt, __isl_keep isl_ast_node *Node); |
345 | | |
346 | | /// Generate LLVM-IR that computes the values of the original induction |
347 | | /// variables in function of the newly generated loop induction variables. |
348 | | /// |
349 | | /// Example: |
350 | | /// |
351 | | /// // Original |
352 | | /// for i |
353 | | /// for j |
354 | | /// S(i) |
355 | | /// |
356 | | /// Schedule: [i,j] -> [i+j, j] |
357 | | /// |
358 | | /// // New |
359 | | /// for c0 |
360 | | /// for c1 |
361 | | /// S(c0 - c1, c1) |
362 | | /// |
363 | | /// Assuming the original code consists of two loops which are |
364 | | /// transformed according to a schedule [i,j] -> [c0=i+j,c1=j]. The resulting |
365 | | /// ast models the original statement as a call expression where each argument |
366 | | /// is an expression that computes the old induction variables from the new |
367 | | /// ones, ordered such that the first argument computes the value of induction |
368 | | /// variable that was outermost in the original code. |
369 | | /// |
370 | | /// @param Expr The call expression that represents the statement. |
371 | | /// @param Stmt The statement that is called. |
372 | | /// @param LTS The loop to SCEV map in which the mapping from the original |
373 | | /// loop to a SCEV representing the new loop iv is added. This |
374 | | /// mapping does not require an explicit induction variable. |
375 | | /// Instead, we think in terms of an implicit induction variable |
376 | | /// that counts the number of times a loop is executed. For each |
377 | | /// original loop this count, expressed in function of the new |
378 | | /// induction variables, is added to the LTS map. |
379 | | void createSubstitutions(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt, |
380 | | LoopToScevMapT <S); |
381 | | void createSubstitutionsVector(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt, |
382 | | std::vector<LoopToScevMapT> &VLTS, |
383 | | std::vector<Value *> &IVS, |
384 | | __isl_take isl_id *IteratorID); |
385 | | virtual void createIf(__isl_take isl_ast_node *If); |
386 | | void createUserVector(__isl_take isl_ast_node *User, |
387 | | std::vector<Value *> &IVS, |
388 | | __isl_take isl_id *IteratorID, |
389 | | __isl_take isl_union_map *Schedule); |
390 | | virtual void createUser(__isl_take isl_ast_node *User); |
391 | | virtual void createBlock(__isl_take isl_ast_node *Block); |
392 | | |
393 | | /// Get the schedule for a given AST node. |
394 | | /// |
395 | | /// This information is used to reason about parallelism of loops or the |
396 | | /// locality of memory accesses under a given schedule. |
397 | | /// |
398 | | /// @param Node The node we want to obtain the schedule for. |
399 | | /// @return Return an isl_union_map that maps from the statements executed |
400 | | /// below this ast node to the scheduling vectors used to enumerate |
401 | | /// them. |
402 | | /// |
403 | | virtual __isl_give isl_union_map * |
404 | | getScheduleForAstNode(__isl_take isl_ast_node *Node); |
405 | | |
406 | | private: |
407 | | /// Create code for a copy statement. |
408 | | /// |
409 | | /// A copy statement is expected to have one read memory access and one write |
410 | | /// memory access (in this very order). Data is loaded from the location |
411 | | /// described by the read memory access and written to the location described |
412 | | /// by the write memory access. @p NewAccesses contains for each access |
413 | | /// the isl ast expression that describes the location accessed. |
414 | | /// |
415 | | /// @param Stmt The copy statement that contains the accesses. |
416 | | /// @param NewAccesses The hash table that contains remappings from memory |
417 | | /// ids to new access expressions. |
418 | | void generateCopyStmt(ScopStmt *Stmt, |
419 | | __isl_keep isl_id_to_ast_expr *NewAccesses); |
420 | | |
421 | | /// Materialize a canonical loop induction variable for `L`, which is a loop |
422 | | /// that is *not* present in the Scop. |
423 | | /// |
424 | | /// Note that this is materialized at the point where the `Builder` is |
425 | | /// currently pointing. |
426 | | /// We also populate the `OutsideLoopIterations` map with `L`s SCEV to keep |
427 | | /// track of the induction variable. |
428 | | /// See [Code generation of induction variables of loops outside Scops] |
429 | | Value *materializeNonScopLoopInductionVariable(const Loop *L); |
430 | | }; |
431 | | |
432 | | #endif // POLLY_ISLNODEBUILDER_H |