1 //===- ScopDetection.h - Detect Scops ---------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Detect the maximal Scops of a function.
11 // A static control part (Scop) is a subgraph of the control flow graph (CFG)
12 // that only has statically known control flow and can therefore be described
13 // within the polyhedral model.
15 // Every Scop fulfills these restrictions:
17 // * It is a single entry single exit region
19 // * Only affine linear bounds in the loops
21 // Every natural loop in a Scop must have a number of loop iterations that can
22 // be described as an affine linear function in surrounding loop iterators or
23 // parameters. (A parameter is a scalar that does not change its value during
24 // execution of the Scop).
26 // * Only comparisons of affine linear expressions in conditions
28 // * All loops and conditions perfectly nested
30 // The control flow needs to be structured such that it could be written using
31 // just 'for' and 'if' statements, without the need for any 'goto', 'break' or
34 // * Side effect free functions call
36 // Only function calls and intrinsics that do not have side effects are allowed
39 // The Scop detection finds the largest Scops by checking if the largest
40 // region is a Scop. If this is not the case, its canonical subregions are
41 // checked until a region is a Scop. It is now tried to extend this Scop by
42 // creating a larger non canonical region.
44 //===----------------------------------------------------------------------===//
46 #ifndef POLLY_SCOPDETECTION_H
47 #define POLLY_SCOPDETECTION_H
49 #include "polly/ScopDetectionDiagnostic.h"
50 #include "polly/Support/ScopHelper.h"
51 #include "llvm/Analysis/AliasAnalysis.h"
52 #include "llvm/Analysis/AliasSetTracker.h"
53 #include "llvm/Analysis/RegionInfo.h"
54 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
55 #include "llvm/Pass.h"
61 void initializeScopDetectionWrapperPassPass(PassRegistry
&);
66 using ParamSetType
= std::set
<const SCEV
*>;
68 // Description of the shape of an array.
70 // Base pointer identifying all accesses to this array.
71 const SCEVUnknown
*BasePointer
;
73 // Sizes of each delinearized dimension.
74 SmallVector
<const SCEV
*, 4> DelinearizedSizes
;
76 ArrayShape(const SCEVUnknown
*B
) : BasePointer(B
) {}
80 const Instruction
*Insn
;
82 // A pointer to the shape description of the array.
83 std::shared_ptr
<ArrayShape
> Shape
;
85 // Subscripts computed by delinearization.
86 SmallVector
<const SCEV
*, 4> DelinearizedSubscripts
;
88 MemAcc(const Instruction
*I
, std::shared_ptr
<ArrayShape
> S
)
89 : Insn(I
), Shape(S
) {}
92 using MapInsnToMemAcc
= std::map
<const Instruction
*, MemAcc
>;
93 using PairInstSCEV
= std::pair
<const Instruction
*, const SCEV
*>;
94 using AFs
= std::vector
<PairInstSCEV
>;
95 using BaseToAFs
= std::map
<const SCEVUnknown
*, AFs
>;
96 using BaseToElSize
= std::map
<const SCEVUnknown
*, const SCEV
*>;
98 extern bool PollyTrackFailures
;
99 extern bool PollyDelinearize
;
100 extern bool PollyUseRuntimeAliasChecks
;
101 extern bool PollyProcessUnprofitable
;
102 extern bool PollyInvariantLoadHoisting
;
103 extern bool PollyAllowUnsignedOperations
;
104 extern bool PollyAllowFullFunction
;
106 /// A function attribute which will cause Polly to skip the function
107 extern StringRef PollySkipFnAttr
;
109 //===----------------------------------------------------------------------===//
110 /// Pass to detect the maximal static control parts (Scops) of a
112 class ScopDetection
{
114 using RegionSet
= SetVector
<const Region
*>;
116 // Remember the valid regions
117 RegionSet ValidRegions
;
119 /// Context variables for SCoP detection.
120 struct DetectionContext
{
121 Region
&CurRegion
; // The region to check.
122 AliasSetTracker AST
; // The AliasSetTracker to hold the alias information.
123 bool Verifying
; // If we are in the verification phase?
125 /// Container to remember rejection reasons for this region.
128 /// Map a base pointer to all access functions accessing it.
130 /// This map is indexed by the base pointer. Each element of the map
131 /// is a list of memory accesses that reference this base pointer.
134 /// The set of base pointers with non-affine accesses.
136 /// This set contains all base pointers and the locations where they are
137 /// used for memory accesses that can not be detected as affine accesses.
138 SetVector
<std::pair
<const SCEVUnknown
*, Loop
*>> NonAffineAccesses
;
139 BaseToElSize ElementSize
;
141 /// The region has at least one load instruction.
142 bool hasLoads
= false;
144 /// The region has at least one store instruction.
145 bool hasStores
= false;
147 /// Flag to indicate the region has at least one unknown access.
148 bool HasUnknownAccess
= false;
150 /// The set of non-affine subregions in the region we analyze.
151 RegionSet NonAffineSubRegionSet
;
153 /// The set of loops contained in non-affine regions.
154 BoxedLoopsSetTy BoxedLoopsSet
;
156 /// Loads that need to be invariant during execution.
157 InvariantLoadsSetTy RequiredILS
;
159 /// Map to memory access description for the corresponding LLVM
161 MapInsnToMemAcc InsnToMemAcc
;
163 /// Initialize a DetectionContext from scratch.
164 DetectionContext(Region
&R
, AliasAnalysis
&AA
, bool Verify
)
165 : CurRegion(R
), AST(AA
), Verifying(Verify
), Log(&R
) {}
167 /// Initialize a DetectionContext with the data from @p DC.
168 DetectionContext(const DetectionContext
&&DC
)
169 : CurRegion(DC
.CurRegion
), AST(DC
.AST
.getAliasAnalysis()),
170 Verifying(DC
.Verifying
), Log(std::move(DC
.Log
)),
171 Accesses(std::move(DC
.Accesses
)),
172 NonAffineAccesses(std::move(DC
.NonAffineAccesses
)),
173 ElementSize(std::move(DC
.ElementSize
)), hasLoads(DC
.hasLoads
),
174 hasStores(DC
.hasStores
), HasUnknownAccess(DC
.HasUnknownAccess
),
175 NonAffineSubRegionSet(std::move(DC
.NonAffineSubRegionSet
)),
176 BoxedLoopsSet(std::move(DC
.BoxedLoopsSet
)),
177 RequiredILS(std::move(DC
.RequiredILS
)) {
182 /// Helper data structure to collect statistics about loop counts.
189 //===--------------------------------------------------------------------===//
193 const DominatorTree
&DT
;
200 /// Map to remember detection contexts for all regions.
201 using DetectionContextMapTy
= DenseMap
<BBPair
, DetectionContext
>;
202 mutable DetectionContextMapTy DetectionContextMap
;
204 /// Remove cached results for @p R.
205 void removeCachedResults(const Region
&R
);
207 /// Remove cached results for the children of @p R recursively.
208 void removeCachedResultsRecursively(const Region
&R
);
210 /// Check if @p S0 and @p S1 do contain multiple possibly aliasing pointers.
212 /// @param S0 A expression to check.
213 /// @param S1 Another expression to check or nullptr.
214 /// @param Scope The loop/scope the expressions are checked in.
216 /// @returns True, if multiple possibly aliasing pointers are used in @p S0
217 /// (and @p S1 if given).
218 bool involvesMultiplePtrs(const SCEV
*S0
, const SCEV
*S1
, Loop
*Scope
) const;
220 /// Add the region @p AR as over approximated sub-region in @p Context.
222 /// @param AR The non-affine subregion.
223 /// @param Context The current detection context.
225 /// @returns True if the subregion can be over approximated, false otherwise.
226 bool addOverApproximatedRegion(Region
*AR
, DetectionContext
&Context
) const;
228 /// Find for a given base pointer terms that hint towards dimension
229 /// sizes of a multi-dimensional array.
231 /// @param Context The current detection context.
232 /// @param BasePointer A base pointer indicating the virtual array we are
234 SmallVector
<const SCEV
*, 4>
235 getDelinearizationTerms(DetectionContext
&Context
,
236 const SCEVUnknown
*BasePointer
) const;
238 /// Check if the dimension size of a delinearized array is valid.
240 /// @param Context The current detection context.
241 /// @param Sizes The sizes of the different array dimensions.
242 /// @param BasePointer The base pointer we are interested in.
243 /// @param Scope The location where @p BasePointer is being used.
244 /// @returns True if one or more array sizes could be derived - meaning: we
245 /// see this array as multi-dimensional.
246 bool hasValidArraySizes(DetectionContext
&Context
,
247 SmallVectorImpl
<const SCEV
*> &Sizes
,
248 const SCEVUnknown
*BasePointer
, Loop
*Scope
) const;
250 /// Derive access functions for a given base pointer.
252 /// @param Context The current detection context.
253 /// @param Sizes The sizes of the different array dimensions.
254 /// @param BasePointer The base pointer of all the array for which to compute
255 /// access functions.
256 /// @param Shape The shape that describes the derived array sizes and
257 /// which should be filled with newly computed access
259 /// @returns True if a set of affine access functions could be derived.
260 bool computeAccessFunctions(DetectionContext
&Context
,
261 const SCEVUnknown
*BasePointer
,
262 std::shared_ptr
<ArrayShape
> Shape
) const;
264 /// Check if all accesses to a given BasePointer are affine.
266 /// @param Context The current detection context.
267 /// @param BasePointer the base pointer we are interested in.
268 /// @param Scope The location where @p BasePointer is being used.
269 /// @param True if consistent (multi-dimensional) array accesses could be
270 /// derived for this array.
271 bool hasBaseAffineAccesses(DetectionContext
&Context
,
272 const SCEVUnknown
*BasePointer
, Loop
*Scope
) const;
274 // Delinearize all non affine memory accesses and return false when there
275 // exists a non affine memory access that cannot be delinearized. Return true
276 // when all array accesses are affine after delinearization.
277 bool hasAffineMemoryAccesses(DetectionContext
&Context
) const;
279 // Try to expand the region R. If R can be expanded return the expanded
280 // region, NULL otherwise.
281 Region
*expandRegion(Region
&R
);
283 /// Find the Scops in this region tree.
285 /// @param The region tree to scan for scops.
286 void findScops(Region
&R
);
288 /// Check if all basic block in the region are valid.
290 /// @param Context The context of scop detection.
292 /// @return True if all blocks in R are valid, false otherwise.
293 bool allBlocksValid(DetectionContext
&Context
) const;
295 /// Check if a region has sufficient compute instructions.
297 /// This function checks if a region has a non-trivial number of instructions
298 /// in each loop. This can be used as an indicator whether a loop is worth
301 /// @param Context The context of scop detection.
302 /// @param NumLoops The number of loops in the region.
304 /// @return True if region is has sufficient compute instructions,
306 bool hasSufficientCompute(DetectionContext
&Context
,
307 int NumAffineLoops
) const;
309 /// Check if the unique affine loop might be amendable to distribution.
311 /// This function checks if the number of non-trivial blocks in the unique
312 /// affine loop in Context.CurRegion is at least two, thus if the loop might
313 /// be amendable to distribution.
315 /// @param Context The context of scop detection.
317 /// @return True only if the affine loop might be amendable to distributable.
318 bool hasPossiblyDistributableLoop(DetectionContext
&Context
) const;
320 /// Check if a region is profitable to optimize.
322 /// Regions that are unlikely to expose interesting optimization opportunities
323 /// are called 'unprofitable' and may be skipped during scop detection.
325 /// @param Context The context of scop detection.
327 /// @return True if region is profitable to optimize, false otherwise.
328 bool isProfitableRegion(DetectionContext
&Context
) const;
330 /// Check if a region is a Scop.
332 /// @param Context The context of scop detection.
334 /// @return True if R is a Scop, false otherwise.
335 bool isValidRegion(DetectionContext
&Context
) const;
337 /// Check if an intrinsic call can be part of a Scop.
339 /// @param II The intrinsic call instruction to check.
340 /// @param Context The current detection context.
342 /// @return True if the call instruction is valid, false otherwise.
343 bool isValidIntrinsicInst(IntrinsicInst
&II
, DetectionContext
&Context
) const;
345 /// Check if a call instruction can be part of a Scop.
347 /// @param CI The call instruction to check.
348 /// @param Context The current detection context.
350 /// @return True if the call instruction is valid, false otherwise.
351 bool isValidCallInst(CallInst
&CI
, DetectionContext
&Context
) const;
353 /// Check if the given loads could be invariant and can be hoisted.
355 /// If true is returned the loads are added to the required invariant loads
356 /// contained in the @p Context.
358 /// @param RequiredILS The loads to check.
359 /// @param Context The current detection context.
361 /// @return True if all loads can be assumed invariant.
362 bool onlyValidRequiredInvariantLoads(InvariantLoadsSetTy
&RequiredILS
,
363 DetectionContext
&Context
) const;
365 /// Check if a value is invariant in the region Reg.
367 /// @param Val Value to check for invariance.
368 /// @param Reg The region to consider for the invariance of Val.
369 /// @param Ctx The current detection context.
371 /// @return True if the value represented by Val is invariant in the region
372 /// identified by Reg.
373 bool isInvariant(Value
&Val
, const Region
&Reg
, DetectionContext
&Ctx
) const;
375 /// Check if the memory access caused by @p Inst is valid.
377 /// @param Inst The access instruction.
378 /// @param AF The access function.
379 /// @param BP The access base pointer.
380 /// @param Context The current detection context.
381 bool isValidAccess(Instruction
*Inst
, const SCEV
*AF
, const SCEVUnknown
*BP
,
382 DetectionContext
&Context
) const;
384 /// Check if a memory access can be part of a Scop.
386 /// @param Inst The instruction accessing the memory.
387 /// @param Context The context of scop detection.
389 /// @return True if the memory access is valid, false otherwise.
390 bool isValidMemoryAccess(MemAccInst Inst
, DetectionContext
&Context
) const;
392 /// Check if an instruction has any non trivial scalar dependencies as part of
395 /// @param Inst The instruction to check.
396 /// @param RefRegion The region in respect to which we check the access
399 /// @return True if the instruction has scalar dependences, false otherwise.
400 bool hasScalarDependency(Instruction
&Inst
, Region
&RefRegion
) const;
402 /// Check if an instruction can be part of a Scop.
404 /// @param Inst The instruction to check.
405 /// @param Context The context of scop detection.
407 /// @return True if the instruction is valid, false otherwise.
408 bool isValidInstruction(Instruction
&Inst
, DetectionContext
&Context
) const;
410 /// Check if the switch @p SI with condition @p Condition is valid.
412 /// @param BB The block to check.
413 /// @param SI The switch to check.
414 /// @param Condition The switch condition.
415 /// @param IsLoopBranch Flag to indicate the branch is a loop exit/latch.
416 /// @param Context The context of scop detection.
418 /// @return True if the branch @p BI is valid.
419 bool isValidSwitch(BasicBlock
&BB
, SwitchInst
*SI
, Value
*Condition
,
420 bool IsLoopBranch
, DetectionContext
&Context
) const;
422 /// Check if the branch @p BI with condition @p Condition is valid.
424 /// @param BB The block to check.
425 /// @param BI The branch to check.
426 /// @param Condition The branch condition.
427 /// @param IsLoopBranch Flag to indicate the branch is a loop exit/latch.
428 /// @param Context The context of scop detection.
430 /// @return True if the branch @p BI is valid.
431 bool isValidBranch(BasicBlock
&BB
, BranchInst
*BI
, Value
*Condition
,
432 bool IsLoopBranch
, DetectionContext
&Context
) const;
434 /// Check if the SCEV @p S is affine in the current @p Context.
436 /// This will also use a heuristic to decide if we want to require loads to be
437 /// invariant to make the expression affine or if we want to treat is as
440 /// @param S The expression to be checked.
441 /// @param Scope The loop nest in which @p S is used.
442 /// @param Context The context of scop detection.
443 bool isAffine(const SCEV
*S
, Loop
*Scope
, DetectionContext
&Context
) const;
445 /// Check if the control flow in a basic block is valid.
447 /// This function checks if a certain basic block is terminated by a
448 /// Terminator instruction we can handle or, if this is not the case,
449 /// registers this basic block as the start of a non-affine region.
451 /// This function optionally allows unreachable statements.
453 /// @param BB The BB to check the control flow.
454 /// @param IsLoopBranch Flag to indicate the branch is a loop exit/latch.
455 // @param AllowUnreachable Allow unreachable statements.
456 /// @param Context The context of scop detection.
458 /// @return True if the BB contains only valid control flow.
459 bool isValidCFG(BasicBlock
&BB
, bool IsLoopBranch
, bool AllowUnreachable
,
460 DetectionContext
&Context
) const;
462 /// Is a loop valid with respect to a given region.
464 /// @param L The loop to check.
465 /// @param Context The context of scop detection.
467 /// @return True if the loop is valid in the region.
468 bool isValidLoop(Loop
*L
, DetectionContext
&Context
) const;
470 /// Count the number of loops and the maximal loop depth in @p L.
472 /// @param L The loop to check.
473 /// @param SE The scalar evolution analysis.
474 /// @param MinProfitableTrips The minimum number of trip counts from which
475 /// a loop is assumed to be profitable and
476 /// consequently is counted.
477 /// returns A tuple of number of loops and their maximal depth.
478 static ScopDetection::LoopStats
479 countBeneficialSubLoops(Loop
*L
, ScalarEvolution
&SE
,
480 unsigned MinProfitableTrips
);
482 /// Check if the function @p F is marked as invalid.
484 /// @note An OpenMP subfunction will be marked as invalid.
485 bool isValidFunction(Function
&F
);
487 /// Can ISL compute the trip count of a loop.
489 /// @param L The loop to check.
490 /// @param Context The context of scop detection.
492 /// @return True if ISL can compute the trip count of the loop.
493 bool canUseISLTripCount(Loop
*L
, DetectionContext
&Context
) const;
495 /// Print the locations of all detected scops.
496 void printLocations(Function
&F
);
498 /// Check if a region is reducible or not.
500 /// @param Region The region to check.
501 /// @param DbgLoc Parameter to save the location of instruction that
502 /// causes irregular control flow if the region is irreducible.
504 /// @return True if R is reducible, false otherwise.
505 bool isReducibleRegion(Region
&R
, DebugLoc
&DbgLoc
) const;
507 /// Track diagnostics for invalid scops.
509 /// @param Context The context of scop detection.
510 /// @param Assert Throw an assert in verify mode or not.
511 /// @param Args Argument list that gets passed to the constructor of RR.
512 template <class RR
, typename
... Args
>
513 inline bool invalid(DetectionContext
&Context
, bool Assert
,
514 Args
&&... Arguments
) const;
517 ScopDetection(Function
&F
, const DominatorTree
&DT
, ScalarEvolution
&SE
,
518 LoopInfo
&LI
, RegionInfo
&RI
, AliasAnalysis
&AA
,
519 OptimizationRemarkEmitter
&ORE
);
521 /// Get the RegionInfo stored in this pass.
523 /// This was added to give the DOT printer easy access to this information.
524 RegionInfo
*getRI() const { return &RI
; }
526 /// Get the LoopInfo stored in this pass.
527 LoopInfo
*getLI() const { return &LI
; }
529 /// Is the region is the maximum region of a Scop?
531 /// @param R The Region to test if it is maximum.
532 /// @param Verify Rerun the scop detection to verify SCoP was not invalidated
535 /// @return Return true if R is the maximum Region in a Scop, false otherwise.
536 bool isMaxRegionInScop(const Region
&R
, bool Verify
= true) const;
538 /// Return the detection context for @p R, nullptr if @p R was invalid.
539 DetectionContext
*getDetectionContext(const Region
*R
) const;
541 /// Return the set of rejection causes for @p R.
542 const RejectLog
*lookupRejectionLog(const Region
*R
) const;
544 /// Return true if @p SubR is a non-affine subregion in @p ScopR.
545 bool isNonAffineSubRegion(const Region
*SubR
, const Region
*ScopR
) const;
547 /// Get a message why a region is invalid
549 /// @param R The region for which we get the error message
551 /// @return The error or "" if no error appeared.
552 std::string
regionIsInvalidBecause(const Region
*R
) const;
554 /// @name Maximum Region In Scops Iterators
556 /// These iterators iterator over all maximum region in Scops of this
559 using iterator
= RegionSet::iterator
;
560 using const_iterator
= RegionSet::const_iterator
;
562 iterator
begin() { return ValidRegions
.begin(); }
563 iterator
end() { return ValidRegions
.end(); }
565 const_iterator
begin() const { return ValidRegions
.begin(); }
566 const_iterator
end() const { return ValidRegions
.end(); }
569 /// Emit rejection remarks for all rejected regions.
571 /// @param F The function to emit remarks for.
572 void emitMissedRemarks(const Function
&F
);
574 /// Mark the function as invalid so we will not extract any scop from
577 /// @param F The function to mark as invalid.
578 static void markFunctionAsInvalid(Function
*F
);
580 /// Verify if all valid Regions in this Function are still valid
581 /// after some transformations.
582 void verifyAnalysis() const;
584 /// Verify if R is still a valid part of Scop after some transformations.
586 /// @param R The Region to verify.
587 void verifyRegion(const Region
&R
) const;
589 /// Count the number of loops and the maximal loop depth in @p R.
591 /// @param R The region to check
592 /// @param SE The scalar evolution analysis.
593 /// @param MinProfitableTrips The minimum number of trip counts from which
594 /// a loop is assumed to be profitable and
595 /// consequently is counted.
596 /// returns A tuple of number of loops and their maximal depth.
597 static ScopDetection::LoopStats
598 countBeneficialLoops(Region
*R
, ScalarEvolution
&SE
, LoopInfo
&LI
,
599 unsigned MinProfitableTrips
);
602 /// OptimizationRemarkEmitter object used to emit diagnostic remarks
603 OptimizationRemarkEmitter
&ORE
;
606 struct ScopAnalysis
: public AnalysisInfoMixin
<ScopAnalysis
> {
607 static AnalysisKey Key
;
609 using Result
= ScopDetection
;
613 Result
run(Function
&F
, FunctionAnalysisManager
&FAM
);
616 struct ScopAnalysisPrinterPass
: public PassInfoMixin
<ScopAnalysisPrinterPass
> {
617 ScopAnalysisPrinterPass(raw_ostream
&OS
) : OS(OS
) {}
619 PreservedAnalyses
run(Function
&F
, FunctionAnalysisManager
&FAM
);
624 struct ScopDetectionWrapperPass
: public FunctionPass
{
626 std::unique_ptr
<ScopDetection
> Result
;
628 ScopDetectionWrapperPass();
630 /// @name FunctionPass interface
632 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
633 void releaseMemory() override
;
634 bool runOnFunction(Function
&F
) override
;
635 void print(raw_ostream
&OS
, const Module
*) const override
;
638 ScopDetection
&getSD() { return *Result
; }
639 const ScopDetection
&getSD() const { return *Result
; }
643 #endif // POLLY_SCOPDETECTION_H