blob: ac28af20a3d47f13cbf843ca0c8b56af1bfc488c [file] [log] [blame]
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001//=- 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
26using namespace llvm;
27using namespace polly;
28
29namespace polly {
30
31struct InvariantEquivClassTy;
32} // namespace polly
33
34struct 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?
63void addReferencesFromStmt(const ScopStmt *Stmt, void *UserPtr,
64 bool CreateScalarRefs = true);
65
66class IslNodeBuilder {
67public:
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 StartBlock(StartBlock) {}
78
79 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 virtual void finalize() { BlockGen.finalizeSCoP(S); }
115
116 IslExprBuilder &getExprBuilder() { return ExprBuilder; }
117
118 /// Get the associated block generator.
119 ///
120 /// @return A reference to the associated block generator.
121 BlockGenerator &getBlockGenerator() { return BlockGen; }
122
123 /// Return the parallel subfunctions that have been created.
124 const ArrayRef<Function *> getParallelSubfunctions() const {
125 return ParallelSubfunctions;
126 }
127
128protected:
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 &LTS);
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
406private:
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