Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -829,6 +829,12 @@ /// @brief Mapping from instructions to (scalar) memory accesses. DenseMap InstructionToAccess; + /// @brief Scalar loads at the beginning of a statement. + MemoryAccessVec LeadingReads; + + /// @bried Scalar stores at the end of a statement. + MemoryAccessVec TrailingWrites; + //@} /// @brief A SCoP statement represents either a basic block (affine/precise @@ -987,6 +993,12 @@ return It->getSecond()->empty() ? nullptr : It->getSecond()->front(); } + /// @brief Return the vector of leading scalar loads. + const MemoryAccessVec &getLeadingReads() const { return LeadingReads; } + + /// @brief Return the vector of trailing scalar stores. + const MemoryAccessVec &getTrailingWrites() const { return TrailingWrites; } + void setBasicBlock(BasicBlock *Block) { // TODO: Handle the case where the statement is a region statement, thus // the entry block was split and needs to be changed in the region R. @@ -995,7 +1007,16 @@ } /// @brief Add @p Access to this statement's list of accesses. - void addAccess(MemoryAccess *Access); + /// + /// Only array accesses can be added with this methods. Use addLeadingLoad() + /// or addTrailingWrite() to add scalar accesses. + void addArrayAccess(MemoryAccess *Access); + + /// @brief Add @p Access to this statement's list of scalar loads. + void addLeadingLoad(MemoryAccess *Access); + + /// @brief Add @p Access to this statement's list of scalar stores. + void addTrailingWrite(MemoryAccess *Access); /// @brief Remove the memory access in @p InvMAs. /// @@ -1876,12 +1897,16 @@ /// @param Subscripts Access subscripts per dimension. /// @param Sizes The array diminsion's sizes. /// @param Kind 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, - ScopArrayInfo::MemoryKind Kind); + /// + /// @return The newly created MemoryAccess instance or NULL if the access + /// would have no effect. + MemoryAccess *addMemoryAccess(BasicBlock *BB, Instruction *Inst, + MemoryAccess::AccessType Type, + Value *BaseAddress, unsigned ElemBytes, + bool Affine, Value *AccessValue, + ArrayRef Subscripts, + ArrayRef Sizes, + ScopArrayInfo::MemoryKind Kind); /// @brief Create a MemoryAccess that represents either a LoadInst or /// StoreInst. Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -896,7 +896,8 @@ } } -void ScopStmt::addAccess(MemoryAccess *Access) { +void ScopStmt::addArrayAccess(MemoryAccess *Access) { + assert(Access->isArrayKind()); Instruction *AccessInst = Access->getAccessInstruction(); MemoryAccessList *&MAL = InstructionToAccess[AccessInst]; @@ -906,6 +907,22 @@ MemAccs.push_back(MAL->front()); } +void ScopStmt::addLeadingLoad(MemoryAccess *Access) { + assert(Access->isScalarKind()); + assert(Access->isRead()); + + LeadingReads.push_back(Access); + MemAccs.push_back(Access); +} + +void ScopStmt::addTrailingWrite(MemoryAccess *Access) { + assert(Access->isScalarKind()); + assert(Access->isWrite()); + + TrailingWrites.push_back(Access); + MemAccs.push_back(Access); +} + void ScopStmt::realignParams() { for (MemoryAccess *MA : *this) MA->realignParams(); @@ -1469,8 +1486,14 @@ auto Predicate = [&](MemoryAccess *Acc) { return Acc->getAccessInstruction() == MA->getAccessInstruction(); }; + LeadingReads.erase( + std::remove_if(LeadingReads.begin(), LeadingReads.end(), Predicate), + LeadingReads.end()); MemAccs.erase(std::remove_if(MemAccs.begin(), MemAccs.end(), Predicate), MemAccs.end()); + TrailingWrites.erase( + std::remove_if(TrailingWrites.begin(), TrailingWrites.end(), Predicate), + TrailingWrites.end()); InstructionToAccess.erase(MA->getAccessInstruction()); delete lookupAccessesFor(MA->getAccessInstruction()); } @@ -3867,19 +3890,19 @@ } } -void ScopInfo::addMemoryAccess(BasicBlock *BB, Instruction *Inst, - MemoryAccess::AccessType Type, - Value *BaseAddress, unsigned ElemBytes, - bool Affine, Value *AccessValue, - ArrayRef Subscripts, - ArrayRef Sizes, - ScopArrayInfo::MemoryKind Kind) { +MemoryAccess *ScopInfo::addMemoryAccess(BasicBlock *BB, Instruction *Inst, + MemoryAccess::AccessType Type, + Value *BaseAddress, unsigned ElemBytes, + bool Affine, Value *AccessValue, + ArrayRef Subscripts, + ArrayRef Sizes, + ScopArrayInfo::MemoryKind Kind) { ScopStmt *Stmt = scop->getStmtForBasicBlock(BB); // Do not create a memory access for anything not in the SCoP. It would be // ignored anyway. if (!Stmt) - return; + return nullptr; AccFuncSetType &AccList = AccFuncMap[BB]; Value *BaseAddr = BaseAddress; @@ -3897,7 +3920,7 @@ AccList.emplace_back(Stmt, Inst, Type, BaseAddress, ElemBytes, Affine, Subscripts, Sizes, AccessValue, Kind, BaseName); - Stmt->addAccess(&AccList.back()); + return &AccList.back(); } void ScopInfo::addArrayAccess(Instruction *MemAccInst, @@ -3908,39 +3931,56 @@ Value *AccessValue) { assert(isa(MemAccInst) || isa(MemAccInst)); assert(isa(MemAccInst) == (Type == MemoryAccess::READ)); - addMemoryAccess(MemAccInst->getParent(), MemAccInst, Type, BaseAddress, - ElemBytes, IsAffine, AccessValue, Subscripts, Sizes, - ScopArrayInfo::MK_Array); + + MemoryAccess *Acc = addMemoryAccess( + MemAccInst->getParent(), MemAccInst, Type, BaseAddress, ElemBytes, + IsAffine, AccessValue, Subscripts, Sizes, ScopArrayInfo::MK_Array); + if (Acc) + Acc->getStatement()->addArrayAccess(Acc); } void ScopInfo::addValueWriteAccess(Instruction *Value) { - addMemoryAccess(Value->getParent(), Value, MemoryAccess::MUST_WRITE, Value, 1, - true, Value, ArrayRef(), - ArrayRef(), ScopArrayInfo::MK_Value); + MemoryAccess *Acc = + addMemoryAccess(Value->getParent(), Value, MemoryAccess::MUST_WRITE, + Value, 1, true, Value, ArrayRef(), + ArrayRef(), ScopArrayInfo::MK_Value); + if (Acc) + Acc->getStatement()->addTrailingWrite(Acc); } void ScopInfo::addValueReadAccess(Value *Value, Instruction *User) { assert(!isa(User)); - addMemoryAccess(User->getParent(), User, MemoryAccess::READ, Value, 1, true, - Value, ArrayRef(), ArrayRef(), - ScopArrayInfo::MK_Value); + MemoryAccess *Acc = + addMemoryAccess(User->getParent(), User, MemoryAccess::READ, Value, 1, + true, Value, ArrayRef(), + ArrayRef(), ScopArrayInfo::MK_Value); + if (Acc) + Acc->getStatement()->addLeadingLoad(Acc); } void ScopInfo::addValueReadAccess(Value *Value, PHINode *User, BasicBlock *UserBB) { - addMemoryAccess(UserBB, User, MemoryAccess::READ, Value, 1, true, Value, - ArrayRef(), ArrayRef(), - ScopArrayInfo::MK_Value); + MemoryAccess *Acc = + addMemoryAccess(UserBB, User, MemoryAccess::READ, Value, 1, true, Value, + ArrayRef(), ArrayRef(), + ScopArrayInfo::MK_Value); + if (Acc) + Acc->getStatement()->addLeadingLoad(Acc); } 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 ? ScopArrayInfo::MK_ExitPHI - : ScopArrayInfo::MK_PHI); + MemoryAccess *Acc = addMemoryAccess( + IncomingBlock, IncomingBlock->getTerminator(), MemoryAccess::MUST_WRITE, + PHI, 1, true, IncomingValue, ArrayRef(), + ArrayRef(), + IsExitBlock ? ScopArrayInfo::MK_ExitPHI : ScopArrayInfo::MK_PHI); + if (Acc) + Acc->getStatement()->addTrailingWrite(Acc); } void ScopInfo::addPHIReadAccess(PHINode *PHI) { - addMemoryAccess(PHI->getParent(), PHI, MemoryAccess::READ, PHI, 1, true, PHI, - ArrayRef(), ArrayRef(), - ScopArrayInfo::MK_PHI); + MemoryAccess *Acc = + addMemoryAccess(PHI->getParent(), PHI, MemoryAccess::READ, PHI, 1, true, + PHI, ArrayRef(), ArrayRef(), + ScopArrayInfo::MK_PHI); + if (Acc) + Acc->getStatement()->addLeadingLoad(Acc); } void ScopInfo::buildScop(Region &R, AssumptionCache &AC) { Index: lib/CodeGen/BlockGenerators.cpp =================================================================== --- lib/CodeGen/BlockGenerators.cpp +++ lib/CodeGen/BlockGenerators.cpp @@ -387,9 +387,8 @@ } void BlockGenerator::generateScalarLoads(ScopStmt &Stmt, ValueMapT &BBMap) { - for (MemoryAccess *MA : Stmt) { - if (MA->isArrayKind() || MA->isWrite()) - continue; + for (MemoryAccess *MA : Stmt.getLeadingReads()) { + assert(MA->isScalarKind() && MA->isRead()); auto *Address = getOrCreateAlloca(*MA); BBMap[MA->getBaseAddr()] = @@ -452,9 +451,8 @@ "generateScalarStores() function in the " "RegionGenerator"); - for (MemoryAccess *MA : Stmt) { - if (MA->isArrayKind() || MA->isRead()) - continue; + for (MemoryAccess *MA : Stmt.getTrailingWrites()) { + assert(MA->isScalarKind() && MA->isWrite()); Value *Val = MA->getAccessValue(); auto *Address = getOrCreateAlloca(*MA);