|
|
|||
File indexing completed on 2026-05-10 08:48:20
0001 //===- ScopDetection.h - Detect Scops ---------------------------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // Detect the maximal Scops of a function. 0010 // 0011 // A static control part (Scop) is a subgraph of the control flow graph (CFG) 0012 // that only has statically known control flow and can therefore be described 0013 // within the polyhedral model. 0014 // 0015 // Every Scop fulfills these restrictions: 0016 // 0017 // * It is a single entry single exit region 0018 // 0019 // * Only affine linear bounds in the loops 0020 // 0021 // Every natural loop in a Scop must have a number of loop iterations that can 0022 // be described as an affine linear function in surrounding loop iterators or 0023 // parameters. (A parameter is a scalar that does not change its value during 0024 // execution of the Scop). 0025 // 0026 // * Only comparisons of affine linear expressions in conditions 0027 // 0028 // * All loops and conditions perfectly nested 0029 // 0030 // The control flow needs to be structured such that it could be written using 0031 // just 'for' and 'if' statements, without the need for any 'goto', 'break' or 0032 // 'continue'. 0033 // 0034 // * Side effect free functions call 0035 // 0036 // Only function calls and intrinsics that do not have side effects are allowed 0037 // (readnone). 0038 // 0039 // The Scop detection finds the largest Scops by checking if the largest 0040 // region is a Scop. If this is not the case, its canonical subregions are 0041 // checked until a region is a Scop. It is now tried to extend this Scop by 0042 // creating a larger non canonical region. 0043 // 0044 //===----------------------------------------------------------------------===// 0045 0046 #ifndef POLLY_SCOPDETECTION_H 0047 #define POLLY_SCOPDETECTION_H 0048 0049 #include "polly/ScopDetectionDiagnostic.h" 0050 #include "polly/Support/ScopHelper.h" 0051 #include "llvm/Analysis/AliasAnalysis.h" 0052 #include "llvm/Analysis/AliasSetTracker.h" 0053 #include "llvm/Analysis/RegionInfo.h" 0054 #include "llvm/Analysis/ScalarEvolutionExpressions.h" 0055 #include "llvm/Pass.h" 0056 #include <set> 0057 0058 namespace polly { 0059 using llvm::AAResults; 0060 using llvm::AliasSetTracker; 0061 using llvm::AnalysisInfoMixin; 0062 using llvm::AnalysisKey; 0063 using llvm::AnalysisUsage; 0064 using llvm::BatchAAResults; 0065 using llvm::BranchInst; 0066 using llvm::CallInst; 0067 using llvm::DenseMap; 0068 using llvm::DominatorTree; 0069 using llvm::Function; 0070 using llvm::FunctionAnalysisManager; 0071 using llvm::FunctionPass; 0072 using llvm::IntrinsicInst; 0073 using llvm::LoopInfo; 0074 using llvm::Module; 0075 using llvm::OptimizationRemarkEmitter; 0076 using llvm::PassInfoMixin; 0077 using llvm::PreservedAnalyses; 0078 using llvm::RegionInfo; 0079 using llvm::ScalarEvolution; 0080 using llvm::SCEVUnknown; 0081 using llvm::SetVector; 0082 using llvm::SmallSetVector; 0083 using llvm::SmallVectorImpl; 0084 using llvm::StringRef; 0085 using llvm::SwitchInst; 0086 0087 using ParamSetType = std::set<const SCEV *>; 0088 0089 // Description of the shape of an array. 0090 struct ArrayShape { 0091 // Base pointer identifying all accesses to this array. 0092 const SCEVUnknown *BasePointer; 0093 0094 // Sizes of each delinearized dimension. 0095 SmallVector<const SCEV *, 4> DelinearizedSizes; 0096 0097 ArrayShape(const SCEVUnknown *B) : BasePointer(B) {} 0098 }; 0099 0100 struct MemAcc { 0101 const Instruction *Insn; 0102 0103 // A pointer to the shape description of the array. 0104 std::shared_ptr<ArrayShape> Shape; 0105 0106 // Subscripts computed by delinearization. 0107 SmallVector<const SCEV *, 4> DelinearizedSubscripts; 0108 0109 MemAcc(const Instruction *I, std::shared_ptr<ArrayShape> S) 0110 : Insn(I), Shape(S) {} 0111 }; 0112 0113 using MapInsnToMemAcc = std::map<const Instruction *, MemAcc>; 0114 using PairInstSCEV = std::pair<const Instruction *, const SCEV *>; 0115 using AFs = std::vector<PairInstSCEV>; 0116 using BaseToAFs = std::map<const SCEVUnknown *, AFs>; 0117 using BaseToElSize = std::map<const SCEVUnknown *, const SCEV *>; 0118 0119 extern bool PollyTrackFailures; 0120 extern bool PollyDelinearize; 0121 extern bool PollyUseRuntimeAliasChecks; 0122 extern bool PollyProcessUnprofitable; 0123 extern bool PollyInvariantLoadHoisting; 0124 extern bool PollyAllowUnsignedOperations; 0125 extern bool PollyAllowFullFunction; 0126 0127 /// A function attribute which will cause Polly to skip the function 0128 extern StringRef PollySkipFnAttr; 0129 0130 //===----------------------------------------------------------------------===// 0131 /// Pass to detect the maximal static control parts (Scops) of a 0132 /// function. 0133 class ScopDetection { 0134 public: 0135 using RegionSet = SetVector<const Region *>; 0136 0137 // Remember the valid regions 0138 RegionSet ValidRegions; 0139 0140 /// Context variables for SCoP detection. 0141 struct DetectionContext { 0142 Region &CurRegion; // The region to check. 0143 BatchAAResults BAA; // The batched alias analysis results. 0144 AliasSetTracker AST; // The AliasSetTracker to hold the alias information. 0145 bool Verifying; // If we are in the verification phase? 0146 0147 /// If this flag is set, the SCoP must eventually be rejected, even with 0148 /// KeepGoing. 0149 bool IsInvalid = false; 0150 0151 /// Container to remember rejection reasons for this region. 0152 RejectLog Log; 0153 0154 /// Map a base pointer to all access functions accessing it. 0155 /// 0156 /// This map is indexed by the base pointer. Each element of the map 0157 /// is a list of memory accesses that reference this base pointer. 0158 BaseToAFs Accesses; 0159 0160 /// The set of base pointers with non-affine accesses. 0161 /// 0162 /// This set contains all base pointers and the locations where they are 0163 /// used for memory accesses that can not be detected as affine accesses. 0164 llvm::SetVector<std::pair<const SCEVUnknown *, Loop *>> NonAffineAccesses; 0165 BaseToElSize ElementSize; 0166 0167 /// The region has at least one load instruction. 0168 bool hasLoads = false; 0169 0170 /// The region has at least one store instruction. 0171 bool hasStores = false; 0172 0173 /// Flag to indicate the region has at least one unknown access. 0174 bool HasUnknownAccess = false; 0175 0176 /// The set of non-affine subregions in the region we analyze. 0177 RegionSet NonAffineSubRegionSet; 0178 0179 /// The set of loops contained in non-affine regions. 0180 BoxedLoopsSetTy BoxedLoopsSet; 0181 0182 /// Loads that need to be invariant during execution. 0183 InvariantLoadsSetTy RequiredILS; 0184 0185 /// Map to memory access description for the corresponding LLVM 0186 /// instructions. 0187 MapInsnToMemAcc InsnToMemAcc; 0188 0189 /// Initialize a DetectionContext from scratch. 0190 DetectionContext(Region &R, AAResults &AA, bool Verify) 0191 : CurRegion(R), BAA(AA), AST(BAA), Verifying(Verify), Log(&R) {} 0192 }; 0193 0194 /// Helper data structure to collect statistics about loop counts. 0195 struct LoopStats { 0196 int NumLoops; 0197 int MaxDepth; 0198 }; 0199 0200 int NextScopID = 0; 0201 int getNextID() { return NextScopID++; } 0202 0203 private: 0204 //===--------------------------------------------------------------------===// 0205 0206 /// Analyses used 0207 //@{ 0208 const DominatorTree &DT; 0209 ScalarEvolution &SE; 0210 LoopInfo &LI; 0211 RegionInfo &RI; 0212 AAResults &AA; 0213 //@} 0214 0215 /// Map to remember detection contexts for all regions. 0216 using DetectionContextMapTy = 0217 DenseMap<BBPair, std::unique_ptr<DetectionContext>>; 0218 DetectionContextMapTy DetectionContextMap; 0219 0220 /// Cache for the isErrorBlock function. 0221 DenseMap<std::tuple<const BasicBlock *, const Region *>, bool> 0222 ErrorBlockCache; 0223 0224 /// Remove cached results for @p R. 0225 void removeCachedResults(const Region &R); 0226 0227 /// Remove cached results for the children of @p R recursively. 0228 void removeCachedResultsRecursively(const Region &R); 0229 0230 /// Check if @p S0 and @p S1 do contain multiple possibly aliasing pointers. 0231 /// 0232 /// @param S0 A expression to check. 0233 /// @param S1 Another expression to check or nullptr. 0234 /// @param Scope The loop/scope the expressions are checked in. 0235 /// 0236 /// @returns True, if multiple possibly aliasing pointers are used in @p S0 0237 /// (and @p S1 if given). 0238 bool involvesMultiplePtrs(const SCEV *S0, const SCEV *S1, Loop *Scope) const; 0239 0240 /// Add the region @p AR as over approximated sub-region in @p Context. 0241 /// 0242 /// @param AR The non-affine subregion. 0243 /// @param Context The current detection context. 0244 /// 0245 /// @returns True if the subregion can be over approximated, false otherwise. 0246 bool addOverApproximatedRegion(Region *AR, DetectionContext &Context) const; 0247 0248 /// Find for a given base pointer terms that hint towards dimension 0249 /// sizes of a multi-dimensional array. 0250 /// 0251 /// @param Context The current detection context. 0252 /// @param BasePointer A base pointer indicating the virtual array we are 0253 /// interested in. 0254 SmallVector<const SCEV *, 4> 0255 getDelinearizationTerms(DetectionContext &Context, 0256 const SCEVUnknown *BasePointer) const; 0257 0258 /// Check if the dimension size of a delinearized array is valid. 0259 /// 0260 /// @param Context The current detection context. 0261 /// @param Sizes The sizes of the different array dimensions. 0262 /// @param BasePointer The base pointer we are interested in. 0263 /// @param Scope The location where @p BasePointer is being used. 0264 /// @returns True if one or more array sizes could be derived - meaning: we 0265 /// see this array as multi-dimensional. 0266 bool hasValidArraySizes(DetectionContext &Context, 0267 SmallVectorImpl<const SCEV *> &Sizes, 0268 const SCEVUnknown *BasePointer, Loop *Scope) const; 0269 0270 /// Derive access functions for a given base pointer. 0271 /// 0272 /// @param Context The current detection context. 0273 /// @param Sizes The sizes of the different array dimensions. 0274 /// @param BasePointer The base pointer of all the array for which to compute 0275 /// access functions. 0276 /// @param Shape The shape that describes the derived array sizes and 0277 /// which should be filled with newly computed access 0278 /// functions. 0279 /// @returns True if a set of affine access functions could be derived. 0280 bool computeAccessFunctions(DetectionContext &Context, 0281 const SCEVUnknown *BasePointer, 0282 std::shared_ptr<ArrayShape> Shape) const; 0283 0284 /// Check if all accesses to a given BasePointer are affine. 0285 /// 0286 /// @param Context The current detection context. 0287 /// @param BasePointer the base pointer we are interested in. 0288 /// @param Scope The location where @p BasePointer is being used. 0289 /// @param True if consistent (multi-dimensional) array accesses could be 0290 /// derived for this array. 0291 bool hasBaseAffineAccesses(DetectionContext &Context, 0292 const SCEVUnknown *BasePointer, Loop *Scope) const; 0293 0294 /// Delinearize all non affine memory accesses and return false when there 0295 /// exists a non affine memory access that cannot be delinearized. Return true 0296 /// when all array accesses are affine after delinearization. 0297 bool hasAffineMemoryAccesses(DetectionContext &Context) const; 0298 0299 /// Try to expand the region R. If R can be expanded return the expanded 0300 /// region, NULL otherwise. 0301 Region *expandRegion(Region &R); 0302 0303 /// Find the Scops in this region tree. 0304 /// 0305 /// @param The region tree to scan for scops. 0306 void findScops(Region &R); 0307 0308 /// Check if all basic block in the region are valid. 0309 /// 0310 /// @param Context The context of scop detection. 0311 bool allBlocksValid(DetectionContext &Context); 0312 0313 /// Check if a region has sufficient compute instructions. 0314 /// 0315 /// This function checks if a region has a non-trivial number of instructions 0316 /// in each loop. This can be used as an indicator whether a loop is worth 0317 /// optimizing. 0318 /// 0319 /// @param Context The context of scop detection. 0320 /// @param NumLoops The number of loops in the region. 0321 /// 0322 /// @return True if region is has sufficient compute instructions, 0323 /// false otherwise. 0324 bool hasSufficientCompute(DetectionContext &Context, 0325 int NumAffineLoops) const; 0326 0327 /// Check if the unique affine loop might be amendable to distribution. 0328 /// 0329 /// This function checks if the number of non-trivial blocks in the unique 0330 /// affine loop in Context.CurRegion is at least two, thus if the loop might 0331 /// be amendable to distribution. 0332 /// 0333 /// @param Context The context of scop detection. 0334 /// 0335 /// @return True only if the affine loop might be amendable to distributable. 0336 bool hasPossiblyDistributableLoop(DetectionContext &Context) const; 0337 0338 /// Check if a region is profitable to optimize. 0339 /// 0340 /// Regions that are unlikely to expose interesting optimization opportunities 0341 /// are called 'unprofitable' and may be skipped during scop detection. 0342 /// 0343 /// @param Context The context of scop detection. 0344 /// 0345 /// @return True if region is profitable to optimize, false otherwise. 0346 bool isProfitableRegion(DetectionContext &Context) const; 0347 0348 /// Check if a region is a Scop. 0349 /// 0350 /// @param Context The context of scop detection. 0351 /// 0352 /// @return If we short-circuited early to not waste time on known-invalid 0353 /// SCoPs. Use Context.IsInvalid to determine whether the region is a 0354 /// valid SCoP. 0355 bool isValidRegion(DetectionContext &Context); 0356 0357 /// Check if an intrinsic call can be part of a Scop. 0358 /// 0359 /// @param II The intrinsic call instruction to check. 0360 /// @param Context The current detection context. 0361 bool isValidIntrinsicInst(IntrinsicInst &II, DetectionContext &Context) const; 0362 0363 /// Check if a call instruction can be part of a Scop. 0364 /// 0365 /// @param CI The call instruction to check. 0366 /// @param Context The current detection context. 0367 bool isValidCallInst(CallInst &CI, DetectionContext &Context) const; 0368 0369 /// Check if the given loads could be invariant and can be hoisted. 0370 /// 0371 /// If true is returned the loads are added to the required invariant loads 0372 /// contained in the @p Context. 0373 /// 0374 /// @param RequiredILS The loads to check. 0375 /// @param Context The current detection context. 0376 /// 0377 /// @return True if all loads can be assumed invariant. 0378 bool onlyValidRequiredInvariantLoads(InvariantLoadsSetTy &RequiredILS, 0379 DetectionContext &Context) const; 0380 0381 /// Check if a value is invariant in the region Reg. 0382 /// 0383 /// @param Val Value to check for invariance. 0384 /// @param Reg The region to consider for the invariance of Val. 0385 /// @param Ctx The current detection context. 0386 /// 0387 /// @return True if the value represented by Val is invariant in the region 0388 /// identified by Reg. 0389 bool isInvariant(Value &Val, const Region &Reg, DetectionContext &Ctx) const; 0390 0391 /// Check if the memory access caused by @p Inst is valid. 0392 /// 0393 /// @param Inst The access instruction. 0394 /// @param AF The access function. 0395 /// @param BP The access base pointer. 0396 /// @param Context The current detection context. 0397 bool isValidAccess(Instruction *Inst, const SCEV *AF, const SCEVUnknown *BP, 0398 DetectionContext &Context) const; 0399 0400 /// Check if a memory access can be part of a Scop. 0401 /// 0402 /// @param Inst The instruction accessing the memory. 0403 /// @param Context The context of scop detection. 0404 bool isValidMemoryAccess(MemAccInst Inst, DetectionContext &Context) const; 0405 0406 /// Check if an instruction can be part of a Scop. 0407 /// 0408 /// @param Inst The instruction to check. 0409 /// @param Context The context of scop detection. 0410 bool isValidInstruction(Instruction &Inst, DetectionContext &Context); 0411 0412 /// Check if the switch @p SI with condition @p Condition is valid. 0413 /// 0414 /// @param BB The block to check. 0415 /// @param SI The switch to check. 0416 /// @param Condition The switch condition. 0417 /// @param IsLoopBranch Flag to indicate the branch is a loop exit/latch. 0418 /// @param Context The context of scop detection. 0419 bool isValidSwitch(BasicBlock &BB, SwitchInst *SI, Value *Condition, 0420 bool IsLoopBranch, DetectionContext &Context) const; 0421 0422 /// Check if the branch @p BI with condition @p Condition is valid. 0423 /// 0424 /// @param BB The block to check. 0425 /// @param BI The branch to check. 0426 /// @param Condition The branch condition. 0427 /// @param IsLoopBranch Flag to indicate the branch is a loop exit/latch. 0428 /// @param Context The context of scop detection. 0429 bool isValidBranch(BasicBlock &BB, BranchInst *BI, Value *Condition, 0430 bool IsLoopBranch, DetectionContext &Context); 0431 0432 /// Check if the SCEV @p S is affine in the current @p Context. 0433 /// 0434 /// This will also use a heuristic to decide if we want to require loads to be 0435 /// invariant to make the expression affine or if we want to treat is as 0436 /// non-affine. 0437 /// 0438 /// @param S The expression to be checked. 0439 /// @param Scope The loop nest in which @p S is used. 0440 /// @param Context The context of scop detection. 0441 bool isAffine(const SCEV *S, Loop *Scope, DetectionContext &Context) const; 0442 0443 /// Check if the control flow in a basic block is valid. 0444 /// 0445 /// This function checks if a certain basic block is terminated by a 0446 /// Terminator instruction we can handle or, if this is not the case, 0447 /// registers this basic block as the start of a non-affine region. 0448 /// 0449 /// This function optionally allows unreachable statements. 0450 /// 0451 /// @param BB The BB to check the control flow. 0452 /// @param IsLoopBranch Flag to indicate the branch is a loop exit/latch. 0453 /// @param AllowUnreachable Allow unreachable statements. 0454 /// @param Context The context of scop detection. 0455 bool isValidCFG(BasicBlock &BB, bool IsLoopBranch, bool AllowUnreachable, 0456 DetectionContext &Context); 0457 0458 /// Is a loop valid with respect to a given region. 0459 /// 0460 /// @param L The loop to check. 0461 /// @param Context The context of scop detection. 0462 bool isValidLoop(Loop *L, DetectionContext &Context); 0463 0464 /// Count the number of loops and the maximal loop depth in @p L. 0465 /// 0466 /// @param L The loop to check. 0467 /// @param SE The scalar evolution analysis. 0468 /// @param MinProfitableTrips The minimum number of trip counts from which 0469 /// a loop is assumed to be profitable and 0470 /// consequently is counted. 0471 /// returns A tuple of number of loops and their maximal depth. 0472 static ScopDetection::LoopStats 0473 countBeneficialSubLoops(Loop *L, ScalarEvolution &SE, 0474 unsigned MinProfitableTrips); 0475 0476 /// Check if the function @p F is marked as invalid. 0477 /// 0478 /// @note An OpenMP subfunction will be marked as invalid. 0479 static bool isValidFunction(Function &F); 0480 0481 /// Can ISL compute the trip count of a loop. 0482 /// 0483 /// @param L The loop to check. 0484 /// @param Context The context of scop detection. 0485 /// 0486 /// @return True if ISL can compute the trip count of the loop. 0487 bool canUseISLTripCount(Loop *L, DetectionContext &Context); 0488 0489 /// Print the locations of all detected scops. 0490 void printLocations(Function &F); 0491 0492 /// Check if a region is reducible or not. 0493 /// 0494 /// @param Region The region to check. 0495 /// @param DbgLoc Parameter to save the location of instruction that 0496 /// causes irregular control flow if the region is irreducible. 0497 /// 0498 /// @return True if R is reducible, false otherwise. 0499 bool isReducibleRegion(Region &R, DebugLoc &DbgLoc) const; 0500 0501 /// Track diagnostics for invalid scops. 0502 /// 0503 /// @param Context The context of scop detection. 0504 /// @param Assert Throw an assert in verify mode or not. 0505 /// @param Args Argument list that gets passed to the constructor of RR. 0506 template <class RR, typename... Args> 0507 inline bool invalid(DetectionContext &Context, bool Assert, 0508 Args &&...Arguments) const; 0509 0510 public: 0511 ScopDetection(const DominatorTree &DT, ScalarEvolution &SE, LoopInfo &LI, 0512 RegionInfo &RI, AAResults &AA, OptimizationRemarkEmitter &ORE); 0513 0514 void detect(Function &F); 0515 0516 /// Get the RegionInfo stored in this pass. 0517 /// 0518 /// This was added to give the DOT printer easy access to this information. 0519 RegionInfo *getRI() const { return &RI; } 0520 0521 /// Get the LoopInfo stored in this pass. 0522 LoopInfo *getLI() const { return &LI; } 0523 0524 /// Is the region is the maximum region of a Scop? 0525 /// 0526 /// @param R The Region to test if it is maximum. 0527 /// @param Verify Rerun the scop detection to verify SCoP was not invalidated 0528 /// meanwhile. Do not use if the region's DetectionContect is 0529 /// referenced by a Scop that is still to be processed. 0530 /// 0531 /// @return Return true if R is the maximum Region in a Scop, false otherwise. 0532 bool isMaxRegionInScop(const Region &R, bool Verify = true); 0533 0534 /// Return the detection context for @p R, nullptr if @p R was invalid. 0535 DetectionContext *getDetectionContext(const Region *R) const; 0536 0537 /// Return the set of rejection causes for @p R. 0538 const RejectLog *lookupRejectionLog(const Region *R) const; 0539 0540 /// Get a message why a region is invalid 0541 /// 0542 /// @param R The region for which we get the error message 0543 /// 0544 /// @return The error or "" if no error appeared. 0545 std::string regionIsInvalidBecause(const Region *R) const; 0546 0547 /// @name Maximum Region In Scops Iterators 0548 /// 0549 /// These iterators iterator over all maximum region in Scops of this 0550 /// function. 0551 //@{ 0552 using iterator = RegionSet::iterator; 0553 using const_iterator = RegionSet::const_iterator; 0554 0555 iterator begin() { return ValidRegions.begin(); } 0556 iterator end() { return ValidRegions.end(); } 0557 0558 const_iterator begin() const { return ValidRegions.begin(); } 0559 const_iterator end() const { return ValidRegions.end(); } 0560 //@} 0561 0562 /// Emit rejection remarks for all rejected regions. 0563 /// 0564 /// @param F The function to emit remarks for. 0565 void emitMissedRemarks(const Function &F); 0566 0567 /// Mark the function as invalid so we will not extract any scop from 0568 /// the function. 0569 /// 0570 /// @param F The function to mark as invalid. 0571 static void markFunctionAsInvalid(Function *F); 0572 0573 /// Verify if all valid Regions in this Function are still valid 0574 /// after some transformations. 0575 void verifyAnalysis(); 0576 0577 /// Verify if R is still a valid part of Scop after some transformations. 0578 /// 0579 /// @param R The Region to verify. 0580 void verifyRegion(const Region &R); 0581 0582 /// Count the number of loops and the maximal loop depth in @p R. 0583 /// 0584 /// @param R The region to check 0585 /// @param SE The scalar evolution analysis. 0586 /// @param MinProfitableTrips The minimum number of trip counts from which 0587 /// a loop is assumed to be profitable and 0588 /// consequently is counted. 0589 /// returns A tuple of number of loops and their maximal depth. 0590 static ScopDetection::LoopStats 0591 countBeneficialLoops(Region *R, ScalarEvolution &SE, LoopInfo &LI, 0592 unsigned MinProfitableTrips); 0593 0594 /// Check if the block is a error block. 0595 /// 0596 /// A error block is currently any block that fulfills at least one of 0597 /// the following conditions: 0598 /// 0599 /// - It is terminated by an unreachable instruction 0600 /// - It contains a call to a non-pure function that is not immediately 0601 /// dominated by a loop header and that does not dominate the region exit. 0602 /// This is a heuristic to pick only error blocks that are conditionally 0603 /// executed and can be assumed to be not executed at all without the 0604 /// domains being available. 0605 /// 0606 /// @param BB The block to check. 0607 /// @param R The analyzed region. 0608 /// 0609 /// @return True if the block is a error block, false otherwise. 0610 bool isErrorBlock(llvm::BasicBlock &BB, const llvm::Region &R); 0611 0612 private: 0613 /// OptimizationRemarkEmitter object used to emit diagnostic remarks 0614 OptimizationRemarkEmitter &ORE; 0615 }; 0616 0617 struct ScopAnalysis : AnalysisInfoMixin<ScopAnalysis> { 0618 static AnalysisKey Key; 0619 0620 using Result = ScopDetection; 0621 0622 ScopAnalysis(); 0623 0624 Result run(Function &F, FunctionAnalysisManager &FAM); 0625 }; 0626 0627 struct ScopAnalysisPrinterPass final : PassInfoMixin<ScopAnalysisPrinterPass> { 0628 ScopAnalysisPrinterPass(raw_ostream &OS) : OS(OS) {} 0629 0630 PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); 0631 0632 raw_ostream &OS; 0633 }; 0634 0635 class ScopDetectionWrapperPass final : public FunctionPass { 0636 std::unique_ptr<ScopDetection> Result; 0637 0638 public: 0639 ScopDetectionWrapperPass(); 0640 0641 /// @name FunctionPass interface 0642 ///@{ 0643 static char ID; 0644 void getAnalysisUsage(AnalysisUsage &AU) const override; 0645 void releaseMemory() override; 0646 bool runOnFunction(Function &F) override; 0647 void print(raw_ostream &OS, const Module *M = nullptr) const override; 0648 ///@} 0649 0650 ScopDetection &getSD() const { return *Result; } 0651 }; 0652 0653 llvm::Pass *createScopDetectionPrinterLegacyPass(llvm::raw_ostream &OS); 0654 } // namespace polly 0655 0656 namespace llvm { 0657 void initializeScopDetectionWrapperPassPass(llvm::PassRegistry &); 0658 void initializeScopDetectionPrinterLegacyPassPass(llvm::PassRegistry &); 0659 } // namespace llvm 0660 0661 #endif // POLLY_SCOPDETECTION_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|