Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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) {}
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
  /// 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.
159
  IslExprBuilder::IDToValueTy IDToValue;
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.
177
  ValueMapT ValueMap;
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.
182
  bool materializeValue(__isl_take isl_id *Id);
183
 
184
  /// Materialize parameters of @p Set.
185
  ///
186
  /// @returns False, iff a problem occurred and the value was not materialized.
187
  bool materializeParameters(__isl_take isl_set *Set);
188
 
189
  /// Materialize all parameters in the current scop.
190
  ///
191
  /// @returns False, iff a problem occurred and the value was not materialized.
192
  bool materializeParameters();
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.
213
  isl::ast_expr getUpperBound(isl::ast_node_for For,
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.
225
  int getNumberOfIterations(isl::ast_node_for For);
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.
245
  void getReferencesInSubtree(const isl::ast_node &For,
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
288
  Value *preloadUnconditionally(__isl_take isl_set *AccessRange,
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
301
  Value *preloadInvariantLoad(const MemoryAccess &MA,
302
                              __isl_take isl_set *Domain);
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.
311
  bool preloadInvariantEquivClass(InvariantEquivClassTy &IAClass);
312
 
313
  void createForVector(__isl_take isl_ast_node *For, int VectorWidth);
314
  void createForSequential(isl::ast_node_for For, bool MarkParallel);
315
 
316
  /// Create LLVM-IR that executes a for node thread parallel.
317
  ///
318
  /// @param For The FOR isl_ast_node for which code is generated.
319
  void createForParallel(__isl_take isl_ast_node *For);
320
 
321
  /// Create new access functions for modified memory accesses.
322
  ///
323
  /// In case the access function of one of the memory references in the Stmt
324
  /// has been modified, we generate a new isl_ast_expr that reflects the
325
  /// newly modified access function and return a map that maps from the
326
  /// individual memory references in the statement (identified by their id)
327
  /// to these newly generated ast expressions.
328
  ///
329
  /// @param Stmt  The statement for which to (possibly) generate new access
330
  ///              functions.
331
  /// @param Node  The ast node corresponding to the statement for us to extract
332
  ///              the local schedule from.
333
  /// @return A new hash table that contains remappings from memory ids to new
334
  ///         access expressions.
335
  __isl_give isl_id_to_ast_expr *
336
  createNewAccesses(ScopStmt *Stmt, __isl_keep isl_ast_node *Node);
337
 
338
  /// Generate LLVM-IR that computes the values of the original induction
339
  /// variables in function of the newly generated loop induction variables.
340
  ///
341
  /// Example:
342
  ///
343
  ///   // Original
344
  ///   for i
345
  ///     for j
346
  ///       S(i)
347
  ///
348
  ///   Schedule: [i,j] -> [i+j, j]
349
  ///
350
  ///   // New
351
  ///   for c0
352
  ///     for c1
353
  ///       S(c0 - c1, c1)
354
  ///
355
  /// Assuming the original code consists of two loops which are
356
  /// transformed according to a schedule [i,j] -> [c0=i+j,c1=j]. The resulting
357
  /// ast models the original statement as a call expression where each argument
358
  /// is an expression that computes the old induction variables from the new
359
  /// ones, ordered such that the first argument computes the value of induction
360
  /// variable that was outermost in the original code.
361
  ///
362
  /// @param Expr The call expression that represents the statement.
363
  /// @param Stmt The statement that is called.
364
  /// @param LTS  The loop to SCEV map in which the mapping from the original
365
  ///             loop to a SCEV representing the new loop iv is added. This
366
  ///             mapping does not require an explicit induction variable.
367
  ///             Instead, we think in terms of an implicit induction variable
368
  ///             that counts the number of times a loop is executed. For each
369
  ///             original loop this count, expressed in function of the new
370
  ///             induction variables, is added to the LTS map.
371
  void createSubstitutions(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
372
                           LoopToScevMapT &LTS);
373
  void createSubstitutionsVector(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
374
                                 std::vector<LoopToScevMapT> &VLTS,
375
                                 std::vector<Value *> &IVS,
376
                                 __isl_take isl_id *IteratorID);
377
  virtual void createIf(__isl_take isl_ast_node *If);
378
  void createUserVector(__isl_take isl_ast_node *User,
379
                        std::vector<Value *> &IVS,
380
                        __isl_take isl_id *IteratorID,
381
                        __isl_take isl_union_map *Schedule);
382
  virtual void createUser(__isl_take isl_ast_node *User);
383
  virtual void createBlock(__isl_take isl_ast_node *Block);
384
 
385
  /// Get the schedule for a given AST node.
386
  ///
387
  /// This information is used to reason about parallelism of loops or the
388
  /// locality of memory accesses under a given schedule.
389
  ///
390
  /// @param Node The node we want to obtain the schedule for.
391
  /// @return Return an isl_union_map that maps from the statements executed
392
  ///         below this ast node to the scheduling vectors used to enumerate
393
  ///         them.
394
  ///
395
  virtual isl::union_map getScheduleForAstNode(const isl::ast_node &Node);
396
 
397
private:
398
  /// Create code for a copy statement.
399
  ///
400
  /// A copy statement is expected to have one read memory access and one write
401
  /// memory access (in this very order). Data is loaded from the location
402
  /// described by the read memory access and written to the location described
403
  /// by the write memory access. @p NewAccesses contains for each access
404
  /// the isl ast expression that describes the location accessed.
405
  ///
406
  /// @param Stmt The copy statement that contains the accesses.
407
  /// @param NewAccesses The hash table that contains remappings from memory
408
  ///                    ids to new access expressions.
409
  void generateCopyStmt(ScopStmt *Stmt,
410
                        __isl_keep isl_id_to_ast_expr *NewAccesses);
411
 
412
  /// Materialize a canonical loop induction variable for `L`, which is a loop
413
  /// that is *not* present in the Scop.
414
  ///
415
  /// Note that this is materialized at the point where the `Builder` is
416
  /// currently pointing.
417
  /// We also populate the `OutsideLoopIterations` map with `L`s SCEV to keep
418
  /// track of the induction variable.
419
  /// See [Code generation of induction variables of loops outside Scops]
420
  Value *materializeNonScopLoopInductionVariable(const Loop *L);
421
};
422
 
423
} // namespace polly
424
 
425
#endif // POLLY_ISLNODEBUILDER_H