Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:48:20

0001 //===- polly/ScopBuilder.h --------------------------------------*- 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 // Create a polyhedral description for a static control flow region.
0010 //
0011 // The pass creates a polyhedral description of the Scops detected by the SCoP
0012 // detection derived from their LLVM-IR code.
0013 //
0014 //===----------------------------------------------------------------------===//
0015 
0016 #ifndef POLLY_SCOPBUILDER_H
0017 #define POLLY_SCOPBUILDER_H
0018 
0019 #include "polly/ScopInfo.h"
0020 #include "polly/Support/ScopHelper.h"
0021 #include "llvm/ADT/ArrayRef.h"
0022 #include "llvm/ADT/SetVector.h"
0023 
0024 namespace polly {
0025 using llvm::SmallSetVector;
0026 
0027 class ScopDetection;
0028 
0029 /// Command line switch whether to model read-only accesses.
0030 extern bool ModelReadOnlyScalars;
0031 
0032 /// Build the Polly IR (Scop and ScopStmt) on a Region.
0033 class ScopBuilder final {
0034 
0035   /// The AAResults to build AliasSetTracker.
0036   AAResults &AA;
0037 
0038   /// Target data for element size computing.
0039   const DataLayout &DL;
0040 
0041   /// DominatorTree to reason about guaranteed execution.
0042   DominatorTree &DT;
0043 
0044   /// LoopInfo for information about loops.
0045   LoopInfo &LI;
0046 
0047   /// Valid Regions for Scop
0048   ScopDetection &SD;
0049 
0050   /// The ScalarEvolution to help building Scop.
0051   ScalarEvolution &SE;
0052 
0053   /// An optimization diagnostic interface to add optimization remarks.
0054   OptimizationRemarkEmitter &ORE;
0055 
0056   /// Set of instructions that might read any memory location.
0057   SmallVector<std::pair<ScopStmt *, Instruction *>, 16> GlobalReads;
0058 
0059   /// Set of all accessed array base pointers.
0060   SmallSetVector<Value *, 16> ArrayBasePointers;
0061 
0062   // The Scop
0063   std::unique_ptr<Scop> scop;
0064 
0065   /// Collection to hold taken assumptions.
0066   ///
0067   /// There are two reasons why we want to record assumptions first before we
0068   /// add them to the assumed/invalid context:
0069   ///   1) If the SCoP is not profitable or otherwise invalid without the
0070   ///      assumed/invalid context we do not have to compute it.
0071   ///   2) Information about the context are gathered rather late in the SCoP
0072   ///      construction (basically after we know all parameters), thus the user
0073   ///      might see overly complicated assumptions to be taken while they will
0074   ///      only be simplified later on.
0075   RecordedAssumptionsTy RecordedAssumptions;
0076 
0077   // Build the SCoP for Region @p R.
0078   void buildScop(Region &R, AssumptionCache &AC);
0079 
0080   /// Adjust the dimensions of @p Dom that was constructed for @p OldL
0081   ///        to be compatible to domains constructed for loop @p NewL.
0082   ///
0083   /// This function assumes @p NewL and @p OldL are equal or there is a CFG
0084   /// edge from @p OldL to @p NewL.
0085   isl::set adjustDomainDimensions(isl::set Dom, Loop *OldL, Loop *NewL);
0086 
0087   /// Compute the domain for each basic block in @p R.
0088   ///
0089   /// @param R                The region we currently traverse.
0090   /// @param InvalidDomainMap BB to InvalidDomain map for the BB of current
0091   ///                         region.
0092   ///
0093   /// @returns True if there was no problem and false otherwise.
0094   bool buildDomains(Region *R,
0095                     DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
0096 
0097   /// Compute the branching constraints for each basic block in @p R.
0098   ///
0099   /// @param R                The region we currently build branching conditions
0100   ///                         for.
0101   /// @param InvalidDomainMap BB to InvalidDomain map for the BB of current
0102   ///                         region.
0103   ///
0104   /// @returns True if there was no problem and false otherwise.
0105   bool buildDomainsWithBranchConstraints(
0106       Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
0107 
0108   /// Build the conditions sets for the terminator @p TI in the @p Domain.
0109   ///
0110   /// This will fill @p ConditionSets with the conditions under which control
0111   /// will be moved from @p TI to its successors. Hence, @p ConditionSets will
0112   /// have as many elements as @p TI has successors.
0113   bool buildConditionSets(BasicBlock *BB, Instruction *TI, Loop *L,
0114                           __isl_keep isl_set *Domain,
0115                           DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
0116                           SmallVectorImpl<__isl_give isl_set *> &ConditionSets);
0117 
0118   /// Build the conditions sets for the branch condition @p Condition in
0119   /// the @p Domain.
0120   ///
0121   /// This will fill @p ConditionSets with the conditions under which control
0122   /// will be moved from @p TI to its successors. Hence, @p ConditionSets will
0123   /// have as many elements as @p TI has successors. If @p TI is nullptr the
0124   /// context under which @p Condition is true/false will be returned as the
0125   /// new elements of @p ConditionSets.
0126   bool buildConditionSets(BasicBlock *BB, Value *Condition, Instruction *TI,
0127                           Loop *L, __isl_keep isl_set *Domain,
0128                           DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
0129                           SmallVectorImpl<__isl_give isl_set *> &ConditionSets);
0130 
0131   /// Build the conditions sets for the switch @p SI in the @p Domain.
0132   ///
0133   /// This will fill @p ConditionSets with the conditions under which control
0134   /// will be moved from @p SI to its successors. Hence, @p ConditionSets will
0135   /// have as many elements as @p SI has successors.
0136   bool buildConditionSets(BasicBlock *BB, SwitchInst *SI, Loop *L,
0137                           __isl_keep isl_set *Domain,
0138                           DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
0139                           SmallVectorImpl<__isl_give isl_set *> &ConditionSets);
0140 
0141   /// Build condition sets for unsigned ICmpInst(s).
0142   /// Special handling is required for unsigned operands to ensure that if
0143   /// MSB (aka the Sign bit) is set for an operands in an unsigned ICmpInst
0144   /// it should wrap around.
0145   ///
0146   /// @param IsStrictUpperBound holds information on the predicate relation
0147   /// between TestVal and UpperBound, i.e,
0148   /// TestVal < UpperBound  OR  TestVal <= UpperBound
0149   __isl_give isl_set *buildUnsignedConditionSets(
0150       BasicBlock *BB, Value *Condition, __isl_keep isl_set *Domain,
0151       const SCEV *SCEV_TestVal, const SCEV *SCEV_UpperBound,
0152       DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
0153       bool IsStrictUpperBound);
0154 
0155   /// Propagate the domain constraints through the region @p R.
0156   ///
0157   /// @param R                The region we currently build branching
0158   /// conditions for.
0159   /// @param InvalidDomainMap BB to InvalidDomain map for the BB of current
0160   ///                         region.
0161   ///
0162   /// @returns True if there was no problem and false otherwise.
0163   bool propagateDomainConstraints(
0164       Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
0165 
0166   /// Propagate domains that are known due to graph properties.
0167   ///
0168   /// As a CFG is mostly structured we use the graph properties to propagate
0169   /// domains without the need to compute all path conditions. In particular,
0170   /// if a block A dominates a block B and B post-dominates A we know that the
0171   /// domain of B is a superset of the domain of A. As we do not have
0172   /// post-dominator information available here we use the less precise region
0173   /// information. Given a region R, we know that the exit is always executed
0174   /// if the entry was executed, thus the domain of the exit is a superset of
0175   /// the domain of the entry. In case the exit can only be reached from
0176   /// within the region the domains are in fact equal. This function will use
0177   /// this property to avoid the generation of condition constraints that
0178   /// determine when a branch is taken. If @p BB is a region entry block we
0179   /// will propagate its domain to the region exit block. Additionally, we put
0180   /// the region exit block in the @p FinishedExitBlocks set so we can later
0181   /// skip edges from within the region to that block.
0182   ///
0183   /// @param BB                 The block for which the domain is currently
0184   ///                           propagated.
0185   /// @param BBLoop             The innermost affine loop surrounding @p BB.
0186   /// @param FinishedExitBlocks Set of region exits the domain was set for.
0187   /// @param InvalidDomainMap   BB to InvalidDomain map for the BB of current
0188   ///                           region.
0189   void propagateDomainConstraintsToRegionExit(
0190       BasicBlock *BB, Loop *BBLoop,
0191       SmallPtrSetImpl<BasicBlock *> &FinishedExitBlocks,
0192       DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
0193 
0194   /// Propagate invalid domains of statements through @p R.
0195   ///
0196   /// This method will propagate invalid statement domains through @p R and at
0197   /// the same time add error block domains to them. Additionally, the domains
0198   /// of error statements and those only reachable via error statements will
0199   /// be replaced by an empty set. Later those will be removed completely.
0200   ///
0201   /// @param R                The currently traversed region.
0202   /// @param InvalidDomainMap BB to InvalidDomain map for the BB of current
0203   ///                         region.
0204   //
0205   /// @returns True if there was no problem and false otherwise.
0206   bool propagateInvalidStmtDomains(
0207       Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
0208 
0209   /// Compute the union of predecessor domains for @p BB.
0210   ///
0211   /// To compute the union of all domains of predecessors of @p BB this
0212   /// function applies similar reasoning on the CFG structure as described for
0213   ///   @see propagateDomainConstraintsToRegionExit
0214   ///
0215   /// @param BB     The block for which the predecessor domains are collected.
0216   /// @param Domain The domain under which BB is executed.
0217   ///
0218   /// @returns The domain under which @p BB is executed.
0219   isl::set getPredecessorDomainConstraints(BasicBlock *BB, isl::set Domain);
0220 
0221   /// Add loop carried constraints to the header block of the loop @p L.
0222   ///
0223   /// @param L                The loop to process.
0224   /// @param InvalidDomainMap BB to InvalidDomain map for the BB of current
0225   ///                         region.
0226   ///
0227   /// @returns True if there was no problem and false otherwise.
0228   bool addLoopBoundsToHeaderDomain(
0229       Loop *L, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
0230 
0231   /// Compute the isl representation for the SCEV @p E in this BB.
0232   ///
0233   /// @param BB               The BB for which isl representation is to be
0234   /// computed.
0235   /// @param InvalidDomainMap A map of BB to their invalid domains.
0236   /// @param E                The SCEV that should be translated.
0237   /// @param NonNegative      Flag to indicate the @p E has to be
0238   /// non-negative.
0239   ///
0240   /// Note that this function will also adjust the invalid context
0241   /// accordingly.
0242   __isl_give isl_pw_aff *
0243   getPwAff(BasicBlock *BB, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
0244            const SCEV *E, bool NonNegative = false);
0245 
0246   /// Create equivalence classes for required invariant accesses.
0247   ///
0248   /// These classes will consolidate multiple required invariant loads from the
0249   /// same address in order to keep the number of dimensions in the SCoP
0250   /// description small. For each such class equivalence class only one
0251   /// representing element, hence one required invariant load, will be chosen
0252   /// and modeled as parameter. The method
0253   /// Scop::getRepresentingInvariantLoadSCEV() will replace each element from an
0254   /// equivalence class with the representing element that is modeled. As a
0255   /// consequence Scop::getIdForParam() will only return an id for the
0256   /// representing element of each equivalence class, thus for each required
0257   /// invariant location.
0258   void buildInvariantEquivalenceClasses();
0259 
0260   /// Try to build a multi-dimensional fixed sized MemoryAccess from the
0261   /// Load/Store instruction.
0262   ///
0263   /// @param Inst       The Load/Store instruction that access the memory
0264   /// @param Stmt       The parent statement of the instruction
0265   ///
0266   /// @returns True if the access could be built, False otherwise.
0267   bool buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt);
0268 
0269   /// Try to build a multi-dimensional parametric sized MemoryAccess.
0270   ///        from the Load/Store instruction.
0271   ///
0272   /// @param Inst       The Load/Store instruction that access the memory
0273   /// @param Stmt       The parent statement of the instruction
0274   ///
0275   /// @returns True if the access could be built, False otherwise.
0276   bool buildAccessMultiDimParam(MemAccInst Inst, ScopStmt *Stmt);
0277 
0278   /// Try to build a MemoryAccess for a memory intrinsic.
0279   ///
0280   /// @param Inst       The instruction that access the memory
0281   /// @param Stmt       The parent statement of the instruction
0282   ///
0283   /// @returns True if the access could be built, False otherwise.
0284   bool buildAccessMemIntrinsic(MemAccInst Inst, ScopStmt *Stmt);
0285 
0286   /// Try to build a MemoryAccess for a call instruction.
0287   ///
0288   /// @param Inst       The call instruction that access the memory
0289   /// @param Stmt       The parent statement of the instruction
0290   ///
0291   /// @returns True if the access could be built, False otherwise.
0292   bool buildAccessCallInst(MemAccInst Inst, ScopStmt *Stmt);
0293 
0294   /// Build a single-dimensional parametric sized MemoryAccess
0295   ///        from the Load/Store instruction.
0296   ///
0297   /// @param Inst       The Load/Store instruction that access the memory
0298   /// @param Stmt       The parent statement of the instruction
0299   ///
0300   /// @returns True if the access could be built, False otherwise.
0301   bool buildAccessSingleDim(MemAccInst Inst, ScopStmt *Stmt);
0302 
0303   /// Finalize all access relations.
0304   ///
0305   /// When building up access relations, temporary access relations that
0306   /// correctly represent each individual access are constructed. However, these
0307   /// access relations can be inconsistent or non-optimal when looking at the
0308   /// set of accesses as a whole. This function finalizes the memory accesses
0309   /// and constructs a globally consistent state.
0310   void finalizeAccesses();
0311 
0312   /// Update access dimensionalities.
0313   ///
0314   /// When detecting memory accesses different accesses to the same array may
0315   /// have built with different dimensionality, as outer zero-values dimensions
0316   /// may not have been recognized as separate dimensions. This function goes
0317   /// again over all memory accesses and updates their dimensionality to match
0318   /// the dimensionality of the underlying ScopArrayInfo object.
0319   void updateAccessDimensionality();
0320 
0321   /// Fold size constants to the right.
0322   ///
0323   /// In case all memory accesses in a given dimension are multiplied with a
0324   /// common constant, we can remove this constant from the individual access
0325   /// functions and move it to the size of the memory access. We do this as this
0326   /// increases the size of the innermost dimension, consequently widens the
0327   /// valid range the array subscript in this dimension can evaluate to, and
0328   /// as a result increases the likelihood that our delinearization is
0329   /// correct.
0330   ///
0331   /// Example:
0332   ///
0333   ///    A[][n]
0334   ///    S[i,j] -> A[2i][2j+1]
0335   ///    S[i,j] -> A[2i][2j]
0336   ///
0337   ///    =>
0338   ///
0339   ///    A[][2n]
0340   ///    S[i,j] -> A[i][2j+1]
0341   ///    S[i,j] -> A[i][2j]
0342   ///
0343   /// Constants in outer dimensions can arise when the elements of a parametric
0344   /// multi-dimensional array are not elementary data types, but e.g.,
0345   /// structures.
0346   void foldSizeConstantsToRight();
0347 
0348   /// Fold memory accesses to handle parametric offset.
0349   ///
0350   /// As a post-processing step, we 'fold' memory accesses to parametric
0351   /// offsets in the access functions. @see MemoryAccess::foldAccess for
0352   /// details.
0353   void foldAccessRelations();
0354 
0355   /// Assume that all memory accesses are within bounds.
0356   ///
0357   /// After we have built a model of all memory accesses, we need to assume
0358   /// that the model we built matches reality -- aka. all modeled memory
0359   /// accesses always remain within bounds. We do this as last step, after
0360   /// all memory accesses have been modeled and canonicalized.
0361   void assumeNoOutOfBounds();
0362 
0363   /// Build the alias checks for this SCoP.
0364   bool buildAliasChecks();
0365 
0366   /// A vector of memory accesses that belong to an alias group.
0367   using AliasGroupTy = SmallVector<MemoryAccess *, 4>;
0368 
0369   /// A vector of alias groups.
0370   using AliasGroupVectorTy = SmallVector<AliasGroupTy, 4>;
0371 
0372   /// Build a given alias group and its access data.
0373   ///
0374   /// @param AliasGroup     The alias group to build.
0375   /// @param HasWriteAccess A set of arrays through which memory is not only
0376   ///                       read, but also written.
0377   //
0378   /// @returns True if __no__ error occurred, false otherwise.
0379   bool buildAliasGroup(AliasGroupTy &AliasGroup,
0380                        DenseSet<const ScopArrayInfo *> HasWriteAccess);
0381 
0382   /// Build all alias groups for this SCoP.
0383   ///
0384   /// @returns True if __no__ error occurred, false otherwise.
0385   bool buildAliasGroups();
0386 
0387   /// Build alias groups for all memory accesses in the Scop.
0388   ///
0389   /// Using the alias analysis and an alias set tracker we build alias sets
0390   /// for all memory accesses inside the Scop. For each alias set we then map
0391   /// the aliasing pointers back to the memory accesses we know, thus obtain
0392   /// groups of memory accesses which might alias. We also collect the set of
0393   /// arrays through which memory is written.
0394   ///
0395   /// @returns A pair consistent of a vector of alias groups and a set of arrays
0396   ///          through which memory is written.
0397   std::tuple<AliasGroupVectorTy, DenseSet<const ScopArrayInfo *>>
0398   buildAliasGroupsForAccesses();
0399 
0400   ///  Split alias groups by iteration domains.
0401   ///
0402   ///  We split each group based on the domains of the minimal/maximal accesses.
0403   ///  That means two minimal/maximal accesses are only in a group if their
0404   ///  access domains intersect. Otherwise, they are in different groups.
0405   ///
0406   ///  @param AliasGroups The alias groups to split
0407   void splitAliasGroupsByDomain(AliasGroupVectorTy &AliasGroups);
0408 
0409   /// Build an instance of MemoryAccess from the Load/Store instruction.
0410   ///
0411   /// @param Inst       The Load/Store instruction that access the memory
0412   /// @param Stmt       The parent statement of the instruction
0413   void buildMemoryAccess(MemAccInst Inst, ScopStmt *Stmt);
0414 
0415   /// Analyze and extract the cross-BB scalar dependences (or, dataflow
0416   /// dependencies) of an instruction.
0417   ///
0418   /// @param UserStmt The statement @p Inst resides in.
0419   /// @param Inst     The instruction to be analyzed.
0420   void buildScalarDependences(ScopStmt *UserStmt, Instruction *Inst);
0421 
0422   /// Build the escaping dependences for @p Inst.
0423   ///
0424   /// Search for uses of the llvm::Value defined by @p Inst that are not
0425   /// within the SCoP. If there is such use, add a SCALAR WRITE such that
0426   /// it is available after the SCoP as escaping value.
0427   ///
0428   /// @param Inst The instruction to be analyzed.
0429   void buildEscapingDependences(Instruction *Inst);
0430 
0431   /// Create MemoryAccesses for the given PHI node in the given region.
0432   ///
0433   /// @param PHIStmt            The statement @p PHI resides in.
0434   /// @param PHI                The PHI node to be handled
0435   /// @param NonAffineSubRegion The non affine sub-region @p PHI is in.
0436   /// @param IsExitBlock        Flag to indicate that @p PHI is in the exit BB.
0437   void buildPHIAccesses(ScopStmt *PHIStmt, PHINode *PHI,
0438                         Region *NonAffineSubRegion, bool IsExitBlock = false);
0439 
0440   /// Build the access functions for the subregion @p SR.
0441   void buildAccessFunctions();
0442 
0443   /// Should an instruction be modeled in a ScopStmt.
0444   ///
0445   /// @param Inst The instruction to check.
0446   /// @param L    The loop in which context the instruction is looked at.
0447   ///
0448   /// @returns True if the instruction should be modeled.
0449   bool shouldModelInst(Instruction *Inst, Loop *L);
0450 
0451   /// Create one or more ScopStmts for @p BB.
0452   ///
0453   /// Consecutive instructions are associated to the same statement until a
0454   /// separator is found.
0455   void buildSequentialBlockStmts(BasicBlock *BB, bool SplitOnStore = false);
0456 
0457   /// Create one or more ScopStmts for @p BB using equivalence classes.
0458   ///
0459   /// Instructions of a basic block that belong to the same equivalence class
0460   /// are added to the same statement.
0461   void buildEqivClassBlockStmts(BasicBlock *BB);
0462 
0463   /// Create ScopStmt for all BBs and non-affine subregions of @p SR.
0464   ///
0465   /// @param SR A subregion of @p R.
0466   ///
0467   /// Some of the statements might be optimized away later when they do not
0468   /// access any memory and thus have no effect.
0469   void buildStmts(Region &SR);
0470 
0471   /// Build the access functions for the statement @p Stmt in or represented by
0472   /// @p BB.
0473   ///
0474   /// @param Stmt               Statement to add MemoryAccesses to.
0475   /// @param BB                 A basic block in @p R.
0476   /// @param NonAffineSubRegion The non affine sub-region @p BB is in.
0477   void buildAccessFunctions(ScopStmt *Stmt, BasicBlock &BB,
0478                             Region *NonAffineSubRegion = nullptr);
0479 
0480   /// Create a new MemoryAccess object and add it to #AccFuncMap.
0481   ///
0482   /// @param Stmt        The statement where the access takes place.
0483   /// @param Inst        The instruction doing the access. It is not necessarily
0484   ///                    inside @p BB.
0485   /// @param AccType     The kind of access.
0486   /// @param BaseAddress The accessed array's base address.
0487   /// @param ElemType    The type of the accessed array elements.
0488   /// @param Affine      Whether all subscripts are affine expressions.
0489   /// @param AccessValue Value read or written.
0490   /// @param Subscripts  Access subscripts per dimension.
0491   /// @param Sizes       The array dimension's sizes.
0492   /// @param Kind        The kind of memory accessed.
0493   ///
0494   /// @return The created MemoryAccess, or nullptr if the access is not within
0495   ///         the SCoP.
0496   MemoryAccess *addMemoryAccess(ScopStmt *Stmt, Instruction *Inst,
0497                                 MemoryAccess::AccessType AccType,
0498                                 Value *BaseAddress, Type *ElemType, bool Affine,
0499                                 Value *AccessValue,
0500                                 ArrayRef<const SCEV *> Subscripts,
0501                                 ArrayRef<const SCEV *> Sizes, MemoryKind Kind);
0502 
0503   /// Create a MemoryAccess that represents either a LoadInst or
0504   /// StoreInst.
0505   ///
0506   /// @param Stmt        The statement to add the MemoryAccess to.
0507   /// @param MemAccInst  The LoadInst or StoreInst.
0508   /// @param AccType     The kind of access.
0509   /// @param BaseAddress The accessed array's base address.
0510   /// @param ElemType    The type of the accessed array elements.
0511   /// @param IsAffine    Whether all subscripts are affine expressions.
0512   /// @param Subscripts  Access subscripts per dimension.
0513   /// @param Sizes       The array dimension's sizes.
0514   /// @param AccessValue Value read or written.
0515   ///
0516   /// @see MemoryKind
0517   void addArrayAccess(ScopStmt *Stmt, MemAccInst MemAccInst,
0518                       MemoryAccess::AccessType AccType, Value *BaseAddress,
0519                       Type *ElemType, bool IsAffine,
0520                       ArrayRef<const SCEV *> Subscripts,
0521                       ArrayRef<const SCEV *> Sizes, Value *AccessValue);
0522 
0523   /// Create a MemoryAccess for writing an llvm::Instruction.
0524   ///
0525   /// The access will be created at the position of @p Inst.
0526   ///
0527   /// @param Inst The instruction to be written.
0528   ///
0529   /// @see ensureValueRead()
0530   /// @see MemoryKind
0531   void ensureValueWrite(Instruction *Inst);
0532 
0533   /// Ensure an llvm::Value is available in the BB's statement, creating a
0534   /// MemoryAccess for reloading it if necessary.
0535   ///
0536   /// @param V        The value expected to be loaded.
0537   /// @param UserStmt Where to reload the value.
0538   ///
0539   /// @see ensureValueStore()
0540   /// @see MemoryKind
0541   void ensureValueRead(Value *V, ScopStmt *UserStmt);
0542 
0543   /// Create a write MemoryAccess for the incoming block of a phi node.
0544   ///
0545   /// Each of the incoming blocks write their incoming value to be picked in the
0546   /// phi's block.
0547   ///
0548   /// @param PHI           PHINode under consideration.
0549   /// @param IncomingStmt  The statement to add the MemoryAccess to.
0550   /// @param IncomingBlock Some predecessor block.
0551   /// @param IncomingValue @p PHI's value when coming from @p IncomingBlock.
0552   /// @param IsExitBlock   When true, uses the .s2a alloca instead of the
0553   ///                      .phiops one. Required for values escaping through a
0554   ///                      PHINode in the SCoP region's exit block.
0555   /// @see addPHIReadAccess()
0556   /// @see MemoryKind
0557   void ensurePHIWrite(PHINode *PHI, ScopStmt *IncomintStmt,
0558                       BasicBlock *IncomingBlock, Value *IncomingValue,
0559                       bool IsExitBlock);
0560 
0561   /// Add user provided parameter constraints to context (command line).
0562   void addUserContext();
0563 
0564   /// Add user provided parameter constraints to context (source code).
0565   void addUserAssumptions(AssumptionCache &AC,
0566                           DenseMap<BasicBlock *, isl::set> &InvalidDomainMap);
0567 
0568   /// Add all recorded assumptions to the assumed context.
0569   void addRecordedAssumptions();
0570 
0571   /// Create a MemoryAccess for reading the value of a phi.
0572   ///
0573   /// The modeling assumes that all incoming blocks write their incoming value
0574   /// to the same location. Thus, this access will read the incoming block's
0575   /// value as instructed by this @p PHI.
0576   ///
0577   /// @param PHIStmt Statement @p PHI resides in.
0578   /// @param PHI     PHINode under consideration; the READ access will be added
0579   ///                here.
0580   ///
0581   /// @see ensurePHIWrite()
0582   /// @see MemoryKind
0583   void addPHIReadAccess(ScopStmt *PHIStmt, PHINode *PHI);
0584 
0585   /// Wrapper function to calculate minimal/maximal accesses to each array.
0586   bool calculateMinMaxAccess(AliasGroupTy AliasGroup,
0587                              Scop::MinMaxVectorTy &MinMaxAccesses);
0588   /// Build the domain of @p Stmt.
0589   void buildDomain(ScopStmt &Stmt);
0590 
0591   /// Fill NestLoops with loops surrounding @p Stmt.
0592   void collectSurroundingLoops(ScopStmt &Stmt);
0593 
0594   /// Check for reductions in @p Stmt.
0595   ///
0596   /// Iterate over all store memory accesses and check for valid binary
0597   /// reduction like chains. For all candidates we check if they have the same
0598   /// base address and there are no other accesses which overlap with them. The
0599   /// base address check rules out impossible reductions candidates early. The
0600   /// overlap check, together with the "only one user" check in
0601   /// collectCandidateReductionLoads, guarantees that none of the intermediate
0602   /// results will escape during execution of the loop nest. We basically check
0603   /// here that no other memory access can access the same memory as the
0604   /// potential reduction.
0605   void checkForReductions(ScopStmt &Stmt);
0606 
0607   /// Verify that all required invariant loads have been hoisted.
0608   ///
0609   /// Invariant load hoisting is not guaranteed to hoist all loads that were
0610   /// assumed to be scop invariant during scop detection. This function checks
0611   /// for cases where the hoisting failed, but where it would have been
0612   /// necessary for our scop modeling to be correct. In case of insufficient
0613   /// hoisting the scop is marked as invalid.
0614   ///
0615   /// In the example below Bound[1] is required to be invariant:
0616   ///
0617   /// for (int i = 1; i < Bound[0]; i++)
0618   ///   for (int j = 1; j < Bound[1]; j++)
0619   ///     ...
0620   void verifyInvariantLoads();
0621 
0622   /// Hoist invariant memory loads and check for required ones.
0623   ///
0624   /// We first identify "common" invariant loads, thus loads that are invariant
0625   /// and can be hoisted. Then we check if all required invariant loads have
0626   /// been identified as (common) invariant. A load is a required invariant load
0627   /// if it was assumed to be invariant during SCoP detection, e.g., to assume
0628   /// loop bounds to be affine or runtime alias checks to be placeable. In case
0629   /// a required invariant load was not identified as (common) invariant we will
0630   /// drop this SCoP. An example for both "common" as well as required invariant
0631   /// loads is given below:
0632   ///
0633   /// for (int i = 1; i < *LB[0]; i++)
0634   ///   for (int j = 1; j < *LB[1]; j++)
0635   ///     A[i][j] += A[0][0] + (*V);
0636   ///
0637   /// Common inv. loads: V, A[0][0], LB[0], LB[1]
0638   /// Required inv. loads: LB[0], LB[1], (V, if it may alias with A or LB)
0639   void hoistInvariantLoads();
0640 
0641   /// Add invariant loads listed in @p InvMAs with the domain of @p Stmt.
0642   void addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs);
0643 
0644   /// Check if @p MA can always be hoisted without execution context.
0645   bool canAlwaysBeHoisted(MemoryAccess *MA, bool StmtInvalidCtxIsEmpty,
0646                           bool MAInvalidCtxIsEmpty,
0647                           bool NonHoistableCtxIsEmpty);
0648 
0649   /// Return true if and only if @p LI is a required invariant load.
0650   bool isRequiredInvariantLoad(LoadInst *LI) const {
0651     return scop->getRequiredInvariantLoads().count(LI);
0652   }
0653 
0654   /// Check if the base ptr of @p MA is in the SCoP but not hoistable.
0655   bool hasNonHoistableBasePtrInScop(MemoryAccess *MA, isl::union_map Writes);
0656 
0657   /// Return the context under which the access cannot be hoisted.
0658   ///
0659   /// @param Access The access to check.
0660   /// @param Writes The set of all memory writes in the scop.
0661   ///
0662   /// @return Return the context under which the access cannot be hoisted or a
0663   ///         nullptr if it cannot be hoisted at all.
0664   isl::set getNonHoistableCtx(MemoryAccess *Access, isl::union_map Writes);
0665 
0666   /// Build the access relation of all memory accesses of @p Stmt.
0667   void buildAccessRelations(ScopStmt &Stmt);
0668 
0669   /// Canonicalize arrays with base pointers from the same equivalence class.
0670   ///
0671   /// Some context: in our normal model we assume that each base pointer is
0672   /// related to a single specific memory region, where memory regions
0673   /// associated with different base pointers are disjoint. Consequently we do
0674   /// not need to compute additional data dependences that model possible
0675   /// overlaps of these memory regions. To verify our assumption we compute
0676   /// alias checks that verify that modeled arrays indeed do not overlap. In
0677   /// case an overlap is detected the runtime check fails and we fall back to
0678   /// the original code.
0679   ///
0680   /// In case of arrays where the base pointers are know to be identical,
0681   /// because they are dynamically loaded by accesses that are in the same
0682   /// invariant load equivalence class, such run-time alias check would always
0683   /// be false.
0684   ///
0685   /// This function makes sure that we do not generate consistently failing
0686   /// run-time checks for code that contains distinct arrays with known
0687   /// equivalent base pointers. It identifies for each invariant load
0688   /// equivalence class a single canonical array and canonicalizes all memory
0689   /// accesses that reference arrays that have base pointers that are known to
0690   /// be equal to the base pointer of such a canonical array to this canonical
0691   /// array.
0692   ///
0693   /// We currently do not canonicalize arrays for which certain memory accesses
0694   /// have been hoisted as loop invariant.
0695   void canonicalizeDynamicBasePtrs();
0696 
0697   /// Construct the schedule of this SCoP.
0698   void buildSchedule();
0699 
0700   /// A loop stack element to keep track of per-loop information during
0701   ///        schedule construction.
0702   using LoopStackElementTy = struct LoopStackElement {
0703     // The loop for which we keep information.
0704     Loop *L;
0705 
0706     // The (possibly incomplete) schedule for this loop.
0707     isl::schedule Schedule;
0708 
0709     // The number of basic blocks in the current loop, for which a schedule has
0710     // already been constructed.
0711     unsigned NumBlocksProcessed;
0712 
0713     LoopStackElement(Loop *L, isl::schedule S, unsigned NumBlocksProcessed)
0714         : L(L), Schedule(S), NumBlocksProcessed(NumBlocksProcessed) {}
0715   };
0716 
0717   /// The loop stack used for schedule construction.
0718   ///
0719   /// The loop stack keeps track of schedule information for a set of nested
0720   /// loops as well as an (optional) 'nullptr' loop that models the outermost
0721   /// schedule dimension. The loops in a loop stack always have a parent-child
0722   /// relation where the loop at position n is the parent of the loop at
0723   /// position n + 1.
0724   using LoopStackTy = SmallVector<LoopStackElementTy, 4>;
0725 
0726   /// Construct schedule information for a given Region and add the
0727   ///        derived information to @p LoopStack.
0728   ///
0729   /// Given a Region we derive schedule information for all RegionNodes
0730   /// contained in this region ensuring that the assigned execution times
0731   /// correctly model the existing control flow relations.
0732   ///
0733   /// @param R              The region which to process.
0734   /// @param LoopStack      A stack of loops that are currently under
0735   ///                       construction.
0736   void buildSchedule(Region *R, LoopStackTy &LoopStack);
0737 
0738   /// Build Schedule for the region node @p RN and add the derived
0739   ///        information to @p LoopStack.
0740   ///
0741   /// In case @p RN is a BasicBlock or a non-affine Region, we construct the
0742   /// schedule for this @p RN and also finalize loop schedules in case the
0743   /// current @p RN completes the loop.
0744   ///
0745   /// In case @p RN is a not-non-affine Region, we delegate the construction to
0746   /// buildSchedule(Region *R, ...).
0747   ///
0748   /// @param RN             The RegionNode region traversed.
0749   /// @param LoopStack      A stack of loops that are currently under
0750   ///                       construction.
0751   void buildSchedule(RegionNode *RN, LoopStackTy &LoopStack);
0752 
0753 public:
0754   explicit ScopBuilder(Region *R, AssumptionCache &AC, AAResults &AA,
0755                        const DataLayout &DL, DominatorTree &DT, LoopInfo &LI,
0756                        ScopDetection &SD, ScalarEvolution &SE,
0757                        OptimizationRemarkEmitter &ORE);
0758   ScopBuilder(const ScopBuilder &) = delete;
0759   ScopBuilder &operator=(const ScopBuilder &) = delete;
0760   ~ScopBuilder() = default;
0761 
0762   /// Try to build the Polly IR of static control part on the current
0763   /// SESE-Region.
0764   ///
0765   /// @return Give up the ownership of the scop object or static control part
0766   ///         for the region
0767   std::unique_ptr<Scop> getScop() { return std::move(scop); }
0768 };
0769 } // end namespace polly
0770 
0771 #endif // POLLY_SCOPBUILDER_H