Use the SubclassData field to hold ExtType, isTrunc, and MemIndexedMode
authorDan Gohman <gohman@apple.com>
Tue, 3 Feb 2009 00:08:45 +0000 (00:08 +0000)
committerDan Gohman <gohman@apple.com>
Tue, 3 Feb 2009 00:08:45 +0000 (00:08 +0000)
information. This eliminates the need for the Flags field in MemSDNode,
so this makes LoadSDNode and StoreSDNode smaller. Also, it makes
FoldingSetNodeIDs for loads and stores two AddIntegers smaller.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63577 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index 06e507ba653f61f989016844b85bd065e41d2253..fafc78181853de1eb31c4e017d44b0e6d9245168 100644 (file)
@@ -1596,10 +1596,6 @@ private:
   //! SVOffset - Memory location offset. Note that base is defined in MemSDNode
   int SVOffset;
 
-  /// Flags - the low bit indicates whether this is a volatile reference;
-  /// the remainder is a log2 encoding of the alignment in bytes.
-  unsigned Flags;
-
 public:
   MemSDNode(unsigned Opc, SDVTList VTs, MVT MemoryVT,
             const Value *srcValue, int SVOff,
@@ -1618,9 +1614,17 @@ public:
             unsigned alignment, bool isvolatile);
 
   /// Returns alignment and volatility of the memory access
-  unsigned getAlignment() const { return (1u << (Flags >> 1)) >> 1; }
-  bool isVolatile() const { return Flags & 1; }
+  unsigned getAlignment() const { return (1u << (SubclassData >> 6)) >> 1; }
+  bool isVolatile() const { return (SubclassData >> 5) & 1; }
   
+  /// getRawSubclassData - Return the SubclassData value, which contains an
+  /// encoding of the alignment and volatile information, as well as bits
+  /// used by subclasses. This function should only be used to compute a
+  /// FoldingSetNodeID value.
+  unsigned getRawSubclassData() const {
+    return SubclassData;
+  }
+
   /// Returns the SrcValue and offset that describes the location of the access
   const Value *getSrcValue() const { return SrcValue; }
   int getSrcValueOffset() const { return SVOffset; }
@@ -1637,10 +1641,6 @@ public:
     return getOperand(getOpcode() == ISD::STORE ? 2 : 1);
   }
 
-  /// getRawFlags - Represent the flags as a bunch of bits.
-  ///
-  unsigned getRawFlags() const { return Flags; }
-
   // Methods to support isa and dyn_cast
   static bool classof(const MemSDNode *) { return true; }
   static bool classof(const SDNode *N) {
@@ -2354,9 +2354,10 @@ public:
                SDVTList VTs, ISD::MemIndexedMode AM, MVT VT,
                const Value *SV, int SVO, unsigned Align, bool Vol)
     : MemSDNode(NodeTy, VTs, VT, SV, SVO, Align, Vol) {
-    SubclassData = AM;
-    InitOperands(Ops, Operands, numOperands);
     assert(Align != 0 && "Loads and stores should have non-zero aligment");
+    SubclassData |= AM << 2;
+    assert(getAddressingMode() == AM && "MemIndexedMode encoding error!");
+    InitOperands(Ops, Operands, numOperands);
     assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) &&
            "Only indexed loads and stores have a non-undef offset operand");
   }
@@ -2364,9 +2365,10 @@ public:
                unsigned numOperands, SDVTList VTs, ISD::MemIndexedMode AM, 
                MVT VT, const Value *SV, int SVO, unsigned Align, bool Vol)
     : MemSDNode(NodeTy, dl, VTs, VT, SV, SVO, Align, Vol) {
-    SubclassData = AM;
-    InitOperands(Ops, Operands, numOperands);
     assert(Align != 0 && "Loads and stores should have non-zero aligment");
+    SubclassData |= AM << 2;
+    assert(getAddressingMode() == AM && "MemIndexedMode encoding error!");
+    InitOperands(Ops, Operands, numOperands);
     assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) &&
            "Only indexed loads and stores have a non-undef offset operand");
   }
@@ -2378,7 +2380,7 @@ public:
   /// getAddressingMode - Return the addressing mode for this load or store:
   /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
   ISD::MemIndexedMode getAddressingMode() const {
-    return ISD::MemIndexedMode(SubclassData & 7);
+    return ISD::MemIndexedMode((SubclassData >> 2) & 7);
   }
 
   /// isIndexed - Return true if this is a pre/post inc/dec load/store.
