[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