Polly 23.0.0git
ScopBuilder.h
Go to the documentation of this file.
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"
21#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/SetVector.h"
23
24namespace polly {
25using llvm::SmallSetVector;
26
27class ScopDetection;
28
29/// Command line switch whether to model read-only accesses.
30extern bool ModelReadOnlyScalars;
31
32/// Build the Polly IR (Scop and ScopStmt) on a Region.
33class ScopBuilder final {
34
35 /// The AAResults to build AliasSetTracker.
36 AAResults &AA;
37
38 /// Target data for element size computing.
39 const DataLayout &DL;
40
41 /// DominatorTree to reason about guaranteed execution.
42 DominatorTree &DT;
43
44 /// LoopInfo for information about loops.
45 LoopInfo &LI;
46
47 /// Valid Regions for Scop
49
50 /// The ScalarEvolution to help building Scop.
51 ScalarEvolution &SE;
52
53 /// An optimization diagnostic interface to add optimization remarks.
54 OptimizationRemarkEmitter &ORE;
55
56 /// Set of instructions that might read any memory location.
57 SmallVector<std::pair<ScopStmt *, Instruction *>, 16> GlobalReads;
58
59 /// Set of all accessed array base pointers.
60 SmallSetVector<Value *, 16> ArrayBasePointers;
61
62 // The Scop
63 std::unique_ptr<Scop> scop;
64
65 /// Collection to hold taken assumptions.
66 ///
67 /// There are two reasons why we want to record assumptions first before we
68 /// add them to the assumed/invalid context:
69 /// 1) If the SCoP is not profitable or otherwise invalid without the
70 /// assumed/invalid context we do not have to compute it.
71 /// 2) Information about the context are gathered rather late in the SCoP
72 /// construction (basically after we know all parameters), thus the user
73 /// might see overly complicated assumptions to be taken while they will
74 /// only be simplified later on.
76
77 // Build the SCoP for Region @p R.
78 void buildScop(Region &R, AssumptionCache &AC);
79
80 /// Adjust the dimensions of @p Dom that was constructed for @p OldL
81 /// to be compatible to domains constructed for loop @p NewL.
82 ///
83 /// This function assumes @p NewL and @p OldL are equal or there is a CFG
84 /// edge from @p OldL to @p NewL.
85 isl::set adjustDomainDimensions(isl::set Dom, Loop *OldL, Loop *NewL);
86
87 /// Compute the domain for each basic block in @p R.
88 ///
89 /// @param R The region we currently traverse.
90 /// @param InvalidDomainMap BB to InvalidDomain map for the BB of current
91 /// region.
92 ///
93 /// @returns True if there was no problem and false otherwise.
94 bool buildDomains(Region *R,
95 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
96
97 /// Compute the branching constraints for each basic block in @p R.
98 ///
99 /// @param R The region we currently build branching conditions
100 /// for.
101 /// @param InvalidDomainMap BB to InvalidDomain map for the BB of current
102 /// region.
103 ///
104 /// @returns True if there was no problem and false otherwise.
106 Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
107
108 /// Build the conditions sets for the terminator @p TI in the @p Domain.
109 ///
110 /// This will fill @p ConditionSets with the conditions under which control
111 /// will be moved from @p TI to its successors. Hence, @p ConditionSets will
112 /// have as many elements as @p TI has successors.
113 ///
114 /// Set @p IsInsideDomain to false when building the conditions that check
115 /// whether @p BB is to be executed, since we are not in its domain yet.
116 bool buildConditionSets(BasicBlock *BB, Instruction *TI, Loop *L,
118 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
119 SmallVectorImpl<__isl_give isl_set *> &ConditionSets,
120 bool IsInsideDomain = true);
121
122 /// Build the conditions sets for the branch condition @p Condition in
123 /// the @p Domain.
124 ///
125 /// This will fill @p ConditionSets with the conditions under which control
126 /// will be moved from @p TI to its successors. Hence, @p ConditionSets will
127 /// have as many elements as @p TI has successors. If @p TI is nullptr the
128 /// context under which @p Condition is true/false will be returned as the
129 /// new elements of @p ConditionSets.
130 ///
131 /// Set @p IsInsideDomain to false when building the conditions that check
132 /// whether @p BB is to be executed, since we are not in its domain yet.
133 bool buildConditionSets(BasicBlock *BB, Value *Condition, Instruction *TI,
134 Loop *L, __isl_keep isl_set *Domain,
135 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
136 SmallVectorImpl<__isl_give isl_set *> &ConditionSets,
137 bool IsInsideDomain = true);
138
139 /// Build the conditions sets for the switch @p SI in the @p Domain.
140 ///
141 /// This will fill @p ConditionSets with the conditions under which control
142 /// will be moved from @p SI to its successors. Hence, @p ConditionSets will
143 /// have as many elements as @p SI has successors.
144 ///
145 /// Set @p IsInsideDomain to false when building the conditions that check
146 /// whether @p BB is to be executed, since we are not in its domain yet.
147 bool buildConditionSets(BasicBlock *BB, SwitchInst *SI, Loop *L,
149 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
150 SmallVectorImpl<__isl_give isl_set *> &ConditionSets,
151 bool IsInsideDomain = true);
152
153 /// Build condition sets for unsigned ICmpInst(s).
154 /// Special handling is required for unsigned operands to ensure that if
155 /// MSB (aka the Sign bit) is set for an operands in an unsigned ICmpInst
156 /// it should wrap around.
157 ///
158 /// @param IsStrictUpperBound holds information on the predicate relation
159 /// between TestVal and UpperBound, i.e,
160 ///
161 /// Set @p IsInsideDomain to false when building the conditions that check
162 /// whether @p BB is to be executed, since we are not in its domain yet.
163 /// TestVal < UpperBound OR TestVal <= UpperBound
165 BasicBlock *BB, Value *Condition, const isl::set &Domain,
166 const SCEV *SCEV_TestVal, const SCEV *SCEV_UpperBound,
167 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
168 bool IsStrictUpperBound, bool IsInsideDomain = true);
169
170 /// Propagate the domain constraints through the region @p R.
171 ///
172 /// @param R The region we currently build branching
173 /// conditions for.
174 /// @param InvalidDomainMap BB to InvalidDomain map for the BB of current
175 /// region.
176 ///
177 /// @returns True if there was no problem and false otherwise.
179 Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
180
181 /// Propagate domains that are known due to graph properties.
182 ///
183 /// As a CFG is mostly structured we use the graph properties to propagate
184 /// domains without the need to compute all path conditions. In particular,
185 /// if a block A dominates a block B and B post-dominates A we know that the
186 /// domain of B is a superset of the domain of A. As we do not have
187 /// post-dominator information available here we use the less precise region
188 /// information. Given a region R, we know that the exit is always executed
189 /// if the entry was executed, thus the domain of the exit is a superset of
190 /// the domain of the entry. In case the exit can only be reached from
191 /// within the region the domains are in fact equal. This function will use
192 /// this property to avoid the generation of condition constraints that
193 /// determine when a branch is taken. If @p BB is a region entry block we
194 /// will propagate its domain to the region exit block. Additionally, we put
195 /// the region exit block in the @p FinishedExitBlocks set so we can later
196 /// skip edges from within the region to that block.
197 ///
198 /// @param BB The block for which the domain is currently
199 /// propagated.
200 /// @param BBLoop The innermost affine loop surrounding @p BB.
201 /// @param FinishedExitBlocks Set of region exits the domain was set for.
202 /// @param InvalidDomainMap BB to InvalidDomain map for the BB of current
203 /// region.
205 BasicBlock *BB, Loop *BBLoop,
206 SmallPtrSetImpl<BasicBlock *> &FinishedExitBlocks,
207 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
208
209 /// Propagate invalid domains of statements through @p R.
210 ///
211 /// This method will propagate invalid statement domains through @p R and at
212 /// the same time add error block domains to them. Additionally, the domains
213 /// of error statements and those only reachable via error statements will
214 /// be replaced by an empty set. Later those will be removed completely.
215 ///
216 /// @param R The currently traversed region.
217 /// @param InvalidDomainMap BB to InvalidDomain map for the BB of current
218 /// region.
219 //
220 /// @returns True if there was no problem and false otherwise.
222 Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
223
224 /// Compute the union of predecessor domains for @p BB.
225 ///
226 /// To compute the union of all domains of predecessors of @p BB this
227 /// function applies similar reasoning on the CFG structure as described for
228 /// @see propagateDomainConstraintsToRegionExit
229 ///
230 /// @param BB The block for which the predecessor domains are collected.
231 /// @param Domain The domain under which BB is executed.
232 ///
233 /// @returns The domain under which @p BB is executed.
235
236 /// Add loop carried constraints to the header block of the loop @p L.
237 ///
238 /// @param L The loop to process.
239 /// @param InvalidDomainMap BB to InvalidDomain map for the BB of current
240 /// region.
241 ///
242 /// @returns True if there was no problem and false otherwise.
244 Loop *L, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
245
246 /// Compute the isl representation for the SCEV @p E in this BB.
247 ///
248 /// @param BB The BB for which isl representation is to be
249 /// computed.
250 /// @param InvalidDomainMap A map of BB to their invalid domains.
251 /// @param E The SCEV that should be translated.
252 /// @param NonNegative Flag to indicate the @p E has to be
253 /// non-negative.
254 /// @param IsInsideDomain If true, assumptions only need to apply during the
255 /// execution of @p BB. That is, when we know that we
256 /// are in its domain. Must be false if the SCEV is
257 /// evaluated outside a ScopStmt, or for code that
258 /// computes the domain (since while doing that, we
259 /// don't know whether we are in the domain yet).
260 ///
261 /// Note that this function will also adjust the invalid context
262 /// accordingly.
263 isl::pw_aff getPwAff(BasicBlock *BB,
264 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
265 const SCEV *E, bool NonNegative = false,
266 bool IsInsideDomain = true);
267
268 /// Create equivalence classes for required invariant accesses.
269 ///
270 /// These classes will consolidate multiple required invariant loads from the
271 /// same address in order to keep the number of dimensions in the SCoP
272 /// description small. For each such class equivalence class only one
273 /// representing element, hence one required invariant load, will be chosen
274 /// and modeled as parameter. The method
275 /// Scop::getRepresentingInvariantLoadSCEV() will replace each element from an
276 /// equivalence class with the representing element that is modeled. As a
277 /// consequence Scop::getIdForParam() will only return an id for the
278 /// representing element of each equivalence class, thus for each required
279 /// invariant location.
281
282 /// Try to build a multi-dimensional fixed sized MemoryAccess from the
283 /// Load/Store instruction.
284 ///
285 /// @param Inst The Load/Store instruction that access the memory
286 /// @param Stmt The parent statement of the instruction
287 ///
288 /// @returns True if the access could be built, False otherwise.
290
291 /// Try to build a multi-dimensional parametric sized MemoryAccess.
292 /// from the Load/Store instruction.
293 ///
294 /// @param Inst The Load/Store instruction that access the memory
295 /// @param Stmt The parent statement of the instruction
296 ///
297 /// @returns True if the access could be built, False otherwise.
299
300 /// Try to build a MemoryAccess for a memory intrinsic.
301 ///
302 /// @param Inst The instruction that access the memory
303 /// @param Stmt The parent statement of the instruction
304 ///
305 /// @returns True if the access could be built, False otherwise.
307
308 /// Try to build a MemoryAccess for a call instruction.
309 ///
310 /// @param Inst The call instruction that access the memory
311 /// @param Stmt The parent statement of the instruction
312 ///
313 /// @returns True if the access could be built, False otherwise.
314 bool buildAccessCallInst(MemAccInst Inst, ScopStmt *Stmt);
315
316 /// Build a single-dimensional parametric sized MemoryAccess
317 /// from the Load/Store instruction.
318 ///
319 /// @param Inst The Load/Store instruction that access the memory
320 /// @param Stmt The parent statement of the instruction
321 ///
322 /// @returns True if the access could be built, False otherwise.
323 bool buildAccessSingleDim(MemAccInst Inst, ScopStmt *Stmt);
324
325 /// Finalize all access relations.
326 ///
327 /// When building up access relations, temporary access relations that
328 /// correctly represent each individual access are constructed. However, these
329 /// access relations can be inconsistent or non-optimal when looking at the
330 /// set of accesses as a whole. This function finalizes the memory accesses
331 /// and constructs a globally consistent state.
332 void finalizeAccesses();
333
334 /// Update access dimensionalities.
335 ///
336 /// When detecting memory accesses different accesses to the same array may
337 /// have built with different dimensionality, as outer zero-values dimensions
338 /// may not have been recognized as separate dimensions. This function goes
339 /// again over all memory accesses and updates their dimensionality to match
340 /// the dimensionality of the underlying ScopArrayInfo object.
342
343 /// Fold size constants to the right.
344 ///
345 /// In case all memory accesses in a given dimension are multiplied with a
346 /// common constant, we can remove this constant from the individual access
347 /// functions and move it to the size of the memory access. We do this as this
348 /// increases the size of the innermost dimension, consequently widens the
349 /// valid range the array subscript in this dimension can evaluate to, and
350 /// as a result increases the likelihood that our delinearization is
351 /// correct.
352 ///
353 /// Example:
354 ///
355 /// A[][n]
356 /// S[i,j] -> A[2i][2j+1]
357 /// S[i,j] -> A[2i][2j]
358 ///
359 /// =>
360 ///
361 /// A[][2n]
362 /// S[i,j] -> A[i][2j+1]
363 /// S[i,j] -> A[i][2j]
364 ///
365 /// Constants in outer dimensions can arise when the elements of a parametric
366 /// multi-dimensional array are not elementary data types, but e.g.,
367 /// structures.
369
370 /// Fold memory accesses to handle parametric offset.
371 ///
372 /// As a post-processing step, we 'fold' memory accesses to parametric
373 /// offsets in the access functions. @see MemoryAccess::foldAccess for
374 /// details.
375 void foldAccessRelations();
376
377 /// Assume that all memory accesses are within bounds.
378 ///
379 /// After we have built a model of all memory accesses, we need to assume
380 /// that the model we built matches reality -- aka. all modeled memory
381 /// accesses always remain within bounds. We do this as last step, after
382 /// all memory accesses have been modeled and canonicalized.
383 void assumeNoOutOfBounds();
384
385 /// Build the alias checks for this SCoP.
386 bool buildAliasChecks();
387
388 /// A vector of memory accesses that belong to an alias group.
389 using AliasGroupTy = SmallVector<MemoryAccess *, 4>;
390
391 /// A vector of alias groups.
392 using AliasGroupVectorTy = SmallVector<AliasGroupTy, 4>;
393
394 /// Build a given alias group and its access data.
395 ///
396 /// @param AliasGroup The alias group to build.
397 /// @param HasWriteAccess A set of arrays through which memory is not only
398 /// read, but also written.
399 //
400 /// @returns True if __no__ error occurred, false otherwise.
401 bool buildAliasGroup(AliasGroupTy &AliasGroup,
402 DenseSet<const ScopArrayInfo *> HasWriteAccess);
403
404 /// Build all alias groups for this SCoP.
405 ///
406 /// @returns True if __no__ error occurred, false otherwise.
407 bool buildAliasGroups();
408
409 /// Build alias groups for all memory accesses in the Scop.
410 ///
411 /// Using the alias analysis and an alias set tracker we build alias sets
412 /// for all memory accesses inside the Scop. For each alias set we then map
413 /// the aliasing pointers back to the memory accesses we know, thus obtain
414 /// groups of memory accesses which might alias. We also collect the set of
415 /// arrays through which memory is written.
416 ///
417 /// @returns A pair consistent of a vector of alias groups and a set of arrays
418 /// through which memory is written.
419 std::tuple<AliasGroupVectorTy, DenseSet<const ScopArrayInfo *>>
421
422 /// Split alias groups by iteration domains.
423 ///
424 /// We split each group based on the domains of the minimal/maximal accesses.
425 /// That means two minimal/maximal accesses are only in a group if their
426 /// access domains intersect. Otherwise, they are in different groups.
427 ///
428 /// @param AliasGroups The alias groups to split
430
431 /// Build an instance of MemoryAccess from the Load/Store instruction.
432 ///
433 /// @param Inst The Load/Store instruction that access the memory
434 /// @param Stmt The parent statement of the instruction
435 void buildMemoryAccess(MemAccInst Inst, ScopStmt *Stmt);
436
437 /// Analyze and extract the cross-BB scalar dependences (or, dataflow
438 /// dependencies) of an instruction.
439 ///
440 /// @param UserStmt The statement @p Inst resides in.
441 /// @param Inst The instruction to be analyzed.
442 void buildScalarDependences(ScopStmt *UserStmt, Instruction *Inst);
443
444 /// Build the escaping dependences for @p Inst.
445 ///
446 /// Search for uses of the llvm::Value defined by @p Inst that are not
447 /// within the SCoP. If there is such use, add a SCALAR WRITE such that
448 /// it is available after the SCoP as escaping value.
449 ///
450 /// @param Inst The instruction to be analyzed.
451 void buildEscapingDependences(Instruction *Inst);
452
453 /// Create MemoryAccesses for the given PHI node in the given region.
454 ///
455 /// @param PHIStmt The statement @p PHI resides in.
456 /// @param PHI The PHI node to be handled
457 /// @param NonAffineSubRegion The non affine sub-region @p PHI is in.
458 /// @param IsExitBlock Flag to indicate that @p PHI is in the exit BB.
459 void buildPHIAccesses(ScopStmt *PHIStmt, PHINode *PHI,
460 Region *NonAffineSubRegion, bool IsExitBlock = false);
461
462 /// Build the access functions for the subregion @p SR.
464
465 /// Should an instruction be modeled in a ScopStmt.
466 ///
467 /// @param Inst The instruction to check.
468 /// @param L The loop in which context the instruction is looked at.
469 ///
470 /// @returns True if the instruction should be modeled.
471 bool shouldModelInst(Instruction *Inst, Loop *L);
472
473 /// Create one or more ScopStmts for @p BB.
474 ///
475 /// Consecutive instructions are associated to the same statement until a
476 /// separator is found.
477 void buildSequentialBlockStmts(BasicBlock *BB, bool SplitOnStore = false);
478
479 /// Create one or more ScopStmts for @p BB using equivalence classes.
480 ///
481 /// Instructions of a basic block that belong to the same equivalence class
482 /// are added to the same statement.
483 void buildEqivClassBlockStmts(BasicBlock *BB);
484
485 /// Create ScopStmt for all BBs and non-affine subregions of @p SR.
486 ///
487 /// @param SR A subregion of @p R.
488 ///
489 /// Some of the statements might be optimized away later when they do not
490 /// access any memory and thus have no effect.
491 void buildStmts(Region &SR);
492
493 /// Build the access functions for the statement @p Stmt in or represented by
494 /// @p BB.
495 ///
496 /// @param Stmt Statement to add MemoryAccesses to.
497 /// @param BB A basic block in @p R.
498 /// @param NonAffineSubRegion The non affine sub-region @p BB is in.
499 void buildAccessFunctions(ScopStmt *Stmt, BasicBlock &BB,
500 Region *NonAffineSubRegion = nullptr);
501
502 /// Create a new MemoryAccess object and add it to #AccFuncMap.
503 ///
504 /// @param Stmt The statement where the access takes place.
505 /// @param Inst The instruction doing the access. It is not necessarily
506 /// inside @p BB.
507 /// @param AccType The kind of access.
508 /// @param BaseAddress The accessed array's base address.
509 /// @param ElemType The type of the accessed array elements.
510 /// @param Affine Whether all subscripts are affine expressions.
511 /// @param AccessValue Value read or written.
512 /// @param Subscripts Access subscripts per dimension.
513 /// @param Sizes The array dimension's sizes.
514 /// @param Kind The kind of memory accessed.
515 ///
516 /// @return The created MemoryAccess, or nullptr if the access is not within
517 /// the SCoP.
518 MemoryAccess *addMemoryAccess(ScopStmt *Stmt, Instruction *Inst,
520 Value *BaseAddress, Type *ElemType, bool Affine,
521 Value *AccessValue,
522 ArrayRef<const SCEV *> Subscripts,
523 ArrayRef<const SCEV *> Sizes, MemoryKind Kind);
524
525 /// Create a MemoryAccess that represents either a LoadInst or
526 /// StoreInst.
527 ///
528 /// @param Stmt The statement to add the MemoryAccess to.
529 /// @param MemAccInst The LoadInst or StoreInst.
530 /// @param AccType The kind of access.
531 /// @param BaseAddress The accessed array's base address.
532 /// @param ElemType The type of the accessed array elements.
533 /// @param IsAffine Whether all subscripts are affine expressions.
534 /// @param Subscripts Access subscripts per dimension.
535 /// @param Sizes The array dimension's sizes.
536 /// @param AccessValue Value read or written.
537 ///
538 /// @see MemoryKind
540 MemoryAccess::AccessType AccType, Value *BaseAddress,
541 Type *ElemType, bool IsAffine,
542 ArrayRef<const SCEV *> Subscripts,
543 ArrayRef<const SCEV *> Sizes, Value *AccessValue);
544
545 /// Create a MemoryAccess for writing an llvm::Instruction.
546 ///
547 /// The access will be created at the position of @p Inst.
548 ///
549 /// @param Inst The instruction to be written.
550 ///
551 /// @see ensureValueRead()
552 /// @see MemoryKind
553 void ensureValueWrite(Instruction *Inst);
554
555 /// Ensure an llvm::Value is available in the BB's statement, creating a
556 /// MemoryAccess for reloading it if necessary.
557 ///
558 /// @param V The value expected to be loaded.
559 /// @param UserStmt Where to reload the value.
560 ///
561 /// @see ensureValueStore()
562 /// @see MemoryKind
563 void ensureValueRead(Value *V, ScopStmt *UserStmt);
564
565 /// Create a write MemoryAccess for the incoming block of a phi node.
566 ///
567 /// Each of the incoming blocks write their incoming value to be picked in the
568 /// phi's block.
569 ///
570 /// @param PHI PHINode under consideration.
571 /// @param IncomingStmt The statement to add the MemoryAccess to.
572 /// @param IncomingBlock Some predecessor block.
573 /// @param IncomingValue @p PHI's value when coming from @p IncomingBlock.
574 /// @param IsExitBlock When true, uses the .s2a alloca instead of the
575 /// .phiops one. Required for values escaping through a
576 /// PHINode in the SCoP region's exit block.
577 /// @see addPHIReadAccess()
578 /// @see MemoryKind
579 void ensurePHIWrite(PHINode *PHI, ScopStmt *IncomintStmt,
580 BasicBlock *IncomingBlock, Value *IncomingValue,
581 bool IsExitBlock);
582
583 /// Add user provided parameter constraints to context (command line).
584 void addUserContext();
585
586 /// Add user provided parameter constraints to context (source code).
587 void addUserAssumptions(AssumptionCache &AC,
588 DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
589
590 /// Add all recorded assumptions to the assumed context.
592
593 /// Create a MemoryAccess for reading the value of a phi.
594 ///
595 /// The modeling assumes that all incoming blocks write their incoming value
596 /// to the same location. Thus, this access will read the incoming block's
597 /// value as instructed by this @p PHI.
598 ///
599 /// @param PHIStmt Statement @p PHI resides in.
600 /// @param PHI PHINode under consideration; the READ access will be added
601 /// here.
602 ///
603 /// @see ensurePHIWrite()
604 /// @see MemoryKind
605 void addPHIReadAccess(ScopStmt *PHIStmt, PHINode *PHI);
606
607 /// Wrapper function to calculate minimal/maximal accesses to each array.
608 bool calculateMinMaxAccess(AliasGroupTy AliasGroup,
609 Scop::MinMaxVectorTy &MinMaxAccesses);
610 /// Build the domain of @p Stmt.
611 void buildDomain(ScopStmt &Stmt);
612
613 /// Fill NestLoops with loops surrounding @p Stmt.
615
616 /// Check for reductions in @p Stmt.
617 ///
618 /// Iterate over all store memory accesses and check for valid binary
619 /// reduction like chains. For all candidates we check if they have the same
620 /// base address and there are no other accesses which overlap with them. The
621 /// base address check rules out impossible reductions candidates early. The
622 /// overlap check, together with the "only one user" check in
623 /// collectCandidateReductionLoads, guarantees that none of the intermediate
624 /// results will escape during execution of the loop nest. We basically check
625 /// here that no other memory access can access the same memory as the
626 /// potential reduction.
627 void checkForReductions(ScopStmt &Stmt);
628
629 /// Verify that all required invariant loads have been hoisted.
630 ///
631 /// Invariant load hoisting is not guaranteed to hoist all loads that were
632 /// assumed to be scop invariant during scop detection. This function checks
633 /// for cases where the hoisting failed, but where it would have been
634 /// necessary for our scop modeling to be correct. In case of insufficient
635 /// hoisting the scop is marked as invalid.
636 ///
637 /// In the example below Bound[1] is required to be invariant:
638 ///
639 /// for (int i = 1; i < Bound[0]; i++)
640 /// for (int j = 1; j < Bound[1]; j++)
641 /// ...
643
644 /// Hoist invariant memory loads and check for required ones.
645 ///
646 /// We first identify "common" invariant loads, thus loads that are invariant
647 /// and can be hoisted. Then we check if all required invariant loads have
648 /// been identified as (common) invariant. A load is a required invariant load
649 /// if it was assumed to be invariant during SCoP detection, e.g., to assume
650 /// loop bounds to be affine or runtime alias checks to be placeable. In case
651 /// a required invariant load was not identified as (common) invariant we will
652 /// drop this SCoP. An example for both "common" as well as required invariant
653 /// loads is given below:
654 ///
655 /// for (int i = 1; i < *LB[0]; i++)
656 /// for (int j = 1; j < *LB[1]; j++)
657 /// A[i][j] += A[0][0] + (*V);
658 ///
659 /// Common inv. loads: V, A[0][0], LB[0], LB[1]
660 /// Required inv. loads: LB[0], LB[1], (V, if it may alias with A or LB)
661 void hoistInvariantLoads();
662
663 /// Add invariant loads listed in @p InvMAs with the domain of @p Stmt.
665
666 /// Check if @p MA can always be hoisted without execution context.
667 bool canAlwaysBeHoisted(MemoryAccess *MA, bool StmtInvalidCtxIsEmpty,
668 bool MAInvalidCtxIsEmpty,
669 bool NonHoistableCtxIsEmpty);
670
671 /// Return true if and only if @p LI is a required invariant load.
672 bool isRequiredInvariantLoad(LoadInst *LI) const {
673 return scop->getRequiredInvariantLoads().count(LI);
674 }
675
676 /// Check if the base ptr of @p MA is in the SCoP but not hoistable.
678
679 /// Return the context under which the access cannot be hoisted.
680 ///
681 /// @param Access The access to check.
682 /// @param Writes The set of all memory writes in the scop.
683 ///
684 /// @return Return the context under which the access cannot be hoisted or a
685 /// nullptr if it cannot be hoisted at all.
687
688 /// Build the access relation of all memory accesses of @p Stmt.
689 void buildAccessRelations(ScopStmt &Stmt);
690
691 /// Canonicalize arrays with base pointers from the same equivalence class.
692 ///
693 /// Some context: in our normal model we assume that each base pointer is
694 /// related to a single specific memory region, where memory regions
695 /// associated with different base pointers are disjoint. Consequently we do
696 /// not need to compute additional data dependences that model possible
697 /// overlaps of these memory regions. To verify our assumption we compute
698 /// alias checks that verify that modeled arrays indeed do not overlap. In
699 /// case an overlap is detected the runtime check fails and we fall back to
700 /// the original code.
701 ///
702 /// In case of arrays where the base pointers are know to be identical,
703 /// because they are dynamically loaded by accesses that are in the same
704 /// invariant load equivalence class, such run-time alias check would always
705 /// be false.
706 ///
707 /// This function makes sure that we do not generate consistently failing
708 /// run-time checks for code that contains distinct arrays with known
709 /// equivalent base pointers. It identifies for each invariant load
710 /// equivalence class a single canonical array and canonicalizes all memory
711 /// accesses that reference arrays that have base pointers that are known to
712 /// be equal to the base pointer of such a canonical array to this canonical
713 /// array.
714 ///
715 /// We currently do not canonicalize arrays for which certain memory accesses
716 /// have been hoisted as loop invariant.
718
719 /// Construct the schedule of this SCoP.
720 void buildSchedule();
721
722 /// A loop stack element to keep track of per-loop information during
723 /// schedule construction.
724 using LoopStackElementTy = struct LoopStackElement {
725 // The loop for which we keep information.
726 Loop *L;
727
728 // The (possibly incomplete) schedule for this loop.
729 isl::schedule Schedule;
730
731 // The number of basic blocks in the current loop, for which a schedule has
732 // already been constructed.
733 unsigned NumBlocksProcessed;
734
735 LoopStackElement(Loop *L, isl::schedule S, unsigned NumBlocksProcessed)
736 : L(L), Schedule(S), NumBlocksProcessed(NumBlocksProcessed) {}
737 };
738
739 /// The loop stack used for schedule construction.
740 ///
741 /// The loop stack keeps track of schedule information for a set of nested
742 /// loops as well as an (optional) 'nullptr' loop that models the outermost
743 /// schedule dimension. The loops in a loop stack always have a parent-child
744 /// relation where the loop at position n is the parent of the loop at
745 /// position n + 1.
746 using LoopStackTy = SmallVector<LoopStackElementTy, 4>;
747
748 /// Construct schedule information for a given Region and add the
749 /// derived information to @p LoopStack.
750 ///
751 /// Given a Region we derive schedule information for all RegionNodes
752 /// contained in this region ensuring that the assigned execution times
753 /// correctly model the existing control flow relations.
754 ///
755 /// @param R The region which to process.
756 /// @param LoopStack A stack of loops that are currently under
757 /// construction.
758 void buildSchedule(Region *R, LoopStackTy &LoopStack);
759
760 /// Build Schedule for the region node @p RN and add the derived
761 /// information to @p LoopStack.
762 ///
763 /// In case @p RN is a BasicBlock or a non-affine Region, we construct the
764 /// schedule for this @p RN and also finalize loop schedules in case the
765 /// current @p RN completes the loop.
766 ///
767 /// In case @p RN is a not-non-affine Region, we delegate the construction to
768 /// buildSchedule(Region *R, ...).
769 ///
770 /// @param RN The RegionNode region traversed.
771 /// @param LoopStack A stack of loops that are currently under
772 /// construction.
773 void buildSchedule(RegionNode *RN, LoopStackTy &LoopStack);
774
775public:
776 explicit ScopBuilder(Region *R, AssumptionCache &AC, AAResults &AA,
777 const DataLayout &DL, DominatorTree &DT, LoopInfo &LI,
778 ScopDetection &SD, ScalarEvolution &SE,
779 OptimizationRemarkEmitter &ORE);
780 ScopBuilder(const ScopBuilder &) = delete;
782 ~ScopBuilder() = default;
783
784 /// Try to build the Polly IR of static control part on the current
785 /// SESE-Region.
786 ///
787 /// @return Give up the ownership of the scop object or static control part
788 /// for the region
789 std::unique_ptr<Scop> getScop() { return std::move(scop); }
790};
791} // end namespace polly
792
793#endif // POLLY_SCOPBUILDER_H
Utility proxy to wrap the common members of LoadInst and StoreInst.
Definition ScopHelper.h:141
Represent memory accesses in statements.
Definition ScopInfo.h:426
AccessType
The access type of a memory access.
Definition ScopInfo.h:452
void buildDomain(ScopStmt &Stmt)
Build the domain of Stmt.
void propagateDomainConstraintsToRegionExit(BasicBlock *BB, Loop *BBLoop, SmallPtrSetImpl< BasicBlock * > &FinishedExitBlocks, DenseMap< BasicBlock *, isl::set > &InvalidDomainMap)
Propagate domains that are known due to graph properties.
bool isRequiredInvariantLoad(LoadInst *LI) const
Return true if and only if LI is a required invariant load.
bool propagateInvalidStmtDomains(Region *R, DenseMap< BasicBlock *, isl::set > &InvalidDomainMap)
Propagate invalid domains of statements through R.
void ensurePHIWrite(PHINode *PHI, ScopStmt *IncomintStmt, BasicBlock *IncomingBlock, Value *IncomingValue, bool IsExitBlock)
Create a write MemoryAccess for the incoming block of a phi node.
void addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs)
Add invariant loads listed in InvMAs with the domain of Stmt.
void canonicalizeDynamicBasePtrs()
Canonicalize arrays with base pointers from the same equivalence class.
bool calculateMinMaxAccess(AliasGroupTy AliasGroup, Scop::MinMaxVectorTy &MinMaxAccesses)
Wrapper function to calculate minimal/maximal accesses to each array.
void verifyInvariantLoads()
Verify that all required invariant loads have been hoisted.
void addUserContext()
Add user provided parameter constraints to context (command line).
void ensureValueRead(Value *V, ScopStmt *UserStmt)
Ensure an llvm::Value is available in the BB's statement, creating a MemoryAccess for reloading it if...
struct LoopStackElement { Loop *L; isl::schedule Schedule; unsigned NumBlocksProcessed; LoopStackElement(Loop *L, isl::schedule S, unsigned NumBlocksProcessed) :L(L), Schedule(S), NumBlocksProcessed(NumBlocksProcessed) {} } LoopStackElementTy
A loop stack element to keep track of per-loop information during schedule construction.
void buildPHIAccesses(ScopStmt *PHIStmt, PHINode *PHI, Region *NonAffineSubRegion, bool IsExitBlock=false)
Create MemoryAccesses for the given PHI node in the given region.
void buildSchedule()
Construct the schedule of this SCoP.
SmallVector< std::pair< ScopStmt *, Instruction * >, 16 > GlobalReads
Set of instructions that might read any memory location.
Definition ScopBuilder.h:57
ScalarEvolution & SE
The ScalarEvolution to help building Scop.
Definition ScopBuilder.h:51
void foldAccessRelations()
Fold memory accesses to handle parametric offset.
std::tuple< AliasGroupVectorTy, DenseSet< const ScopArrayInfo * > > buildAliasGroupsForAccesses()
Build alias groups for all memory accesses in the Scop.
bool propagateDomainConstraints(Region *R, DenseMap< BasicBlock *, isl::set > &InvalidDomainMap)
Propagate the domain constraints through the region R.
void addPHIReadAccess(ScopStmt *PHIStmt, PHINode *PHI)
Create a MemoryAccess for reading the value of a phi.
bool buildAccessCallInst(MemAccInst Inst, ScopStmt *Stmt)
Try to build a MemoryAccess for a call instruction.
void buildScalarDependences(ScopStmt *UserStmt, Instruction *Inst)
Analyze and extract the cross-BB scalar dependences (or, dataflow dependencies) of an instruction.
void foldSizeConstantsToRight()
Fold size constants to the right.
SmallSetVector< Value *, 16 > ArrayBasePointers
Set of all accessed array base pointers.
Definition ScopBuilder.h:60
SmallVector< LoopStackElementTy, 4 > LoopStackTy
The loop stack used for schedule construction.
MemoryAccess * addMemoryAccess(ScopStmt *Stmt, Instruction *Inst, MemoryAccess::AccessType AccType, Value *BaseAddress, Type *ElemType, bool Affine, Value *AccessValue, ArrayRef< const SCEV * > Subscripts, ArrayRef< const SCEV * > Sizes, MemoryKind Kind)
Create a new MemoryAccess object and add it to AccFuncMap.
void hoistInvariantLoads()
Hoist invariant memory loads and check for required ones.
isl::pw_aff getPwAff(BasicBlock *BB, DenseMap< BasicBlock *, isl::set > &InvalidDomainMap, const SCEV *E, bool NonNegative=false, bool IsInsideDomain=true)
Compute the isl representation for the SCEV E in this BB.
SmallVector< AliasGroupTy, 4 > AliasGroupVectorTy
A vector of alias groups.
AAResults & AA
The AAResults to build AliasSetTracker.
Definition ScopBuilder.h:36
bool buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt)
Try to build a multi-dimensional fixed sized MemoryAccess from the Load/Store instruction.
DominatorTree & DT
DominatorTree to reason about guaranteed execution.
Definition ScopBuilder.h:42
const DataLayout & DL
Target data for element size computing.
Definition ScopBuilder.h:39
bool buildAccessMemIntrinsic(MemAccInst Inst, ScopStmt *Stmt)
Try to build a MemoryAccess for a memory intrinsic.
void assumeNoOutOfBounds()
Assume that all memory accesses are within bounds.
isl::set getNonHoistableCtx(MemoryAccess *Access, isl::union_map Writes)
Return the context under which the access cannot be hoisted.
void buildInvariantEquivalenceClasses()
Create equivalence classes for required invariant accesses.
ScopBuilder & operator=(const ScopBuilder &)=delete
bool buildConditionSets(BasicBlock *BB, Instruction *TI, Loop *L, __isl_keep isl_set *Domain, DenseMap< BasicBlock *, isl::set > &InvalidDomainMap, SmallVectorImpl< __isl_give isl_set * > &ConditionSets, bool IsInsideDomain=true)
Build the conditions sets for the terminator TI in the Domain.
bool buildAliasGroups()
Build all alias groups for this SCoP.
void addArrayAccess(ScopStmt *Stmt, MemAccInst MemAccInst, MemoryAccess::AccessType AccType, Value *BaseAddress, Type *ElemType, bool IsAffine, ArrayRef< const SCEV * > Subscripts, ArrayRef< const SCEV * > Sizes, Value *AccessValue)
Create a MemoryAccess that represents either a LoadInst or StoreInst.
isl::set adjustDomainDimensions(isl::set Dom, Loop *OldL, Loop *NewL)
Adjust the dimensions of Dom that was constructed for OldL to be compatible to domains constructed fo...
bool buildAccessMultiDimParam(MemAccInst Inst, ScopStmt *Stmt)
Try to build a multi-dimensional parametric sized MemoryAccess.
void buildEscapingDependences(Instruction *Inst)
Build the escaping dependences for Inst.
void buildEqivClassBlockStmts(BasicBlock *BB)
Create one or more ScopStmts for BB using equivalence classes.
void splitAliasGroupsByDomain(AliasGroupVectorTy &AliasGroups)
Split alias groups by iteration domains.
bool buildAliasGroup(AliasGroupTy &AliasGroup, DenseSet< const ScopArrayInfo * > HasWriteAccess)
Build a given alias group and its access data.
void addUserAssumptions(AssumptionCache &AC, DenseMap< BasicBlock *, isl::set > &InvalidDomainMap)
Add user provided parameter constraints to context (source code).
void checkForReductions(ScopStmt &Stmt)
Check for reductions in Stmt.
bool buildDomains(Region *R, DenseMap< BasicBlock *, isl::set > &InvalidDomainMap)
Compute the domain for each basic block in R.
void buildSequentialBlockStmts(BasicBlock *BB, bool SplitOnStore=false)
Create one or more ScopStmts for BB.
ScopDetection & SD
Valid Regions for Scop.
Definition ScopBuilder.h:48
isl::set buildUnsignedConditionSets(BasicBlock *BB, Value *Condition, const isl::set &Domain, const SCEV *SCEV_TestVal, const SCEV *SCEV_UpperBound, DenseMap< BasicBlock *, isl::set > &InvalidDomainMap, bool IsStrictUpperBound, bool IsInsideDomain=true)
Build condition sets for unsigned ICmpInst(s).
bool shouldModelInst(Instruction *Inst, Loop *L)
Should an instruction be modeled in a ScopStmt.
std::unique_ptr< Scop > scop
Definition ScopBuilder.h:63
void buildMemoryAccess(MemAccInst Inst, ScopStmt *Stmt)
Build an instance of MemoryAccess from the Load/Store instruction.
bool buildAliasChecks()
Build the alias checks for this SCoP.
void updateAccessDimensionality()
Update access dimensionalities.
void addRecordedAssumptions()
Add all recorded assumptions to the assumed context.
void buildAccessRelations(ScopStmt &Stmt)
Build the access relation of all memory accesses of Stmt.
RecordedAssumptionsTy RecordedAssumptions
Collection to hold taken assumptions.
Definition ScopBuilder.h:75
bool hasNonHoistableBasePtrInScop(MemoryAccess *MA, isl::union_map Writes)
Check if the base ptr of MA is in the SCoP but not hoistable.
bool addLoopBoundsToHeaderDomain(Loop *L, DenseMap< BasicBlock *, isl::set > &InvalidDomainMap)
Add loop carried constraints to the header block of the loop L.
bool buildDomainsWithBranchConstraints(Region *R, DenseMap< BasicBlock *, isl::set > &InvalidDomainMap)
Compute the branching constraints for each basic block in R.
void buildAccessFunctions()
Build the access functions for the subregion SR.
bool canAlwaysBeHoisted(MemoryAccess *MA, bool StmtInvalidCtxIsEmpty, bool MAInvalidCtxIsEmpty, bool NonHoistableCtxIsEmpty)
Check if MA can always be hoisted without execution context.
bool buildAccessSingleDim(MemAccInst Inst, ScopStmt *Stmt)
Build a single-dimensional parametric sized MemoryAccess from the Load/Store instruction.
std::unique_ptr< Scop > getScop()
Try to build the Polly IR of static control part on the current SESE-Region.
void collectSurroundingLoops(ScopStmt &Stmt)
Fill NestLoops with loops surrounding Stmt.
void finalizeAccesses()
Finalize all access relations.
void buildScop(Region &R, AssumptionCache &AC)
LoopInfo & LI
LoopInfo for information about loops.
Definition ScopBuilder.h:45
~ScopBuilder()=default
OptimizationRemarkEmitter & ORE
An optimization diagnostic interface to add optimization remarks.
Definition ScopBuilder.h:54
void buildStmts(Region &SR)
Create ScopStmt for all BBs and non-affine subregions of SR.
ScopBuilder(const ScopBuilder &)=delete
void ensureValueWrite(Instruction *Inst)
Create a MemoryAccess for writing an llvm::Instruction.
SmallVector< MemoryAccess *, 4 > AliasGroupTy
A vector of memory accesses that belong to an alias group.
isl::set getPredecessorDomainConstraints(BasicBlock *BB, isl::set Domain)
Compute the union of predecessor domains for BB.
ScopBuilder(Region *R, AssumptionCache &AC, AAResults &AA, const DataLayout &DL, DominatorTree &DT, LoopInfo &LI, ScopDetection &SD, ScalarEvolution &SE, OptimizationRemarkEmitter &ORE)
Pass to detect the maximal static control parts (Scops) of a function.
Statement of the Scop.
Definition ScopInfo.h:1135
SmallVector< MinMaxAccessTy, 4 > MinMaxVectorTy
Vector of minimal/maximal accesses to different arrays.
Definition ScopInfo.h:1631
#define __isl_keep
Definition ctx.h:26
#define S(TYPE, NAME)
#define isl_set
SmallVector< InvariantAccess, 8 > InvariantAccessesTy
Ordered container type to hold invariant accesses.
Definition ScopInfo.h:1098
MemoryKind
The different memory kinds used in Polly.
Definition ScopInfo.h:95
@ Value
MemoryKind::Value: Models an llvm::Value.
Definition ScopInfo.h:149
@ PHI
MemoryKind::PHI: Models PHI nodes within the SCoP.
Definition ScopInfo.h:186
bool ModelReadOnlyScalars
Command line switch whether to model read-only accesses.
llvm::SmallVector< Assumption, 8 > RecordedAssumptionsTy
Definition ScopHelper.h:81
static TupleKindPtr Domain("Domain")