@@ -2404,21 +2406,23 @@ protected:
              const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
     : LSBaseSDNode(ISD::LOAD, ChainPtrOff, 3,
                    VTs, AM, LVT, SV, O, Align, Vol) {
-    SubclassData |= (unsigned short)ETy << 3;
+    SubclassData |= (unsigned short)ETy;
+    assert(getExtensionType() == ETy && "LoadExtType encoding error!");
   }
   LoadSDNode(SDValue *ChainPtrOff, DebugLoc dl, SDVTList VTs,
              ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT LVT,
              const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
     : LSBaseSDNode(ISD::LOAD, dl, ChainPtrOff, 3,
                    VTs, AM, LVT, SV, O, Align, Vol) {
-    SubclassData |= (unsigned short)ETy << 3;
+    SubclassData |= (unsigned short)ETy;
+    assert(getExtensionType() == ETy && "LoadExtType encoding error!");
   }
 public:
 
   /// getExtensionType - Return whether this is a plain node,
   /// or one of the varieties of value-extending loads.
   ISD::LoadExtType getExtensionType() const {
-    return ISD::LoadExtType((SubclassData >> 3) & 3);
+    return ISD::LoadExtType(SubclassData & 3);
   }
 
   const SDValue &getBasePtr() const { return getOperand(1); }
@@ -2440,21 +2444,23 @@ protected:
               const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
     : LSBaseSDNode(ISD::STORE, ChainValuePtrOff, 4,
                    VTs, AM, SVT, SV, O, Align, Vol) {
-    SubclassData |= (unsigned short)isTrunc << 3;
+    SubclassData |= (unsigned short)isTrunc;
+    assert(isTruncatingStore() == isTrunc && "isTrunc encoding error!");
   }
   StoreSDNode(SDValue *ChainValuePtrOff, DebugLoc dl, SDVTList VTs,
               ISD::MemIndexedMode AM, bool isTrunc, MVT SVT,
               const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
     : LSBaseSDNode(ISD::STORE, dl, ChainValuePtrOff, 4,
                    VTs, AM, SVT, SV, O, Align, Vol) {
-    SubclassData |= (unsigned short)isTrunc << 3;
+    SubclassData |= (unsigned short)isTrunc;
+    assert(isTruncatingStore() == isTrunc && "isTrunc encoding error!");
   }
 public:
 
   /// isTruncatingStore - Return true if the op does a truncation before store.
   /// For integers this is the same as doing a TRUNCATE and storing the result.
   /// For floats, it is the same as doing an FP_ROUND and storing the result.
-  bool isTruncatingStore() const { return (SubclassData >> 3) & 1; }
+  bool isTruncatingStore() const { return SubclassData & 1; }
 
   const SDValue &getValue() const { return getOperand(1); }
   const SDValue &getBasePtr() const { return getOperand(2); }
index 32f55439ec64a0ad648b6a79bb77ac275988317d..1d8e3afec27ef3becb70ba5c0386a9b0358067b8 100644 (file)
@@ -429,18 +429,14 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
   }
   case ISD::LOAD: {
     const LoadSDNode *LD = cast<LoadSDNode>(N);
-    ID.AddInteger(LD->getAddressingMode());
-    ID.AddInteger(LD->getExtensionType());
     ID.AddInteger(LD->getMemoryVT().getRawBits());
-    ID.AddInteger(LD->getRawFlags());
+    ID.AddInteger(LD->getRawSubclassData());
     break;
   }
   case ISD::STORE: {
     const StoreSDNode *ST = cast<StoreSDNode>(N);
-    ID.AddInteger(ST->getAddressingMode());
-    ID.AddInteger(ST->isTruncatingStore());
     ID.AddInteger(ST->getMemoryVT().getRawBits());
-    ID.AddInteger(ST->getRawFlags());
+    ID.AddInteger(ST->getRawSubclassData());
     break;
   }
   case ISD::ATOMIC_CMP_SWAP:
@@ -456,7 +452,8 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
   case ISD::ATOMIC_LOAD_UMIN:
   case ISD::ATOMIC_LOAD_UMAX: {
     const AtomicSDNode *AT = cast<AtomicSDNode>(N);
-    ID.AddInteger(AT->getRawFlags());
+    ID.AddInteger(AT->getMemoryVT().getRawBits());
+    ID.AddInteger(AT->getRawSubclassData());
     break;
   }
   } // end switch (N->getOpcode())
@@ -476,11 +473,20 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, const SDNode *N) {
 }
 
 /// encodeMemSDNodeFlags - Generic routine for computing a value for use in
