summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/include/polly/ScopInfo.h334
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp79
-rw-r--r--polly/lib/CodeGen/BlockGenerators.cpp20
-rw-r--r--polly/lib/CodeGen/IslNodeBuilder.cpp8
4 files changed, 232 insertions, 209 deletions
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h
index 07ab57a6630..98e798920d3 100644
--- a/polly/include/polly/ScopInfo.h
+++ b/polly/include/polly/ScopInfo.h
@@ -97,20 +97,125 @@ typedef std::map<const BasicBlock *, AccFuncSetType> AccFuncMapType;
///
class ScopArrayInfo {
public:
- /// @brief The type of a memory access.
- enum ARRAYKIND {
- // Scalar references to SSA values.
- KIND_SCALAR,
-
- // Scalar references used to model PHI nodes
- KIND_PHI,
-
- // Like KIND_PHI, but for PHIs in the exit node. Depending on context, these
- // are handled like KIND_SCALAR.
- KIND_EXIT_PHI,
-
- // References to (multi-dimensional) arrays
- KIND_ARRAY,
+ /// @brief The kind of a ScopArrayInfo memory object.
+ ///
+ /// We distinguish between arrays and various scalar memory objects. We use
+ /// the term ``array'' to describe memory objects that consist of a set of
+ /// individual data elements arranged in a multi-dimensional grid. A scalar
+ /// memory object describes an individual data element and is used to model
+ /// the definition and uses of llvm::Values.
+ ///
+ /// The polyhedral model does traditionally not reason about SSA values. To
+ /// reason about llvm::Values we model them "as if" they were zero-dimensional
+ /// memory objects, even though they were not actually allocated in (main)
+ /// memory. Memory for such objects is only alloca[ed] at CodeGeneration
+ /// time. To relate the memory slots used during code generation with the
+ /// llvm::Values they belong to the new names for these corresponding stack
+ /// slots are derived by appending suffixes (currently ".s2a" and ".phiops")
+ /// to the name of the original llvm::Value. To describe how def/uses are
+ /// modeled exactly we use these suffixes here as well.
+ ///
+ /// There are currently four different kinds of memory objects:
+ enum MemoryKind {
+ /// MK_Array: Models a one or multi-dimensional array
+ ///
+ /// A memory object that can be described by a multi-dimensional array.
+ /// Memory objects of this type are used to model actual multi-dimensional
+ /// arrays as they exist in LLVM-IR, but they are also used to describe
+ /// other objects:
+ /// - A single data element allocated on the stack using 'alloca' is
+ /// modeled as a one-dimensional, single-element array.
+ /// - A single data element allocated as a global variable is modeled as
+ /// one-dimensional, single-element array.
+ /// - Certain multi-dimensional arrays with variable size, which in
+ /// LLVM-IR are commonly expressed as a single-dimensional access with a
+ /// complicated access function, are modeled as multi-dimensional
+ /// memory objects (grep for "delinearization").
+ MK_Array,
+
+ /// MK_Value: Models an llvm::Value
+ ///
+ /// Memory objects of type MK_Value are used to model the data flow
+ /// induced by llvm::Values. For each llvm::Value that is used across
+ /// BasicBocks one ScopArrayInfo object is created. A single memory WRITE
+ /// stores the llvm::Value at its definition into the memory object and at
+ /// each use of the llvm::Value (ignoring trivial intra-block uses) a
+ /// corresponding READ is added. For instance, the use/def chain of a
+ /// llvm::Value %V depicted below
+ /// ______________________
+ /// |DefBB: |
+ /// | %V = float op ... |
+ /// ----------------------
+ /// | |
+ /// _________________ _________________
+ /// |UseBB1: | |UseBB2: |
+ /// | use float %V | | use float %V |
+ /// ----------------- -----------------
+ ///
+ /// is modeled as if the following memory accesses occured:
+ ///
+ /// __________________________
+ /// |entry: |
+ /// | %V.s2a = alloca float |
+ /// --------------------------
+ /// |
+ /// ___________________________________
+ /// |DefBB: |
+ /// | store %float %V, float* %V.sa2 |
+ /// -----------------------------------
+ /// | |
+ /// ____________________________________ ___________________________________
+ /// |UseBB1: | |UseBB2: |
+ /// | %V.reload1 = load float* %V.s2a | | %V.reload2 = load float* %V.s2a|
+ /// | use float %V.reload1 | | use float %V.reload2 |
+ /// ------------------------------------ -----------------------------------
+ ///
+ MK_Value,
+
+ /// MK_PHI: Models PHI nodes within the SCoP
+ ///
+ /// Besides the MK_Value memory object used to model the normal
+ /// llvm::Value dependences described above, PHI nodes require an additional
+ /// memory object of type MK_PHI to describe the forwarding of values to
+ /// the PHI node.
+ ///
+ /// As an example, a PHIInst instructions
+ ///
+ /// %PHI = phi float [ %Val1, %IncomingBlock1 ], [ %Val2, %IncomingBlock2 ]
+ ///
+ /// is modeled as if the accesses occured this way:
+ ///
+ /// _______________________________
+ /// |entry: |
+ /// | %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 |
+ /// -----------------------------------------
+ ///
+ /// Note that there can also be a scalar write access for %PHI if used in a
+ /// different BasicBlock, i.e. there can be a memory object %PHI.phiops as
+ /// well as a memory object %PHI.s2a.
+ MK_PHI,
+
+ /// MK_ExitPHI: Models PHI nodes in the SCoP's exit block
+ ///
+ /// For PHI nodes in the Scop's exit block a special memory object kind is
+ /// used. The modeling used is identical to MK_PHI, with the exception
+ /// that there are no READs from these memory objects. The PHINode's
+ /// llvm::Value is treated as a value escaping the SCoP. WRITE accesses
+ /// write directly to the escaping value's ".s2a" alloca.
+ MK_ExitPHI
};
/// @brief Construct a ScopArrayInfo object.
@@ -123,7 +228,7 @@ public:
/// @param DL The data layout of the module.
/// @param S The scop this array object belongs to.
ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *IslCtx,
- ArrayRef<const SCEV *> DimensionSizes, enum ARRAYKIND Kind,
+ ArrayRef<const SCEV *> DimensionSizes, enum MemoryKind Kind,
const DataLayout &DL, Scop *S);
/// @brief Update the sizes of the ScopArrayInfo object.
@@ -201,7 +306,7 @@ public:
/// original PHI node as virtual base pointer, we have this additional
/// attribute to distinguish the PHI node specific array modeling from the
/// normal scalar array modeling.
- bool isPHI() const { return Kind == KIND_PHI; };
+ bool isPHIKind() const { return Kind == MK_PHI; };
/// @brief Dump a readable representation to stderr.
void dump() const;
@@ -250,7 +355,7 @@ private:
/// @brief The type of this scop array info object.
///
/// We distinguish between SCALAR, PHI and ARRAY objects.
- enum ARRAYKIND Kind;
+ enum MemoryKind Kind;
/// @brief The data layout of the module.
const DataLayout &DL;
@@ -265,114 +370,6 @@ class MemoryAccess {
friend class ScopStmt;
public:
- /// @brief Description of the cause of a MemoryAccess being added.
- ///
- /// We distinguish between explicit and implicit accesses. Explicit are those
- /// for which there is a load or store instruction in the analyzed IR.
- /// Implicit accesses are derived from defintions and uses of llvm::Values.
- /// The polyhedral model has no notion of such values or SSA form, hence they
- /// are modeled "as if" they were accesses to zero-dimensional arrays even if
- /// they do represent accesses to (main) memory in the analyzed IR code. The
- /// actual memory for the zero-dimensional arrays is only created using
- /// allocas at CodeGeneration, with suffixes (currently ".s2a" and ".phiops")
- /// added to the value's name. To describe how def/uses are modeled using
- /// accesses we use these these suffixes here as well.
- /// There are currently three separate kinds of 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 used in a different
- /// BasicBlock. For instance, a use/def chain of such as %V in
- /// ______________________
- /// |DefBB: |
- /// | %V = float op ... |
- /// ----------------------
- /// | |
- /// _________________ _________________
- /// |UseBB1: | |UseBB2: |
- /// | use float %V | | use float %V |
- /// ----------------- -----------------
- ///
- /// is modeled as if the accesses had occured this way:
- ///
- /// __________________________
- /// |entry: |
- /// | %V.s2a = alloca float |
- /// --------------------------
- /// |
- /// ___________________________________
- /// |DefBB: |
- /// | store %float %V, float* %V.sa2 |
- /// -----------------------------------
- /// | |
- /// ____________________________________ ____________________________________
- /// |UseBB1: | |UseBB2: |
- /// | %V.reload1 = load float* %V.s2a | | %V.reload2 = load float* %V.s2a |
- /// | use float %V.reload1 | | use float %V.reload2 |
- /// ------------------------------------ ------------------------------------
- ///
- /// #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 within the SCoP
- ///
- /// PHIInst instructions such as
- ///
- /// %PHI = phi float [ %Val1, %IncomingBlock1 ], [ %Val2, %IncomingBlock2 ]
- ///
- /// are modeled as if the accesses occured this way:
- ///
- /// _______________________________
- /// |entry: |
- /// | %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 such alloca in the analyzed code. 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, i.e. there can be a %PHI.phiops as well as a
- /// %PHI.s2a.
- ///
- ///
- /// * Accesses to emulate PHI nodes that are in the SCoP's exit block
- ///
- /// Like the previous, but the PHI itself is not located in the SCoP itself.
- /// There will be no READ type MemoryAccess for such values. The PHINode's
- /// llvm::Value is treated as a value escaping the SCoP. WRITE accesses write
- /// directly to the escaping value's ".s2a" alloca.
- enum AccessOrigin { EXPLICIT, SCALAR, PHI, EXIT_PHI };
-
/// @brief The access type of a memory access
///
/// There are three kind of access types:
@@ -421,9 +418,9 @@ private:
/// scop statement.
isl_id *Id;
- /// @brief What is modeled by this MemoetyAccess.
- /// @see AccessOrigin
- enum AccessOrigin Origin;
+ /// @brief What is modeled by this MemoryAccess.
+ /// @see ScopArrayInfo::MemoryKind
+ ScopArrayInfo::MemoryKind Kind;
/// @brief Whether it a reading or writing access, and if writing, whether it
/// is conditional (MAY_WRITE).
@@ -463,6 +460,13 @@ private:
// @{
/// @brief The base address (e.g., A for A[i+j]).
+ ///
+ /// The #BaseAddr of a memory access of kind MK_Array is the base pointer
+ /// of the memory access.
+ /// The #BaseAddr of a memory access of kind MK_PHI or MK_ExitPHI is the
+ /// PHI node itself.
+ /// The #BaseAddr of a memory access of kind MK_Value is the instruction
+ /// defining the value.
AssertingVH<Value> BaseAddr;
/// @brief An unique name of the accessed array.
@@ -479,13 +483,27 @@ private:
// @{
/// @brief The access instruction of this memory access.
+ ///
+ /// For memory accesses of kind MK_Array the access instruction is the
+ /// Load or Store instruction performing the access.
+ ///
+ /// For memory accesses of kind MK_PHI or MK_ExitPHI the access
+ /// instruction of a load access is the PHI instruction. The access
+ /// instruction of a PHI-store is the incoming's block's terminator
+ /// intruction.
+ ///
+ /// For memory accesses of kind MK_Value the access instruction of a load
+ /// access is the instruction that uses the load. The access instruction of
+ /// a write access is the intruction that defines the llvm::Value.
Instruction *AccessInstruction;
/// @brief The value associated with this memory access.
///
- /// - For real memory accesses it is the loaded result or the stored value.
- /// - For straight line scalar accesses it is the access instruction itself.
- /// - For PHI operand accesses it is the operand value.
+ /// - For array memory accesses (MK_Array) it is the loaded result or the
+ /// stored value.
+ /// - For accesses of kind MK_Value it is the access instruction itself.
+ /// - For accesses of kind MK_PHI or MK_ExitPHI it is the operand value
+ /// of the PHI node.
///
AssertingVH<Value> AccessValue;
@@ -572,14 +590,15 @@ public:
/// @param ElemBytes Number of accessed bytes.
/// @param AccType Whether read or write access.
/// @param IsAffine Whether the subscripts are affine expressions.
- /// @param Origin What is the purpose of this access?
+ /// @param Kind The kind of memory accessed.
/// @param Subscripts Subscipt expressions
/// @param Sizes Dimension lengths of the accessed array.
/// @param BaseName Name of the acessed array.
MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst, AccessType Type,
Value *BaseAddress, unsigned ElemBytes, bool Affine,
ArrayRef<const SCEV *> Subscripts, ArrayRef<const SCEV *> Sizes,
- Value *AccessValue, AccessOrigin Origin, StringRef BaseName);
+ Value *AccessValue, ScopArrayInfo::MemoryKind Kind,
+ StringRef BaseName);
~MemoryAccess();
/// @brief Get the type of a memory access.
@@ -674,21 +693,22 @@ public:
bool isStrideZero(__isl_take const isl_map *Schedule) const;
/// @brief Whether this is an access of an explicit load or store in the IR.
- bool isExplicit() const { return Origin == EXPLICIT; }
+ bool isArrayKind() const { return Kind == ScopArrayInfo::MK_Array; }
- /// @brief Whether this access represents a register access or models PHI
- /// nodes.
- bool isImplicit() const { return !isExplicit(); }
+ /// @brief Whether this access is an array to a scalar memory object.
+ ///
+ /// Scalar accesses are accesses to MK_Value, MK_PHI or MK_ExitPHI.
+ bool isScalarKind() const { return !isArrayKind(); }
/// @brief Is this MemoryAccess modeling scalar dependences?
- bool isScalar() const { return Origin == SCALAR; }
+ bool isValueKind() const { return Kind == ScopArrayInfo::MK_Value; }
/// @brief Is this MemoryAccess modeling special PHI node accesses?
- bool isPHI() const { return Origin == PHI; }
+ bool isPHIKind() const { return Kind == ScopArrayInfo::MK_PHI; }
/// @brief Is this MemoryAccess modeling the accesses of a PHI node in the
/// SCoP's exit block?
- bool isExitPHI() const { return Origin == EXIT_PHI; }
+ bool isExitPHIKind() const { return Kind == ScopArrayInfo::MK_ExitPHI; }
/// @brief Get the statement that contains this memory access.
ScopStmt *getStatement() const { return Statement; }
@@ -1607,18 +1627,18 @@ public:
/// @brief Return the (possibly new) ScopArrayInfo object for @p Access.
///
/// @param ElementType The type of the elements stored in this array.
- /// @param Kind The kind of array info object.
+ /// @param Kind The kind of the array info object.
const ScopArrayInfo *getOrCreateScopArrayInfo(Value *BasePtr,
Type *ElementType,
ArrayRef<const SCEV *> Sizes,
- ScopArrayInfo::ARRAYKIND Kind);
+ ScopArrayInfo::MemoryKind Kind);
/// @brief Return the cached ScopArrayInfo object for @p BasePtr.
///
- /// @param BasePtr The base pointer the object has been stored for.
- /// @param Kind The kind of array info object.
+ /// @param BasePtr The base pointer the object has been stored for.
+ /// @param Kind The kind of array info object.
const ScopArrayInfo *getScopArrayInfo(Value *BasePtr,
- ScopArrayInfo::ARRAYKIND Kind);
+ ScopArrayInfo::MemoryKind Kind);
void setContext(isl_set *NewContext);
@@ -1827,13 +1847,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 Origin Purpose of this access.
+ /// @param Kind The kind of memory accessed.
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,
- MemoryAccess::AccessOrigin Origin);
+ ScopArrayInfo::MemoryKind Kind);
/// @brief Create a MemoryAccess that represents either a LoadInst or
/// StoreInst.
@@ -1846,11 +1866,11 @@ class ScopInfo : public RegionPass {
/// @param Subscripts Access subscripts per dimension.
/// @param Sizes The array dimension's sizes.
/// @param AccessValue Value read or written.
- /// @see AccessOrigin
- void addExplicitAccess(Instruction *MemAccInst, MemoryAccess::AccessType Type,
- Value *BaseAddress, unsigned ElemBytes, bool IsAffine,
- ArrayRef<const SCEV *> Subscripts,
- ArrayRef<const SCEV *> Sizes, Value *AccessValue);
+ /// @see ScopArrayInfo::MemoryKind
+ void addArrayAccess(Instruction *MemAccInst, MemoryAccess::AccessType Type,
+ Value *BaseAddress, unsigned ElemBytes, bool IsAffine,
+ ArrayRef<const SCEV *> Subscripts,
+ ArrayRef<const SCEV *> Sizes, Value *AccessValue);
/// @brief Create a MemoryAccess for writing an llvm::Value.
///
@@ -1858,7 +1878,7 @@ class ScopInfo : public RegionPass {
///
/// @param Value The value to be written.
/// @see addScalarReadAccess()
- /// @see AccessOrigin
+ /// @see ScopArrayInfo::MemoryKind
void addScalarWriteAccess(Instruction *Value);
/// @brief Create a MemoryAccess for reloading an llvm::Value.
@@ -1868,7 +1888,7 @@ class ScopInfo : public RegionPass {
/// @param Value The scalar expected to be loaded.
/// @param User User of the scalar; this is where the access is added.
/// @see addScalarWriteAccess()
- /// @see AccessOrigin
+ /// @see ScopArrayInfo::MemoryKind
void addScalarReadAccess(Value *Value, Instruction *User);
/// @brief Create a MemoryAccess for reloading an llvm::Value.
@@ -1882,7 +1902,7 @@ class ScopInfo : public RegionPass {
/// @param UserBB Incoming block for the incoming @p Value.
/// @see addPHIWriteAccess()
/// @see addScalarWriteAccess()
- /// @see AccessOrigin
+ /// @see ScopArrayInfo::MemoryKind
void addScalarReadAccess(Value *Value, PHINode *User, BasicBlock *UserBB);
/// @brief Create a write MemoryAccess for the incoming block of a phi node.
@@ -1897,7 +1917,7 @@ class ScopInfo : public RegionPass {
/// .phiops one. Required for values escaping through a
/// PHINode in the SCoP region's exit block.
/// @see addPHIReadAccess()
- /// @see AccessOrigin
+ /// @see ScopArrayInfo::MemoryKind
void addPHIWriteAccess(PHINode *PHI, BasicBlock *IncomingBlock,
Value *IncomingValue, bool IsExitBlock);
@@ -1910,7 +1930,7 @@ class ScopInfo : public RegionPass {
/// @param PHI PHINode under consideration; the READ access will be added
/// here.
/// @see addPHIWriteAccess()
- /// @see AccessOrigin
+ /// @see ScopArrayInfo::MemoryKind
void addPHIReadAccess(PHINode *PHI);
public:
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index 86a20234acc..0bc7b262e75 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -166,15 +166,15 @@ static const ScopArrayInfo *identifyBasePtrOriginSAI(Scop *S, Value *BasePtr) {
return nullptr;
return S->getScopArrayInfo(OriginBaseSCEVUnknown->getValue(),
- ScopArrayInfo::KIND_ARRAY);
+ ScopArrayInfo::MK_Array);
}
ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *Ctx,
- ArrayRef<const SCEV *> Sizes, enum ARRAYKIND Kind,
+ ArrayRef<const SCEV *> Sizes, enum MemoryKind Kind,
const DataLayout &DL, Scop *S)
: BasePtr(BasePtr), ElementType(ElementType), Kind(Kind), DL(DL), S(*S) {
std::string BasePtrName =
- getIslCompatibleName("MemRef_", BasePtr, Kind == KIND_PHI ? "__phi" : "");
+ getIslCompatibleName("MemRef_", BasePtr, Kind == MK_PHI ? "__phi" : "");
Id = isl_id_alloc(Ctx, BasePtrName.c_str(), this);
updateSizes(Sizes);
@@ -701,8 +701,8 @@ MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst,
unsigned ElemBytes, bool Affine,
ArrayRef<const SCEV *> Subscripts,
ArrayRef<const SCEV *> Sizes, Value *AccessValue,
- AccessOrigin Origin, StringRef BaseName)
- : Origin(Origin), AccType(Type), RedType(RT_NONE), Statement(Stmt),
+ ScopArrayInfo::MemoryKind Kind, StringRef BaseName)
+ : Kind(Kind), AccType(Type), RedType(RT_NONE), Statement(Stmt),
BaseAddr(BaseAddress), BaseName(BaseName), ElemBytes(ElemBytes),
Sizes(Sizes.begin(), Sizes.end()), AccessInstruction(AccessInst),
AccessValue(AccessValue), IsAffine(Affine),
@@ -746,7 +746,7 @@ void MemoryAccess::print(raw_ostream &OS) const {
break;
}
OS << "[Reduction Type: " << getReductionType() << "] ";
- OS << "[Scalar: " << isImplicit() << "]\n";
+ OS << "[Scalar: " << isScalarKind() << "]\n";
OS.indent(16) << getOriginalAccessRelationStr() << ";\n";
if (hasNewAccessRelation())
OS.indent(11) << "new: " << getNewAccessRelationStr() << ";\n";
@@ -879,15 +879,15 @@ void ScopStmt::buildAccessRelations() {
for (MemoryAccess *Access : MemAccs) {
Type *ElementType = Access->getAccessValue()->getType();
- ScopArrayInfo::ARRAYKIND Ty;
- if (Access->isPHI())
- Ty = ScopArrayInfo::KIND_PHI;
- else if (Access->isExitPHI())
- Ty = ScopArrayInfo::KIND_EXIT_PHI;
- else if (Access->isScalar())
- Ty = ScopArrayInfo::KIND_SCALAR;
+ ScopArrayInfo::MemoryKind Ty;
+ if (Access->isPHIKind())
+ Ty = ScopArrayInfo::MK_PHI;
+ else if (Access->isExitPHIKind())
+ Ty = ScopArrayInfo::MK_ExitPHI;
+ else if (Access->isValueKind())
+ Ty = ScopArrayInfo::MK_Value;
else
- Ty = ScopArrayInfo::KIND_ARRAY;
+ Ty = ScopArrayInfo::MK_Array;
const ScopArrayInfo *SAI = getParent()->getOrCreateScopArrayInfo(
Access->getBaseAddr(), ElementType, Access->Sizes, Ty);
@@ -2466,7 +2466,7 @@ bool Scop::buildAliasGroups(AliasAnalysis &AA) {
continue;
for (MemoryAccess *MA : Stmt) {
- if (MA->isImplicit())
+ if (MA->isScalarKind())
continue;
if (!MA->isRead())
HasWriteAccess.insert(MA->getBaseAddr());
@@ -2867,7 +2867,7 @@ void Scop::hoistInvariantLoads() {
MemoryAccessList InvMAs;
for (MemoryAccess *MA : Stmt) {
- if (MA->isImplicit() || MA->isWrite() || !MA->isAffine())
+ if (MA->isScalarKind() || MA->isWrite() || !MA->isAffine())
continue;
// Skip accesses that have an invariant base pointer which is defined but
@@ -2957,7 +2957,7 @@ void Scop::hoistInvariantLoads() {
const ScopArrayInfo *
Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *AccessType,
ArrayRef<const SCEV *> Sizes,
- ScopArrayInfo::ARRAYKIND Kind) {
+ ScopArrayInfo::MemoryKind Kind) {
auto &SAI = ScopArrayInfoMap[std::make_pair(BasePtr, Kind)];
if (!SAI) {
auto &DL = getRegion().getEntry()->getModule()->getDataLayout();
@@ -2973,7 +2973,7 @@ Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *AccessType,
}
const ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr,
- ScopArrayInfo::ARRAYKIND Kind) {
+ ScopArrayInfo::MemoryKind Kind) {
auto *SAI = ScopArrayInfoMap[std::make_pair(BasePtr, Kind)].get();
assert(SAI && "No ScopArrayInfo available for this base pointer");
return SAI;
@@ -3738,8 +3738,8 @@ void ScopInfo::buildMemoryAccess(
SizesSCEV.push_back(SE->getSCEV(ConstantInt::get(
IntegerType::getInt64Ty(BasePtr->getContext()), Size)));
- addExplicitAccess(Inst, Type, BasePointer->getValue(), Size, true,
- Subscripts, SizesSCEV, Val);
+ addArrayAccess(Inst, Type, BasePointer->getValue(), Size, true,
+ Subscripts, SizesSCEV, Val);
return;
}
}
@@ -3747,9 +3747,9 @@ void ScopInfo::buildMemoryAccess(
auto AccItr = InsnToMemAcc.find(Inst);
if (PollyDelinearize && AccItr != InsnToMemAcc.end()) {
- addExplicitAccess(Inst, Type, BasePointer->getValue(), Size, true,
- AccItr->second.DelinearizedSubscripts,
- AccItr->second.Shape->DelinearizedSizes, Val);
+ addArrayAccess(Inst, Type, BasePointer->getValue(), Size, true,
+ AccItr->second.DelinearizedSubscripts,
+ AccItr->second.Shape->DelinearizedSizes, Val);
return;
}
@@ -3780,9 +3780,9 @@ void ScopInfo::buildMemoryAccess(
if (!IsAffine && Type == MemoryAccess::MUST_WRITE)
Type = MemoryAccess::MAY_WRITE;
- addExplicitAccess(Inst, Type, BasePointer->getValue(), Size, IsAffine,
- ArrayRef<const SCEV *>(AccessFunction),
- ArrayRef<const SCEV *>(SizeSCEV), Val);
+ addArrayAccess(Inst, Type, BasePointer->getValue(), Size, IsAffine,
+ ArrayRef<const SCEV *>(AccessFunction),
+ ArrayRef<const SCEV *>(SizeSCEV), Val);
}
void ScopInfo::buildAccessFunctions(Region &R, Region &SR) {
@@ -3871,7 +3871,7 @@ void ScopInfo::addMemoryAccess(BasicBlock *BB, Instruction *Inst,
bool Affine, Value *AccessValue,
ArrayRef<const SCEV *> Subscripts,
ArrayRef<const SCEV *> Sizes,
- MemoryAccess::AccessOrigin Origin) {
+ ScopArrayInfo::MemoryKind Kind) {
ScopStmt *Stmt = scop->getStmtForBasicBlock(BB);
// Do not create a memory access for anything not in the SCoP. It would be
@@ -3889,48 +3889,51 @@ void ScopInfo::addMemoryAccess(BasicBlock *BB, Instruction *Inst,
Type = MemoryAccess::MAY_WRITE;
AccList.emplace_back(Stmt, Inst, Type, BaseAddress, ElemBytes, Affine,
- Subscripts, Sizes, AccessValue, Origin, BaseName);
+ Subscripts, Sizes, AccessValue, Kind, BaseName);
Stmt->addAccess(&AccList.back());
}
-void ScopInfo::addExplicitAccess(
- Instruction *MemAccInst, MemoryAccess::AccessType Type, Value *BaseAddress,
- unsigned ElemBytes, bool IsAffine, ArrayRef<const SCEV *> Subscripts,
- ArrayRef<const SCEV *> Sizes, Value *AccessValue) {
+void ScopInfo::addArrayAccess(Instruction *MemAccInst,
+ MemoryAccess::AccessType Type, Value *BaseAddress,
+ unsigned ElemBytes, bool IsAffine,
+ ArrayRef<const SCEV *> Subscripts,
+ ArrayRef<const SCEV *> Sizes,
+ Value *AccessValue) {
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,
- MemoryAccess::EXPLICIT);
+ ScopArrayInfo::MK_Array);
}
void ScopInfo::addScalarWriteAccess(Instruction *Value) {
addMemoryAccess(Value->getParent(), Value, MemoryAccess::MUST_WRITE, Value, 1,
true, Value, ArrayRef<const SCEV *>(),
- ArrayRef<const SCEV *>(), MemoryAccess::SCALAR);
+ ArrayRef<const SCEV *>(), ScopArrayInfo::MK_Value);
}
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 *>(),
- MemoryAccess::SCALAR);
+ ScopArrayInfo::MK_Value);
}
void ScopInfo::addScalarReadAccess(Value *Value, PHINode *User,
BasicBlock *UserBB) {
addMemoryAccess(UserBB, User, MemoryAccess::READ, Value, 1, true, Value,
ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(),
- MemoryAccess::SCALAR);
+ ScopArrayInfo::MK_Value);
}
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 ? MemoryAccess::EXIT_PHI : MemoryAccess::PHI);
+ IsExitBlock ? ScopArrayInfo::MK_ExitPHI
+ : ScopArrayInfo::MK_PHI);
}
void ScopInfo::addPHIReadAccess(PHINode *PHI) {
addMemoryAccess(PHI->getParent(), PHI, MemoryAccess::READ, PHI, 1, true, PHI,
ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(),
- MemoryAccess::PHI);
+ ScopArrayInfo::MK_PHI);
}
void ScopInfo::buildScop(Region &R, DominatorTree &DT, AssumptionCache &AC) {
diff --git a/polly/lib/CodeGen/BlockGenerators.cpp b/polly/lib/CodeGen/BlockGenerators.cpp
index 67d2e2260c9..43fec9a9e39 100644
--- a/polly/lib/CodeGen/BlockGenerators.cpp
+++ b/polly/lib/CodeGen/BlockGenerators.cpp
@@ -332,14 +332,14 @@ Value *BlockGenerator::getOrCreateAlloca(Value *ScalarBase,
}
Value *BlockGenerator::getOrCreateAlloca(MemoryAccess &Access) {
- if (Access.isPHI())
+ if (Access.isPHIKind())
return getOrCreatePHIAlloca(Access.getBaseAddr());
else
return getOrCreateScalarAlloca(Access.getBaseAddr());
}
Value *BlockGenerator::getOrCreateAlloca(const ScopArrayInfo *Array) {
- if (Array->isPHI())
+ if (Array->isPHIKind())
return getOrCreatePHIAlloca(Array->getBasePtr());
else
return getOrCreateScalarAlloca(Array->getBasePtr());
@@ -388,7 +388,7 @@ void BlockGenerator::handleOutsideUsers(const Region &R, Instruction *Inst,
void BlockGenerator::generateScalarLoads(ScopStmt &Stmt, ValueMapT &BBMap) {
for (MemoryAccess *MA : Stmt) {
- if (MA->isExplicit() || MA->isWrite())
+ if (MA->isArrayKind() || MA->isWrite())
continue;
auto *Address = getOrCreateAlloca(*MA);
@@ -453,7 +453,7 @@ void BlockGenerator::generateScalarStores(ScopStmt &Stmt, LoopToScevMapT &LTS,
"RegionGenerator");
for (MemoryAccess *MA : Stmt) {
- if (MA->isExplicit() || MA->isRead())
+ if (MA->isArrayKind() || MA->isRead())
continue;
Value *Val = MA->getAccessValue();
@@ -484,7 +484,7 @@ void BlockGenerator::createScalarInitialization(Scop &S) {
auto &Array = Pair.second;
if (Array->getNumberOfDimensions() != 0)
continue;
- if (Array->isPHI()) {
+ if (Array->isPHIKind()) {
// For PHI nodes, the only values we need to store are the ones that
// reach the PHI node from outside the region. In general there should
// only be one such incoming edge and this edge should enter through
@@ -578,7 +578,7 @@ void BlockGenerator::findOutsideUsers(Scop &S) {
if (Array->getNumberOfDimensions() != 0)
continue;
- if (Array->isPHI())
+ if (Array->isPHIKind())
continue;
auto *Inst = dyn_cast<Instruction>(Array->getBasePtr());
@@ -1188,7 +1188,7 @@ void RegionGenerator::generateScalarStores(ScopStmt &Stmt, LoopToScevMapT &LTS,
"function in the BlockGenerator");
for (MemoryAccess *MA : Stmt) {
- if (MA->isExplicit() || MA->isRead())
+ if (MA->isArrayKind() || MA->isRead())
continue;
Instruction *ScalarInst = MA->getAccessInstruction();
@@ -1200,8 +1200,8 @@ void RegionGenerator::generateScalarStores(ScopStmt &Stmt, LoopToScevMapT &LTS,
auto SavedInsertionPoint = Builder.GetInsertPoint();
ValueMapT *LocalBBMap = &BBMap;
- // Implicit writes induced by PHIs must be written in the incoming blocks.
- if (MA->isPHI() || MA->isExitPHI()) {
+ // Scalar writes induced by PHIs must be written in the incoming blocks.
+ if (MA->isPHIKind() || MA->isExitPHIKind()) {
BasicBlock *ExitingBB = ScalarInst->getParent();
BasicBlock *ExitingBBCopy = BlockMap[ExitingBB];
Builder.SetInsertPoint(ExitingBBCopy->getTerminator());
@@ -1217,7 +1217,7 @@ void RegionGenerator::generateScalarStores(ScopStmt &Stmt, LoopToScevMapT &LTS,
Builder.CreateStore(Val, Address);
// Restore the insertion point if necessary.
- if (MA->isPHI() || MA->isExitPHI())
+ if (MA->isPHIKind() || MA->isExitPHIKind())
Builder.SetInsertPoint(SavedInsertBB, SavedInsertionPoint);
}
}
diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp
index 71ef9c5c569..f75a304d07b 100644
--- a/polly/lib/CodeGen/IslNodeBuilder.cpp
+++ b/polly/lib/CodeGen/IslNodeBuilder.cpp
@@ -219,7 +219,7 @@ static isl_stat addReferencesFromStmt(const ScopStmt *Stmt, void *UserPtr) {
}
for (auto &Access : *Stmt) {
- if (Access->isExplicit()) {
+ if (Access->isArrayKind()) {
auto *BasePtr = Access->getScopArrayInfo()->getBasePtr();
if (Instruction *OpInst = dyn_cast<Instruction>(BasePtr))
if (Stmt->getParent()->getRegion().contains(OpInst))
@@ -1008,7 +1008,7 @@ bool IslNodeBuilder::preloadInvariantEquivClass(
return true;
MemoryAccess *MA = MAs.front();
- assert(MA->isExplicit() && MA->isRead());
+ assert(MA->isArrayKind() && MA->isRead());
// If the access function was already mapped, the preload of this equivalence
// class was triggered earlier already and doesn't need to be done again.
@@ -1023,7 +1023,7 @@ bool IslNodeBuilder::preloadInvariantEquivClass(
// If the base pointer of this class is dependent on another one we have to
// make sure it was preloaded already.
- auto *SAI = S.getScopArrayInfo(MA->getBaseAddr(), ScopArrayInfo::KIND_ARRAY);
+ auto *SAI = S.getScopArrayInfo(MA->getBaseAddr(), ScopArrayInfo::MK_Array);
if (const auto *BaseIAClass = S.lookupInvariantEquivClass(SAI->getBasePtr()))
if (!preloadInvariantEquivClass(*BaseIAClass))
return false;
@@ -1075,7 +1075,7 @@ bool IslNodeBuilder::preloadInvariantEquivClass(
// For scalar derived SAIs we remap the alloca used for the derived value.
if (BasePtr == MA->getAccessInstruction()) {
- if (DerivedSAI->isPHI())
+ if (DerivedSAI->isPHIKind())
PHIOpMap[BasePtr] = Alloca;
else
ScalarMap[BasePtr] = Alloca;
OpenPOWER on IntegriCloud