Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -243,8 +243,8 @@ /// could allow us to handle the above example. ReductionType RedType = RT_NONE; - /// @brief The access instruction of this memory access. - Instruction *Inst; + /// @brief The access value that caused this memory access. + Value *AccessValue; /// Updated access relation read from JSCOP file. isl_map *newAccessRelation; @@ -307,13 +307,13 @@ /// @brief Create a memory access from an access in LLVM-IR. /// /// @param Access The memory access. - /// @param AccInst The access instruction. + /// @param AccessVal The access value that caused this memory access. /// @param Statement The statement that contains the access. /// @param SAI The ScopArrayInfo object for this base pointer. /// @param Identifier An identifier that is unique for all memory accesses /// belonging to the same scop statement. - MemoryAccess(const IRAccess &Access, Instruction *AccInst, - ScopStmt *Statement, const ScopArrayInfo *SAI, int Identifier); + MemoryAccess(const IRAccess &Access, Value *AccessVale, ScopStmt *Statement, + const ScopArrayInfo *SAI, int Identifier); ~MemoryAccess(); @@ -377,8 +377,18 @@ 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; } + /// + /// This can be a nullptr if and only if this memory access is a scalar write + /// access that was created for a non-instruction (Constant, Argument,...) as + /// it is a PHI operand. + /// + Instruction *getAccessInstruction() const { + return dyn_cast(AccessValue); + } /// 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 @@ -496,8 +506,8 @@ typedef SmallVector MemoryAccessVec; MemoryAccessVec MemAccs; - /// @brief Mapping from instructions to (scalar) memory accesses. - DenseMap InstructionToAccess; + /// @brief Mapping from values to (scalar) memory accesses they induced. + DenseMap ValueToAccess; //@} @@ -635,31 +645,30 @@ /// @brief Return true if this statement represents a whole region. bool isRegionStmt() const { return R != nullptr; } - /// @brief Return the (scalar) memory accesses for @p Inst. - const MemoryAccessList &getAccessesFor(const Instruction *Inst) const { - MemoryAccessList *MAL = lookupAccessesFor(Inst); + /// @brief Return the (scalar) memory accesses for @p Val. + const MemoryAccessList &getAccessesFor(const Value *Val) const { + MemoryAccessList *MAL = lookupAccessesFor(Val); assert(MAL && "Cannot get memory accesses because they do not exist!"); return *MAL; } - /// @brief Return the (scalar) memory accesses for @p Inst if any. - MemoryAccessList *lookupAccessesFor(const Instruction *Inst) const { - auto It = InstructionToAccess.find(Inst); - return It == InstructionToAccess.end() ? nullptr : It->getSecond(); + /// @brief Return the (scalar) memory accesses for @p Val if any. + MemoryAccessList *lookupAccessesFor(const Value *Val) const { + auto It = ValueToAccess.find(Val); + return It == ValueToAccess.end() ? nullptr : It->getSecond(); } - /// @brief Return the __first__ (scalar) memory access for @p Inst. - const MemoryAccess &getAccessFor(const Instruction *Inst) const { - MemoryAccess *MA = lookupAccessFor(Inst); + /// @brief Return the __first__ (scalar) memory access for @p Val. + const MemoryAccess &getAccessFor(const Value *Val) const { + MemoryAccess *MA = lookupAccessFor(Val); assert(MA && "Cannot get memory access because it does not exist!"); return *MA; } - /// @brief Return the __first__ (scalar) memory access for @p Inst if any. - MemoryAccess *lookupAccessFor(const Instruction *Inst) const { - auto It = InstructionToAccess.find(Inst); - return It == InstructionToAccess.end() ? nullptr - : &It->getSecond()->front(); + /// @brief Return the __first__ (scalar) memory access for @p Val if any. + MemoryAccess *lookupAccessFor(const Value *Val) const { + auto It = ValueToAccess.find(Val); + return It == ValueToAccess.end() ? nullptr : &It->getSecond()->front(); } void setBasicBlock(BasicBlock *Block) { Index: include/polly/TempScopInfo.h =================================================================== --- include/polly/TempScopInfo.h +++ include/polly/TempScopInfo.h @@ -129,7 +129,7 @@ /// Mapping BBs to its condition constrains typedef std::map BBCondMapType; -typedef std::vector> AccFuncSetType; +typedef std::vector> AccFuncSetType; typedef std::map AccFuncMapType; //===---------------------------------------------------------------------===// Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -444,11 +444,11 @@ return AccessRelation; } -MemoryAccess::MemoryAccess(const IRAccess &Access, Instruction *AccInst, +MemoryAccess::MemoryAccess(const IRAccess &Access, Value *AccessVal, ScopStmt *Statement, const ScopArrayInfo *SAI, int Identifier) - : AccType(getMemoryAccessType(Access)), Statement(Statement), Inst(AccInst), - newAccessRelation(nullptr) { + : AccType(getMemoryAccessType(Access)), Statement(Statement), + AccessValue(AccessVal), newAccessRelation(nullptr) { isl_ctx *Ctx = Statement->getIslCtx(); BaseAddr = Access.getBase(); @@ -670,15 +670,10 @@ } // @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)) +static Type *getAccessType(IRAccess &Access, Value *AccessValue) { + if (StoreInst *Store = dyn_cast(AccessValue)) return Store->getValueOperand()->getType(); - if (BranchInst *Branch = dyn_cast(AccessInst)) - return Branch->getCondition()->getType(); - return AccessInst->getType(); + return AccessValue->getType(); } void ScopStmt::buildAccesses(TempScop &tempScop, BasicBlock *Block, @@ -689,8 +684,8 @@ for (auto &AccessPair : *AFS) { IRAccess &Access = AccessPair.first; - Instruction *AccessInst = AccessPair.second; - Type *ElementType = getAccessType(Access, AccessInst); + Value *AccessValue = AccessPair.second; + Type *ElementType = getAccessType(Access, AccessValue); const ScopArrayInfo *SAI = getParent()->getOrCreateScopArrayInfo( Access.getBase(), ElementType, Access.Sizes, Access.isPHI()); @@ -698,10 +693,10 @@ if (isApproximated && Access.isWrite()) Access.setMayWrite(); - MemoryAccessList *&MAL = InstructionToAccess[AccessInst]; + MemoryAccessList *&MAL = ValueToAccess[AccessValue]; if (!MAL) MAL = new MemoryAccessList(); - MAL->emplace_front(Access, AccessInst, this, SAI, MemAccs.size()); + MAL->emplace_front(Access, AccessValue, this, SAI, MemAccs.size()); MemAccs.push_back(&MAL->front()); } } @@ -975,6 +970,8 @@ // First collect candidate load-store reduction chains by iterating over all // stores and collecting possible reduction loads. for (MemoryAccess *StoreMA : MemAccs) { + if (StoreMA->isScalar()) + continue; if (StoreMA->isRead()) continue; @@ -1065,7 +1062,7 @@ } ScopStmt::~ScopStmt() { - DeleteContainerSeconds(InstructionToAccess); + DeleteContainerSeconds(ValueToAccess); isl_set_free(Domain); } Index: lib/Analysis/TempScopInfo.cpp =================================================================== --- lib/Analysis/TempScopInfo.cpp +++ lib/Analysis/TempScopInfo.cpp @@ -142,14 +142,9 @@ } } - // If the operand is a constant, global or argument we use the terminator - // of the incoming basic block as the access instruction. - if (!OpI) - OpI = OpBB->getTerminator(); - IRAccess ScalarAccess(IRAccess::MUST_WRITE, PHI, ZeroOffset, 1, true, /* IsPHI */ true); - AccFuncMap[OpBB].push_back(std::make_pair(ScalarAccess, OpI)); + AccFuncMap[OpBB].push_back(std::make_pair(ScalarAccess, Op)); } if (!OnlyNonAffineSubRegionOperands) { Index: lib/CodeGen/BlockGenerators.cpp =================================================================== --- lib/CodeGen/BlockGenerators.cpp +++ lib/CodeGen/BlockGenerators.cpp @@ -497,21 +497,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); } @@ -1125,11 +1118,12 @@ continue; Instruction *ScalarBase = cast(MA->getBaseAddr()); - Instruction *ScalarInst = MA->getAccessInstruction(); + Value *ScalarVal = MA->getAccessValue(); + Instruction *ScalarInst = dyn_cast(ScalarVal); PHINode *ScalarBasePHI = dyn_cast(ScalarBase); // Only generate accesses that belong to this basic block. - if (ScalarInst->getParent() != BB) + if (ScalarInst && ScalarInst->getParent() != BB) continue; Value *Val = nullptr; @@ -1137,11 +1131,13 @@ if (MA->getScopArrayInfo()->isPHI()) { int PHIIdx = ScalarBasePHI->getBasicBlockIndex(BB); + if (PHIIdx < 0) + continue; ScalarAddr = getOrCreateAlloca(ScalarBase, PHIOpMap, ".phiops"); Val = ScalarBasePHI->getIncomingValue(PHIIdx); } else { ScalarAddr = getOrCreateAlloca(ScalarBase, ScalarMap, ".s2a"); - Val = ScalarInst; + Val = ScalarVal; } Val = getNewScalarValue(Val, R, ScalarMap, BBMap, GlobalMap);