summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/include/polly/ScopInfo.h74
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp38
-rw-r--r--polly/lib/CodeGen/BlockGenerators.cpp6
-rw-r--r--polly/lib/CodeGen/IslNodeBuilder.cpp2
4 files changed, 88 insertions, 32 deletions
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h
index ac2c440fb73..53cc5a7c93d 100644
--- a/polly/include/polly/ScopInfo.h
+++ b/polly/include/polly/ScopInfo.h
@@ -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.
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index b23ddcdb32a..219627b287c 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -606,11 +606,11 @@ MemoryAccess::MemoryAccess(Instruction *AccessInst, __isl_take isl_id *Id,
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) const {
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 isl_map *Schedule) const {
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(AliasAnalysis &AA) {
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(BasicBlock *BB, Instruction *Inst,
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(BasicBlock *BB, Instruction *Inst,
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) {
diff --git a/polly/lib/CodeGen/BlockGenerators.cpp b/polly/lib/CodeGen/BlockGenerators.cpp
index 3d1fd4d25e1..8de5f5970f1 100644
--- a/polly/lib/CodeGen/BlockGenerators.cpp
+++ b/polly/lib/CodeGen/BlockGenerators.cpp
@@ -407,7 +407,7 @@ void BlockGenerator::generateScalarLoads(ScopStmt &Stmt,
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::generateScalarStores(ScopStmt &Stmt, BasicBlock *BB,
"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::generateScalarStores(ScopStmt &Stmt, BasicBlock *BB,
for (MemoryAccess *MA : Stmt) {
- if (!MA->isScalar() || MA->isRead())
+ if (MA->isExplicit() || MA->isRead())
continue;
Instruction *ScalarInst = MA->getAccessInstruction();
diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp
index 427f6bc3e49..85c92402dcd 100644
--- a/polly/lib/CodeGen/IslNodeBuilder.cpp
+++ b/polly/lib/CodeGen/IslNodeBuilder.cpp
@@ -217,7 +217,7 @@ static isl_stat addReferencesFromStmt(const ScopStmt *Stmt, void *UserPtr) {
}
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))
OpenPOWER on IntegriCloud