Index: polly/trunk/include/polly/ScopInfo.h =================================================================== --- polly/trunk/include/polly/ScopInfo.h +++ polly/trunk/include/polly/ScopInfo.h @@ -244,7 +244,15 @@ ReductionType RedType = RT_NONE; /// @brief The access instruction of this memory access. - Instruction *Inst; + Instruction *AccessInstruction; + + /// @brief The value associated with this memory access. + /// + /// - For real memory accesses it is the loaded result or the stored value. + /// - For straigt line scalar accesses it is the access instruction itself. + /// - For PHI operand accesses it is the operand value. + /// + Value *AccessValue; /// Updated access relation read from JSCOP file. isl_map *newAccessRelation; @@ -377,8 +385,11 @@ const std::string &getBaseName() const { return BaseName; } + /// @brief Return the access value of this memory access. + Value *getAccessValue() const { return AccessValue; } + /// @brief Return the access instruction of this memory access. - Instruction *getAccessInstruction() const { return Inst; } + Instruction *getAccessInstruction() const { return AccessInstruction; } /// Get the stride of this memory access in the specified Schedule. Schedule /// is a map from the statement to a schedule where the innermost dimension is Index: polly/trunk/include/polly/TempScopInfo.h =================================================================== --- polly/trunk/include/polly/TempScopInfo.h +++ polly/trunk/include/polly/TempScopInfo.h @@ -33,6 +33,7 @@ class IRAccess { public: Value *BaseAddress; + Value *AccessValue; const SCEV *Offset; @@ -58,22 +59,25 @@ /// /// @param IsPHI Are we modeling special PHI node accesses? explicit IRAccess(TypeKind Type, Value *BaseAddress, const SCEV *Offset, - unsigned elemBytes, bool Affine, bool IsPHI = false) - : BaseAddress(BaseAddress), Offset(Offset), ElemBytes(elemBytes), - Type(Type), IsAffine(Affine), IsPHI(IsPHI) {} + unsigned elemBytes, bool Affine, Value *AccessValue, + bool IsPHI = false) + : BaseAddress(BaseAddress), AccessValue(AccessValue), Offset(Offset), + ElemBytes(elemBytes), Type(Type), IsAffine(Affine), IsPHI(IsPHI) {} explicit IRAccess(TypeKind Type, Value *BaseAddress, const SCEV *Offset, unsigned elemBytes, bool Affine, SmallVector Subscripts, - SmallVector Sizes) - : BaseAddress(BaseAddress), Offset(Offset), ElemBytes(elemBytes), - Type(Type), IsAffine(Affine), IsPHI(false), Subscripts(Subscripts), - Sizes(Sizes) {} + SmallVector Sizes, Value *AccessValue) + : BaseAddress(BaseAddress), AccessValue(AccessValue), Offset(Offset), + ElemBytes(elemBytes), Type(Type), IsAffine(Affine), IsPHI(false), + Subscripts(Subscripts), Sizes(Sizes) {} enum TypeKind getType() const { return Type; } Value *getBase() const { return BaseAddress; } + Value *getAccessValue() const { return AccessValue; } + const SCEV *getOffset() const { return Offset; } unsigned getElemSizeInBytes() const { return ElemBytes; } Index: polly/trunk/lib/Analysis/ScopInfo.cpp =================================================================== --- polly/trunk/lib/Analysis/ScopInfo.cpp +++ polly/trunk/lib/Analysis/ScopInfo.cpp @@ -447,7 +447,8 @@ MemoryAccess::MemoryAccess(const IRAccess &Access, Instruction *AccInst, ScopStmt *Statement, const ScopArrayInfo *SAI, int Identifier) - : AccType(getMemoryAccessType(Access)), Statement(Statement), Inst(AccInst), + : AccType(getMemoryAccessType(Access)), Statement(Statement), + AccessInstruction(AccInst), AccessValue(Access.getAccessValue()), newAccessRelation(nullptr) { isl_ctx *Ctx = Statement->getIslCtx(); @@ -669,18 +670,6 @@ Domain = NewDomain; } -// @brief Get the data-type of the elements accessed -static Type *getAccessType(IRAccess &Access, Instruction *AccessInst) { - if (Access.isPHI()) - return Access.getBase()->getType(); - - if (StoreInst *Store = dyn_cast(AccessInst)) - return Store->getValueOperand()->getType(); - if (BranchInst *Branch = dyn_cast(AccessInst)) - return Branch->getCondition()->getType(); - return AccessInst->getType(); -} - void ScopStmt::buildAccesses(TempScop &tempScop, BasicBlock *Block, bool isApproximated) { AccFuncSetType *AFS = tempScop.getAccessFunctions(Block); @@ -690,7 +679,7 @@ for (auto &AccessPair : *AFS) { IRAccess &Access = AccessPair.first; Instruction *AccessInst = AccessPair.second; - Type *ElementType = getAccessType(Access, AccessInst); + Type *ElementType = Access.getAccessValue()->getType(); const ScopArrayInfo *SAI = getParent()->getOrCreateScopArrayInfo( Access.getBase(), ElementType, Access.Sizes, Access.isPHI()); Index: polly/trunk/lib/Analysis/TempScopInfo.cpp =================================================================== --- polly/trunk/lib/Analysis/TempScopInfo.cpp +++ polly/trunk/lib/Analysis/TempScopInfo.cpp @@ -135,9 +135,10 @@ // we have to insert a scalar dependence from the definition of OpI to // OpBB if the definition is not in OpBB. if (OpIBB != OpBB) { - IRAccess ScalarRead(IRAccess::READ, OpI, ZeroOffset, 1, true); + IRAccess ScalarRead(IRAccess::READ, OpI, ZeroOffset, 1, true, OpI); AccFuncMap[OpBB].push_back(std::make_pair(ScalarRead, PHI)); - IRAccess ScalarWrite(IRAccess::MUST_WRITE, OpI, ZeroOffset, 1, true); + IRAccess ScalarWrite(IRAccess::MUST_WRITE, OpI, ZeroOffset, 1, true, + OpI); AccFuncMap[OpIBB].push_back(std::make_pair(ScalarWrite, OpI)); } } @@ -147,13 +148,13 @@ if (!OpI) OpI = OpBB->getTerminator(); - IRAccess ScalarAccess(IRAccess::MUST_WRITE, PHI, ZeroOffset, 1, true, + IRAccess ScalarAccess(IRAccess::MUST_WRITE, PHI, ZeroOffset, 1, true, Op, /* IsPHI */ true); AccFuncMap[OpBB].push_back(std::make_pair(ScalarAccess, OpI)); } if (!OnlyNonAffineSubRegionOperands) { - IRAccess ScalarAccess(IRAccess::READ, PHI, ZeroOffset, 1, true, + IRAccess ScalarAccess(IRAccess::READ, PHI, ZeroOffset, 1, true, PHI, /* IsPHI */ true); Functions.push_back(std::make_pair(ScalarAccess, PHI)); } @@ -211,7 +212,7 @@ // Do not build a read access that is not in the current SCoP // Use the def instruction as base address of the IRAccess, so that it will // become the name of the scalar access in the polyhedral form. - IRAccess ScalarAccess(IRAccess::READ, Inst, ZeroOffset, 1, true); + IRAccess ScalarAccess(IRAccess::READ, Inst, ZeroOffset, 1, true, Inst); AccFuncMap[UseParent].push_back(std::make_pair(ScalarAccess, UI)); } @@ -224,7 +225,7 @@ if (R->contains(OpInst)) continue; - IRAccess ScalarAccess(IRAccess::READ, Op, ZeroOffset, 1, true); + IRAccess ScalarAccess(IRAccess::READ, Op, ZeroOffset, 1, true, Op); AccFuncMap[Inst->getParent()].push_back( std::make_pair(ScalarAccess, Inst)); } @@ -240,17 +241,20 @@ const ScopDetection::BoxedLoopsSetTy *BoxedLoops) { unsigned Size; Type *SizeType; + Value *Val; enum IRAccess::TypeKind Type; if (LoadInst *Load = dyn_cast(Inst)) { SizeType = Load->getType(); Size = TD->getTypeStoreSize(SizeType); Type = IRAccess::READ; + Val = Load; } else { StoreInst *Store = cast(Inst); SizeType = Store->getValueOperand()->getType(); Size = TD->getTypeStoreSize(SizeType); Type = IRAccess::MUST_WRITE; + Val = Store->getValueOperand(); } const SCEV *AccessFunction = SE->getSCEVAtScope(getPointerOperand(*Inst), L); @@ -264,7 +268,7 @@ if (PollyDelinearize && AccItr != InsnToMemAcc.end()) return IRAccess(Type, BasePointer->getValue(), AccessFunction, Size, true, AccItr->second.DelinearizedSubscripts, - AccItr->second.Shape->DelinearizedSizes); + AccItr->second.Shape->DelinearizedSizes, Val); // Check if the access depends on a loop contained in a non-affine subregion. bool isVariantInNonAffineLoop = false; @@ -287,7 +291,7 @@ Type = IRAccess::MAY_WRITE; return IRAccess(Type, BasePointer->getValue(), AccessFunction, Size, IsAffine, - Subscripts, Sizes); + Subscripts, Sizes, Val); } void TempScopInfo::buildAccessFunctions(Region &R, Region &SR) { @@ -326,7 +330,8 @@ buildScalarDependences(Inst, &R, NonAffineSubRegion)) { // If the Instruction is used outside the statement, we need to build the // write access. - IRAccess ScalarAccess(IRAccess::MUST_WRITE, Inst, ZeroOffset, 1, true); + IRAccess ScalarAccess(IRAccess::MUST_WRITE, Inst, ZeroOffset, 1, true, + Inst); Functions.push_back(std::make_pair(ScalarAccess, Inst)); } } Index: polly/trunk/lib/CodeGen/BlockGenerators.cpp =================================================================== --- polly/trunk/lib/CodeGen/BlockGenerators.cpp +++ polly/trunk/lib/CodeGen/BlockGenerators.cpp @@ -495,21 +495,14 @@ continue; Instruction *Base = cast(MA->getBaseAddr()); - Instruction *Inst = MA->getAccessInstruction(); + Value *Val = MA->getAccessValue(); - Value *Val = nullptr; AllocaInst *Address = nullptr; - - if (MA->getScopArrayInfo()->isPHI()) { - PHINode *BasePHI = dyn_cast(Base); - int PHIIdx = BasePHI->getBasicBlockIndex(BB); - assert(PHIIdx >= 0); + if (MA->getScopArrayInfo()->isPHI()) Address = getOrCreateAlloca(Base, PHIOpMap, ".phiops"); - Val = BasePHI->getIncomingValue(PHIIdx); - } else { + else Address = getOrCreateAlloca(Base, ScalarMap, ".s2a"); - Val = Inst; - } + Val = getNewScalarValue(Val, R, ScalarMap, BBMap, GlobalMap); Builder.CreateStore(Val, Address); } @@ -1124,23 +1117,18 @@ Instruction *ScalarBase = cast(MA->getBaseAddr()); Instruction *ScalarInst = MA->getAccessInstruction(); - PHINode *ScalarBasePHI = dyn_cast(ScalarBase); // Only generate accesses that belong to this basic block. if (ScalarInst->getParent() != BB) continue; - Value *Val = nullptr; + Value *Val = MA->getAccessValue(); AllocaInst *ScalarAddr = nullptr; - if (MA->getScopArrayInfo()->isPHI()) { - int PHIIdx = ScalarBasePHI->getBasicBlockIndex(BB); + if (MA->getScopArrayInfo()->isPHI()) ScalarAddr = getOrCreateAlloca(ScalarBase, PHIOpMap, ".phiops"); - Val = ScalarBasePHI->getIncomingValue(PHIIdx); - } else { + else ScalarAddr = getOrCreateAlloca(ScalarBase, ScalarMap, ".s2a"); - Val = ScalarInst; - } Val = getNewScalarValue(Val, R, ScalarMap, BBMap, GlobalMap); Builder.CreateStore(Val, ScalarAddr);