[polly] r248616 - Let MemoryAccess remember its purpose
Michael Kruse via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 14:21:01 PDT 2015
Author: meinersbur
Date: Fri Sep 25 16:21:00 2015
New Revision: 248616
URL: http://llvm.org/viewvc/llvm-project?rev=248616&view=rev
Log:
Let MemoryAccess remember its purpose
There are three possible reasons to add a memory memory access: For explicit load and stores, for llvm::Value defs/uses, and to emulate PHI nodes (the latter two called implicit accesses). Previously MemoryAccess only stored IsPHI. Register accesses could be identified through the isScalar() method if it was no IsPHI. isScalar() determined the number of dimensions of the underlaying array, scalars represented by zero dimensions.
For the work on de-LICM, implicit accesses can have more than zero dimensions, making the distinction of isScalars() useless, hence now stored explicitly in the MemoryAccess. Instead, we replace it by isImplicit() and avoid the term scalar for zero-dimensional arrays as it might be confused with llvm::Value which are also often referred to as scalars (or alternatively, as registers).
No behavioral change intended, under the condition that it was impossible to create explicit accesses to zero-dimensional "arrays".
Modified:
polly/trunk/include/polly/ScopInfo.h
polly/trunk/lib/Analysis/ScopInfo.cpp
polly/trunk/lib/CodeGen/BlockGenerators.cpp
polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=248616&r1=248615&r2=248616&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Fri Sep 25 16:21:00 2015
@@ -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.
Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=248616&r1=248615&r2=248616&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Fri Sep 25 16:21:00 2015
@@ -606,11 +606,11 @@ MemoryAccess::MemoryAccess(Instruction *
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
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 is
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(AliasAnalysi
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(BasicBloc
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(BasicBloc
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) {
Modified: polly/trunk/lib/CodeGen/BlockGenerators.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/BlockGenerators.cpp?rev=248616&r1=248615&r2=248616&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/BlockGenerators.cpp (original)
+++ polly/trunk/lib/CodeGen/BlockGenerators.cpp Fri Sep 25 16:21:00 2015
@@ -407,7 +407,7 @@ void BlockGenerator::generateScalarLoads
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::generateScalarStore
"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::generateScalarStor
for (MemoryAccess *MA : Stmt) {
- if (!MA->isScalar() || MA->isRead())
+ if (MA->isExplicit() || MA->isRead())
continue;
Instruction *ScalarInst = MA->getAccessInstruction();
Modified: polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslNodeBuilder.cpp?rev=248616&r1=248615&r2=248616&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslNodeBuilder.cpp (original)
+++ polly/trunk/lib/CodeGen/IslNodeBuilder.cpp Fri Sep 25 16:21:00 2015
@@ -217,7 +217,7 @@ static isl_stat addReferencesFromStmt(co
}
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))
More information about the llvm-commits
mailing list