rename DenseMap to IndexedMap.
[oota-llvm.git] / include / llvm / CodeGen / SelectionDAGNodes.h
index dea371e8894e32d44eee85dbd46210bcc18ae7d4..b928387b78dcefa9899d58324a1e8d172db7f219 100644 (file)
@@ -20,9 +20,9 @@
 #define LLVM_CODEGEN_SELECTIONDAGNODES_H
 
 #include "llvm/Value.h"
+#include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/iterator"
-#include "llvm/ADT/SmallVector.h"
 #include "llvm/CodeGen/ValueTypes.h"
 #include "llvm/Support/DataTypes.h"
 #include <cassert>
@@ -84,6 +84,13 @@ namespace ISD {
 
     // The address of the GOT
     GLOBAL_OFFSET_TABLE,
+    
+    // FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
+    // llvm.returnaddress on the DAG.  These nodes take one operand, the index
+    // of the frame or return address to return.  An index of zero corresponds
+    // to the current function's frame or return address, an index of one to the
+    // parent's frame or return address, and so on.
+    FRAMEADDR, RETURNADDR,
 
     // TargetConstant* - Like Constant*, but the DAG does not do any folding or
     // simplification of the constant.
@@ -133,20 +140,25 @@ namespace ISD {
     // UNDEF - An undefined node
     UNDEF,
     
-    /// FORMAL_ARGUMENTS(CHAIN, CC#, ISVARARG) - This node represents the formal
-    /// arguments for a function.  CC# is a Constant value indicating the
-    /// calling convention of the function, and ISVARARG is a flag that
-    /// indicates whether the function is varargs or not.  This node has one
-    /// result value for each incoming argument, plus one for the output chain.
-    /// It must be custom legalized.
+    /// FORMAL_ARGUMENTS(CHAIN, CC#, ISVARARG, FLAG0, ..., FLAGn) - This node
+    /// represents the formal arguments for a function.  CC# is a Constant value
+    /// indicating the calling convention of the function, and ISVARARG is a
+    /// flag that indicates whether the function is varargs or not. This node
+    /// has one result value for each incoming argument, plus one for the output
+    /// chain. It must be custom legalized. See description of CALL node for
+    /// FLAG argument contents explanation.
     /// 
     FORMAL_ARGUMENTS,
     
     /// RV1, RV2...RVn, CHAIN = CALL(CHAIN, CC#, ISVARARG, ISTAILCALL, CALLEE,
-    ///                              ARG0, SIGN0, ARG1, SIGN1, ... ARGn, SIGNn)
+    ///                              ARG0, FLAG0, ARG1, FLAG1, ... ARGn, FLAGn)
     /// This node represents a fully general function call, before the legalizer
-    /// runs.  This has one result value for each argument / signness pair, plus
-    /// a chain result. It must be custom legalized.
+    /// runs.  This has one result value for each argument / flag pair, plus
+    /// a chain result. It must be custom legalized. Flag argument indicates
+    /// misc. argument attributes. Currently:
+    /// Bit 0 - signness
+    /// Bit 1 - 'inreg' attribute
+    /// Bit 2 - 'sret' attribute
     CALL,
 
     // EXTRACT_ELEMENT - This is used to get the first or second (determined by
@@ -370,9 +382,10 @@ namespace ISD {
     // operations.
     FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI,
     
-    // Other operators.  LOAD and STORE have token chains as their first
-    // operand, then the same operands as an LLVM load/store instruction, then a
-    // SRCVALUE node that provides alias analysis information.
+    // LOAD and STORE have token chains as their first operand, then the same
+    // operands as an LLVM load/store instruction, then an offset node that
+    // is added / subtracted from the base pointer to form the address (for
+    // indexed memory ops).
     LOAD, STORE,
     
     // Abstract vector version of LOAD.  VLOAD has a constant element count as
@@ -405,6 +418,10 @@ namespace ISD {
     // is the value to branch to, which must be of the same type as the target's
     // pointer type.
     BRIND,
+
+    // BR_JT - Jumptable branch. The first operand is the chain, the second
+    // is the jumptable index, the last one is the jumptable entry index.
+    BR_JT,
     
     // BRCOND - Conditional branch.  The first operand is the chain,
     // the second is the condition, the third is the block to branch
@@ -431,6 +448,13 @@ namespace ISD {
     //   Operand #2n+3: A TargetConstant, indicating if the reg is a use/def
     //   Operand #last: Optional, an incoming flag.
     INLINEASM,
+    
+    // LABEL - Represents a label in mid basic block used to track
+    // locations needed for debug and exception handling tables.  This node
+    // returns a chain.
+    //   Operand #0 : input chain.
+    //   Operand #1 : module unique number use to identify the label.
+    LABEL,
 
     // STACKSAVE - STACKSAVE has one operand, an input chain.  It produces a
     // value, the same type as the pointer type for the system, and an output
@@ -494,16 +518,10 @@ namespace ISD {
     
     // DEBUG_LOC - This node is used to represent source line information
     // embedded in the code.  It takes a token chain as input, then a line
-    // number, then a column then a file id (provided by MachineDebugInfo.) It
+    // number, then a column then a file id (provided by MachineModuleInfo.) It
     // produces a token chain as output.
     DEBUG_LOC,
     
-    // DEBUG_LABEL - This node is used to mark a location in the code where a
-    // label should be generated for use by the debug information.  It takes a
-    // token chain as input and then a unique id (provided by MachineDebugInfo.)
-    // It produces a token chain as output.
-    DEBUG_LABEL,
-    
     // BUILTIN_OP_END - This must be the last enum value in this list.
     BUILTIN_OP_END
   };
@@ -519,8 +537,8 @@ namespace ISD {
   bool isBuildVectorAllZeros(const SDNode *N);
   
   //===--------------------------------------------------------------------===//
-  /// MemOpAddrMode enum - This enum defines the three load / store addressing
-  /// modes.
+  /// MemIndexedMode enum - This enum defines the load / store indexed 
+  /// addressing modes.
   ///
   /// UNINDEXED    "Normal" load / store. The effective address is already
   ///              computed and is available in the base pointer. The offset
@@ -528,9 +546,9 @@ namespace ISD {
   ///              chain, an unindexed load produces one value (result of the
   ///              load); an unindexed store does not produces a value.
   ///
-  /// PRE_INDEXED  Similar to the unindexed mode where the effective address is
-  ///              the result of computation of the base pointer. However, it
-  ///              considers the computation as being folded into the load /
+  /// PRE_INC      Similar to the unindexed mode where the effective address is
+  /// PRE_DEC      the value of the base pointer add / subtract the offset.
+  ///              It considers the computation as being folded into the load /
   ///              store operation (i.e. the load / store does the address
   ///              computation as well as performing the memory transaction).
   ///              The base operand is always undefined. In addition to
@@ -539,18 +557,21 @@ namespace ISD {
   ///              computation); a pre-indexed store produces one value (result
   ///              of the address computation).
   ///
-  /// POST_INDEXED The effective address is the value of the base pointer. The
-  ///              value of the offset operand is then added to the base after
-  ///              memory transaction. In addition to producing a chain,
-  ///              post-indexed load produces two values (the result of the load
-  ///              and the result of the base + offset computation); a
-  ///              post-indexed store produces one value (the the result of the
-  ///              base + offset computation).
+  /// POST_INC     The effective address is the value of the base pointer. The
+  /// POST_DEC     value of the offset operand is then added to / subtracted
+  ///              from the base after memory transaction. In addition to
+  ///              producing a chain, post-indexed load produces two values
+  ///              (the result of the load and the result of the base +/- offset
+  ///              computation); a post-indexed store produces one value (the
+  ///              the result of the base +/- offset computation).
   ///
-  enum MemOpAddrMode {
+  enum MemIndexedMode {
     UNINDEXED = 0,
-    PRE_INDEXED,
-    POST_INDEXED
+    PRE_INC,
+    PRE_DEC,
+    POST_INC,
+    POST_DEC,
+    LAST_INDEXED_MODE
   };
 
   //===--------------------------------------------------------------------===//
@@ -739,7 +760,7 @@ template<> struct simplify_type<const SDOperand> {
 
 /// SDNode - Represents one node in the SelectionDAG.
 ///
-class SDNode {
+class SDNode : public FoldingSetNode {
   /// NodeType - The operation that this node performs.
   ///
   unsigned short NodeType;
@@ -763,9 +784,6 @@ class SDNode {
   SDNode *Prev, *Next;
   friend struct ilist_traits<SDNode>;
 
-  /// NextInBucket - This is used by the SelectionDAGCSEMap.
-  void *NextInBucket;
-  
   /// Uses - These are all of the SDNode's that use a value produced by this
   /// node.
   SmallVector<SDNode*,3> Uses;
@@ -775,7 +793,6 @@ class SDNode {
 public:
   virtual ~SDNode() {
     assert(NumOperands == 0 && "Operand list not cleared before deletion");
-    assert(NextInBucket == 0 && "Still in CSEMap?");
     NodeType = ISD::DELETED_NODE;
   }
   
@@ -806,12 +823,20 @@ public:
   /// operation.
   bool hasNUsesOfValue(unsigned NUses, unsigned Value) const;
 
-  // isOnlyUse - Return true if this node is the only use of N.
+  /// isOnlyUse - Return true if this node is the only use of N.
+  ///
   bool isOnlyUse(SDNode *N) const;
 
-  // isOperand - Return true if this node is an operand of N.
+  /// isOperand - Return true if this node is an operand of N.
+  ///
   bool isOperand(SDNode *N) const;
 
+  /// isPredecessor - Return true if this node is a predecessor of N. This node
+  /// is either an operand of N or it can be reached by recursively traversing
+  /// up the operands.
+  /// NOTE: this is an expensive method. Use it carefully.
+  bool isPredecessor(SDNode *N) const;
+
   /// getNumOperands - Return the number of values used by this operation.
   ///
   unsigned getNumOperands() const { return NumOperands; }
@@ -854,16 +879,16 @@ public:
   /// getOperationName - Return the opcode of this operation for printing.
   ///
   const char* getOperationName(const SelectionDAG *G = 0) const;
+  static const char* getIndexedModeName(ISD::MemIndexedMode AM);
   void dump() const;
   void dump(const SelectionDAG *G) const;
 
   static bool classof(const SDNode *) { return true; }
 
-  
-  /// NextInBucket accessors, these are private to SelectionDAGCSEMap.
-  void *getNextInBucket() const { return NextInBucket; }
-  void SetNextInBucket(void *N) { NextInBucket = N; }
-  
+  /// Profile - Gather unique data for the node.
+  ///
+  void Profile(FoldingSetNodeID &ID);
+
 protected:
   friend class SelectionDAG;
   
@@ -876,7 +901,6 @@ protected:
     ValueList = getValueTypeList(VT);
     NumValues = 1;
     Prev = 0; Next = 0;
-    NextInBucket = 0;
   }
   SDNode(unsigned NT, SDOperand Op)
     : NodeType(NT), NodeId(-1) {
@@ -887,7 +911,6 @@ protected:
     ValueList = 0;
     NumValues = 0;
     Prev = 0; Next = 0;
-    NextInBucket = 0;
   }
   SDNode(unsigned NT, SDOperand N1, SDOperand N2)
     : NodeType(NT), NodeId(-1) {
@@ -899,7 +922,6 @@ protected:
     ValueList = 0;
     NumValues = 0;
     Prev = 0; Next = 0;
-    NextInBucket = 0;
   }
   SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3)
     : NodeType(NT), NodeId(-1) {
@@ -914,7 +936,6 @@ protected:
     ValueList = 0;
     NumValues = 0;
     Prev = 0; Next = 0;
-    NextInBucket = 0;
   }
   SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4)
     : NodeType(NT), NodeId(-1) {
@@ -930,7 +951,6 @@ protected:
     ValueList = 0;
     NumValues = 0;
     Prev = 0; Next = 0;
-    NextInBucket = 0;
   }
   SDNode(unsigned Opc, const SDOperand *Ops, unsigned NumOps)
     : NodeType(Opc), NodeId(-1) {
@@ -945,7 +965,6 @@ protected:
     ValueList = 0;
     NumValues = 0;
     Prev = 0; Next = 0;
-    NextInBucket = 0;
   }
 
   /// MorphNodeTo - This clears the return value and operands list, and sets the
@@ -1378,7 +1397,7 @@ public:
 ///
 class LoadSDNode : public SDNode {
   // AddrMode - unindexed, pre-indexed, post-indexed.
-  ISD::MemOpAddrMode AddrMode;
+  ISD::MemIndexedMode AddrMode;
 
   // ExtType - non-ext, anyext, sext, zext.
   ISD::LoadExtType ExtType;
@@ -1400,20 +1419,20 @@ class LoadSDNode : public SDNode {
 protected:
   friend class SelectionDAG;
   LoadSDNode(SDOperand Chain, SDOperand Ptr, SDOperand Off,
-             ISD::MemOpAddrMode AM, ISD::LoadExtType ETy, MVT::ValueType LVT,
+             ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT::ValueType LVT,
              const Value *SV, int O=0, unsigned Align=1, bool Vol=false)
     : SDNode(ISD::LOAD, Chain, Ptr, Off),
       AddrMode(AM), ExtType(ETy), LoadedVT(LVT), SrcValue(SV), SVOffset(O),
       Alignment(Align), IsVolatile(Vol) {
-    assert((Off.getOpcode() == ISD::UNDEF || AddrMode == ISD::POST_INDEXED) &&
-           "Only post-indexed load has a non-undef offset operand");
+    assert((Off.getOpcode() == ISD::UNDEF || AddrMode != ISD::UNINDEXED) &&
+           "Only indexed load has a non-undef offset operand");
   }
 public:
 
   const SDOperand getChain() const { return getOperand(0); }
   const SDOperand getBasePtr() const { return getOperand(1); }
   const SDOperand getOffset() const { return getOperand(2); }
-  ISD::MemOpAddrMode getAddressingMode() const { return AddrMode; }
+  ISD::MemIndexedMode getAddressingMode() const { return AddrMode; }
   ISD::LoadExtType getExtensionType() const { return ExtType; }
   MVT::ValueType getLoadedVT() const { return LoadedVT; }
   const Value *getSrcValue() const { return SrcValue; }
@@ -1431,7 +1450,7 @@ public:
 ///
 class StoreSDNode : public SDNode {
   // AddrMode - unindexed, pre-indexed, post-indexed.
-  ISD::MemOpAddrMode AddrMode;
+  ISD::MemIndexedMode AddrMode;
 
   // IsTruncStore - True is the op does a truncation before store.
   bool IsTruncStore;
@@ -1453,13 +1472,13 @@ class StoreSDNode : public SDNode {
 protected:
   friend class SelectionDAG;
   StoreSDNode(SDOperand Chain, SDOperand Value, SDOperand Ptr, SDOperand Off,
-              ISD::MemOpAddrMode AM, bool isTrunc, MVT::ValueType SVT,
+              ISD::MemIndexedMode AM, bool isTrunc, MVT::ValueType SVT,
               const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
     : SDNode(ISD::STORE, Chain, Value, Ptr, Off),
       AddrMode(AM), IsTruncStore(isTrunc), StoredVT(SVT), SrcValue(SV),
       SVOffset(O), Alignment(Align), IsVolatile(Vol) {
-    assert((Off.getOpcode() == ISD::UNDEF || AddrMode == ISD::POST_INDEXED) &&
-           "Only post-indexed store has a non-undef offset operand");
+    assert((Off.getOpcode() == ISD::UNDEF || AddrMode != ISD::UNINDEXED) &&
+           "Only indexed store has a non-undef offset operand");
   }
 public:
 
@@ -1467,7 +1486,7 @@ public:
   const SDOperand getValue() const { return getOperand(1); }
   const SDOperand getBasePtr() const { return getOperand(2); }
   const SDOperand getOffset() const { return getOperand(3); }
-  ISD::MemOpAddrMode getAddressingMode() const { return AddrMode; }
+  ISD::MemIndexedMode getAddressingMode() const { return AddrMode; }
   bool isTruncatingStore() const { return IsTruncStore; }
   MVT::ValueType getStoredVT() const { return StoredVT; }
   const Value *getSrcValue() const { return SrcValue; }
@@ -1475,7 +1494,7 @@ public:
   unsigned getAlignment() const { return Alignment; }
   bool isVolatile() const { return IsVolatile; }
 
-  static bool classof(const LoadSDNode *) { return true; }
+  static bool classof(const StoreSDNode *) { return true; }
   static bool classof(const SDNode *N) {
     return N->getOpcode() == ISD::STORE;
   }