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