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