Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/include/polly/ScopBuilder.h
Line
Count
Source
1
//===- polly/ScopBuilder.h --------------------------------------*- 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
// Create a polyhedral description for a static control flow region.
10
//
11
// The pass creates a polyhedral description of the Scops detected by the SCoP
12
// detection derived from their LLVM-IR code.
13
//
14
//===----------------------------------------------------------------------===//
15
16
#ifndef POLLY_SCOPBUILDER_H
17
#define POLLY_SCOPBUILDER_H
18
19
#include "polly/ScopInfo.h"
20
#include "polly/Support/ScopHelper.h"
21
#include "llvm/ADT/ArrayRef.h"
22
#include "llvm/ADT/SetVector.h"
23
24
namespace polly {
25
26
class ScopDetection;
27
28
/// Command line switch whether to model read-only accesses.
29
extern bool ModelReadOnlyScalars;
30
31
/// Build the Polly IR (Scop and ScopStmt) on a Region.
32
class ScopBuilder {
33
34
  /// The AliasAnalysis to build AliasSetTracker.
35
  AliasAnalysis &AA;
36
37
  /// Target data for element size computing.
38
  const DataLayout &DL;
39
40
  /// DominatorTree to reason about guaranteed execution.
41
  DominatorTree &DT;
42
43
  /// LoopInfo for information about loops.
44
  LoopInfo &LI;
45
46
  /// Valid Regions for Scop
47
  ScopDetection &SD;
48
49
  /// The ScalarEvolution to help building Scop.
50
  ScalarEvolution &SE;
51
52
  /// An optimization diagnostic interface to add optimization remarks.
53
  OptimizationRemarkEmitter &ORE;
54
55
  /// Set of instructions that might read any memory location.
56
  SmallVector<std::pair<ScopStmt *, Instruction *>, 16> GlobalReads;
57
58
  /// Set of all accessed array base pointers.
59
  SmallSetVector<Value *, 16> ArrayBasePointers;
60
61
  // The Scop
62
  std::unique_ptr<Scop> scop;
63
64
  // Methods for pattern matching against Fortran code generated by dragonegg.
65
  // @{
66
67
  /// Try to match for the descriptor of a Fortran array whose allocation
68
  /// is not visible. That is, we can see the load/store into the memory, but
69
  /// we don't actually know where the memory is allocated. If ALLOCATE had been
70
  /// called on the Fortran array, then we will see the lowered malloc() call.
71
  /// If not, this is dubbed as an "invisible allocation".
72
  ///
73
  /// "<descriptor>" is the descriptor of the Fortran array.
74
  ///
75
  /// Pattern match for "@descriptor":
76
  ///  1. %mem = load double*, double** bitcast (%"struct.array1_real(kind=8)"*
77
  ///    <descriptor> to double**), align 32
78
  ///
79
  ///  2. [%slot = getelementptr inbounds i8, i8* %mem, i64 <index>]
80
  ///  2 is optional because if you are writing to the 0th index, you don't
81
  ///     need a GEP.
82
  ///
83
  ///  3.1 store/load <memtype> <val>, <memtype>* %slot
84
  ///  3.2 store/load <memtype> <val>, <memtype>* %mem
85
  ///
86
  /// @see polly::MemoryAccess, polly::ScopArrayInfo
87
  ///
88
  /// @note assumes -polly-canonicalize has been run.
89
  ///
90
  /// @param Inst The LoadInst/StoreInst that accesses the memory.
91
  ///
92
  /// @returns Reference to <descriptor> on success, nullptr on failure.
93
  Value *findFADAllocationInvisible(MemAccInst Inst);
94
95
  /// Try to match for the descriptor of a Fortran array whose allocation
96
  /// call is visible. When we have a Fortran array, we try to look for a
97
  /// Fortran array where we can see the lowered ALLOCATE call. ALLOCATE
98
  /// is materialized as a malloc(...) which we pattern match for.
99
  ///
100
  /// Pattern match for "%untypedmem":
101
  ///  1. %untypedmem = i8* @malloc(...)
102
  ///
103
  ///  2. %typedmem = bitcast i8* %untypedmem to <memtype>
104
  ///
105
  ///  3. [%slot = getelementptr inbounds i8, i8* %typedmem, i64 <index>]
106
  ///  3 is optional because if you are writing to the 0th index, you don't
107
  ///     need a GEP.
108
  ///
109
  ///  4.1 store/load <memtype> <val>, <memtype>* %slot, align 8
110
  ///  4.2 store/load <memtype> <val>, <memtype>* %mem, align 8
111
  ///
112
  /// @see polly::MemoryAccess, polly::ScopArrayInfo
113
  ///
114
  /// @note assumes -polly-canonicalize has been run.
115
  ///
116
  /// @param Inst The LoadInst/StoreInst that accesses the memory.
117
  ///
118
  /// @returns Reference to %untypedmem on success, nullptr on failure.
119
  Value *findFADAllocationVisible(MemAccInst Inst);
120
121
  // @}
122
123
  // Build the SCoP for Region @p R.
124
  void buildScop(Region &R, AssumptionCache &AC);
125
126
  /// Create equivalence classes for required invariant accesses.
127
  ///
128
  /// These classes will consolidate multiple required invariant loads from the
129
  /// same address in order to keep the number of dimensions in the SCoP
130
  /// description small. For each such class equivalence class only one
131
  /// representing element, hence one required invariant load, will be chosen
132
  /// and modeled as parameter. The method
133
  /// Scop::getRepresentingInvariantLoadSCEV() will replace each element from an
134
  /// equivalence class with the representing element that is modeled. As a
135
  /// consequence Scop::getIdForParam() will only return an id for the
136
  /// representing element of each equivalence class, thus for each required
137
  /// invariant location.
138
  void buildInvariantEquivalenceClasses();
139
140
  /// Try to build a multi-dimensional fixed sized MemoryAccess from the
141
  /// Load/Store instruction.
142
  ///
143
  /// @param Inst       The Load/Store instruction that access the memory
144
  /// @param Stmt       The parent statement of the instruction
145
  ///
146
  /// @returns True if the access could be built, False otherwise.
147
  bool buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt);
148
149
  /// Try to build a multi-dimensional parametric sized MemoryAccess.
150
  ///        from the Load/Store instruction.
151
  ///
152
  /// @param Inst       The Load/Store instruction that access the memory
153
  /// @param Stmt       The parent statement of the instruction
154
  ///
155
  /// @returns True if the access could be built, False otherwise.
156
  bool buildAccessMultiDimParam(MemAccInst Inst, ScopStmt *Stmt);
157
158
  /// Try to build a MemoryAccess for a memory intrinsic.
159
  ///
160
  /// @param Inst       The instruction that access the memory
161
  /// @param Stmt       The parent statement of the instruction
162
  ///
163
  /// @returns True if the access could be built, False otherwise.
164
  bool buildAccessMemIntrinsic(MemAccInst Inst, ScopStmt *Stmt);
165
166
  /// Try to build a MemoryAccess for a call instruction.
167
  ///
168
  /// @param Inst       The call instruction that access the memory
169
  /// @param Stmt       The parent statement of the instruction
170
  ///
171
  /// @returns True if the access could be built, False otherwise.
172
  bool buildAccessCallInst(MemAccInst Inst, ScopStmt *Stmt);
173
174
  /// Build a single-dimensional parametric sized MemoryAccess
175
  ///        from the Load/Store instruction.
176
  ///
177
  /// @param Inst       The Load/Store instruction that access the memory
178
  /// @param Stmt       The parent statement of the instruction
179
  void buildAccessSingleDim(MemAccInst Inst, ScopStmt *Stmt);
180
181
  /// Finalize all access relations.
182
  ///
183
  /// When building up access relations, temporary access relations that
184
  /// correctly represent each individual access are constructed. However, these
185
  /// access relations can be inconsistent or non-optimal when looking at the
186
  /// set of accesses as a whole. This function finalizes the memory accesses
187
  /// and constructs a globally consistent state.
188
  void finalizeAccesses();
189
190
  /// Update access dimensionalities.
191
  ///
192
  /// When detecting memory accesses different accesses to the same array may
193
  /// have built with different dimensionality, as outer zero-values dimensions
194
  /// may not have been recognized as separate dimensions. This function goes
195
  /// again over all memory accesses and updates their dimensionality to match
196
  /// the dimensionality of the underlying ScopArrayInfo object.
197
  void updateAccessDimensionality();
198
199
  /// Fold size constants to the right.
200
  ///
201
  /// In case all memory accesses in a given dimension are multiplied with a
202
  /// common constant, we can remove this constant from the individual access
203
  /// functions and move it to the size of the memory access. We do this as this
204
  /// increases the size of the innermost dimension, consequently widens the
205
  /// valid range the array subscript in this dimension can evaluate to, and
206
  /// as a result increases the likelihood that our delinearization is
207
  /// correct.
208
  ///
209
  /// Example:
210
  ///
211
  ///    A[][n]
212
  ///    S[i,j] -> A[2i][2j+1]
213
  ///    S[i,j] -> A[2i][2j]
214
  ///
215
  ///    =>
216
  ///
217
  ///    A[][2n]
218
  ///    S[i,j] -> A[i][2j+1]
219
  ///    S[i,j] -> A[i][2j]
220
  ///
221
  /// Constants in outer dimensions can arise when the elements of a parametric
222
  /// multi-dimensional array are not elementary data types, but e.g.,
223
  /// structures.
224
  void foldSizeConstantsToRight();
225
226
  /// Fold memory accesses to handle parametric offset.
227
  ///
228
  /// As a post-processing step, we 'fold' memory accesses to parametric
229
  /// offsets in the access functions. @see MemoryAccess::foldAccess for
230
  /// details.
231
  void foldAccessRelations();
232
233
  /// Assume that all memory accesses are within bounds.
234
  ///
235
  /// After we have built a model of all memory accesses, we need to assume
236
  /// that the model we built matches reality -- aka. all modeled memory
237
  /// accesses always remain within bounds. We do this as last step, after
238
  /// all memory accesses have been modeled and canonicalized.
239
  void assumeNoOutOfBounds();
240
241
  /// Mark arrays that have memory accesses with FortranArrayDescriptor.
242
  void markFortranArrays();
243
244
  /// Build the alias checks for this SCoP.
245
  bool buildAliasChecks();
246
247
  /// A vector of memory accesses that belong to an alias group.
248
  using AliasGroupTy = SmallVector<MemoryAccess *, 4>;
249
250
  /// A vector of alias groups.
251
  using AliasGroupVectorTy = SmallVector<AliasGroupTy, 4>;
252
253
  /// Build a given alias group and its access data.
254
  ///
255
  /// @param AliasGroup     The alias group to build.
256
  /// @param HasWriteAccess A set of arrays through which memory is not only
257
  ///                       read, but also written.
258
  //
259
  /// @returns True if __no__ error occurred, false otherwise.
260
  bool buildAliasGroup(AliasGroupTy &AliasGroup,
261
                       DenseSet<const ScopArrayInfo *> HasWriteAccess);
262
263
  /// Build all alias groups for this SCoP.
264
  ///
265
  /// @returns True if __no__ error occurred, false otherwise.
266
  bool buildAliasGroups();
267
268
  /// Build alias groups for all memory accesses in the Scop.
269
  ///
270
  /// Using the alias analysis and an alias set tracker we build alias sets
271
  /// for all memory accesses inside the Scop. For each alias set we then map
272
  /// the aliasing pointers back to the memory accesses we know, thus obtain
273
  /// groups of memory accesses which might alias. We also collect the set of
274
  /// arrays through which memory is written.
275
  ///
276
  /// @returns A pair consistent of a vector of alias groups and a set of arrays
277
  ///          through which memory is written.
278
  std::tuple<AliasGroupVectorTy, DenseSet<const ScopArrayInfo *>>
279
  buildAliasGroupsForAccesses();
280
281
  ///  Split alias groups by iteration domains.
282
  ///
283
  ///  We split each group based on the domains of the minimal/maximal accesses.
284
  ///  That means two minimal/maximal accesses are only in a group if their
285
  ///  access domains intersect. Otherwise, they are in different groups.
286
  ///
287
  ///  @param AliasGroups The alias groups to split
288
  void splitAliasGroupsByDomain(AliasGroupVectorTy &AliasGroups);
289
290
  /// Build an instance of MemoryAccess from the Load/Store instruction.
291
  ///
292
  /// @param Inst       The Load/Store instruction that access the memory
293
  /// @param Stmt       The parent statement of the instruction
294
  void buildMemoryAccess(MemAccInst Inst, ScopStmt *Stmt);
295
296
  /// Analyze and extract the cross-BB scalar dependences (or, dataflow
297
  /// dependencies) of an instruction.
298
  ///
299
  /// @param UserStmt The statement @p Inst resides in.
300
  /// @param Inst     The instruction to be analyzed.
301
  void buildScalarDependences(ScopStmt *UserStmt, Instruction *Inst);
302
303
  /// Build the escaping dependences for @p Inst.
304
  ///
305
  /// Search for uses of the llvm::Value defined by @p Inst that are not
306
  /// within the SCoP. If there is such use, add a SCALAR WRITE such that
307
  /// it is available after the SCoP as escaping value.
308
  ///
309
  /// @param Inst The instruction to be analyzed.
310
  void buildEscapingDependences(Instruction *Inst);
311
312
  /// Create MemoryAccesses for the given PHI node in the given region.
313
  ///
314
  /// @param PHIStmt            The statement @p PHI resides in.
315
  /// @param PHI                The PHI node to be handled
316
  /// @param NonAffineSubRegion The non affine sub-region @p PHI is in.
317
  /// @param IsExitBlock        Flag to indicate that @p PHI is in the exit BB.
318
  void buildPHIAccesses(ScopStmt *PHIStmt, PHINode *PHI,
319
                        Region *NonAffineSubRegion, bool IsExitBlock = false);
320
321
  /// Build the access functions for the subregion @p SR.
322
  void buildAccessFunctions();
323
324
  /// Should an instruction be modeled in a ScopStmt.
325
  ///
326
  /// @param Inst The instruction to check.
327
  /// @param L    The loop in which context the instruction is looked at.
328
  ///
329
  /// @returns True if the instruction should be modeled.
330
  bool shouldModelInst(Instruction *Inst, Loop *L);
331
332
  /// Create one or more ScopStmts for @p BB.
333
  ///
334
  /// Consecutive instructions are associated to the same statement until a
335
  /// separator is found.
336
  void buildSequentialBlockStmts(BasicBlock *BB, bool SplitOnStore = false);
337
338
  /// Create one or more ScopStmts for @p BB using equivalence classes.
339
  ///
340
  /// Instructions of a basic block that belong to the same equivalence class
341
  /// are added to the same statement.
342
  void buildEqivClassBlockStmts(BasicBlock *BB);
343
344
  /// Create ScopStmt for all BBs and non-affine subregions of @p SR.
345
  ///
346
  /// @param SR A subregion of @p R.
347
  ///
348
  /// Some of the statements might be optimized away later when they do not
349
  /// access any memory and thus have no effect.
350
  void buildStmts(Region &SR);
351
352
  /// Build the access functions for the statement @p Stmt in or represented by
353
  /// @p BB.
354
  ///
355
  /// @param Stmt               Statement to add MemoryAccesses to.
356
  /// @param BB                 A basic block in @p R.
357
  /// @param NonAffineSubRegion The non affine sub-region @p BB is in.
358
  void buildAccessFunctions(ScopStmt *Stmt, BasicBlock &BB,
359
                            Region *NonAffineSubRegion = nullptr);
360
361
  /// Create a new MemoryAccess object and add it to #AccFuncMap.
362
  ///
363
  /// @param Stmt        The statement where the access takes place.
364
  /// @param Inst        The instruction doing the access. It is not necessarily
365
  ///                    inside @p BB.
366
  /// @param AccType     The kind of access.
367
  /// @param BaseAddress The accessed array's base address.
368
  /// @param ElemType    The type of the accessed array elements.
369
  /// @param Affine      Whether all subscripts are affine expressions.
370
  /// @param AccessValue Value read or written.
371
  /// @param Subscripts  Access subscripts per dimension.
372
  /// @param Sizes       The array dimension's sizes.
373
  /// @param Kind        The kind of memory accessed.
374
  ///
375
  /// @return The created MemoryAccess, or nullptr if the access is not within
376
  ///         the SCoP.
377
  MemoryAccess *addMemoryAccess(ScopStmt *Stmt, Instruction *Inst,
378
                                MemoryAccess::AccessType AccType,
379
                                Value *BaseAddress, Type *ElemType, bool Affine,
380
                                Value *AccessValue,
381
                                ArrayRef<const SCEV *> Subscripts,
382
                                ArrayRef<const SCEV *> Sizes, MemoryKind Kind);
383
384
  /// Create a MemoryAccess that represents either a LoadInst or
385
  /// StoreInst.
386
  ///
387
  /// @param Stmt        The statement to add the MemoryAccess to.
388
  /// @param MemAccInst  The LoadInst or StoreInst.
389
  /// @param AccType     The kind of access.
390
  /// @param BaseAddress The accessed array's base address.
391
  /// @param ElemType    The type of the accessed array elements.
392
  /// @param IsAffine    Whether all subscripts are affine expressions.
393
  /// @param Subscripts  Access subscripts per dimension.
394
  /// @param Sizes       The array dimension's sizes.
395
  /// @param AccessValue Value read or written.
396
  ///
397
  /// @see MemoryKind
398
  void addArrayAccess(ScopStmt *Stmt, MemAccInst MemAccInst,
399
                      MemoryAccess::AccessType AccType, Value *BaseAddress,
400
                      Type *ElemType, bool IsAffine,
401
                      ArrayRef<const SCEV *> Subscripts,
402
                      ArrayRef<const SCEV *> Sizes, Value *AccessValue);
403
404
  /// Create a MemoryAccess for writing an llvm::Instruction.
405
  ///
406
  /// The access will be created at the position of @p Inst.
407
  ///
408
  /// @param Inst The instruction to be written.
409
  ///
410
  /// @see ensureValueRead()
411
  /// @see MemoryKind
412
  void ensureValueWrite(Instruction *Inst);
413
414
  /// Ensure an llvm::Value is available in the BB's statement, creating a
415
  /// MemoryAccess for reloading it if necessary.
416
  ///
417
  /// @param V        The value expected to be loaded.
418
  /// @param UserStmt Where to reload the value.
419
  ///
420
  /// @see ensureValueStore()
421
  /// @see MemoryKind
422
  void ensureValueRead(Value *V, ScopStmt *UserStmt);
423
424
  /// Create a write MemoryAccess for the incoming block of a phi node.
425
  ///
426
  /// Each of the incoming blocks write their incoming value to be picked in the
427
  /// phi's block.
428
  ///
429
  /// @param PHI           PHINode under consideration.
430
  /// @param IncomingStmt  The statement to add the MemoryAccess to.
431
  /// @param IncomingBlock Some predecessor block.
432
  /// @param IncomingValue @p PHI's value when coming from @p IncomingBlock.
433
  /// @param IsExitBlock   When true, uses the .s2a alloca instead of the
434
  ///                      .phiops one. Required for values escaping through a
435
  ///                      PHINode in the SCoP region's exit block.
436
  /// @see addPHIReadAccess()
437
  /// @see MemoryKind
438
  void ensurePHIWrite(PHINode *PHI, ScopStmt *IncomintStmt,
439
                      BasicBlock *IncomingBlock, Value *IncomingValue,
440
                      bool IsExitBlock);
441
442
  /// Add user provided parameter constraints to context (command line).
443
  void addUserContext();
444
445
  /// Add all recorded assumptions to the assumed context.
446
  void addRecordedAssumptions();
447
448
  /// Create a MemoryAccess for reading the value of a phi.
449
  ///
450
  /// The modeling assumes that all incoming blocks write their incoming value
451
  /// to the same location. Thus, this access will read the incoming block's
452
  /// value as instructed by this @p PHI.
453
  ///
454
  /// @param PHIStmt Statement @p PHI resides in.
455
  /// @param PHI     PHINode under consideration; the READ access will be added
456
  ///                here.
457
  ///
458
  /// @see ensurePHIWrite()
459
  /// @see MemoryKind
460
  void addPHIReadAccess(ScopStmt *PHIStmt, PHINode *PHI);
461
462
  /// Wrapper function to calculate minimal/maximal accesses to each array.
463
  bool calculateMinMaxAccess(AliasGroupTy AliasGroup,
464
                             Scop::MinMaxVectorTy &MinMaxAccesses);
465
  /// Build the domain of @p Stmt.
466
  void buildDomain(ScopStmt &Stmt);
467
468
  /// Fill NestLoops with loops surrounding @p Stmt.
469
  void collectSurroundingLoops(ScopStmt &Stmt);
470
471
  /// Check for reductions in @p Stmt.
472
  ///
473
  /// Iterate over all store memory accesses and check for valid binary
474
  /// reduction like chains. For all candidates we check if they have the same
475
  /// base address and there are no other accesses which overlap with them. The
476
  /// base address check rules out impossible reductions candidates early. The
477
  /// overlap check, together with the "only one user" check in
478
  /// collectCandidateReductionLoads, guarantees that none of the intermediate
479
  /// results will escape during execution of the loop nest. We basically check
480
  /// here that no other memory access can access the same memory as the
481
  /// potential reduction.
482
  void checkForReductions(ScopStmt &Stmt);
483
484
  /// Verify that all required invariant loads have been hoisted.
485
  ///
486
  /// Invariant load hoisting is not guaranteed to hoist all loads that were
487
  /// assumed to be scop invariant during scop detection. This function checks
488
  /// for cases where the hoisting failed, but where it would have been
489
  /// necessary for our scop modeling to be correct. In case of insufficient
490
  /// hoisting the scop is marked as invalid.
491
  ///
492
  /// In the example below Bound[1] is required to be invariant:
493
  ///
494
  /// for (int i = 1; i < Bound[0]; i++)
495
  ///   for (int j = 1; j < Bound[1]; j++)
496
  ///     ...
497
  void verifyInvariantLoads();
498
499
  /// Hoist invariant memory loads and check for required ones.
500
  ///
501
  /// We first identify "common" invariant loads, thus loads that are invariant
502
  /// and can be hoisted. Then we check if all required invariant loads have
503
  /// been identified as (common) invariant. A load is a required invariant load
504
  /// if it was assumed to be invariant during SCoP detection, e.g., to assume
505
  /// loop bounds to be affine or runtime alias checks to be placeable. In case
506
  /// a required invariant load was not identified as (common) invariant we will
507
  /// drop this SCoP. An example for both "common" as well as required invariant
508
  /// loads is given below:
509
  ///
510
  /// for (int i = 1; i < *LB[0]; i++)
511
  ///   for (int j = 1; j < *LB[1]; j++)
512
  ///     A[i][j] += A[0][0] + (*V);
513
  ///
514
  /// Common inv. loads: V, A[0][0], LB[0], LB[1]
515
  /// Required inv. loads: LB[0], LB[1], (V, if it may alias with A or LB)
516
  void hoistInvariantLoads();
517
518
  /// Add invariant loads listed in @p InvMAs with the domain of @p Stmt.
519
  void addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs);
