Grammer correction.
[oota-llvm.git] / include / llvm / CodeGen / SelectionDAGNodes.h
index de117a898e265589080caa39e122662cff6f176d..eb48ce8f6d1b688852a2810c8b61ca22709bce13 100644 (file)
@@ -22,7 +22,6 @@
 #include "llvm/CodeGen/ValueTypes.h"
 #include "llvm/Value.h"
 #include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/iterator"
 #include "llvm/Support/DataTypes.h"
 #include <cassert>
@@ -35,6 +34,9 @@ class GlobalValue;
 class MachineBasicBlock;
 class SDNode;
 template <typename T> struct simplify_type;
+template <typename T> struct ilist_traits;
+template<typename NodeTy, typename Traits> class iplist;
+template<typename NodeTy> class ilist_iterator;
 
 /// ISD namespace - This namespace contains an enum which represents all of the
 /// SelectionDAG node types and value types.
@@ -61,9 +63,14 @@ namespace ISD {
     AssertSext, AssertZext,
 
     // Various leaf nodes.
-    Constant, ConstantFP, GlobalAddress, FrameIndex, ConstantPool,
+    Constant, ConstantFP, STRING,
+    GlobalAddress, FrameIndex, ConstantPool,
     BasicBlock, ExternalSymbol, VALUETYPE, CONDCODE, Register,
     
+    // ConstantVec works like Constant or ConstantFP, except that it is not a
+    // leaf node.  All operands are either Constant or ConstantFP nodes.
+    ConstantVec,
+    
     // TargetConstant - Like Constant, but the DAG does not do any folding or
     // simplification of the constant.  This is used by the DAG->DAG selector.
     TargetConstant,
@@ -85,12 +92,6 @@ namespace ISD {
     // SelectionDAG.  The register is available from the RegSDNode object.
     CopyFromReg,
 
-    // ImplicitDef - This node indicates that the specified register is
-    // implicitly defined by some operation (e.g. its a live-in argument).  The
-    // two operands to this are the token chain coming in and the register.
-    // The only result is the token chain going out.
-    ImplicitDef,
-
     // UNDEF - An undefined node
     UNDEF,
 
@@ -104,13 +105,27 @@ namespace ISD {
     // two values of the same integer value type, this produces a value twice as
     // big.  Like EXTRACT_ELEMENT, this can only be used before legalization.
     BUILD_PAIR,
-
+    
+    // MERGE_VALUES - This node takes multiple discrete operands and returns
+    // them all as its individual results.  This nodes has exactly the same
+    // number of inputs and outputs, and is only valid before legalization.
+    // This node is useful for some pieces of the code generator that want to
+    // think about a single node with multiple results, not multiple nodes.
+    MERGE_VALUES,
 
     // Simple integer binary arithmetic operators.
     ADD, SUB, MUL, SDIV, UDIV, SREM, UREM,
     
     // Simple binary floating point operators.
     FADD, FSUB, FMUL, FDIV, FREM,
+    
+    // Simple abstract vector operators.  Unlike the integer and floating point
+    // binary operators, these nodes also take two additional operands:
+    // a constant element count, and a value type node indicating the type of
+    // the elements.  The order is op0, op1, count, type.  All vector opcodes,
+    // including VLOAD, must currently have count and type as their 3rd and 4th
+    // arguments.
+    VADD, VSUB, VMUL,
 
     // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing
     // an unsigned/signed value of type i[2*n], then return the top part.
@@ -199,6 +214,14 @@ namespace ISD {
     // FP_EXTEND - Extend a smaller FP type into a larger FP type.
     FP_EXTEND,
 
+    // BIT_CONVERT - Theis operator converts between integer and FP values, as
+    // if one was stored to memory as integer and the other was loaded from the
+    // same address (or equivalently for vector format conversions, etc).  The 
+    // source and result are required to have the same bit size (e.g. 
+    // f32 <-> i32).  This can also be used for int-to-int or fp-to-fp 
+    // conversions, but that is a noop, deleted by getNode().
+    BIT_CONVERT,
+    
     // FNEG, FABS, FSQRT, FSIN, FCOS - Perform unary floating point negation,
     // absolute value, square root, sine and cosine operations.
     FNEG, FABS, FSQRT, FSIN, FCOS,
@@ -207,6 +230,11 @@ namespace ISD {
     // operand, then the same operands as an LLVM load/store instruction, then a
     // SRCVALUE node that provides alias analysis information.
     LOAD, STORE,
+    
+    // Abstract vector version of LOAD.  VLOAD has a token chain as the first
+    // operand, followed by a pointer operand, a constant element count, a value
+    // type node indicating the type of the elements, and a SRCVALUE node.
+    VLOAD,
 
     // EXTLOAD, SEXTLOAD, ZEXTLOAD - These three operators all load a value from
     // memory and extend them to a larger value (e.g. load a byte into a word
@@ -305,6 +333,12 @@ namespace ISD {
     // PCMARKER - This corresponds to the pcmarker intrinsic.
     PCMARKER,
 
+    // READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
+    // The only operand is a chain and a value and a chain are produced.  The
+    // value is the contents of the architecture specific cycle counter like 
+    // register (or other high accuracy low latency clock source)
+    READCYCLECOUNTER,
+
     // READPORT, WRITEPORT, READIO, WRITEIO - These correspond to the LLVM
     // intrinsics of the same name.  The first operand is a token chain, the
     // other operands match the intrinsic.  These produce a token chain in
@@ -314,6 +348,24 @@ namespace ISD {
     // HANDLENODE node - Used as a handle for various purposes.
     HANDLENODE,
 
+    // LOCATION - This node is used to represent a source location for debug
+    // info.  It takes token chain as input, then a line number, then a column
+    // number, then a filename, then a working dir.  It produces a token chain
+    // as output.
+    LOCATION,
+    
+    // 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
+    // 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,
   };
@@ -501,12 +553,20 @@ class SDNode {
 
   /// NumOperands/NumValues - The number of entries in the Operand/Value list.
   unsigned short NumOperands, NumValues;
+  
+  /// Prev/Next pointers - These pointers form the linked list of of the
+  /// AllNodes list in the current DAG.
+  SDNode *Prev, *Next;
+  friend struct ilist_traits<SDNode>;
 
   /// Uses - These are all of the SDNode's that use a value produced by this
   /// node.
   std::vector<SDNode*> Uses;
 public:
-
+  virtual ~SDNode() {
+    assert(NumOperands == 0 && "Operand list not cleared before deletion");
+  }
+  
   //===--------------------------------------------------------------------===//
   //  Accessors
   //
@@ -577,12 +637,16 @@ public:
 
 protected:
   friend class SelectionDAG;
+  
+  /// getValueTypeList - Return a pointer to the specified value type.
+  ///
+  static MVT::ValueType *getValueTypeList(MVT::ValueType VT);
 
   SDNode(unsigned NT, MVT::ValueType VT) : NodeType(NT), NodeDepth(1) {
     OperandList = 0; NumOperands = 0;
-    ValueList = new MVT::ValueType[1];
-    ValueList[0] = VT;
+    ValueList = getValueTypeList(VT);
     NumValues = 1;
+    Prev = 0; Next = 0;
   }
   SDNode(unsigned NT, SDOperand Op)
     : NodeType(NT), NodeDepth(Op.Val->getNodeDepth()+1) {
@@ -592,6 +656,7 @@ protected:
     Op.Val->Uses.push_back(this);
     ValueList = 0;
     NumValues = 0;
+    Prev = 0; Next = 0;
   }
   SDNode(unsigned NT, SDOperand N1, SDOperand N2)
     : NodeType(NT) {
@@ -606,6 +671,7 @@ protected:
     N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this);
     ValueList = 0;
     NumValues = 0;
+    Prev = 0; Next = 0;
   }
   SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3)
     : NodeType(NT) {
@@ -626,6 +692,7 @@ protected:
     N3.Val->Uses.push_back(this);
     ValueList = 0;
     NumValues = 0;
+    Prev = 0; Next = 0;
   }
   SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4)
     : NodeType(NT) {
@@ -649,6 +716,7 @@ protected:
     N3.Val->Uses.push_back(this); N4.Val->Uses.push_back(this);
     ValueList = 0;
     NumValues = 0;
+    Prev = 0; Next = 0;
   }
   SDNode(unsigned Opc, const std::vector<SDOperand> &Nodes) : NodeType(Opc) {
     NumOperands = Nodes.size();
@@ -664,11 +732,7 @@ protected:
     NodeDepth = ND+1;
     ValueList = 0;
     NumValues = 0;
-  }
-
-  virtual ~SDNode() {
-    assert(NumOperands == 0 && "Operand list not cleared before deletion");
-    delete [] ValueList;
+    Prev = 0; Next = 0;
   }
 
   /// MorphNodeTo - This clears the return value and operands list, and sets the
@@ -676,7 +740,6 @@ protected:
   /// the SelectionDAG class.
   void MorphNodeTo(unsigned Opc) {
     NodeType = Opc;
-    delete [] ValueList;
     ValueList = 0;
     NumValues = 0;
     
@@ -691,24 +754,13 @@ protected:
   
   void setValueTypes(MVT::ValueType VT) {
     assert(NumValues == 0 && "Should not have values yet!");
-    ValueList = new MVT::ValueType[1];
-    ValueList[0] = VT;
+    ValueList = getValueTypeList(VT);
     NumValues = 1;
   }
-  void setValueTypes(MVT::ValueType VT1, MVT::ValueType VT2) {
-    assert(NumValues == 0 && "Should not have values yet!");
-    ValueList = new MVT::ValueType[2];
-    ValueList[0] = VT1;
-    ValueList[1] = VT2;
-    NumValues = 2;
-  }
-  void setValueTypes(const std::vector<MVT::ValueType> &VTs) {
+  void setValueTypes(MVT::ValueType *List, unsigned NumVal) {
     assert(NumValues == 0 && "Should not have values yet!");
-    if (VTs.size() == 0) return;  // don't alloc memory.
-    ValueList = new MVT::ValueType[VTs.size()];
-    for (unsigned i = 0, e = VTs.size(); i != e; ++i)
-      ValueList[i] = VTs[i];
-    NumValues = VTs.size();
+    ValueList = List;
+    NumValues = NumVal;
   }
   
   void setOperands(SDOperand Op0) {
@@ -761,6 +813,21 @@ protected:
     Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this);
     Op4.Val->Uses.push_back(this);
   }
+  void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2, SDOperand Op3,
+                   SDOperand Op4, SDOperand Op5) {
+    assert(NumOperands == 0 && "Should not have operands yet!");
+    OperandList = new SDOperand[6];
+    OperandList[0] = Op0;
+    OperandList[1] = Op1;
+    OperandList[2] = Op2;
+    OperandList[3] = Op3;
+    OperandList[4] = Op4;
+    OperandList[5] = Op5;
+    NumOperands = 6;
+    Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this);
+    Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this);
+    Op4.Val->Uses.push_back(this); Op5.Val->Uses.push_back(this);
+  }
   void addUser(SDNode *User) {
     Uses.push_back(User);
   }
@@ -819,6 +886,20 @@ public:
   SDOperand getValue() const { return getOperand(0); }
 };
 
+class StringSDNode : public SDNode {
+  std::string Value;
+protected:
+  friend class SelectionDAG;
+  StringSDNode(const std::string &val)
+    : SDNode(ISD::STRING, MVT::Other), Value(val) {
+  }
+public:
+  const std::string &getValue() const { return Value; }
+  static bool classof(const StringSDNode *) { return true; }
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::STRING;
+  }
+};  
 
 class ConstantSDNode : public SDNode {
   uint64_t Value;
@@ -875,15 +956,19 @@ public:
 
 class GlobalAddressSDNode : public SDNode {
   GlobalValue *TheGlobal;
+  int offset;
 protected:
   friend class SelectionDAG;
-  GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT::ValueType VT)
+  GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT::ValueType VT,
+                      int o=0)
     : SDNode(isTarget ? ISD::TargetGlobalAddress : ISD::GlobalAddress, VT) {
     TheGlobal = const_cast<GlobalValue*>(GA);
+    offset = o;
   }
 public:
 
   GlobalValue *getGlobal() const { return TheGlobal; }
