46#ifndef POLLY_SCOPDETECTION_H
47#define POLLY_SCOPDETECTION_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"
60using llvm::AliasSetTracker;
61using llvm::AnalysisInfoMixin;
62using llvm::AnalysisKey;
63using llvm::AnalysisUsage;
64using llvm::BatchAAResults;
65using llvm::BranchInst;
68using llvm::DominatorTree;
70using llvm::FunctionAnalysisManager;
71using llvm::FunctionPass;
72using llvm::IntrinsicInst;
75using llvm::OptimizationRemarkEmitter;
76using llvm::PassInfoMixin;
77using llvm::PreservedAnalyses;
78using llvm::RegionInfo;
79using llvm::ScalarEvolution;
80using llvm::SCEVUnknown;
82using llvm::SmallSetVector;
83using llvm::SmallVectorImpl;
85using llvm::SwitchInst;
109 MemAcc(
const Instruction *I, std::shared_ptr<ArrayShape>
S)
115using AFs = std::vector<PairInstSCEV>;
208 const DominatorTree &
DT;
217 DenseMap<BBPair, std::unique_ptr<DetectionContext>>;
221 DenseMap<std::tuple<const BasicBlock *, const Region *>,
bool>
254 SmallVector<const SCEV *, 4>
256 const SCEVUnknown *BasePointer)
const;
267 SmallVectorImpl<const SCEV *> &Sizes,
268 const SCEVUnknown *BasePointer, Loop *Scope)
const;
281 const SCEVUnknown *BasePointer,
282 std::shared_ptr<ArrayShape> Shape)
const;
292 const SCEVUnknown *BasePointer, Loop *Scope)
const;
325 int NumAffineLoops)
const;
397 bool isValidAccess(Instruction *Inst,
const SCEV *AF,
const SCEVUnknown *BP,
419 bool isValidSwitch(BasicBlock &BB, SwitchInst *SI, Value *Condition,
429 bool isValidBranch(BasicBlock &BB, BranchInst *BI, Value *Condition,
455 bool isValidCFG(BasicBlock &BB,
bool IsLoopBranch,
bool AllowUnreachable,
474 unsigned MinProfitableTrips);
506 template <
class RR,
typename... Args>
508 Args &&...Arguments)
const;
512 RegionInfo &
RI, AAResults &
AA, OptimizationRemarkEmitter &
ORE);
592 unsigned MinProfitableTrips);
610 bool isErrorBlock(llvm::BasicBlock &BB,
const llvm::Region &R);
614 OptimizationRemarkEmitter &
ORE;
624 Result run(Function &F, FunctionAnalysisManager &FAM);
630 PreservedAnalyses
run(Function &F, FunctionAnalysisManager &FAM);
647 void print(raw_ostream &OS,
const Module *
M =
nullptr)
const override;
static cl::opt< bool > Verify("polly-codegen-verify", cl::desc("Verify the function generated by Polly"), cl::Hidden, cl::cat(PollyCategory))
static RegisterPass< ScopPrinterWrapperPass > M("dot-scops", "Polly - Print Scops of function")
Utility proxy to wrap the common members of LoadInst and StoreInst.
Stores all errors that occurred during the detection.
std::unique_ptr< ScopDetection > Result
void releaseMemory() override
void getAnalysisUsage(AnalysisUsage &AU) const override
ScopDetectionWrapperPass()
void print(raw_ostream &OS, const Module *M=nullptr) const override
ScopDetection & getSD() const
bool runOnFunction(Function &F) override
Pass to detect the maximal static control parts (Scops) of a function.
static void markFunctionAsInvalid(Function *F)
Mark the function as invalid so we will not extract any scop from the function.
bool addOverApproximatedRegion(Region *AR, DetectionContext &Context) const
Add the region AR as over approximated sub-region in Context.
bool isValidAccess(Instruction *Inst, const SCEV *AF, const SCEVUnknown *BP, DetectionContext &Context) const
Check if the memory access caused by Inst is valid.
bool onlyValidRequiredInvariantLoads(InvariantLoadsSetTy &RequiredILS, DetectionContext &Context) const
Check if the given loads could be invariant and can be hoisted.
bool isInvariant(Value &Val, const Region &Reg, DetectionContext &Ctx) const
Check if a value is invariant in the region Reg.
bool isReducibleRegion(Region &R, DebugLoc &DbgLoc) const
Check if a region is reducible or not.
bool computeAccessFunctions(DetectionContext &Context, const SCEVUnknown *BasePointer, std::shared_ptr< ArrayShape > Shape) const
Derive access functions for a given base pointer.
DetectionContext * getDetectionContext(const Region *R) const
Return the detection context for R, nullptr if R was invalid.
void removeCachedResultsRecursively(const Region &R)
Remove cached results for the children of R recursively.
bool hasSufficientCompute(DetectionContext &Context, int NumAffineLoops) const
Check if a region has sufficient compute instructions.
bool isProfitableRegion(DetectionContext &Context) const
Check if a region is profitable to optimize.
void emitMissedRemarks(const Function &F)
Emit rejection remarks for all rejected regions.
bool isValidLoop(Loop *L, DetectionContext &Context)
Is a loop valid with respect to a given region.
static ScopDetection::LoopStats countBeneficialLoops(Region *R, ScalarEvolution &SE, LoopInfo &LI, unsigned MinProfitableTrips)
Count the number of loops and the maximal loop depth in R.
const RejectLog * lookupRejectionLog(const Region *R) const
Return the set of rejection causes for R.
RegionInfo * getRI() const
Get the RegionInfo stored in this pass.
bool involvesMultiplePtrs(const SCEV *S0, const SCEV *S1, Loop *Scope) const
Check if S0 and S1 do contain multiple possibly aliasing pointers.
bool isValidSwitch(BasicBlock &BB, SwitchInst *SI, Value *Condition, bool IsLoopBranch, DetectionContext &Context) const
Check if the switch SI with condition Condition is valid.
bool isValidRegion(DetectionContext &Context)
Check if a region is a Scop.
Region * expandRegion(Region &R)
Try to expand the region R.
const DominatorTree & DT
Analyses used.
bool hasBaseAffineAccesses(DetectionContext &Context, const SCEVUnknown *BasePointer, Loop *Scope) const
Check if all accesses to a given BasePointer are affine.
OptimizationRemarkEmitter & ORE
OptimizationRemarkEmitter object used to emit diagnostic remarks.
bool hasAffineMemoryAccesses(DetectionContext &Context) const
Delinearize all non affine memory accesses and return false when there exists a non affine memory acc...
bool isValidMemoryAccess(MemAccInst Inst, DetectionContext &Context) const
Check if a memory access can be part of a Scop.
bool isValidCFG(BasicBlock &BB, bool IsLoopBranch, bool AllowUnreachable, DetectionContext &Context)
Check if the control flow in a basic block is valid.
void printLocations(Function &F)
Print the locations of all detected scops.
bool hasValidArraySizes(DetectionContext &Context, SmallVectorImpl< const SCEV * > &Sizes, const SCEVUnknown *BasePointer, Loop *Scope) const
Check if the dimension size of a delinearized array is valid.
DenseMap< std::tuple< const BasicBlock *, const Region * >, bool > ErrorBlockCache
Cache for the isErrorBlock function.
void removeCachedResults(const Region &R)
Remove cached results for R.
bool isValidBranch(BasicBlock &BB, BranchInst *BI, Value *Condition, bool IsLoopBranch, DetectionContext &Context)
Check if the branch BI with condition Condition is valid.
bool hasPossiblyDistributableLoop(DetectionContext &Context) const
Check if the unique affine loop might be amendable to distribution.
void verifyAnalysis()
Verify if all valid Regions in this Function are still valid after some transformations.
RegionSet::iterator iterator
SmallVector< const SCEV *, 4 > getDelinearizationTerms(DetectionContext &Context, const SCEVUnknown *BasePointer) const
Find for a given base pointer terms that hint towards dimension sizes of a multi-dimensional array.
const_iterator begin() const
bool isValidInstruction(Instruction &Inst, DetectionContext &Context)
Check if an instruction can be part of a Scop.
bool isAffine(const SCEV *S, Loop *Scope, DetectionContext &Context) const
Check if the SCEV S is affine in the current Context.
DenseMap< BBPair, std::unique_ptr< DetectionContext > > DetectionContextMapTy
Map to remember detection contexts for all regions.
DetectionContextMapTy DetectionContextMap
bool allBlocksValid(DetectionContext &Context)
Check if all basic block in the region are valid.
LoopInfo * getLI() const
Get the LoopInfo stored in this pass.
void findScops(Region &R)
Find the Scops in this region tree.
SetVector< const Region * > RegionSet
bool isValidIntrinsicInst(IntrinsicInst &II, DetectionContext &Context) const
Check if an intrinsic call can be part of a Scop.
std::string regionIsInvalidBecause(const Region *R) const
Get a message why a region is invalid.
bool isMaxRegionInScop(const Region &R, bool Verify=true)
Is the region is the maximum region of a Scop?
RegionSet::const_iterator const_iterator
const_iterator end() const
bool isValidCallInst(CallInst &CI, DetectionContext &Context) const
Check if a call instruction can be part of a Scop.
void verifyRegion(const Region &R)
Verify if R is still a valid part of Scop after some transformations.
static bool isValidFunction(Function &F)
Check if the function F is marked as invalid.
bool isErrorBlock(llvm::BasicBlock &BB, const llvm::Region &R)
Check if the block is a error block.
bool invalid(DetectionContext &Context, bool Assert, Args &&...Arguments) const
Track diagnostics for invalid scops.
bool canUseISLTripCount(Loop *L, DetectionContext &Context)
Can ISL compute the trip count of a loop.
static ScopDetection::LoopStats countBeneficialSubLoops(Loop *L, ScalarEvolution &SE, unsigned MinProfitableTrips)
Count the number of loops and the maximal loop depth in L.
This file contains the declaration of the PolyhedralInfo class, which will provide an interface to ex...
void initializeScopDetectionWrapperPassPass(llvm::PassRegistry &)
void initializeScopDetectionPrinterLegacyPassPass(llvm::PassRegistry &)
StringRef PollySkipFnAttr
A function attribute which will cause Polly to skip the function.
std::map< const SCEVUnknown *, AFs > BaseToAFs
bool PollyAllowFullFunction
std::set< const SCEV * > ParamSetType
std::map< const SCEVUnknown *, const SCEV * > BaseToElSize
bool PollyProcessUnprofitable
std::pair< const Instruction *, const SCEV * > PairInstSCEV
llvm::Pass * createScopDetectionPrinterLegacyPass(llvm::raw_ostream &OS)
std::vector< PairInstSCEV > AFs
llvm::SetVector< llvm::AssertingVH< llvm::LoadInst > > InvariantLoadsSetTy
Type for a set of invariant loads.
llvm::SetVector< const llvm::Loop * > BoxedLoopsSetTy
Set of loops (used to remember loops in non-affine subregions).
std::map< const Instruction *, MemAcc > MapInsnToMemAcc
bool PollyUseRuntimeAliasChecks
bool PollyAllowUnsignedOperations
bool PollyInvariantLoadHoisting
const SCEVUnknown * BasePointer
SmallVector< const SCEV *, 4 > DelinearizedSizes
ArrayShape(const SCEVUnknown *B)
std::shared_ptr< ArrayShape > Shape
MemAcc(const Instruction *I, std::shared_ptr< ArrayShape > S)
SmallVector< const SCEV *, 4 > DelinearizedSubscripts
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
ScopAnalysisPrinterPass(raw_ostream &OS)
Result run(Function &F, FunctionAnalysisManager &FAM)
Context variables for SCoP detection.
BaseToAFs Accesses
Map a base pointer to all access functions accessing it.
InvariantLoadsSetTy RequiredILS
Loads that need to be invariant during execution.
bool hasLoads
The region has at least one load instruction.
bool IsInvalid
If this flag is set, the SCoP must eventually be rejected, even with KeepGoing.
bool HasUnknownAccess
Flag to indicate the region has at least one unknown access.
BoxedLoopsSetTy BoxedLoopsSet
The set of loops contained in non-affine regions.
MapInsnToMemAcc InsnToMemAcc
Map to memory access description for the corresponding LLVM instructions.
RejectLog Log
Container to remember rejection reasons for this region.
DetectionContext(Region &R, AAResults &AA, bool Verify)
Initialize a DetectionContext from scratch.
RegionSet NonAffineSubRegionSet
The set of non-affine subregions in the region we analyze.
llvm::SetVector< std::pair< const SCEVUnknown *, Loop * > > NonAffineAccesses
The set of base pointers with non-affine accesses.
bool hasStores
The region has at least one store instruction.
Helper data structure to collect statistics about loop counts.