520
521
  /// Check if @p MA can always be hoisted without execution context.
522
  bool canAlwaysBeHoisted(MemoryAccess *MA, bool StmtInvalidCtxIsEmpty,
523
                          bool MAInvalidCtxIsEmpty,
524
                          bool NonHoistableCtxIsEmpty);
525
526
  /// Return true if and only if @p LI is a required invariant load.
527
56
  bool isRequiredInvariantLoad(LoadInst *LI) const {
528
56
    return scop->getRequiredInvariantLoads().count(LI);
529
56
  }
530
531
  /// Check if the base ptr of @p MA is in the SCoP but not hoistable.
532
  bool hasNonHoistableBasePtrInScop(MemoryAccess *MA, isl::union_map Writes);
533
534
  /// Return the context under which the access cannot be hoisted.
535
  ///
536
  /// @param Access The access to check.
537
  /// @param Writes The set of all memory writes in the scop.
538
  ///
539
  /// @return Return the context under which the access cannot be hoisted or a
540
  ///         nullptr if it cannot be hoisted at all.
541
  isl::set getNonHoistableCtx(MemoryAccess *Access, isl::union_map Writes);
542
543
  /// Collect loads which might form a reduction chain with @p StoreMA.
544
  ///
545
  /// Check if the stored value for @p StoreMA is a binary operator with one or
