Back to home page

EIC code displayed by LXR

 
 

    


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