+  int getOffset() const { return offset; }
 
   static bool classof(const GlobalAddressSDNode *) { return true; }
   static bool classof(const SDNode *N) {
@@ -1085,6 +1170,28 @@ template <> struct GraphTraits<SDNode*> {
   }
 };
 
+template<>
+struct ilist_traits<SDNode> {
+  static SDNode *getPrev(const SDNode *N) { return N->Prev; }
+  static SDNode *getNext(const SDNode *N) { return N->Next; }
+  
+  static void setPrev(SDNode *N, SDNode *Prev) { N->Prev = Prev; }
+  static void setNext(SDNode *N, SDNode *Next) { N->Next = Next; }
+  
+  static SDNode *createSentinel() {
+    return new SDNode(ISD::EntryToken, MVT::Other);
+  }
+  static void destroySentinel(SDNode *N) { delete N; }
+  //static SDNode *createNode(const SDNode &V) { return new SDNode(V); }
+  
+  
+  void addNodeToList(SDNode *NTy) {}
+  void removeNodeFromList(SDNode *NTy) {}
+  void transferNodesFromList(iplist<SDNode, ilist_traits> &L2,
+                             const ilist_iterator<SDNode> &X,
+                             const ilist_iterator<SDNode> &Y) {}
+};
+
 } // end llvm namespace
 
 #endif