546
  /// two loads as operands. If the binary operand is commutative & associative,
547
  /// used only once (by @p StoreMA) and its load operands are also used only
548
  /// once, we have found a possible reduction chain. It starts at an operand
549
  /// load and includes the binary operator and @p StoreMA.
550
  ///
551
  /// Note: We allow only one use to ensure the load and binary operator cannot
552
  ///       escape this block or into any other store except @p StoreMA.
553
  void collectCandidateReductionLoads(MemoryAccess *StoreMA,
554
                                      SmallVectorImpl<MemoryAccess *> &Loads);
555
556
  /// Build the access relation of all memory accesses of @p Stmt.
557
  void buildAccessRelations(ScopStmt &Stmt);
558
559
  /// Canonicalize arrays with base pointers from the same equivalence class.
560
  ///
561
  /// Some context: in our normal model we assume that each base pointer is
562
  /// related to a single specific memory region, where memory regions
563
  /// associated with different base pointers are disjoint. Consequently we do
564
  /// not need to compute additional data dependences that model possible
565
  /// overlaps of these memory regions. To verify our assumption we compute
566
  /// alias checks that verify that modeled arrays indeed do not overlap. In
567
  /// case an overlap is detected the runtime check fails and we fall back to
568
  /// the original code.
569
  ///
