/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 |