diff options
| -rw-r--r-- | polly/include/polly/CodeGen/BlockGenerators.h | 4 | ||||
| -rw-r--r-- | polly/include/polly/ScopBuilder.h | 13 | ||||
| -rw-r--r-- | polly/include/polly/ScopInfo.h | 349 | ||||
| -rw-r--r-- | polly/lib/Analysis/ScopBuilder.cpp | 31 | ||||
| -rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 57 | ||||
| -rw-r--r-- | polly/lib/CodeGen/BlockGenerators.cpp | 4 | ||||
| -rw-r--r-- | polly/lib/CodeGen/PPCGCodeGeneration.cpp | 8 |
7 files changed, 233 insertions, 233 deletions
diff --git a/polly/include/polly/CodeGen/BlockGenerators.h b/polly/include/polly/CodeGen/BlockGenerators.h index 2e907c9fcdc..dcf6bc6b9ff 100644 --- a/polly/include/polly/CodeGen/BlockGenerators.h +++ b/polly/include/polly/CodeGen/BlockGenerators.h @@ -854,8 +854,8 @@ private: /// leaving the subregion because the exiting block as an edge back into the /// subregion. /// - /// @param MA The WRITE of MK_PHI/MK_ExitPHI for a PHI in the subregion's - /// exit block. + /// @param MA The WRITE of MemoryKind::PHI/MemoryKind::ExitPHI for a PHI in + /// the subregion's exit block. /// @param LTS Virtual induction variable mapping. /// @param BBMap A mapping from old values to their new values in this block. /// @param L Loop surrounding this region statement. diff --git a/polly/include/polly/ScopBuilder.h b/polly/include/polly/ScopBuilder.h index 8dc9677c87b..1e33d01c10e 100644 --- a/polly/include/polly/ScopBuilder.h +++ b/polly/include/polly/ScopBuilder.h @@ -171,8 +171,7 @@ class ScopBuilder { Value *BaseAddress, Type *ElemType, bool Affine, Value *AccessValue, ArrayRef<const SCEV *> Subscripts, - ArrayRef<const SCEV *> Sizes, - ScopArrayInfo::MemoryKind Kind); + ArrayRef<const SCEV *> Sizes, MemoryKind Kind); /// Create a MemoryAccess that represents either a LoadInst or /// StoreInst. @@ -186,7 +185,7 @@ class ScopBuilder { /// @param Sizes The array dimension's sizes. /// @param AccessValue Value read or written. /// - /// @see ScopArrayInfo::MemoryKind + /// @see MemoryKind void addArrayAccess(MemAccInst MemAccInst, MemoryAccess::AccessType AccType, Value *BaseAddress, Type *ElemType, bool IsAffine, ArrayRef<const SCEV *> Subscripts, @@ -199,7 +198,7 @@ class ScopBuilder { /// @param Inst The instruction to be written. /// /// @see ensureValueRead() - /// @see ScopArrayInfo::MemoryKind + /// @see MemoryKind void ensureValueWrite(Instruction *Inst); /// Ensure an llvm::Value is available in the BB's statement, creating a @@ -209,7 +208,7 @@ class ScopBuilder { /// @param UserBB Where to reload the value. /// /// @see ensureValueStore() - /// @see ScopArrayInfo::MemoryKind + /// @see MemoryKind void ensureValueRead(Value *V, BasicBlock *UserBB); /// Create a write MemoryAccess for the incoming block of a phi node. @@ -224,7 +223,7 @@ class ScopBuilder { /// .phiops one. Required for values escaping through a /// PHINode in the SCoP region's exit block. /// @see addPHIReadAccess() - /// @see ScopArrayInfo::MemoryKind + /// @see MemoryKind void ensurePHIWrite(PHINode *PHI, BasicBlock *IncomingBlock, Value *IncomingValue, bool IsExitBlock); @@ -238,7 +237,7 @@ class ScopBuilder { /// here. /// /// @see ensurePHIWrite() - /// @see ScopArrayInfo::MemoryKind + /// @see MemoryKind void addPHIReadAccess(PHINode *PHI); public: diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h index 9adb929684c..3ea7491d5d1 100644 --- a/polly/include/polly/ScopInfo.h +++ b/polly/include/polly/ScopInfo.h @@ -82,6 +82,129 @@ enum AssumptionKind { /// Enum to distinguish between assumptions and restrictions. enum AssumptionSign { AS_ASSUMPTION, AS_RESTRICTION }; +/// The different memory kinds used in Polly. +/// +/// We distinguish between arrays and various scalar memory objects. We use +/// the term ``array'' to describe memory objects that consist of a set of +/// individual data elements arranged in a multi-dimensional grid. A scalar +/// memory object describes an individual data element and is used to model +/// the definition and uses of llvm::Values. +/// +/// The polyhedral model does traditionally not reason about SSA values. To +/// reason about llvm::Values we model them "as if" they were zero-dimensional +/// memory objects, even though they were not actually allocated in (main) +/// memory. Memory for such objects is only alloca[ed] at CodeGeneration +/// time. To relate the memory slots used during code generation with the +/// llvm::Values they belong to the new names for these corresponding stack +/// slots are derived by appending suffixes (currently ".s2a" and ".phiops") +/// to the name of the original llvm::Value. To describe how def/uses are +/// modeled exactly we use these suffixes here as well. +/// +/// There are currently four different kinds of memory objects: +enum class MemoryKind { + /// MemoryKind::Array: Models a one or multi-dimensional array + /// + /// A memory object that can be described by a multi-dimensional array. + /// Memory objects of this type are used to model actual multi-dimensional + /// arrays as they exist in LLVM-IR, but they are also used to describe + /// other objects: + /// - A single data element allocated on the stack using 'alloca' is + /// modeled as a one-dimensional, single-element array. + /// - A single data element allocated as a global variable is modeled as + /// one-dimensional, single-element array. + /// - Certain multi-dimensional arrays with variable size, which in + /// LLVM-IR are commonly expressed as a single-dimensional access with a + /// complicated access function, are modeled as multi-dimensional + /// memory objects (grep for "delinearization"). + Array, + + /// MemoryKind::Value: Models an llvm::Value + /// + /// Memory objects of type MemoryKind::Value are used to model the data flow + /// induced by llvm::Values. For each llvm::Value that is used across + /// BasicBocks one ScopArrayInfo object is created. A single memory WRITE + /// stores the llvm::Value at its definition into the memory object and at + /// each use of the llvm::Value (ignoring trivial intra-block uses) a + /// corresponding READ is added. For instance, the use/def chain of a + /// llvm::Value %V depicted below + /// ______________________ + /// |DefBB: | + /// | %V = float op ... | + /// ---------------------- + /// | | + /// _________________ _________________ + /// |UseBB1: | |UseBB2: | + /// | use float %V | | use float %V | + /// ----------------- ----------------- + /// + /// is modeled as if the following memory accesses occured: + /// + /// __________________________ + /// |entry: | + /// | %V.s2a = alloca float | + /// -------------------------- + /// | + /// ___________________________________ + /// |DefBB: | + /// | store %float %V, float* %V.s2a | + /// ----------------------------------- + /// | | + /// ____________________________________ ___________________________________ + /// |UseBB1: | |UseBB2: | + /// | %V.reload1 = load float* %V.s2a | | %V.reload2 = load float* %V.s2a| + /// | use float %V.reload1 | | use float %V.reload2 | + /// ------------------------------------ ----------------------------------- + /// + Value, + + /// MemoryKind::PHI: Models PHI nodes within the SCoP + /// + /// Besides the MemoryKind::Value memory object used to model the normal + /// llvm::Value dependences described above, PHI nodes require an additional + /// memory object of type MemoryKind::PHI to describe the forwarding of values + /// to + /// the PHI node. + /// + /// As an example, a PHIInst instructions + /// + /// %PHI = phi float [ %Val1, %IncomingBlock1 ], [ %Val2, %IncomingBlock2 ] + /// + /// is modeled as if the accesses occured this way: + /// + /// _______________________________ + /// |entry: | + /// | %PHI.phiops = alloca float | + /// ------------------------------- + /// | | + /// __________________________________ __________________________________ + /// |IncomingBlock1: | |IncomingBlock2: | + /// | ... | | ... | + /// | store float %Val1 %PHI.phiops | | store float %Val2 %PHI.phiops | + /// | br label % JoinBlock | | br label %JoinBlock | + /// ---------------------------------- ---------------------------------- + /// \ / + /// \ / + /// _________________________________________ + /// |JoinBlock: | + /// | %PHI = load float, float* PHI.phiops | + /// ----------------------------------------- + /// + /// Note that there can also be a scalar write access for %PHI if used in a + /// different BasicBlock, i.e. there can be a memory object %PHI.phiops as + /// well as a memory object %PHI.s2a. + PHI, + + /// MemoryKind::ExitPHI: Models PHI nodes in the SCoP's exit block + /// + /// For PHI nodes in the Scop's exit block a special memory object kind is + /// used. The modeling used is identical to MemoryKind::PHI, with the + /// exception + /// that there are no READs from these memory objects. The PHINode's + /// llvm::Value is treated as a value escaping the SCoP. WRITE accesses + /// write directly to the escaping value's ".s2a" alloca. + ExitPHI +}; + /// Maps from a loop to the affine function expressing its backedge taken count. /// The backedge taken count already enough to express iteration domain as we /// only allow loops with canonical induction variable. @@ -99,127 +222,6 @@ typedef std::vector<std::unique_ptr<MemoryAccess>> AccFuncVector; /// class ScopArrayInfo { public: - /// The kind of a ScopArrayInfo memory object. - /// - /// We distinguish between arrays and various scalar memory objects. We use - /// the term ``array'' to describe memory objects that consist of a set of - /// individual data elements arranged in a multi-dimensional grid. A scalar - /// memory object describes an individual data element and is used to model - /// the definition and uses of llvm::Values. - /// - /// The polyhedral model does traditionally not reason about SSA values. To - /// reason about llvm::Values we model them "as if" they were zero-dimensional - /// memory objects, even though they were not actually allocated in (main) - /// memory. Memory for such objects is only alloca[ed] at CodeGeneration - /// time. To relate the memory slots used during code generation with the - /// llvm::Values they belong to the new names for these corresponding stack - /// slots are derived by appending suffixes (currently ".s2a" and ".phiops") - /// to the name of the original llvm::Value. To describe how def/uses are - /// modeled exactly we use these suffixes here as well. - /// - /// There are currently four different kinds of memory objects: - enum MemoryKind { - /// MK_Array: Models a one or multi-dimensional array - /// - /// A memory object that can be described by a multi-dimensional array. - /// Memory objects of this type are used to model actual multi-dimensional - /// arrays as they exist in LLVM-IR, but they are also used to describe - /// other objects: - /// - A single data element allocated on the stack using 'alloca' is - /// modeled as a one-dimensional, single-element array. - /// - A single data element allocated as a global variable is modeled as - /// one-dimensional, single-element array. - /// - Certain multi-dimensional arrays with variable size, which in - /// LLVM-IR are commonly expressed as a single-dimensional access with a - /// complicated access function, are modeled as multi-dimensional - /// memory objects (grep for "delinearization"). - MK_Array, - - /// MK_Value: Models an llvm::Value - /// - /// Memory objects of type MK_Value are used to model the data flow - /// induced by llvm::Values. For each llvm::Value that is used across - /// BasicBocks one ScopArrayInfo object is created. A single memory WRITE - /// stores the llvm::Value at its definition into the memory object and at - /// each use of the llvm::Value (ignoring trivial intra-block uses) a - /// corresponding READ is added. For instance, the use/def chain of a - /// llvm::Value %V depicted below - /// ______________________ - /// |DefBB: | - /// | %V = float op ... | - /// ---------------------- - /// | | - /// _________________ _________________ - /// |UseBB1: | |UseBB2: | - /// | use float %V | | use float %V | - /// ----------------- ----------------- - /// - /// is modeled as if the following memory accesses occured: - /// - /// __________________________ - /// |entry: | - /// | %V.s2a = alloca float | - /// -------------------------- - /// | - /// ___________________________________ - /// |DefBB: | - /// | store %float %V, float* %V.s2a | - /// ----------------------------------- - /// | | - /// ____________________________________ ___________________________________ - /// |UseBB1: | |UseBB2: | - /// | %V.reload1 = load float* %V.s2a | | %V.reload2 = load float* %V.s2a| - /// | use float %V.reload1 | | use float %V.reload2 | - /// ------------------------------------ ----------------------------------- - /// - MK_Value, - - /// MK_PHI: Models PHI nodes within the SCoP - /// - /// Besides the MK_Value memory object used to model the normal - /// llvm::Value dependences described above, PHI nodes require an additional - /// memory object of type MK_PHI to describe the forwarding of values to - /// the PHI node. - /// - /// As an example, a PHIInst instructions - /// - /// %PHI = phi float [ %Val1, %IncomingBlock1 ], [ %Val2, %IncomingBlock2 ] - /// - /// is modeled as if the accesses occured this way: - /// - /// _______________________________ - /// |entry: | - /// | %PHI.phiops = alloca float | - /// ------------------------------- - /// | | - /// __________________________________ __________________________________ - /// |IncomingBlock1: | |IncomingBlock2: | - /// | ... | | ... | - /// | store float %Val1 %PHI.phiops | | store float %Val2 %PHI.phiops | - /// | br label % JoinBlock | | br label %JoinBlock | - /// ---------------------------------- ---------------------------------- - /// \ / - /// \ / - /// _________________________________________ - /// |JoinBlock: | - /// | %PHI = load float, float* PHI.phiops | - /// ----------------------------------------- - /// - /// Note that there can also be a scalar write access for %PHI if used in a - /// different BasicBlock, i.e. there can be a memory object %PHI.phiops as - /// well as a memory object %PHI.s2a. - MK_PHI, - - /// MK_ExitPHI: Models PHI nodes in the SCoP's exit block - /// - /// For PHI nodes in the Scop's exit block a special memory object kind is - /// used. The modeling used is identical to MK_PHI, with the exception - /// that there are no READs from these memory objects. The PHINode's - /// llvm::Value is treated as a value escaping the SCoP. WRITE accesses - /// write directly to the escaping value's ".s2a" alloca. - MK_ExitPHI - }; - /// Construct a ScopArrayInfo object. /// /// @param BasePtr The array base pointer. @@ -277,7 +279,8 @@ public: /// Return the number of dimensions. unsigned getNumberOfDimensions() const { - if (Kind == MK_PHI || Kind == MK_ExitPHI || Kind == MK_Value) + if (Kind == MemoryKind::PHI || Kind == MemoryKind::ExitPHI || + Kind == MemoryKind::Value) return 0; return DimensionSizes.size(); } @@ -320,7 +323,7 @@ public: enum MemoryKind getKind() const { return Kind; } /// Is this array info modeling an llvm::Value? - bool isValueKind() const { return Kind == MK_Value; } + bool isValueKind() const { return Kind == MemoryKind::Value; } /// Is this array info modeling special PHI node memory? /// @@ -332,13 +335,13 @@ public: /// original PHI node as virtual base pointer, we have this additional /// attribute to distinguish the PHI node specific array modeling from the /// normal scalar array modeling. - bool isPHIKind() const { return Kind == MK_PHI; } + bool isPHIKind() const { return Kind == MemoryKind::PHI; } - /// Is this array info modeling an MK_ExitPHI? - bool isExitPHIKind() const { return Kind == MK_ExitPHI; } + /// Is this array info modeling an MemoryKind::ExitPHI? + bool isExitPHIKind() const { return Kind == MemoryKind::ExitPHI; } /// Is this array info modeling an array? - bool isArrayKind() const { return Kind == MK_Array; } + bool isArrayKind() const { return Kind == MemoryKind::Array; } /// Dump a readable representation to stderr. void dump() const; @@ -460,8 +463,8 @@ private: isl_id *Id; /// What is modeled by this MemoryAccess. - /// @see ScopArrayInfo::MemoryKind - ScopArrayInfo::MemoryKind Kind; + /// @see MemoryKind + MemoryKind Kind; /// Whether it a reading or writing access, and if writing, whether it /// is conditional (MAY_WRITE). @@ -509,12 +512,12 @@ private: /// The base address (e.g., A for A[i+j]). /// - /// The #BaseAddr of a memory access of kind MK_Array is the base pointer - /// of the memory access. - /// The #BaseAddr of a memory access of kind MK_PHI or MK_ExitPHI is the - /// PHI node itself. - /// The #BaseAddr of a memory access of kind MK_Value is the instruction - /// defining the value. + /// The #BaseAddr of a memory access of kind MemoryKind::Array is the base + /// pointer of the memory access. + /// The #BaseAddr of a memory access of kind MemoryKind::PHI or + /// MemoryKind::ExitPHI is the PHI node itself. + /// The #BaseAddr of a memory access of kind MemoryKind::Value is the + /// instruction defining the value. AssertingVH<Value> BaseAddr; /// An unique name of the accessed array. @@ -532,18 +535,19 @@ private: /// The access instruction of this memory access. /// - /// For memory accesses of kind MK_Array the access instruction is the - /// Load or Store instruction performing the access. + /// For memory accesses of kind MemoryKind::Array the access instruction is + /// the Load or Store instruction performing the access. /// - /// For memory accesses of kind MK_PHI or MK_ExitPHI the access - /// instruction of a load access is the PHI instruction. The access + /// For memory accesses of kind MemoryKind::PHI or MemoryKind::ExitPHI the + /// access instruction of a load access is the PHI instruction. The access /// instruction of a PHI-store is the incoming's block's terminator /// instruction. /// - /// For memory accesses of kind MK_Value the access instruction of a load - /// access is nullptr because generally there can be multiple instructions in - /// the statement using the same llvm::Value. The access instruction of a - /// write access is the instruction that defines the llvm::Value. + /// For memory accesses of kind MemoryKind::Value the access instruction of a + /// load access is nullptr because generally there can be multiple + /// instructions in the statement using the same llvm::Value. The access + /// instruction of a write access is the instruction that defines the + /// llvm::Value. Instruction *AccessInstruction; /// Incoming block and value of a PHINode. @@ -551,12 +555,13 @@ private: /// The value associated with this memory access. /// - /// - For array memory accesses (MK_Array) it is the loaded result or the - /// stored value. If the access instruction is a memory intrinsic it + /// - For array memory accesses (MemoryKind::Array) it is the loaded result + /// or the stored value. If the access instruction is a memory intrinsic it /// the access value is also the memory intrinsic. - /// - For accesses of kind MK_Value it is the access instruction itself. - /// - For accesses of kind MK_PHI or MK_ExitPHI it is the PHI node itself - /// (for both, READ and WRITE accesses). + /// - For accesses of kind MemoryKind::Value it is the access instruction + /// itself. + /// - For accesses of kind MemoryKind::PHI or MemoryKind::ExitPHI it is the + /// PHI node itself (for both, READ and WRITE accesses). /// AssertingVH<Value> AccessValue; @@ -688,8 +693,7 @@ public: MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst, AccessType AccType, Value *BaseAddress, Type *ElemType, bool Affine, ArrayRef<const SCEV *> Subscripts, ArrayRef<const SCEV *> Sizes, - Value *AccessValue, ScopArrayInfo::MemoryKind Kind, - StringRef BaseName); + Value *AccessValue, MemoryKind Kind, StringRef BaseName); /// Create a new MemoryAccess that corresponds to @p AccRel. /// @@ -898,26 +902,26 @@ public: bool isStrideZero(__isl_take const isl_map *Schedule) const; /// Return the kind when this access was first detected. - ScopArrayInfo::MemoryKind getOriginalKind() const { + MemoryKind getOriginalKind() const { assert(!getOriginalScopArrayInfo() /* not yet initialized */ || getOriginalScopArrayInfo()->getKind() == Kind); return Kind; } /// Return the kind considering a potential setNewAccessRelation. - ScopArrayInfo::MemoryKind getLatestKind() const { + MemoryKind getLatestKind() const { return getLatestScopArrayInfo()->getKind(); } /// Whether this is an access of an explicit load or store in the IR. bool isOriginalArrayKind() const { - return getOriginalKind() == ScopArrayInfo::MK_Array; + return getOriginalKind() == MemoryKind::Array; } /// Whether storage memory is either an custom .s2a/.phiops alloca /// (false) or an existing pointer into an array (true). bool isLatestArrayKind() const { - return getLatestKind() == ScopArrayInfo::MK_Array; + return getLatestKind() == MemoryKind::Array; } /// Old name of isOriginalArrayKind. @@ -926,15 +930,16 @@ public: /// Whether this access is an array to a scalar memory object, without /// considering changes by setNewAccessRelation. /// - /// Scalar accesses are accesses to MK_Value, MK_PHI or MK_ExitPHI. + /// Scalar accesses are accesses to MemoryKind::Value, MemoryKind::PHI or + /// MemoryKind::ExitPHI. bool isOriginalScalarKind() const { - return getOriginalKind() != ScopArrayInfo::MK_Array; + return getOriginalKind() != MemoryKind::Array; } /// Whether this access is an array to a scalar memory object, also /// considering changes by setNewAccessRelation. bool isLatestScalarKind() const { - return getLatestKind() != ScopArrayInfo::MK_Array; + return getLatestKind() != MemoryKind::Array; } /// Old name of isOriginalScalarKind. @@ -942,12 +947,12 @@ public: /// Was this MemoryAccess detected as a scalar dependences? bool isOriginalValueKind() const { - return getOriginalKind() == ScopArrayInfo::MK_Value; + return getOriginalKind() == MemoryKind::Value; } /// Is this MemoryAccess currently modeling scalar dependences? bool isLatestValueKind() const { - return getLatestKind() == ScopArrayInfo::MK_Value; + return getLatestKind() == MemoryKind::Value; } /// Old name of isOriginalValueKind(). @@ -955,14 +960,12 @@ public: /// Was this MemoryAccess detected as a special PHI node access? bool isOriginalPHIKind() const { - return getOriginalKind() == ScopArrayInfo::MK_PHI; + return getOriginalKind() == MemoryKind::PHI; } /// Is this MemoryAccess modeling special PHI node accesses, also /// considering a potential change by setNewAccessRelation? - bool isLatestPHIKind() const { - return getLatestKind() == ScopArrayInfo::MK_PHI; - } + bool isLatestPHIKind() const { return getLatestKind() == MemoryKind::PHI; } /// Old name of isOriginalPHIKind. bool isPHIKind() const { return isOriginalPHIKind(); } @@ -970,14 +973,14 @@ public: /// Was this MemoryAccess detected as the accesses of a PHI node in the /// SCoP's exit block? bool isOriginalExitPHIKind() const { - return getOriginalKind() == ScopArrayInfo::MK_ExitPHI; + return getOriginalKind() == MemoryKind::ExitPHI; } /// Is this MemoryAccess modeling the accesses of a PHI node in the /// SCoP's exit block? Can be changed to an array access using /// setNewAccessRelation(). bool isLatestExitPHIKind() const { - return getLatestKind() == ScopArrayInfo::MK_ExitPHI; + return getLatestKind() == MemoryKind::ExitPHI; } /// Old name of isOriginalExitPHIKind(). @@ -1172,11 +1175,11 @@ private: DenseMap<const Instruction *, MemoryAccessList> InstructionToAccess; /// The set of values defined elsewhere required in this ScopStmt and - /// their MK_Value READ MemoryAccesses. + /// their MemoryKind::Value READ MemoryAccesses. DenseMap<Value *, MemoryAccess *> ValueReads; /// The set of values defined in this ScopStmt that are required - /// elsewhere, mapped to their MK_Value WRITE MemoryAccesses. + /// elsewhere, mapped to their MemoryKind::Value WRITE MemoryAccesses. DenseMap<Instruction *, MemoryAccess *> ValueWrites; /// Map from PHI nodes to its incoming value when coming from this @@ -1533,9 +1536,8 @@ private: /// The affinator used to translate SCEVs to isl expressions. SCEVAffinator Affinator; - typedef std::map< - std::pair<AssertingVH<const Value>, enum ScopArrayInfo::MemoryKind>, - std::unique_ptr<ScopArrayInfo>> + typedef std::map<std::pair<AssertingVH<const Value>, enum MemoryKind>, + std::unique_ptr<ScopArrayInfo>> ArrayInfoMapTy; typedef StringMap<std::unique_ptr<ScopArrayInfo>> ArrayNameMapTy; @@ -2364,7 +2366,7 @@ public: const ScopArrayInfo *getOrCreateScopArrayInfo(Value *BasePtr, Type *ElementType, ArrayRef<const SCEV *> Sizes, - ScopArrayInfo::MemoryKind Kind, + MemoryKind Kind, const char *BaseName = nullptr); /// Create an array and return the corresponding ScopArrayInfo object. @@ -2380,14 +2382,13 @@ public: /// /// @param BasePtr The base pointer the object has been stored for. /// @param Kind The kind of array info object. - const ScopArrayInfo *getScopArrayInfo(Value *BasePtr, - ScopArrayInfo::MemoryKind Kind); + const ScopArrayInfo *getScopArrayInfo(Value *BasePtr, MemoryKind Kind); /// Invalidate ScopArrayInfo object for base address. /// /// @param BasePtr The base pointer of the ScopArrayInfo object to invalidate. /// @param Kind The Kind of the ScopArrayInfo object. - void invalidateScopArrayInfo(Value *BasePtr, ScopArrayInfo::MemoryKind Kind) { + void invalidateScopArrayInfo(Value *BasePtr, MemoryKind Kind) { auto It = ScopArrayInfoMap.find(std::make_pair(BasePtr, Kind)); if (It == ScopArrayInfoMap.end()) return; diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp index d737621e193..6d1bf88c5af 100644 --- a/polly/lib/Analysis/ScopBuilder.cpp +++ b/polly/lib/Analysis/ScopBuilder.cpp @@ -482,7 +482,7 @@ MemoryAccess *ScopBuilder::addMemoryAccess( BasicBlock *BB, Instruction *Inst, MemoryAccess::AccessType AccType, Value *BaseAddress, Type *ElementType, bool Affine, Value *AccessValue, ArrayRef<const SCEV *> Subscripts, ArrayRef<const SCEV *> Sizes, - ScopArrayInfo::MemoryKind Kind) { + MemoryKind Kind) { ScopStmt *Stmt = scop->getStmtFor(BB); // Do not create a memory access for anything not in the SCoP. It would be @@ -501,9 +501,10 @@ MemoryAccess *ScopBuilder::addMemoryAccess( if (Stmt->isRegionStmt()) { // Accesses that dominate the exit block of a non-affine region are always - // executed. In non-affine regions there may exist MK_Values that do not - // dominate the exit. MK_Values will always dominate the exit and MK_PHIs - // only if there is at most one PHI_WRITE in the non-affine region. + // executed. In non-affine regions there may exist MemoryKind::Values that + // do not dominate the exit. MemoryKind::Values will always dominate the + // exit and MemoryKind::PHIs only if there is at most one PHI_WRITE in the + // non-affine region. if (DT.dominates(BB, Stmt->getRegion()->getExit())) isKnownMustAccess = true; } @@ -511,7 +512,7 @@ MemoryAccess *ScopBuilder::addMemoryAccess( // Non-affine PHI writes do not "happen" at a particular instruction, but // after exiting the statement. Therefore they are guaranteed to execute and // overwrite the old value. - if (Kind == ScopArrayInfo::MK_PHI || Kind == ScopArrayInfo::MK_ExitPHI) + if (Kind == MemoryKind::PHI || Kind == MemoryKind::ExitPHI) isKnownMustAccess = true; if (!isKnownMustAccess && AccType == MemoryAccess::MUST_WRITE) @@ -533,7 +534,7 @@ void ScopBuilder::addArrayAccess( ArrayBasePointers.insert(BaseAddress); addMemoryAccess(MemAccInst->getParent(), MemAccInst, AccType, BaseAddress, ElementType, IsAffine, AccessValue, Subscripts, Sizes, - ScopArrayInfo::MK_Array); + MemoryKind::Array); } void ScopBuilder::ensureValueWrite(Instruction *Inst) { @@ -549,7 +550,7 @@ void ScopBuilder::ensureValueWrite(Instruction *Inst) { addMemoryAccess(Inst->getParent(), Inst, MemoryAccess::MUST_WRITE, Inst, Inst->getType(), true, Inst, ArrayRef<const SCEV *>(), - ArrayRef<const SCEV *>(), ScopArrayInfo::MK_Value); + ArrayRef<const SCEV *>(), MemoryKind::Value); } void ScopBuilder::ensureValueRead(Value *V, BasicBlock *UserBB) { @@ -598,7 +599,7 @@ void ScopBuilder::ensureValueRead(Value *V, BasicBlock *UserBB) { addMemoryAccess(UserBB, nullptr, MemoryAccess::READ, V, V->getType(), true, V, ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(), - ScopArrayInfo::MK_Value); + MemoryKind::Value); if (ValueInst) ensureValueWrite(ValueInst); } @@ -610,7 +611,7 @@ void ScopBuilder::ensurePHIWrite(PHINode *PHI, BasicBlock *IncomingBlock, // and would be created later anyway. if (IsExitBlock) scop->getOrCreateScopArrayInfo(PHI, PHI->getType(), {}, - ScopArrayInfo::MK_ExitPHI); + MemoryKind::ExitPHI); ScopStmt *IncomingStmt = scop->getStmtFor(IncomingBlock); if (!IncomingStmt) @@ -630,11 +631,11 @@ void ScopBuilder::ensurePHIWrite(PHINode *PHI, BasicBlock *IncomingBlock, return; } - MemoryAccess *Acc = addMemoryAccess( - IncomingStmt->getEntryBlock(), PHI, MemoryAccess::MUST_WRITE, PHI, - PHI->getType(), true, PHI, ArrayRef<const SCEV *>(), - ArrayRef<const SCEV *>(), - IsExitBlock ? ScopArrayInfo::MK_ExitPHI : ScopArrayInfo::MK_PHI); + MemoryAccess *Acc = + addMemoryAccess(IncomingStmt->getEntryBlock(), PHI, + MemoryAccess::MUST_WRITE, PHI, PHI->getType(), true, PHI, + ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(), + IsExitBlock ? MemoryKind::ExitPHI : MemoryKind::PHI); assert(Acc); Acc->addIncoming(IncomingBlock, IncomingValue); } @@ -642,7 +643,7 @@ void ScopBuilder::ensurePHIWrite(PHINode *PHI, BasicBlock *IncomingBlock, void ScopBuilder::addPHIReadAccess(PHINode *PHI) { addMemoryAccess(PHI->getParent(), PHI, MemoryAccess::READ, PHI, PHI->getType(), true, PHI, ArrayRef<const SCEV *>(), - ArrayRef<const SCEV *>(), ScopArrayInfo::MK_PHI); + ArrayRef<const SCEV *>(), MemoryKind::PHI); } void ScopBuilder::buildScop(Region &R) { diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index 3192bedea68..ed74c990f29 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -182,7 +182,7 @@ static const ScopArrayInfo *identifyBasePtrOriginSAI(Scop *S, Value *BasePtr) { return nullptr; return S->getScopArrayInfo(OriginBaseSCEVUnknown->getValue(), - ScopArrayInfo::MK_Array); + MemoryKind::Array); } ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *Ctx, @@ -191,13 +191,14 @@ ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *Ctx, const char *BaseName) : BasePtr(BasePtr), ElementType(ElementType), Kind(Kind), DL(DL), S(*S) { std::string BasePtrName = - BaseName ? BaseName : getIslCompatibleName("MemRef_", BasePtr, - Kind == MK_PHI ? "__phi" : ""); + BaseName ? BaseName + : getIslCompatibleName("MemRef_", BasePtr, + Kind == MemoryKind::PHI ? "__phi" : ""); Id = isl_id_alloc(Ctx, BasePtrName.c_str(), this); updateSizes(Sizes); - if (!BasePtr || Kind != MK_Array) { + if (!BasePtr || Kind != MemoryKind::Array) { BasePtrOriginSAI = nullptr; return; } @@ -884,7 +885,7 @@ MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst, Type *ElementType, bool Affine, ArrayRef<const SCEV *> Subscripts, ArrayRef<const SCEV *> Sizes, Value *AccessValue, - ScopArrayInfo::MemoryKind Kind, StringRef BaseName) + MemoryKind Kind, StringRef BaseName) : Kind(Kind), AccType(AccType), RedType(RT_NONE), Statement(Stmt), InvalidDomain(nullptr), BaseAddr(BaseAddress), BaseName(BaseName), ElementType(ElementType), Sizes(Sizes.begin(), Sizes.end()), @@ -901,10 +902,9 @@ MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst, MemoryAccess::MemoryAccess(ScopStmt *Stmt, AccessType AccType, __isl_take isl_map *AccRel) - : Kind(ScopArrayInfo::MemoryKind::MK_Array), AccType(AccType), - RedType(RT_NONE), Statement(Stmt), InvalidDomain(nullptr), - AccessInstruction(nullptr), IsAffine(true), AccessRelation(nullptr), - NewAccessRelation(AccRel) { + : Kind(MemoryKind::Array), AccType(AccType), RedType(RT_NONE), + Statement(Stmt), InvalidDomain(nullptr), AccessInstruction(nullptr), + IsAffine(true), AccessRelation(nullptr), NewAccessRelation(AccRel) { auto *ArrayInfoId = isl_map_get_tuple_id(NewAccessRelation, isl_dim_out); auto *SAI = ScopArrayInfo::getFromId(ArrayInfoId); Sizes.push_back(nullptr); @@ -1146,15 +1146,15 @@ void ScopStmt::buildAccessRelations() { for (MemoryAccess *Access : MemAccs) { Type *ElementType = Access->getElementType(); - ScopArrayInfo::MemoryKind Ty; + MemoryKind Ty; if (Access->isPHIKind()) - Ty = ScopArrayInfo::MK_PHI; + Ty = MemoryKind::PHI; else if (Access->isExitPHIKind()) - Ty = ScopArrayInfo::MK_ExitPHI; + Ty = MemoryKind::ExitPHI; else if (Access->isValueKind()) - Ty = ScopArrayInfo::MK_Value; + Ty = MemoryKind::Value; else - Ty = ScopArrayInfo::MK_Array; + Ty = MemoryKind::Array; auto *SAI = S.getOrCreateScopArrayInfo(Access->getBaseAddr(), ElementType, Access->Sizes, Ty); @@ -1734,12 +1734,12 @@ void ScopStmt::print(raw_ostream &OS) const { void ScopStmt::dump() const { print(dbgs()); } void ScopStmt::removeMemoryAccess(MemoryAccess *MA) { - // Remove the memory accesses from this statement - // together with all scalar accesses that were caused by it. - // MK_Value READs have no access instruction, hence would not be removed by - // this function. However, it is only used for invariant LoadInst accesses, - // its arguments are always affine, hence synthesizable, and therefore there - // are no MK_Value READ accesses to be removed. + // Remove the memory accesses from this statement together with all scalar + // accesses that were caused by it. MemoryKind::Value READs have no access + // instruction, hence would not be removed by this function. However, it is + // only used for invariant LoadInst accesses, its arguments are always affine, + // hence synthesizable, and therefore there are no MemoryKind::Value READ + // accesses to be removed. auto Predicate = [&](MemoryAccess *Acc) { return Acc->getAccessInstruction() == MA->getAccessInstruction(); }; @@ -3344,7 +3344,7 @@ void Scop::updateAccessDimensionality() { if (!Access->isArrayKind()) continue; auto &SAI = ScopArrayInfoMap[std::make_pair(Access->getBaseAddr(), - ScopArrayInfo::MK_Array)]; + MemoryKind::Array)]; if (SAI->getNumberOfDimensions() != 1) continue; unsigned DivisibleSize = SAI->getElemSizeInBytes(); @@ -3688,9 +3688,10 @@ void Scop::hoistInvariantLoads() { isl_union_map_free(Writes); } -const ScopArrayInfo *Scop::getOrCreateScopArrayInfo( - Value *BasePtr, Type *ElementType, ArrayRef<const SCEV *> Sizes, - ScopArrayInfo::MemoryKind Kind, const char *BaseName) { +const ScopArrayInfo * +Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *ElementType, + ArrayRef<const SCEV *> Sizes, MemoryKind Kind, + const char *BaseName) { assert((BasePtr || BaseName) && "BasePtr and BaseName can not be nullptr at the same time."); assert(!(BasePtr && BaseName) && "BaseName is redundant."); @@ -3723,14 +3724,12 @@ Scop::createScopArrayInfo(Type *ElementType, const std::string &BaseName, else SCEVSizes.push_back(nullptr); - auto *SAI = - getOrCreateScopArrayInfo(nullptr, ElementType, SCEVSizes, - ScopArrayInfo::MK_Array, BaseName.c_str()); + auto *SAI = getOrCreateScopArrayInfo(nullptr, ElementType, SCEVSizes, + MemoryKind::Array, BaseName.c_str()); return SAI; } -const ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr, - ScopArrayInfo::MemoryKind Kind) { +const ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr, MemoryKind Kind) { auto *SAI = ScopArrayInfoMap[std::make_pair(BasePtr, Kind)].get(); assert(SAI && "No ScopArrayInfo available for this base pointer"); return SAI; diff --git a/polly/lib/CodeGen/BlockGenerators.cpp b/polly/lib/CodeGen/BlockGenerators.cpp index 0cf65eccd60..236e0ceccd8 100644 --- a/polly/lib/CodeGen/BlockGenerators.cpp +++ b/polly/lib/CodeGen/BlockGenerators.cpp @@ -1366,8 +1366,8 @@ Value *RegionGenerator::getExitScalar(MemoryAccess *MA, LoopToScevMapT <S, return buildExitPHI(MA, LTS, BBMap, L); } - // MK_Value accesses leaving the subregion must dominate the exit block; just - // pass the copied value + // MemoryKind::Value accesses leaving the subregion must dominate the exit + // block; just pass the copied value. Value *OldVal = MA->getAccessValue(); return getNewValue(*Stmt, OldVal, BBMap, LTS, L); } diff --git a/polly/lib/CodeGen/PPCGCodeGeneration.cpp b/polly/lib/CodeGen/PPCGCodeGeneration.cpp index 6f3ede81f1f..456382c2be6 100644 --- a/polly/lib/CodeGen/PPCGCodeGeneration.cpp +++ b/polly/lib/CodeGen/PPCGCodeGeneration.cpp @@ -1245,7 +1245,7 @@ void GPUNodeBuilder::createKernel(__isl_take isl_ast_node *KernelStmt) { IDToSAI.clear(); Annotator.resetAlternativeAliasBases(); for (auto &BasePtr : LocalArrays) - S.invalidateScopArrayInfo(BasePtr, ScopArrayInfo::MK_Array); + S.invalidateScopArrayInfo(BasePtr, MemoryKind::Array); LocalArrays.clear(); std::string ASMString = finalizeKernelFunction(); @@ -1347,7 +1347,7 @@ GPUNodeBuilder::createKernelFunctionDecl(ppcg_kernel *Kernel, Sizes.push_back(SE.getSCEV(V)); } const ScopArrayInfo *SAIRep = - S.getOrCreateScopArrayInfo(Val, EleTy, Sizes, ScopArrayInfo::MK_Array); + S.getOrCreateScopArrayInfo(Val, EleTy, Sizes, MemoryKind::Array); LocalArrays.push_back(Val); isl_ast_build_free(Build); @@ -1526,8 +1526,8 @@ void GPUNodeBuilder::createKernelVariables(ppcg_kernel *Kernel, Function *FN) { } else { llvm_unreachable("unknown variable type"); } - SAI = S.getOrCreateScopArrayInfo(Allocation, EleTy, Sizes, - ScopArrayInfo::MK_Array); + SAI = + S.getOrCreateScopArrayInfo(Allocation, EleTy, Sizes, MemoryKind::Array); Id = isl_id_alloc(S.getIslCtx(), Var.name, nullptr); IDToValue[Id] = Allocation; LocalArrays.push_back(Allocation); |