570
  /// In case of arrays where the base pointers are know to be identical,
571
  /// because they are dynamically loaded by accesses that are in the same
572
  /// invariant load equivalence class, such run-time alias check would always
573
  /// be false.
574
  ///
575
  /// This function makes sure that we do not generate consistently failing
576
  /// run-time checks for code that contains distinct arrays with known
577
  /// equivalent base pointers. It identifies for each invariant load
578
  /// equivalence class a single canonical array and canonicalizes all memory
579
  /// accesses that reference arrays that have base pointers that are known to
580
  /// be equal to the base pointer of such a canonical array to this canonical
581
  /// array.
582
  ///
583
  /// We currently do not canonicalize arrays for which certain memory accesses
584
  /// have been hoisted as loop invariant.
585
  void canonicalizeDynamicBasePtrs();
586
587
  /// Construct the schedule of this SCoP.
588
  void buildSchedule();
589
590
  /// A loop stack element to keep track of per-loop information during
591
  ///        schedule construction.
592
  using LoopStackElementTy = struct LoopStackElement {
593
    // The loop for which we keep information.
594
    Loop *L;
595
596
    // The (possibly incomplete) schedule for this loop.
597
    isl::schedule Schedule;
598
599
    // The number of basic blocks in the current loop, for which a schedule has
600
    // already been constructed.
601
    unsigned NumBlocksProcessed;
602
603
    LoopStackElement(Loop *L, isl::schedule S, unsigned NumBlocksProcessed)
604
2.82k
        : L(L), Schedule(S), NumBlocksProcessed(NumBlocksProcessed) {}
605
  };
