Index: include/polly/CodeGen/BlockGenerators.h =================================================================== --- include/polly/CodeGen/BlockGenerators.h +++ include/polly/CodeGen/BlockGenerators.h @@ -37,6 +37,7 @@ class MemoryAccess; class ScopArrayInfo; class IslExprBuilder; +class MemAccInst; /// @brief Generate a new basic block for a polyhedral statement. class BlockGenerator { @@ -483,9 +484,8 @@ /// @param NewAccesses A map from memory access ids to new ast expressions, /// which may contain new access expressions for certain /// memory accesses. - Value *generateLocationAccessed(ScopStmt &Stmt, const Instruction *Inst, - Value *Pointer, ValueMapT &BBMap, - LoopToScevMapT <S, + Value *generateLocationAccessed(ScopStmt &Stmt, MemAccInst *Inst, + ValueMapT &BBMap, LoopToScevMapT <S, isl_id_to_ast_expr *NewAccesses); /// @param NewAccesses A map from memory access ids to new ast expressions, Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -65,6 +65,67 @@ class ScopStmt; class ScopInfo; +/// @brief Utility class to wrap the common members of LoadInst and StoreInst. +/// +/// This works like LLVM utility classes like CallSite, IntrinsicInst, +/// MemIntrinsic, MemTransferInst, etc. +/// Unfortunately it is not possible to have an implicit conversion from +/// LoadInst*/StoreInst* in C++. Such casts must be written explicitely using +/// llvm::cast. +class MemAccInst : public Instruction { +public: + Value *getValueOperand() { + return isStore() ? asStore()->getValueOperand() : asLoad(); + } + const Value *getValueOperand() const { + return isStore() ? asStore()->getValueOperand() : asLoad(); + } + + Value *getPointerOperand() { + return getOperand(isStore() ? StoreInst::getPointerOperandIndex() + : LoadInst::getPointerOperandIndex()); + } + const Value *getPointerOperand() const { + return getOperand(isStore() ? StoreInst::getPointerOperandIndex() + : LoadInst::getPointerOperandIndex()); + } + + unsigned getAlignment() const { + return isStore() ? asStore()->getAlignment() : asLoad()->getAlignment(); + } + bool isVolatile() const { + return isStore() ? asStore()->isVolatile() : asLoad()->isVolatile(); + } + bool isSimple() const { + return isStore() ? asStore()->isSimple() : asLoad()->isSimple(); + } + AtomicOrdering getOrdering() const { + return isStore() ? asStore()->getOrdering() : asLoad()->getOrdering(); + } + bool isUnordered() const { + return isStore() ? asStore()->isUnordered() : asLoad()->isUnordered(); + } + + bool isLoad() const { return isa(this); } + LoadInst *asLoad() { return cast(this); } + const LoadInst *asLoad() const { return cast(this); } + + bool isStore() const { return isa(this); } + StoreInst *asStore() { return cast(this); } + const StoreInst *asStore() const { return cast(this); } + + static inline bool classof(const LoadInst *I) { return true; } + static inline bool classof(const StoreInst *I) { return true; } + static inline bool classof(const Instruction *I) { + return isa(I) || isa(I); + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +typedef DenseMap OutgoingValueMapTy; + //===---------------------------------------------------------------------===// /// @brief Enumeration of assumptions Polly can take. @@ -1826,7 +1887,7 @@ /// @param R The region on which to build the data access dictionary. /// @param BoxedLoops The set of loops that are overapproximated in @p R. /// @param ScopRIL The required invariant loads equivalence classes. - void buildMemoryAccess(Instruction *Inst, Loop *L, Region *R, + void buildMemoryAccess(MemAccInst *Inst, Loop *L, Region *R, const ScopDetection::BoxedLoopsSetTy *BoxedLoops, const InvariantLoadsSetTy &ScopRIL); @@ -1905,7 +1966,7 @@ /// @param Sizes The array dimension's sizes. /// @param AccessValue Value read or written. /// @see ScopArrayInfo::MemoryKind - void addArrayAccess(Instruction *MemAccInst, MemoryAccess::AccessType Type, + void addArrayAccess(MemAccInst *MemAccInst, MemoryAccess::AccessType Type, Value *BaseAddress, unsigned ElemBytes, bool IsAffine, ArrayRef Subscripts, ArrayRef Sizes, Value *AccessValue); Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -2477,8 +2477,8 @@ continue; if (!MA->isRead()) HasWriteAccess.insert(MA->getBaseAddr()); - Instruction *Acc = MA->getAccessInstruction(); - PtrToAcc[getPointerOperand(*Acc)] = MA; + auto Acc = cast(MA->getAccessInstruction()); + PtrToAcc[Acc->getPointerOperand()] = MA; AST.add(Acc); } } @@ -3683,28 +3683,16 @@ extern MapInsnToMemAcc InsnToMemAcc; void ScopInfo::buildMemoryAccess( - Instruction *Inst, Loop *L, Region *R, + MemAccInst *Inst, Loop *L, Region *R, const ScopDetection::BoxedLoopsSetTy *BoxedLoops, const InvariantLoadsSetTy &ScopRIL) { - unsigned Size; - Type *SizeType; - Value *Val; - enum MemoryAccess::AccessType Type; - - if (LoadInst *Load = dyn_cast(Inst)) { - SizeType = Load->getType(); - Size = TD->getTypeAllocSize(SizeType); - Type = MemoryAccess::READ; - Val = Load; - } else { - StoreInst *Store = cast(Inst); - SizeType = Store->getValueOperand()->getType(); - Size = TD->getTypeAllocSize(SizeType); - Type = MemoryAccess::MUST_WRITE; - Val = Store->getValueOperand(); - } - auto Address = getPointerOperand(*Inst); + Value *Address = Inst->getPointerOperand(); + Value *Val = Inst->getValueOperand(); + Type *SizeType = Val->getType(); + unsigned Size = TD->getTypeAllocSize(SizeType); + enum MemoryAccess::AccessType Type = + Inst->isLoad() ? MemoryAccess::READ : MemoryAccess::MUST_WRITE; const SCEV *AccessFunction = SE->getSCEVAtScope(Address, L); const SCEVUnknown *BasePointer = @@ -3861,8 +3849,8 @@ // invariant and will be hoisted for the SCoP to be processed. Though, // there might be other invariant accesses that will be hoisted and // that would allow to make a non-affine access affine. - if (isa(Inst) || isa(Inst)) - buildMemoryAccess(Inst, L, &R, BoxedLoops, ScopRIL); + if (isa(Inst)) + buildMemoryAccess(cast(Inst), L, &R, BoxedLoops, ScopRIL); if (isIgnoredIntrinsic(Inst)) continue; @@ -3920,14 +3908,13 @@ Stmt->addAccess(&AccList.back()); } -void ScopInfo::addArrayAccess(Instruction *MemAccInst, +void ScopInfo::addArrayAccess(MemAccInst *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)); + assert(MemAccInst->isLoad() == (Type == MemoryAccess::READ)); addMemoryAccess(MemAccInst->getParent(), MemAccInst, Type, BaseAddress, ElemBytes, IsAffine, AccessValue, Subscripts, Sizes, ScopArrayInfo::MK_Array); Index: lib/CodeGen/BlockGenerators.cpp =================================================================== --- lib/CodeGen/BlockGenerators.cpp +++ lib/CodeGen/BlockGenerators.cpp @@ -168,9 +168,10 @@ NewInst->setName("p_" + Inst->getName()); } -Value *BlockGenerator::generateLocationAccessed( - ScopStmt &Stmt, const Instruction *Inst, Value *Pointer, ValueMapT &BBMap, - LoopToScevMapT <S, isl_id_to_ast_expr *NewAccesses) { +Value * +BlockGenerator::generateLocationAccessed(ScopStmt &Stmt, MemAccInst *Inst, + ValueMapT &BBMap, LoopToScevMapT <S, + isl_id_to_ast_expr *NewAccesses) { const MemoryAccess &MA = Stmt.getArrayAccessFor(Inst); isl_ast_expr *AccessExpr = isl_id_to_ast_expr_get(NewAccesses, MA.getId()); @@ -196,7 +197,8 @@ return Address; } - return getNewValue(Stmt, Pointer, BBMap, LTS, getLoopForInst(Inst)); + return getNewValue(Stmt, Inst->getPointerOperand(), BBMap, LTS, + getLoopForInst(Inst)); } Loop *BlockGenerator::getLoopForInst(const llvm::Instruction *Inst) { @@ -209,9 +211,8 @@ if (Value *PreloadLoad = GlobalMap.lookup(Load)) return PreloadLoad; - auto *Pointer = Load->getPointerOperand(); - Value *NewPointer = - generateLocationAccessed(Stmt, Load, Pointer, BBMap, LTS, NewAccesses); + Value *NewPointer = generateLocationAccessed(Stmt, cast(Load), + BBMap, LTS, NewAccesses); Value *ScalarLoad = Builder.CreateAlignedLoad( NewPointer, Load->getAlignment(), Load->getName() + "_p_scalar_"); @@ -225,9 +226,8 @@ void BlockGenerator::generateScalarStore(ScopStmt &Stmt, StoreInst *Store, ValueMapT &BBMap, LoopToScevMapT <S, isl_id_to_ast_expr *NewAccesses) { - auto *Pointer = Store->getPointerOperand(); - Value *NewPointer = - generateLocationAccessed(Stmt, Store, Pointer, BBMap, LTS, NewAccesses); + Value *NewPointer = generateLocationAccessed(Stmt, cast(Store), + BBMap, LTS, NewAccesses); Value *ValueOperand = getNewValue(Stmt, Store->getValueOperand(), BBMap, LTS, getLoopForInst(Store)); @@ -703,8 +703,9 @@ unsigned Offset = NegativeStride ? VectorWidth - 1 : 0; Value *NewPointer = nullptr; - NewPointer = generateLocationAccessed(Stmt, Load, Pointer, ScalarMaps[Offset], - VLTS[Offset], NewAccesses); + NewPointer = + generateLocationAccessed(Stmt, cast(Load), ScalarMaps[Offset], + VLTS[Offset], NewAccesses); Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType, "vector_ptr"); LoadInst *VecLoad = @@ -730,8 +731,8 @@ __isl_keep isl_id_to_ast_expr *NewAccesses) { auto *Pointer = Load->getPointerOperand(); Type *VectorPtrType = getVectorPtrTy(Pointer, 1); - Value *NewPointer = generateLocationAccessed(Stmt, Load, Pointer, BBMap, - VLTS[0], NewAccesses); + Value *NewPointer = generateLocationAccessed(Stmt, cast(Load), + BBMap, VLTS[0], NewAccesses); Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType, Load->getName() + "_p_vec_p"); LoadInst *ScalarLoad = @@ -760,7 +761,7 @@ for (int i = 0; i < VectorWidth; i++) { Value *NewPointer = generateLocationAccessed( - Stmt, Load, Pointer, ScalarMaps[i], VLTS[i], NewAccesses); + Stmt, cast(Load), ScalarMaps[i], VLTS[i], NewAccesses); Value *ScalarLoad = Builder.CreateLoad(NewPointer, Load->getName() + "_p_scalar_"); Vector = Builder.CreateInsertElement( @@ -851,7 +852,7 @@ if (Access.isStrideOne(isl_map_copy(Schedule))) { Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth()); Value *NewPointer = generateLocationAccessed( - Stmt, Store, Pointer, ScalarMaps[0], VLTS[0], NewAccesses); + Stmt, cast(Store), ScalarMaps[0], VLTS[0], NewAccesses); Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType, "vector_ptr"); @@ -863,7 +864,7 @@ for (unsigned i = 0; i < ScalarMaps.size(); i++) { Value *Scalar = Builder.CreateExtractElement(Vector, Builder.getInt32(i)); Value *NewPointer = generateLocationAccessed( - Stmt, Store, Pointer, ScalarMaps[i], VLTS[i], NewAccesses); + Stmt, cast(Store), ScalarMaps[i], VLTS[i], NewAccesses); Builder.CreateStore(Scalar, NewPointer); } }