-/// the CSE map that carries both alignment and volatility information.
+/// the CSE map that carries alignment, volatility, indexing mode, and
+/// extension/truncation information.
 ///
 static inline unsigned
-encodeMemSDNodeFlags(bool isVolatile, unsigned Alignment) {
-  return isVolatile | ((Log2_32(Alignment) + 1) << 1);
+encodeMemSDNodeFlags(int ConvType, ISD::MemIndexedMode AM,
+                     bool isVolatile, unsigned Alignment) {
+  assert((ConvType & 3) == ConvType &&
+         "ConvType may not require more than 2 bits!");
+  assert((AM & 7) == AM &&
+         "AM may not require more than 3 bits!");
+  return ConvType |
+         (AM << 2) |
+         (isVolatile << 5) |
+         ((Log2_32(Alignment) + 1) << 6);
 }
 
 //===----------------------------------------------------------------------===//
@@ -853,7 +859,6 @@ SDValue SelectionDAG::getNOT(DebugLoc DL, SDValue Val, MVT VT) {
   } else {
     NegOne = getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT);
   }
-
   return getNode(ISD::XOR, DL, VT, Val, NegOne);
 }
 
@@ -3417,6 +3422,7 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, MVT MemVT,
 
   SDVTList VTs = getVTList(VT, MVT::Other);
   FoldingSetNodeID ID;
+  ID.AddInteger(MemVT.getRawBits());
   SDValue Ops[] = {Chain, Ptr, Cmp, Swp};
   AddNodeIDNode(ID, Opcode, VTs, Ops, 4);
   void* IP = 0;
@@ -3445,6 +3451,7 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT,
 
   SDVTList VTs = getVTList(VT, MVT::Other);
   FoldingSetNodeID ID;
+  ID.AddInteger(MemVT.getRawBits());
   SDValue Ops[] = {Chain, Ptr, Cmp, Swp};
   AddNodeIDNode(ID, Opcode, VTs, Ops, 4);
   void* IP = 0;
@@ -3483,6 +3490,7 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, MVT MemVT,
 
   SDVTList VTs = getVTList(VT, MVT::Other);
   FoldingSetNodeID ID;
+  ID.AddInteger(MemVT.getRawBits());
   SDValue Ops[] = {Chain, Ptr, Val};
   AddNodeIDNode(ID, Opcode, VTs, Ops, 3);
   void* IP = 0;
@@ -3521,6 +3529,7 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT,
 
   SDVTList VTs = getVTList(VT, MVT::Other);
   FoldingSetNodeID ID;
+  ID.AddInteger(MemVT.getRawBits());
   SDValue Ops[] = {Chain, Ptr, Val};
   AddNodeIDNode(ID, Opcode, VTs, Ops, 3);
   void* IP = 0;
@@ -3727,10 +3736,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
   SDValue Ops[] = { Chain, Ptr, Offset };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::LOAD, VTs, Ops, 3);
-  ID.AddInteger(AM);
-  ID.AddInteger(ExtType);
   ID.AddInteger(EVT.getRawBits());
-  ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment));
+  ID.AddInteger(encodeMemSDNodeFlags(ExtType, AM, isVolatile, Alignment));
   void *IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDValue(E, 0);
@@ -3778,10 +3785,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl,
   SDValue Ops[] = { Chain, Ptr, Offset };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::LOAD, VTs, Ops, 3);
-  ID.AddInteger(AM);
-  ID.AddInteger(ExtType);
   ID.AddInteger(EVT.getRawBits());
-  ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment));
+  ID.AddInteger(encodeMemSDNodeFlags(ExtType, AM, isVolatile, Alignment));
   void *IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDValue(E, 0);
@@ -3868,10 +3873,9 @@ SDValue SelectionDAG::getStore(SDValue Chain, SDValue Val,
   SDValue Ops[] = { Chain, Val, Ptr, Undef };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
-  ID.AddInteger(ISD::UNINDEXED);
-  ID.AddInteger(false);
   ID.AddInteger(VT.getRawBits());
-  ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment));
+  ID.AddInteger(encodeMemSDNodeFlags(false, ISD::UNINDEXED,
+                                     isVolatile, Alignment));
   void *IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDValue(E, 0);
@@ -3896,10 +3900,9 @@ SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val,
   SDValue Ops[] = { Chain, Val, Ptr, Undef };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
-  ID.AddInteger(ISD::UNINDEXED);
-  ID.AddInteger(false);
   ID.AddInteger(VT.getRawBits());
-  ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment));
+  ID.AddInteger(encodeMemSDNodeFlags(false, ISD::UNINDEXED,
+                                     isVolatile, Alignment));
   void *IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDValue(E, 0);