606
607
  /// The loop stack used for schedule construction.
608
  ///
609
  /// The loop stack keeps track of schedule information for a set of nested
610
  /// loops as well as an (optional) 'nullptr' loop that models the outermost
611
  /// schedule dimension. The loops in a loop stack always have a parent-child
612
  /// relation where the loop at position n is the parent of the loop at
613
  /// position n + 1.
614
  using LoopStackTy = SmallVector<LoopStackElementTy, 4>;
615
616
  /// Construct schedule information for a given Region and add the
617
  ///        derived information to @p LoopStack.
618
  ///
619
  /// Given a Region we derive schedule information for all RegionNodes
620
  /// contained in this region ensuring that the assigned execution times
621
  /// correctly model the existing control flow relations.
622
  ///
623
  /// @param R              The region which to process.
624
  /// @param LoopStack      A stack of loops that are currently under
625
  ///                       construction.
626
  void buildSchedule(Region *R, LoopStackTy &LoopStack);
627
628
  /// Build Schedule for the region node @p RN and add the derived
629
  ///        information to @p LoopStack.
630
  ///
631
  /// In case @p RN is a BasicBlock or a non-affine Region, we construct the
632
  /// schedule for this @p RN and also finalize loop schedules in case the
633
  /// current @p RN completes the loop.
