diff options
| -rw-r--r-- | polly/include/polly/ScopInfo.h | 74 | ||||
| -rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 38 | ||||
| -rw-r--r-- | polly/lib/CodeGen/BlockGenerators.cpp | 6 | ||||
| -rw-r--r-- | polly/lib/CodeGen/IslNodeBuilder.cpp | 2 |
4 files changed, 88 insertions, 32 deletions
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h index ac2c440fb73..53cc5a7c93d 100644 --- a/polly/include/polly/ScopInfo.h +++ b/polly/include/polly/ScopInfo.h @@ -218,6 +218,56 @@ class MemoryAccess { friend class ScopStmt; public: + /// @brief Description of the reason why a MemoryAccess was added. + /// + /// There are currently three separate 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 being used in a different + /// BasicBlock. In CodeGeneration, it results in alloca postfixed with .s2a. + /// #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 + /// + /// CodeGeneration converts a PHI node such as + /// %PHI = phi float [ %Val1, %IncomingBlock1 ], [ %Val2, %IncomingBlock2 ] + /// into + /// + /// %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 no alloca before CodeGeneration. 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. + enum AccessOrigin { EXPLICIT, SCALAR, PHI }; + /// @brief The access type of a memory access /// /// There are three kind of access types: @@ -266,8 +316,9 @@ private: /// scop statement. isl_id *Id; - /// @brief Is this MemoryAccess modeling special PHI node accesses? - bool IsPHI; + /// @brief The accesses' purpose. + /// @see AccessOrigin + enum AccessOrigin Origin; /// @brief Whether it a reading or writing access, and if writing, whether it /// is conditional (MAY_WRITE). @@ -351,7 +402,7 @@ private: bool isAffine() const { return IsAffine; } /// @brief Is this MemoryAccess modeling special PHI node accesses? - bool isPHI() const { return IsPHI; } + bool isPHI() const { return Origin == PHI; } void setStatement(ScopStmt *Stmt) { this->Statement = Stmt; } @@ -422,14 +473,14 @@ public: /// @param ElemBytes Number of accessed bytes. /// @param AccType Whether read or write access. /// @param IsAffine Whether the subscripts are affine expressions. - /// @param IsPHI Are we modeling special PHI node accesses? + /// @param Origin What is the purpose of this access? /// @param Subscripts Subscipt expressions /// @param Sizes Dimension lengths of the accessed array. /// @param BaseName Name of the acessed array. MemoryAccess(Instruction *AccessInst, __isl_take isl_id *Id, AccessType Type, Value *BaseAddress, unsigned ElemBytes, bool Affine, ArrayRef<const SCEV *> Subscripts, ArrayRef<const SCEV *> Sizes, - Value *AccessValue, bool IsPHI, StringRef BaseName); + Value *AccessValue, AccessOrigin Origin, StringRef BaseName); ~MemoryAccess(); /// @brief Get the type of a memory access. @@ -523,8 +574,12 @@ public: /// statement. bool isStrideZero(__isl_take const isl_map *Schedule) const; - /// @brief Check if this is a scalar memory access. - bool isScalar() const; + /// @brief Whether this is an access of an explicit load or store in the IR. + bool isExplicit() const { return Origin == EXPLICIT; } + + /// @brief Whether this access represents a register access or models PHI + /// nodes. + bool isImplicit() const { return !isExplicit(); } /// @brief Get the statement that contains this memory access. ScopStmt *getStatement() const { return Statement; } @@ -1483,12 +1538,13 @@ class ScopInfo : public RegionPass { /// @param AccessValue Value read or written. /// @param Subscripts Access subscripts per dimension. /// @param Sizes The array diminsion's sizes. - /// @param IsPHI Whether this is an emulated PHI node. + /// @param Origin Purpose of this access. void addMemoryAccess(BasicBlock *BB, Instruction *Inst, MemoryAccess::AccessType Type, Value *BaseAddress, unsigned ElemBytes, bool Affine, Value *AccessValue, ArrayRef<const SCEV *> Subscripts, - ArrayRef<const SCEV *> Sizes, bool IsPHI); + ArrayRef<const SCEV *> Sizes, + MemoryAccess::AccessOrigin Origin); /// @brief Create a MemoryAccess that represents either a LoadInst or /// StoreInst. diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index b23ddcdb32a..219627b287c 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -606,11 +606,11 @@ MemoryAccess::MemoryAccess(Instruction *AccessInst, __isl_take isl_id *Id, unsigned ElemBytes, bool Affine, ArrayRef<const SCEV *> Subscripts, ArrayRef<const SCEV *> Sizes, Value *AccessValue, - bool IsPHI, StringRef BaseName) - : Id(Id), IsPHI(IsPHI), AccType(Type), RedType(RT_NONE), Statement(nullptr), - BaseAddr(BaseAddress), BaseName(BaseName), ElemBytes(ElemBytes), - Sizes(Sizes.begin(), Sizes.end()), AccessInstruction(AccessInst), - AccessValue(AccessValue), IsAffine(Affine), + AccessOrigin Origin, StringRef BaseName) + : Id(Id), Origin(Origin), AccType(Type), RedType(RT_NONE), + Statement(nullptr), BaseAddr(BaseAddress), BaseName(BaseName), + ElemBytes(ElemBytes), Sizes(Sizes.begin(), Sizes.end()), + AccessInstruction(AccessInst), AccessValue(AccessValue), IsAffine(Affine), Subscripts(Subscripts.begin(), Subscripts.end()), AccessRelation(nullptr), NewAccessRelation(nullptr) {} @@ -647,7 +647,7 @@ void MemoryAccess::print(raw_ostream &OS) const { break; } OS << "[Reduction Type: " << getReductionType() << "] "; - OS << "[Scalar: " << isScalar() << "]\n"; + OS << "[Scalar: " << isImplicit() << "]\n"; OS.indent(16) << getOriginalAccessRelationStr() << ";\n"; if (hasNewAccessRelation()) OS.indent(11) << "new: " << getNewAccessRelationStr() << ";\n"; @@ -730,10 +730,6 @@ bool MemoryAccess::isStrideZero(const isl_map *Schedule) const { return isStrideX(Schedule, 0); } -bool MemoryAccess::isScalar() const { - return isl_map_n_out(AccessRelation) == 0; -} - bool MemoryAccess::isStrideOne(const isl_map *Schedule) const { return isStrideX(Schedule, 1); } @@ -1978,7 +1974,7 @@ bool Scop::buildAliasGroups(AliasAnalysis &AA) { continue; for (MemoryAccess *MA : Stmt) { - if (MA->isScalar()) + if (MA->isImplicit()) continue; if (!MA->isRead()) HasWriteAccess.insert(MA->getBaseAddr()); @@ -2948,7 +2944,8 @@ void ScopInfo::addMemoryAccess(BasicBlock *BB, Instruction *Inst, Value *BaseAddress, unsigned ElemBytes, bool Affine, Value *AccessValue, ArrayRef<const SCEV *> Subscripts, - ArrayRef<const SCEV *> Sizes, bool IsPHI) { + ArrayRef<const SCEV *> Sizes, + MemoryAccess::AccessOrigin Origin) { AccFuncSetType &AccList = AccFuncMap[BB]; size_t Identifier = AccList.size(); @@ -2959,7 +2956,7 @@ void ScopInfo::addMemoryAccess(BasicBlock *BB, Instruction *Inst, isl_id *Id = isl_id_alloc(ctx, IdName.c_str(), nullptr); AccList.emplace_back(Inst, Id, Type, BaseAddress, ElemBytes, Affine, - Subscripts, Sizes, AccessValue, IsPHI, BaseName); + Subscripts, Sizes, AccessValue, Origin, BaseName); } void ScopInfo::addExplicitAccess( @@ -2969,34 +2966,37 @@ void ScopInfo::addExplicitAccess( assert(isa<LoadInst>(MemAccInst) || isa<StoreInst>(MemAccInst)); assert(isa<LoadInst>(MemAccInst) == (Type == MemoryAccess::READ)); addMemoryAccess(MemAccInst->getParent(), MemAccInst, Type, BaseAddress, - ElemBytes, IsAffine, AccessValue, Subscripts, Sizes, false); + ElemBytes, IsAffine, AccessValue, Subscripts, Sizes, + MemoryAccess::EXPLICIT); } void ScopInfo::addScalarWriteAccess(Instruction *Value) { addMemoryAccess(Value->getParent(), Value, MemoryAccess::MUST_WRITE, Value, 1, true, Value, ArrayRef<const SCEV *>(), - ArrayRef<const SCEV *>(), false); + ArrayRef<const SCEV *>(), MemoryAccess::SCALAR); } void ScopInfo::addScalarReadAccess(Value *Value, Instruction *User) { assert(!isa<PHINode>(User)); addMemoryAccess(User->getParent(), User, MemoryAccess::READ, Value, 1, true, Value, ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(), - false); + MemoryAccess::SCALAR); } void ScopInfo::addScalarReadAccess(Value *Value, PHINode *User, BasicBlock *UserBB) { addMemoryAccess(UserBB, User, MemoryAccess::READ, Value, 1, true, Value, - ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(), false); + ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(), + MemoryAccess::SCALAR); } void ScopInfo::addPHIWriteAccess(PHINode *PHI, BasicBlock *IncomingBlock, Value *IncomingValue, bool IsExitBlock) { addMemoryAccess(IncomingBlock, IncomingBlock->getTerminator(), MemoryAccess::MUST_WRITE, PHI, 1, true, IncomingValue, ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(), - !IsExitBlock); + IsExitBlock ? MemoryAccess::SCALAR : MemoryAccess::PHI); } void ScopInfo::addPHIReadAccess(PHINode *PHI) { addMemoryAccess(PHI->getParent(), PHI, MemoryAccess::READ, PHI, 1, true, PHI, - ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(), true); + ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(), + MemoryAccess::PHI); } Scop *ScopInfo::buildScop(Region &R, DominatorTree &DT) { diff --git a/polly/lib/CodeGen/BlockGenerators.cpp b/polly/lib/CodeGen/BlockGenerators.cpp index 3d1fd4d25e1..8de5f5970f1 100644 --- a/polly/lib/CodeGen/BlockGenerators.cpp +++ b/polly/lib/CodeGen/BlockGenerators.cpp @@ -407,7 +407,7 @@ void BlockGenerator::generateScalarLoads(ScopStmt &Stmt, return; for (MemoryAccess *MA : *MAL) { - if (!MA->isScalar() || !MA->isRead()) + if (MA->isExplicit() || !MA->isRead()) continue; auto *Address = getOrCreateAlloca(*MA); @@ -461,7 +461,7 @@ void BlockGenerator::generateScalarStores(ScopStmt &Stmt, BasicBlock *BB, "function in the RegionGenerator"); for (MemoryAccess *MA : Stmt) { - if (!MA->isScalar() || MA->isRead()) + if (MA->isExplicit() || MA->isRead()) continue; Value *Val = MA->getAccessValue(); @@ -1113,7 +1113,7 @@ void RegionGenerator::generateScalarStores(ScopStmt &Stmt, BasicBlock *BB, for (MemoryAccess *MA : Stmt) { - if (!MA->isScalar() || MA->isRead()) + if (MA->isExplicit() || MA->isRead()) continue; Instruction *ScalarInst = MA->getAccessInstruction(); diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp index 427f6bc3e49..85c92402dcd 100644 --- a/polly/lib/CodeGen/IslNodeBuilder.cpp +++ b/polly/lib/CodeGen/IslNodeBuilder.cpp @@ -217,7 +217,7 @@ static isl_stat addReferencesFromStmt(const ScopStmt *Stmt, void *UserPtr) { } for (auto &Access : *Stmt) { - if (!Access->isScalar()) { + if (Access->isExplicit()) { auto *BasePtr = Access->getScopArrayInfo()->getBasePtr(); if (Instruction *OpInst = dyn_cast<Instruction>(BasePtr)) if (Stmt->getParent()->getRegion().contains(OpInst)) |