@@ -3932,10 +3935,9 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, SDValue Val,
   SDValue Ops[] = { Chain, Val, Ptr, Undef };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
-  ID.AddInteger(ISD::UNINDEXED);
-  ID.AddInteger(1);
   ID.AddInteger(SVT.getRawBits());
-  ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment));
+  ID.AddInteger(encodeMemSDNodeFlags(true, ISD::UNINDEXED,
+                                     isVolatile, Alignment));
   void *IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDValue(E, 0);
@@ -3968,10 +3970,9 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val,
   SDValue Ops[] = { Chain, Val, Ptr, Undef };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
-  ID.AddInteger(ISD::UNINDEXED);
-  ID.AddInteger(1);
   ID.AddInteger(SVT.getRawBits());
-  ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment));
+  ID.AddInteger(encodeMemSDNodeFlags(true, ISD::UNINDEXED,
+                                     isVolatile, Alignment));
   void *IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDValue(E, 0);
@@ -3993,10 +3994,8 @@ SelectionDAG::getIndexedStore(SDValue OrigStore, SDValue Base,
   SDValue Ops[] = { ST->getChain(), ST->getValue(), Base, Offset };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
-  ID.AddInteger(AM);
-  ID.AddInteger(ST->isTruncatingStore());
   ID.AddInteger(ST->getMemoryVT().getRawBits());
-  ID.AddInteger(ST->getRawFlags());
+  ID.AddInteger(ST->getRawSubclassData());
   void *IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDValue(E, 0);
@@ -4020,10 +4019,8 @@ SelectionDAG::getIndexedStore(SDValue OrigStore, DebugLoc dl, SDValue Base,
   SDValue Ops[] = { ST->getChain(), ST->getValue(), Base, Offset };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
-  ID.AddInteger(AM);
-  ID.AddInteger(ST->isTruncatingStore());
   ID.AddInteger(ST->getMemoryVT().getRawBits());
-  ID.AddInteger(ST->getRawFlags());
+  ID.AddInteger(ST->getRawSubclassData());
   void *IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDValue(E, 0);
@@ -5339,9 +5336,8 @@ GlobalAddressSDNode::GlobalAddressSDNode(bool isTarget, const GlobalValue *GA,
 MemSDNode::MemSDNode(unsigned Opc, SDVTList VTs, MVT memvt,
                      const Value *srcValue, int SVO,
                      unsigned alignment, bool vol)
- : SDNode(Opc, VTs), MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO),
-   Flags(encodeMemSDNodeFlags(vol, alignment)) {
-
+ : SDNode(Opc, VTs), MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO) {
+  SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, vol, alignment);
   assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!");
   assert(getAlignment() == alignment && "Alignment representation error!");
   assert(isVolatile() == vol && "Volatile representation error!");
@@ -5351,8 +5347,8 @@ MemSDNode::MemSDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops,
                      unsigned NumOps, MVT memvt, const Value *srcValue,
                      int SVO, unsigned alignment, bool vol)
    : SDNode(Opc, VTs, Ops, NumOps),
-     MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO),
-     Flags(vol | ((Log2_32(alignment) + 1) << 1)) {
+     MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO) {
+  SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, vol, alignment);
   assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!");
   assert(getAlignment() == alignment && "Alignment representation error!");
   assert(isVolatile() == vol && "Volatile representation error!");
@@ -5361,9 +5357,8 @@ MemSDNode::MemSDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops,
 MemSDNode::MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, MVT memvt,
                      const Value *srcValue, int SVO,
                      unsigned alignment, bool vol)
- : SDNode(Opc, dl, VTs), MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO),
-   Flags(encodeMemSDNodeFlags(vol, alignment)) {
-
+ : SDNode(Opc, dl, VTs), MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO) {
+  SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, vol, alignment);
   assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!");
   assert(getAlignment() == alignment && "Alignment representation error!");
   assert(isVolatile() == vol && "Volatile representation error!");
@@ -5374,8 +5369,8 @@ MemSDNode::MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs,
                      unsigned NumOps, MVT memvt, const Value *srcValue,
                      int SVO, unsigned alignment, bool vol)
    : SDNode(Opc, dl, VTs, Ops, NumOps),
-     MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO),
-     Flags(vol | ((Log2_32(alignment) + 1) << 1)) {
+     MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO) {
+  SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, vol, alignment);
   assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!");
   assert(getAlignment() == alignment && "Alignment representation error!");
   assert(isVolatile() == vol && "Volatile representation error!");