Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -97,20 +97,128 @@ /// class ScopArrayInfo { public: - /// @brief The type of a memory access. - enum ARRAYKIND { - // Scalar references to SSA values. - KIND_SCALAR, + /// @brief 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 KIND { + /// * KIND_ARRAY: Models a 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"). + KIND_ARRAY, - // Scalar references used to model PHI nodes + /// * KIND_VALUE: Models an llvm::Value + /// + /// Memory objects of type KIND_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 instrance, 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.sa2 | + /// ----------------------------------- + /// | | + /// ____________________________________ + /// ____________________________________ + /// |UseBB1: | |UseBB2: | + /// | %V.reload1 = load float* %V.s2a | | %V.reload2 = load float* %V.s2a + /// | + /// | use float %V.reload1 | | use float %V.reload2 | + /// ------------------------------------ + /// ------------------------------------ + /// + KIND_VALUE, + + /// KIND_PHI: Models PHI nodes within the SCoP + /// + /// Besides the KIND_VALUE memory object used to model the normal + /// llvm::Value dependences described above, PHI nodes require an additional + /// memory object of type KIND_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. KIND_PHI, - // Like KIND_PHI, but for PHIs in the exit node. Depending on context, these - // are handled like KIND_SCALAR. + /// * KIND_EXIT_PHI: 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 KIND_PHI, with the exception + /// that there are no READ 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. KIND_EXIT_PHI, - - // References to (multi-dimensional) arrays - KIND_ARRAY, }; /// @brief Construct a ScopArrayInfo object. @@ -123,7 +231,7 @@ /// @param DL The data layout of the module. /// @param S The scop this array object belongs to. ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *IslCtx, - ArrayRef DimensionSizes, enum ARRAYKIND Kind, + ArrayRef DimensionSizes, enum KIND Kind, const DataLayout &DL, Scop *S); /// @brief Update the sizes of the ScopArrayInfo object. @@ -250,7 +358,7 @@ /// @brief The type of this scop array info object. /// /// We distinguish between SCALAR, PHI and ARRAY objects. - enum ARRAYKIND Kind; + enum KIND Kind; /// @brief The data layout of the module. const DataLayout &DL; @@ -265,113 +373,7 @@ friend class ScopStmt; public: - /// @brief Description of the cause of a MemoryAccess being added. - /// - /// We distinguish between explicit and implicit accesses. Explicit are those - /// for which there is a load or store instruction in the analyzed IR. - /// Implicit accesses are derived from defintions and uses of llvm::Values. - /// The polyhedral model has no notion of such values or SSA form, hence they - /// are modeled "as if" they were accesses to zero-dimensional arrays even if - /// they do represent accesses to (main) memory in the analyzed IR code. The - /// actual memory for the zero-dimensional arrays is only created using - /// allocas at CodeGeneration, with suffixes (currently ".s2a" and ".phiops") - /// added to the value's name. To describe how def/uses are modeled using - /// accesses we use these these suffixes here as well. - /// There are currently three separate kinds of access origins: - /// - /// - /// * Explicit access - /// - /// Memory is accessed by either a load (READ) or store (*_WRITE) found in the - /// IR. #AccessInst is the LoadInst respectively StoreInst. The #BaseAddr is - /// the array pointer being accesses without subscript. #AccessValue is the - /// llvm::Value the StoreInst writes, respectively the result of the LoadInst - /// (the LoadInst itself). - /// - /// - /// * Accessing an llvm::Value (a scalar) - /// - /// This is either a *_WRITE for the value's definition (i.e. exactly one per - /// llvm::Value) or a READ when the scalar is used in a different - /// BasicBlock. For instance, a use/def chain of such as %V in - /// ______________________ - /// |DefBB: | - /// | %V = float op ... | - /// ---------------------- - /// | | - /// _________________ _________________ - /// |UseBB1: | |UseBB2: | - /// | use float %V | | use float %V | - /// ----------------- ----------------- - /// - /// is modeled as if the accesses had occured this way: - /// - /// __________________________ - /// |entry: | - /// | %V.s2a = alloca float | - /// -------------------------- - /// | - /// ___________________________________ - /// |DefBB: | - /// | store %float %V, float* %V.sa2 | - /// ----------------------------------- - /// | | - /// ____________________________________ ____________________________________ - /// |UseBB1: | |UseBB2: | - /// | %V.reload1 = load float* %V.s2a | | %V.reload2 = load float* %V.s2a | - /// | use float %V.reload1 | | use float %V.reload2 | - /// ------------------------------------ ------------------------------------ - /// - /// #AccessInst is either the llvm::Value for WRITEs or the value's user for - /// READS. The #BaseAddr is represented by the value's definition (i.e. the - /// llvm::Value itself) as no such alloca yet exists before CodeGeneration. - /// #AccessValue is also the llvm::Value itself. - /// - /// - /// * Accesses to emulate PHI nodes within the SCoP - /// - /// PHIInst instructions such as - /// - /// %PHI = phi float [ %Val1, %IncomingBlock1 ], [ %Val2, %IncomingBlock2 ] - /// - /// are 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 | - /// ----------------------------------------- - /// - /// Since the stores and loads do not exist in the analyzed code, the - /// #AccessInst of a load is the PHIInst and a incoming block's terminator for - /// stores. The #BaseAddr is represented through the PHINode because there - /// also such alloca in the analyzed code. The #AccessValue is represented by - /// the PHIInst itself. - /// - /// Note that there can also be a scalar write access for %PHI if used in a - /// different BasicBlock, i.e. there can be a %PHI.phiops as well as a - /// %PHI.s2a. - /// - /// - /// * Accesses to emulate PHI nodes that are in the SCoP's exit block - /// - /// Like the previous, but the PHI itself is not located in the SCoP itself. - /// There will be no READ type MemoryAccess for such values. The PHINode's - /// llvm::Value is treated as a value escaping the SCoP. WRITE accesses write - /// directly to the escaping value's ".s2a" alloca. - enum AccessOrigin { EXPLICIT, SCALAR, PHI, EXIT_PHI }; + typedef ScopArrayInfo::KIND ARRAYKIND; /// @brief The access type of a memory access /// @@ -421,9 +423,9 @@ /// scop statement. isl_id *Id; - /// @brief What is modeled by this MemoetyAccess. - /// @see AccessOrigin - enum AccessOrigin Origin; + /// @brief What is modeled by this MemoryAccess. + /// @see KIND + ARRAYKIND ArrayKind; /// @brief Whether it a reading or writing access, and if writing, whether it /// is conditional (MAY_WRITE). @@ -463,6 +465,13 @@ // @{ /// @brief The base address (e.g., A for A[i+j]). + /// + /// The #BaseAddr of a memory access of kind KIND_ARRAY is the base pointer + /// of the memory access. + /// The #BaseAddr of a memory access of kind KIND_PHI or KIND_EXIT_PHI is the + /// PHI node itself. + /// The #BaseAddr of a memory access of kind KIND_VALUE is the instruction + /// defining the value. AssertingVH BaseAddr; /// @brief An unique name of the accessed array. @@ -479,13 +488,27 @@ // @{ /// @brief The access instruction of this memory access. + /// + /// For memory accesses of kind KIND_ARRAY the access instruction is the + /// Load or Store instruction performing the access. + /// + /// For memory accesses of kind KIND_PHI or KIND_EXIT_PHI 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 + /// intruction. + /// + /// For memory accesses of kind KIND_VALUE the access instruction of a load + /// access is the instruction that uses the load. The access instruction of + /// a write access is the intruction that defines the llvm::Value. Instruction *AccessInstruction; /// @brief The value associated with this memory access. /// - /// - For real memory accesses it is the loaded result or the stored value. - /// - For straight line scalar accesses it is the access instruction itself. - /// - For PHI operand accesses it is the operand value. + /// - For array memory accesses (KIND_ARRAY) it is the loaded result or the + /// stored value. + /// - For accesses of kind KIND_VALUE it is the access instruction itself. + /// - For accesses of kind KIND_PHI or KIND_EXIT_PHI it is the operand value + /// of the PHI node. /// AssertingVH AccessValue; @@ -572,14 +595,14 @@ /// @param ElemBytes Number of accessed bytes. /// @param AccType Whether read or write access. /// @param IsAffine Whether the subscripts are affine expressions. - /// @param Origin What is the purpose of this access? + /// @param ArrayKind The kind of memory accessed. /// @param Subscripts Subscipt expressions /// @param Sizes Dimension lengths of the accessed array. /// @param BaseName Name of the acessed array. MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst, AccessType Type, Value *BaseAddress, unsigned ElemBytes, bool Affine, ArrayRef Subscripts, ArrayRef Sizes, - Value *AccessValue, AccessOrigin Origin, StringRef BaseName); + Value *AccessValue, ARRAYKIND ArrayKind, StringRef BaseName); ~MemoryAccess(); /// @brief Get the type of a memory access. @@ -674,21 +697,24 @@ bool isStrideZero(__isl_take const isl_map *Schedule) const; /// @brief Whether this is an access of an explicit load or store in the IR. - bool isExplicit() const { return Origin == EXPLICIT; } + bool isKindArray() const { return ArrayKind == ScopArrayInfo::KIND_ARRAY; } - /// @brief Whether this access represents a register access or models PHI - /// nodes. - bool isImplicit() const { return !isExplicit(); } + /// @brief Whether this access is an array to a scalar memory object. + /// + /// Scalar accesses are accesses to KIND_VALUE, KIND_PHI or KIND_EXIT_PHI. + bool isKindScalar() const { return !isKindArray(); } /// @brief Is this MemoryAccess modeling scalar dependences? - bool isScalar() const { return Origin == SCALAR; } + bool isKindValue() const { return ArrayKind == ScopArrayInfo::KIND_VALUE; } /// @brief Is this MemoryAccess modeling special PHI node accesses? - bool isPHI() const { return Origin == PHI; } + bool isKindPHI() const { return ArrayKind == ScopArrayInfo::KIND_PHI; } /// @brief Is this MemoryAccess modeling the accesses of a PHI node in the /// SCoP's exit block? - bool isExitPHI() const { return Origin == EXIT_PHI; } + bool isKindExitPHI() const { + return ArrayKind == ScopArrayInfo::KIND_EXIT_PHI; + } /// @brief Get the statement that contains this memory access. ScopStmt *getStatement() const { return Statement; } @@ -1595,14 +1621,14 @@ const ScopArrayInfo *getOrCreateScopArrayInfo(Value *BasePtr, Type *ElementType, ArrayRef Sizes, - ScopArrayInfo::ARRAYKIND Kind); + ScopArrayInfo::KIND Kind); /// @brief Return the cached ScopArrayInfo object for @p BasePtr. /// /// @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::ARRAYKIND Kind); + ScopArrayInfo::KIND Kind); void setContext(isl_set *NewContext); @@ -1811,13 +1837,13 @@ /// @param AccessValue Value read or written. /// @param Subscripts Access subscripts per dimension. /// @param Sizes The array diminsion's sizes. - /// @param Origin Purpose of this access. + /// @param ArrayKind The kind of memory accessed. void addMemoryAccess(BasicBlock *BB, Instruction *Inst, MemoryAccess::AccessType Type, Value *BaseAddress, unsigned ElemBytes, bool Affine, Value *AccessValue, ArrayRef Subscripts, ArrayRef Sizes, - MemoryAccess::AccessOrigin Origin); + MemoryAccess::ARRAYKIND ArrayKind); /// @brief Create a MemoryAccess that represents either a LoadInst or /// StoreInst. @@ -1830,11 +1856,11 @@ /// @param Subscripts Access subscripts per dimension. /// @param Sizes The array dimension's sizes. /// @param AccessValue Value read or written. - /// @see AccessOrigin - void addExplicitAccess(Instruction *MemAccInst, MemoryAccess::AccessType Type, - Value *BaseAddress, unsigned ElemBytes, bool IsAffine, - ArrayRef Subscripts, - ArrayRef Sizes, Value *AccessValue); + /// @see ScopArrayInfo::KIND + void addArrayAccess(Instruction *MemAccInst, MemoryAccess::AccessType Type, + Value *BaseAddress, unsigned ElemBytes, bool IsAffine, + ArrayRef Subscripts, + ArrayRef Sizes, Value *AccessValue); /// @brief Create a MemoryAccess for writing an llvm::Value. /// @@ -1842,7 +1868,7 @@ /// /// @param Value The value to be written. /// @see addScalarReadAccess() - /// @see AccessOrigin + /// @see ScopArrayInfo::KIND void addScalarWriteAccess(Instruction *Value); /// @brief Create a MemoryAccess for reloading an llvm::Value. @@ -1852,7 +1878,7 @@ /// @param Value The scalar expected to be loaded. /// @param User User of the scalar; this is where the access is added. /// @see addScalarWriteAccess() - /// @see AccessOrigin + /// @see ScopArrayInfo::KIND void addScalarReadAccess(Value *Value, Instruction *User); /// @brief Create a MemoryAccess for reloading an llvm::Value. @@ -1866,7 +1892,7 @@ /// @param UserBB Incoming block for the incoming @p Value. /// @see addPHIWriteAccess() /// @see addScalarWriteAccess() - /// @see AccessOrigin + /// @see ScopArrayInfo::KIND void addScalarReadAccess(Value *Value, PHINode *User, BasicBlock *UserBB); /// @brief Create a write MemoryAccess for the incoming block of a phi node. @@ -1881,7 +1907,7 @@ /// .phiops one. Required for values escaping through a /// PHINode in the SCoP region's exit block. /// @see addPHIReadAccess() - /// @see AccessOrigin + /// @see ScopArrayInfo::KIND void addPHIWriteAccess(PHINode *PHI, BasicBlock *IncomingBlock, Value *IncomingValue, bool IsExitBlock); @@ -1894,7 +1920,7 @@ /// @param PHI PHINode under consideration; the READ access will be added /// here. /// @see addPHIWriteAccess() - /// @see AccessOrigin + /// @see ScopArrayInfo::KIND void addPHIReadAccess(PHINode *PHI); public: Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -170,7 +170,7 @@ } ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *Ctx, - ArrayRef Sizes, enum ARRAYKIND Kind, + ArrayRef Sizes, enum KIND Kind, const DataLayout &DL, Scop *S) : BasePtr(BasePtr), ElementType(ElementType), Kind(Kind), DL(DL), S(*S) { std::string BasePtrName = @@ -702,8 +702,8 @@ unsigned ElemBytes, bool Affine, ArrayRef Subscripts, ArrayRef Sizes, Value *AccessValue, - AccessOrigin Origin, StringRef BaseName) - : Origin(Origin), AccType(Type), RedType(RT_NONE), Statement(Stmt), + ARRAYKIND ArrayKind, StringRef BaseName) + : ArrayKind(ArrayKind), AccType(Type), RedType(RT_NONE), Statement(Stmt), BaseAddr(BaseAddress), BaseName(BaseName), ElemBytes(ElemBytes), Sizes(Sizes.begin(), Sizes.end()), AccessInstruction(AccessInst), AccessValue(AccessValue), IsAffine(Affine), @@ -747,7 +747,7 @@ break; } OS << "[Reduction Type: " << getReductionType() << "] "; - OS << "[Scalar: " << isImplicit() << "]\n"; + OS << "[Scalar: " << isKindScalar() << "]\n"; OS.indent(16) << getOriginalAccessRelationStr() << ";\n"; if (hasNewAccessRelation()) OS.indent(11) << "new: " << getNewAccessRelationStr() << ";\n"; @@ -880,13 +880,13 @@ for (MemoryAccess *Access : MemAccs) { Type *ElementType = Access->getAccessValue()->getType(); - ScopArrayInfo::ARRAYKIND Ty; - if (Access->isPHI()) + ScopArrayInfo::KIND Ty; + if (Access->isKindPHI()) Ty = ScopArrayInfo::KIND_PHI; - else if (Access->isExitPHI()) + else if (Access->isKindExitPHI()) Ty = ScopArrayInfo::KIND_EXIT_PHI; - else if (Access->isScalar()) - Ty = ScopArrayInfo::KIND_SCALAR; + else if (Access->isKindValue()) + Ty = ScopArrayInfo::KIND_VALUE; else Ty = ScopArrayInfo::KIND_ARRAY; @@ -2467,7 +2467,7 @@ continue; for (MemoryAccess *MA : Stmt) { - if (MA->isImplicit()) + if (MA->isKindScalar()) continue; if (!MA->isRead()) HasWriteAccess.insert(MA->getBaseAddr()); @@ -2868,7 +2868,7 @@ MemoryAccessList InvMAs; for (MemoryAccess *MA : Stmt) { - if (MA->isImplicit() || MA->isWrite() || !MA->isAffine()) + if (MA->isKindScalar() || MA->isWrite() || !MA->isAffine()) continue; // Skip accesses that have an invariant base pointer which is defined but @@ -2959,7 +2959,7 @@ const ScopArrayInfo * Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *AccessType, ArrayRef Sizes, - ScopArrayInfo::ARRAYKIND Kind) { + ScopArrayInfo::KIND Kind) { auto &SAI = ScopArrayInfoMap[std::make_pair(BasePtr, Kind)]; if (!SAI) { auto &DL = getRegion().getEntry()->getModule()->getDataLayout(); @@ -2976,7 +2976,7 @@ } const ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr, - ScopArrayInfo::ARRAYKIND Kind) { + ScopArrayInfo::KIND Kind) { auto *SAI = ScopArrayInfoMap[std::make_pair(BasePtr, Kind)].get(); assert(SAI && "No ScopArrayInfo available for this base pointer"); return SAI; @@ -3734,8 +3734,8 @@ SizesSCEV.push_back(SE->getSCEV(ConstantInt::get( IntegerType::getInt64Ty(BasePtr->getContext()), Size))); - addExplicitAccess(Inst, Type, BasePointer->getValue(), Size, true, - Subscripts, SizesSCEV, Val); + addArrayAccess(Inst, Type, BasePointer->getValue(), Size, true, + Subscripts, SizesSCEV, Val); return; } } @@ -3743,9 +3743,9 @@ auto AccItr = InsnToMemAcc.find(Inst); if (PollyDelinearize && AccItr != InsnToMemAcc.end()) { - addExplicitAccess(Inst, Type, BasePointer->getValue(), Size, true, - AccItr->second.DelinearizedSubscripts, - AccItr->second.Shape->DelinearizedSizes, Val); + addArrayAccess(Inst, Type, BasePointer->getValue(), Size, true, + AccItr->second.DelinearizedSubscripts, + AccItr->second.Shape->DelinearizedSizes, Val); return; } @@ -3776,9 +3776,9 @@ if (!IsAffine && Type == MemoryAccess::MUST_WRITE) Type = MemoryAccess::MAY_WRITE; - addExplicitAccess(Inst, Type, BasePointer->getValue(), Size, IsAffine, - ArrayRef(AccessFunction), - ArrayRef(SizeSCEV), Val); + addArrayAccess(Inst, Type, BasePointer->getValue(), Size, IsAffine, + ArrayRef(AccessFunction), + ArrayRef(SizeSCEV), Val); } void ScopInfo::buildAccessFunctions(Region &R, Region &SR) { @@ -3867,7 +3867,7 @@ bool Affine, Value *AccessValue, ArrayRef Subscripts, ArrayRef Sizes, - MemoryAccess::AccessOrigin Origin) { + MemoryAccess::ARRAYKIND ArrayKind) { ScopStmt *Stmt = scop->getStmtForBasicBlock(BB); // Do not create a memory access for anything not in the SCoP. It would be @@ -3885,48 +3885,51 @@ Type = MemoryAccess::MAY_WRITE; AccList.emplace_back(Stmt, Inst, Type, BaseAddress, ElemBytes, Affine, - Subscripts, Sizes, AccessValue, Origin, BaseName); + Subscripts, Sizes, AccessValue, ArrayKind, BaseName); Stmt->addAccess(&AccList.back()); } -void ScopInfo::addExplicitAccess( - Instruction *MemAccInst, MemoryAccess::AccessType Type, Value *BaseAddress, - unsigned ElemBytes, bool IsAffine, ArrayRef Subscripts, - ArrayRef Sizes, Value *AccessValue) { +void ScopInfo::addArrayAccess(Instruction *MemAccInst, + MemoryAccess::AccessType Type, Value *BaseAddress, + unsigned ElemBytes, bool IsAffine, + ArrayRef Subscripts, + ArrayRef Sizes, + Value *AccessValue) { assert(isa(MemAccInst) || isa(MemAccInst)); assert(isa(MemAccInst) == (Type == MemoryAccess::READ)); addMemoryAccess(MemAccInst->getParent(), MemAccInst, Type, BaseAddress, ElemBytes, IsAffine, AccessValue, Subscripts, Sizes, - MemoryAccess::EXPLICIT); + ScopArrayInfo::KIND_ARRAY); } void ScopInfo::addScalarWriteAccess(Instruction *Value) { addMemoryAccess(Value->getParent(), Value, MemoryAccess::MUST_WRITE, Value, 1, true, Value, ArrayRef(), - ArrayRef(), MemoryAccess::SCALAR); + ArrayRef(), ScopArrayInfo::KIND_VALUE); } void ScopInfo::addScalarReadAccess(Value *Value, Instruction *User) { assert(!isa(User)); addMemoryAccess(User->getParent(), User, MemoryAccess::READ, Value, 1, true, Value, ArrayRef(), ArrayRef(), - MemoryAccess::SCALAR); + ScopArrayInfo::KIND_VALUE); } void ScopInfo::addScalarReadAccess(Value *Value, PHINode *User, BasicBlock *UserBB) { addMemoryAccess(UserBB, User, MemoryAccess::READ, Value, 1, true, Value, ArrayRef(), ArrayRef(), - MemoryAccess::SCALAR); + ScopArrayInfo::KIND_VALUE); } void ScopInfo::addPHIWriteAccess(PHINode *PHI, BasicBlock *IncomingBlock, Value *IncomingValue, bool IsExitBlock) { addMemoryAccess(IncomingBlock, IncomingBlock->getTerminator(), MemoryAccess::MUST_WRITE, PHI, 1, true, IncomingValue, ArrayRef(), ArrayRef(), - IsExitBlock ? MemoryAccess::EXIT_PHI : MemoryAccess::PHI); + IsExitBlock ? ScopArrayInfo::KIND_EXIT_PHI + : ScopArrayInfo::KIND_PHI); } void ScopInfo::addPHIReadAccess(PHINode *PHI) { addMemoryAccess(PHI->getParent(), PHI, MemoryAccess::READ, PHI, 1, true, PHI, ArrayRef(), ArrayRef(), - MemoryAccess::PHI); + ScopArrayInfo::KIND_PHI); } void ScopInfo::buildScop(Region &R, DominatorTree &DT, AssumptionCache &AC) { Index: lib/CodeGen/BlockGenerators.cpp =================================================================== --- lib/CodeGen/BlockGenerators.cpp +++ lib/CodeGen/BlockGenerators.cpp @@ -332,7 +332,7 @@ } Value *BlockGenerator::getOrCreateAlloca(MemoryAccess &Access) { - if (Access.isPHI()) + if (Access.isKindPHI()) return getOrCreatePHIAlloca(Access.getBaseAddr()); else return getOrCreateScalarAlloca(Access.getBaseAddr()); @@ -388,7 +388,7 @@ void BlockGenerator::generateScalarLoads(ScopStmt &Stmt, ValueMapT &BBMap) { for (MemoryAccess *MA : Stmt) { - if (MA->isExplicit() || MA->isWrite()) + if (MA->isKindArray() || MA->isWrite()) continue; auto *Address = getOrCreateAlloca(*MA); @@ -453,7 +453,7 @@ "RegionGenerator"); for (MemoryAccess *MA : Stmt) { - if (MA->isExplicit() || MA->isRead()) + if (MA->isKindArray() || MA->isRead()) continue; Value *Val = MA->getAccessValue(); @@ -1188,7 +1188,7 @@ "function in the BlockGenerator"); for (MemoryAccess *MA : Stmt) { - if (MA->isExplicit() || MA->isRead()) + if (MA->isKindArray() || MA->isRead()) continue; Instruction *ScalarInst = MA->getAccessInstruction(); @@ -1200,8 +1200,8 @@ auto SavedInsertionPoint = Builder.GetInsertPoint(); ValueMapT *LocalBBMap = &BBMap; - // Implicit writes induced by PHIs must be written in the incoming blocks. - if (MA->isPHI() || MA->isExitPHI()) { + // Scalar writes induced by PHIs must be written in the incoming blocks. + if (MA->isKindPHI() || MA->isKindExitPHI()) { BasicBlock *ExitingBB = ScalarInst->getParent(); BasicBlock *ExitingBBCopy = BlockMap[ExitingBB]; Builder.SetInsertPoint(ExitingBBCopy->getTerminator()); @@ -1217,7 +1217,7 @@ Builder.CreateStore(Val, Address); // Restore the insertion point if necessary. - if (MA->isPHI() || MA->isExitPHI()) + if (MA->isKindPHI() || MA->isKindExitPHI()) Builder.SetInsertPoint(SavedInsertBB, SavedInsertionPoint); } } Index: lib/CodeGen/IslNodeBuilder.cpp =================================================================== --- lib/CodeGen/IslNodeBuilder.cpp +++ lib/CodeGen/IslNodeBuilder.cpp @@ -219,7 +219,7 @@ } for (auto &Access : *Stmt) { - if (Access->isExplicit()) { + if (Access->isKindArray()) { auto *BasePtr = Access->getScopArrayInfo()->getBasePtr(); if (Instruction *OpInst = dyn_cast(BasePtr)) if (Stmt->getParent()->getRegion().contains(OpInst)) @@ -1008,7 +1008,7 @@ return true; MemoryAccess *MA = MAs.front(); - assert(MA->isExplicit() && MA->isRead()); + assert(MA->isKindArray() && MA->isRead()); // If the access function was already mapped, the preload of this equivalence // class was triggered earlier already and doesn't need to be done again.