[llvm] d09218a - [Hexagon] Opaquify pointer usage in GEP commoning

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 24 14:07:04 PDT 2021


Author: Krzysztof Parzyszek
Date: 2021-06-24T16:06:36-05:00
New Revision: d09218a82e1a5dc082bff0b0c4f5cfbdf7736c7d

URL: https://github.com/llvm/llvm-project/commit/d09218a82e1a5dc082bff0b0c4f5cfbdf7736c7d
DIFF: https://github.com/llvm/llvm-project/commit/d09218a82e1a5dc082bff0b0c4f5cfbdf7736c7d.diff

LOG: [Hexagon] Opaquify pointer usage in GEP commoning

Added: 
    

Modified: 
    llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp b/llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp
index 11e7d5a17fa9b..9f18d0b3162c7 100644
--- a/llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp
@@ -11,6 +11,7 @@
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/PostDominators.h"
@@ -179,8 +180,20 @@ namespace {
       Root      = 0x01,
       Internal  = 0x02,
       Used      = 0x04,
-      InBounds  = 0x08
+      InBounds  = 0x08,
+      Pointer   = 0x10,   // See note below.
     };
+    // Note: GEP indices generally traverse nested types, and so a GepNode
+    // (representing a single index) can be associated with some composite
+    // type. The exception is the GEP input, which is a pointer, and not
+    // a composite type (at least not in the sense of having sub-types).
+    // Also, the corresponding index plays a 
diff erent role as well: it is
+    // simply added to the input pointer. Since pointer types are becoming
+    // opaque (i.e. are no longer going to include the pointee type), the
+    // two pieces of information (1) the fact that it's a pointer, and
+    // (2) the pointee type, need to be stored separately. The pointee type
+    // will be stored in the PTy member, while the fact that the node
+    // operates on a pointer will be reflected by the flag "Pointer".
 
     uint32_t Flags = 0;
     union {
@@ -188,7 +201,9 @@ namespace {
       Value *BaseVal;
     };
     Value *Idx = nullptr;
-    Type *PTy = nullptr;  // Type of the pointer operand.
+    Type *PTy = nullptr;    // Type indexed by this node. For pointer nodes
+                            // this is the "pointee" type, and indexing a
+                            // pointer does not change the type.
 
     GepNode() : Parent(nullptr) {}
     GepNode(const GepNode *N) : Flags(N->Flags), Idx(N->Idx), PTy(N->PTy) {
@@ -201,12 +216,6 @@ namespace {
     friend raw_ostream &operator<< (raw_ostream &OS, const GepNode &GN);
   };
 
-  Type *next_type(Type *Ty, Value *Idx) {
-    if (auto *PTy = dyn_cast<PointerType>(Ty))
-      return PTy->getElementType();
-    return GetElementPtrInst::getTypeAtIndex(Ty, Idx);
-  }
-
   raw_ostream &operator<< (raw_ostream &OS, const GepNode &GN) {
     OS << "{ {";
     bool Comma = false;
@@ -230,6 +239,11 @@ namespace {
         OS << ',';
       OS << "inbounds";
     }
+    if (GN.Flags & GepNode::Pointer) {
+      if (Comma)
+        OS << ',';
+      OS << "pointer";
+    }
     OS << "} ";
     if (GN.Flags & GepNode::Root)
       OS << "BaseVal:" << GN.BaseVal->getName() << '(' << GN.BaseVal << ')';
@@ -347,7 +361,8 @@ void HexagonCommonGEP::processGepInst(GetElementPtrInst *GepI,
     // chain. Link to it here.
     N->Parent = F->second;
   }
-  N->PTy = PtrOp->getType();
+  N->PTy = GepI->getSourceElementType();
+  N->Flags |= GepNode::Pointer;
   N->Idx = *GepI->idx_begin();
 
   // Collect the list of users of this GEP instruction. Will add it to the
@@ -367,10 +382,10 @@ void HexagonCommonGEP::processGepInst(GetElementPtrInst *GepI,
   Nodes.push_back(N);
   NodeOrder.insert(N);
 
-  // Skip the first index operand, since we only handle 0. This dereferences
-  // the pointer operand.
+  // Skip the first index operand, since it was already handled above. This
+  // dereferences the pointer operand.
   GepNode *PN = N;
-  Type *PtrTy = cast<PointerType>(PtrOp->getType())->getElementType();
+  Type *PtrTy = GepI->getSourceElementType();
   for (User::op_iterator OI = GepI->idx_begin()+1, OE = GepI->idx_end();
        OI != OE; ++OI) {
     Value *Op = *OI;
@@ -383,7 +398,7 @@ void HexagonCommonGEP::processGepInst(GetElementPtrInst *GepI,
     NodeOrder.insert(Nx);
     PN = Nx;
 
-    PtrTy = next_type(PtrTy, Op);
+    PtrTy = GetElementPtrInst::getTypeAtIndex(PtrTy, Op);
   }
 
   // After last node has been created, update the use information.
@@ -503,16 +518,18 @@ static bool node_eq(GepNode *N1, GepNode *N2, NodePairSet &Eq,
       return false;
     // Not previously compared.
     bool Root1 = N1->Flags & GepNode::Root;
-    bool Root2 = N2->Flags & GepNode::Root;
+    uint32_t CmpFlags = GepNode::Root | GepNode::Pointer;
+    bool Different = (N1->Flags & CmpFlags) != (N2->Flags & CmpFlags);
     NodePair P = node_pair(N1, N2);
-    // If the Root flag has 
diff erent values, the nodes are 
diff erent.
+    // If the root/pointer flags have 
diff erent values, the nodes are
+    // 
diff erent.
     // If both nodes are root nodes, but their base pointers 
diff er,
     // they are 
diff erent.
-    if (Root1 != Root2 || (Root1 && N1->BaseVal != N2->BaseVal)) {
+    if (Different || (Root1 && N1->BaseVal != N2->BaseVal)) {
       Ne.insert(P);
       return false;
     }
-    // Here the root flags are identical, and for root nodes the
+    // Here the root/pointer flags are identical, and for root nodes the
     // base pointers are equal, so the root nodes are equal.
     // For non-root nodes, compare their parent nodes.
     if (Root1 || node_eq(N1->Parent, N2->Parent, Eq, Ne)) {
@@ -927,8 +944,10 @@ namespace {
     for (NodeToValueMap::const_iterator I = Loc.Map.begin(), E = Loc.Map.end();
          I != E; ++I) {
       OS << I->first << " -> ";
-      BasicBlock *B = cast<BasicBlock>(I->second);
-      OS << B->getName() << '(' << B << ')';
+      if (BasicBlock *B = cast_or_null<BasicBlock>(I->second))
+        OS << B->getName() << '(' << B << ')';
+      else
+        OS << "<null-block>";
       OS << '\n';
     }
     return OS;
@@ -1088,41 +1107,39 @@ Value *HexagonCommonGEP::fabricateGEP(NodeVect &NA, BasicBlock::iterator At,
 
   GetElementPtrInst *NewInst = nullptr;
   Value *Input = RN->BaseVal;
-  Value **IdxList = new Value*[Num+1];
-  unsigned nax = 0;
+  Type *InpTy = RN->PTy;
+
+  unsigned Idx = 0;
   do {
-    unsigned IdxC = 0;
+    SmallVector<Value*, 4> IdxList;
     // If the type of the input of the first node is not a pointer,
     // we need to add an artificial i32 0 to the indices (because the
     // actual input in the IR will be a pointer).
-    if (!NA[nax]->PTy->isPointerTy()) {
+    if (!(NA[Idx]->Flags & GepNode::Pointer)) {
       Type *Int32Ty = Type::getInt32Ty(*Ctx);
-      IdxList[IdxC++] = ConstantInt::get(Int32Ty, 0);
+      IdxList.push_back(ConstantInt::get(Int32Ty, 0));
     }
 
     // Keep adding indices from NA until we have to stop and generate
     // an "intermediate" GEP.
-    while (++nax <= Num) {
-      GepNode *N = NA[nax-1];
-      IdxList[IdxC++] = N->Idx;
-      if (nax < Num) {
-        // We have to stop, if the expected type of the output of this node
-        // is not the same as the input type of the next node.
-        Type *NextTy = next_type(N->PTy, N->Idx);
-        if (NextTy != NA[nax]->PTy)
+    while (++Idx <= Num) {
+      GepNode *N = NA[Idx-1];
+      IdxList.push_back(N->Idx);
+      if (Idx < Num) {
+        // We have to stop if we reach a pointer.
+        if (NA[Idx]->Flags & GepNode::Pointer)
           break;
       }
     }
-    ArrayRef<Value*> A(IdxList, IdxC);
-    Type *InpTy = Input->getType();
-    Type *ElTy = cast<PointerType>(InpTy->getScalarType())->getElementType();
-    NewInst = GetElementPtrInst::Create(ElTy, Input, A, "cgep", &*At);
+    NewInst = GetElementPtrInst::Create(InpTy, Input, IdxList, "cgep", &*At);
     NewInst->setIsInBounds(RN->Flags & GepNode::InBounds);
     LLVM_DEBUG(dbgs() << "new GEP: " << *NewInst << '\n');
-    Input = NewInst;
-  } while (nax <= Num);
+    if (Idx < Num) {
+      Input = NewInst;
+      InpTy = NA[Idx]->PTy;
+    }
+  } while (Idx <= Num);
 
-  delete[] IdxList;
   return NewInst;
 }
 


        


More information about the llvm-commits mailing list