634
  ///
635
  /// In case @p RN is a not-non-affine Region, we delegate the construction to
636
  /// buildSchedule(Region *R, ...).
637
  ///
638
  /// @param RN             The RegionNode region traversed.
639
  /// @param LoopStack      A stack of loops that are currently under
640
  ///                       construction.
641
  void buildSchedule(RegionNode *RN, LoopStackTy &LoopStack);
642
643
public:
644
  explicit ScopBuilder(Region *R, AssumptionCache &AC, AliasAnalysis &AA,
645
                       const DataLayout &DL, DominatorTree &DT, LoopInfo &LI,
646
                       ScopDetection &SD, ScalarEvolution &SE,
647
                       OptimizationRemarkEmitter &ORE);
648
  ScopBuilder(const ScopBuilder &) = delete;
649
  ScopBuilder &operator=(const ScopBuilder &) = delete;
650
1.20k
  ~ScopBuilder() = default;
651
652
  /// Try to build the Polly IR of static control part on the current
653
  /// SESE-Region.
654
  ///
655
  /// @return Give up the ownership of the scop object or static control part
656
  ///         for the region
657
1.20k
  std::unique_ptr<Scop> getScop() { return std::move(scop); }
658
};
659
} // end namespace polly
660
661
#endif // POLLY_SCOPBUILDER_H