Delete an unused function.
[oota-llvm.git] / include / llvm / CodeGen / SelectionDAGNodes.h
index 964b498915260450269168f61a96515913a59348..559bc0271a957651a0c786414a6715c342cedc92 100644 (file)
@@ -40,10 +40,13 @@ class MachineBasicBlock;
 class MachineConstantPoolValue;
 class SDNode;
 class Value;
+class MCSymbol;
 template <typename T> struct DenseMapInfo;
 template <typename T> struct simplify_type;
 template <typename T> struct ilist_traits;
 
+void checkForCycles(const SDNode *N);
+  
 /// SDVTList - This represents a list of ValueType's that has been intern'd by
 /// a SelectionDAG.  Instances of this simple value class are returned by
 /// SelectionDAG::getVTList(...).
@@ -436,6 +439,12 @@ namespace ISD {
     //   5) ISD::CvtCode indicating the type of conversion to do
     CONVERT_RNDSAT,
 
+    // FP16_TO_FP32, FP32_TO_FP16 - These operators are used to perform
+    // promotions and truncation for half-precision (16 bit) floating
+    // numbers. We need special nodes since FP16 is a storage-only type with
+    // special semantics of operations.
+    FP16_TO_FP32, FP32_TO_FP16,
+
     // FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
     // FLOG, FLOG2, FLOG10, FEXP, FEXP2,
     // FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR - Perform various unary floating
@@ -490,9 +499,16 @@ namespace ISD {
     // return values: a chain and a flag result.  The inputs are as follows:
     //   Operand #0   : Input chain.
     //   Operand #1   : a ExternalSymbolSDNode with a pointer to the asm string.
-    //   Operand #2n+2: A RegisterNode.
-    //   Operand #2n+3: A TargetConstant, indicating if the reg is a use/def
+    //   Operand #2   : a MDNodeSDNode with the !srcloc metadata.
+    //   After this, it is followed by a list of operands with this format:
+    //     ConstantSDNode: Flags that encode whether it is a mem or not, the
+    //                     of operands that follow, etc.  See InlineAsm.h.
+    //     ... however many operands ...
     //   Operand #last: Optional, an incoming flag.
+    //
+    // The variable width operands are required to represent target addressing
+    // modes as a single "operand", even though they may have multiple
+    // SDOperands.
     INLINEASM,
 
     // EH_LABEL - Represents a label in mid basic block used to track
@@ -533,6 +549,10 @@ namespace ISD {
     // SRCVALUE - This is a node type that holds a Value* that is used to
     // make reference to a value in the LLVM IR.
     SRCVALUE,
+    
+    // MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to
+    // reference metadata in the IR.
+    MDNODE_SDNODE,
 
     // PCMARKER - This corresponds to the pcmarker intrinsic.
     PCMARKER,
@@ -607,7 +627,7 @@ namespace ISD {
   /// which do not reference a specific memory location should be less than
   /// this value. Those that do must not be less than this value, and can
   /// be used with SelectionDAG::getMemIntrinsicNode.
-  static const int FIRST_TARGET_MEMORY_OPCODE = 1 << 14;
+  static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+100;
 
   /// Node predicates
 
@@ -819,6 +839,8 @@ public:
   /// set the SDNode
   void setNode(SDNode *N) { Node = N; }
 
+  inline SDNode *operator->() const { return Node; }
+  
   bool operator==(const SDValue &O) const {
     return Node == O.Node && ResNo == O.ResNo;
   }
@@ -1023,11 +1045,15 @@ private:
   /// then they will be delete[]'d when the node is destroyed.
   uint16_t OperandsNeedDelete : 1;
 
+  /// HasDebugValue - This tracks whether this node has one or more dbg_value
+  /// nodes corresponding to it.
+  uint16_t HasDebugValue : 1;
+
 protected:
   /// SubclassData - This member is defined by this class, but is not used for
   /// anything.  Subclasses can use it to hold whatever state they find useful.
   /// This field is initialized to zero by the ctor.
-  uint16_t SubclassData : 15;
+  uint16_t SubclassData : 14;
 
 private:
   /// NodeId - Unique id per SDNode in the DAG.
@@ -1090,6 +1116,12 @@ public:
     return ~NodeType;
   }
 
+  /// getHasDebugValue - get this bit.
+  bool getHasDebugValue() const { return HasDebugValue; }
+
+  /// setHasDebugValue - set this bit.
+  void setHasDebugValue(bool b) { HasDebugValue = b; }
+
   /// use_empty - Return true if there are no uses of this node.
   ///
   bool use_empty() const { return UseList == NULL; }
@@ -1285,37 +1317,55 @@ public:
   void print_details(raw_ostream &OS, const SelectionDAG *G) const;
   void print(raw_ostream &OS, const SelectionDAG *G = 0) const;
   void printr(raw_ostream &OS, const SelectionDAG *G = 0) const;
-  /// printWithDepth - Print a SelectionDAG node and children up to
-  /// depth "depth."  "limit" controls whether a message should be
-  /// printed if we hit depth "depth."
+
+  /// printrFull - Print a SelectionDAG node and all children down to
+  /// the leaves.  The given SelectionDAG allows target-specific nodes
+  /// to be printed in human-readable form.  Unlike printr, this will
+  /// print the whole DAG, including children that appear multiple
+  /// times.
   ///
-  void printWithDepth(raw_ostream &O, const SelectionDAG *G = 0,
-                      unsigned depth = -1, unsigned indent = 0,
-                      bool limit = false) const;
-  /// printWithFullDepth - Print a SelectionDAG node and all children
-  /// down to the leaves.
+  void printrFull(raw_ostream &O, const SelectionDAG *G = 0) const;
+
+  /// printrWithDepth - Print a SelectionDAG node and children up to
+  /// depth "depth."  The given SelectionDAG allows target-specific
+  /// nodes to be printed in human-readable form.  Unlike printr, this
+  /// will print children that appear multiple times wherever they are
+  /// used.
   ///
-  void printWithFullDepth(raw_ostream &O, const SelectionDAG *G = 0,
-                          unsigned indent = 0) const;
+  void printrWithDepth(raw_ostream &O, const SelectionDAG *G = 0,
+                       unsigned depth = 100) const;
+
+
   /// dump - Dump this node, for debugging.
   void dump() const;
+
   /// dumpr - Dump (recursively) this node and its use-def subgraph.
   void dumpr() const;
+
   /// dump - Dump this node, for debugging.
   /// The given SelectionDAG allows target-specific nodes to be printed
   /// in human-readable form.
   void dump(const SelectionDAG *G) const;
+
   /// dumpr - Dump (recursively) this node and its use-def subgraph.
   /// The given SelectionDAG allows target-specific nodes to be printed
   /// in human-readable form.
   void dumpr(const SelectionDAG *G) const;
-  /// dumpWithDepth - printWithDepth to dbgs().
+
+  /// dumprFull - printrFull to dbgs().  The given SelectionDAG allows
+  /// target-specific nodes to be printed in human-readable form.
+  /// Unlike dumpr, this will print the whole DAG, including children
+  /// that appear multiple times.
   ///
-  void dumpWithDepth(const SelectionDAG *G = 0, unsigned depth = 1,
-                     unsigned indent = 0, bool limit = false) const;
-  /// dumpWithFullDepth - printWithFullDepth to dbgs().
+  void dumprFull(const SelectionDAG *G = 0) const;
+
+  /// dumprWithDepth - printrWithDepth to dbgs().  The given
+  /// SelectionDAG allows target-specific nodes to be printed in
+  /// human-readable form.  Unlike dumpr, this will print children
+  /// that appear multiple times wherever they are used.
   ///
-  void dumpWithFullDepth(const SelectionDAG *G = 0, unsigned indent = 0) const;
+  void dumprWithDepth(const SelectionDAG *G = 0, unsigned depth = 100) const;
+
 
   static bool classof(const SDNode *) { return true; }
 
@@ -1335,8 +1385,8 @@ protected:
 
   SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs, const SDValue *Ops,
          unsigned NumOps)
-    : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0),
-      NodeId(-1),
+    : NodeType(Opc), OperandsNeedDelete(true), HasDebugValue(false),
+      SubclassData(0), NodeId(-1),
       OperandList(NumOps ? new SDUse[NumOps] : 0),
       ValueList(VTs.VTs), UseList(NULL),
       NumOperands(NumOps), NumValues(VTs.NumVTs),
@@ -1345,14 +1395,15 @@ protected:
       OperandList[i].setUser(this);
       OperandList[i].setInitial(Ops[i]);
     }
+    checkForCycles(this);
   }
 
   /// This constructor adds no operands itself; operands can be
   /// set later with InitOperands.
   SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs)
-    : NodeType(Opc), OperandsNeedDelete(false), SubclassData(0),
-      NodeId(-1), OperandList(0), ValueList(VTs.VTs), UseList(NULL),
-      NumOperands(0), NumValues(VTs.NumVTs),
+    : NodeType(Opc), OperandsNeedDelete(false), HasDebugValue(false),
+      SubclassData(0), NodeId(-1), OperandList(0), ValueList(VTs.VTs),
+      UseList(NULL), NumOperands(0), NumValues(VTs.NumVTs),
       debugLoc(dl) {}
 
   /// InitOperands - Initialize the operands list of this with 1 operand.
@@ -1361,6 +1412,7 @@ protected:
     Ops[0].setInitial(Op0);
     NumOperands = 1;
     OperandList = Ops;
+    checkForCycles(this);
   }
 
   /// InitOperands - Initialize the operands list of this with 2 operands.
@@ -1371,6 +1423,7 @@ protected:
     Ops[1].setInitial(Op1);
     NumOperands = 2;
     OperandList = Ops;
+    checkForCycles(this);
   }
 
   /// InitOperands - Initialize the operands list of this with 3 operands.
@@ -1384,6 +1437,7 @@ protected:
     Ops[2].setInitial(Op2);
     NumOperands = 3;
     OperandList = Ops;
+    checkForCycles(this);
   }
 
   /// InitOperands - Initialize the operands list of this with 4 operands.
@@ -1399,6 +1453,7 @@ protected:
     Ops[3].setInitial(Op3);
     NumOperands = 4;
     OperandList = Ops;
+    checkForCycles(this);
   }
 
   /// InitOperands - Initialize the operands list of this with N operands.
@@ -1409,6 +1464,7 @@ protected:
     }
     NumOperands = N;
     OperandList = Ops;
+    checkForCycles(this);
   }
 
   /// DropOperands - Release the operands and set this node to have
@@ -1519,13 +1575,12 @@ class HandleSDNode : public SDNode {
 public:
   // FIXME: Remove the "noinline" attribute once <rdar://problem/5852746> is
   // fixed.
-#ifdef __GNUC__
+#if __GNUC__==4 && __GNUC_MINOR__==2 && defined(__APPLE__) && !defined(__llvm__)
   explicit __attribute__((__noinline__)) HandleSDNode(SDValue X)
 #else
   explicit HandleSDNode(SDValue X)
 #endif
-    : SDNode(ISD::HANDLENODE, DebugLoc::getUnknownLoc(),
-             getSDVTList(MVT::Other)) {
+    : SDNode(ISD::HANDLENODE, DebugLoc(), getSDVTList(MVT::Other)) {
     InitOperands(&Op, X);
   }
   ~HandleSDNode();
@@ -1567,7 +1622,10 @@ public:
     return SubclassData;
   }
 
+  // We access subclass data here so that we can check consistency
+  // with MachineMemOperand information.
   bool isVolatile() const { return (SubclassData >> 5) & 1; }
+  bool isNonTemporal() const { return (SubclassData >> 6) & 1; }
 
   /// Returns the SrcValue and offset that describes the location of the access
   const Value *getSrcValue() const { return MMO->getValue(); }
@@ -1733,7 +1791,12 @@ public:
   bool isSplat() const { return isSplatMask(Mask, getValueType(0)); }
   int  getSplatIndex() const { 
     assert(isSplat() && "Cannot get splat index for non-splat!");
-    return Mask[0];
+    EVT VT = getValueType(0);
+    for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
+      if (Mask[i] != -1)
+        return Mask[i];
+    }
+    return -1;
   }
   static bool isSplatMask(const int *Mask, EVT VT);
 
@@ -1748,7 +1811,7 @@ class ConstantSDNode : public SDNode {
   friend class SelectionDAG;
   ConstantSDNode(bool isTarget, const ConstantInt *val, EVT VT)
     : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant,
-             DebugLoc::getUnknownLoc(), getSDVTList(VT)), Value(val) {
+             DebugLoc(), getSDVTList(VT)), Value(val) {
   }
 public:
 
@@ -1772,13 +1835,19 @@ class ConstantFPSDNode : public SDNode {
   friend class SelectionDAG;
   ConstantFPSDNode(bool isTarget, const ConstantFP *val, EVT VT)
     : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP,
-             DebugLoc::getUnknownLoc(), getSDVTList(VT)), Value(val) {
+             DebugLoc(), getSDVTList(VT)), Value(val) {
   }
 public:
 
   const APFloat& getValueAPF() const { return Value->getValueAPF(); }
   const ConstantFP *getConstantFPValue() const { return Value; }
 
+  /// isZero - Return true if the value is positive or negative zero.
+  bool isZero() const { return Value->isZero(); }
+
+  /// isNaN - Return true if the value is a NaN.
+  bool isNaN() const { return Value->isNaN(); }
+
   /// isExactlyValue - We don't rely on operator== working on double values, as
   /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
   /// As such, this method can be used to do an exact bit-for-bit comparison of
@@ -1837,7 +1906,7 @@ class FrameIndexSDNode : public SDNode {
   friend class SelectionDAG;
   FrameIndexSDNode(int fi, EVT VT, bool isTarg)
     : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex,
-      DebugLoc::getUnknownLoc(), getSDVTList(VT)), FI(fi) {
+      DebugLoc(), getSDVTList(VT)), FI(fi) {
   }
 public:
 
@@ -1856,7 +1925,7 @@ class JumpTableSDNode : public SDNode {
   friend class SelectionDAG;
   JumpTableSDNode(int jti, EVT VT, bool isTarg, unsigned char TF)
     : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable,
-      DebugLoc::getUnknownLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) {
+      DebugLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) {
   }
 public:
 
@@ -1882,7 +1951,7 @@ class ConstantPoolSDNode : public SDNode {
   ConstantPoolSDNode(bool isTarget, Constant *c, EVT VT, int o, unsigned Align,
                      unsigned char TF)
     : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
-             DebugLoc::getUnknownLoc(),
+             DebugLoc(),
              getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) {
     assert((int)Offset >= 0 && "Offset is too large");
     Val.ConstVal = c;
@@ -1890,7 +1959,7 @@ class ConstantPoolSDNode : public SDNode {
   ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
                      EVT VT, int o, unsigned Align, unsigned char TF)
     : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
-             DebugLoc::getUnknownLoc(),
+             DebugLoc(),
              getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) {
     assert((int)Offset >= 0 && "Offset is too large");
     Val.MachineCPVal = v;
@@ -1938,8 +2007,7 @@ class BasicBlockSDNode : public SDNode {
   /// blocks out of order when they're jumped to, which makes it a bit
   /// harder.  Let's see if we need it first.
   explicit BasicBlockSDNode(MachineBasicBlock *mbb)
-    : SDNode(ISD::BasicBlock, DebugLoc::getUnknownLoc(),
-             getSDVTList(MVT::Other)), MBB(mbb) {
+    : SDNode(ISD::BasicBlock, DebugLoc(), getSDVTList(MVT::Other)), MBB(mbb) {
   }
 public:
 
@@ -1985,8 +2053,7 @@ class SrcValueSDNode : public SDNode {
   friend class SelectionDAG;
   /// Create a SrcValue for a general value.
   explicit SrcValueSDNode(const Value *v)
-    : SDNode(ISD::SRCVALUE, DebugLoc::getUnknownLoc(),
-             getSDVTList(MVT::Other)), V(v) {}
+    : SDNode(ISD::SRCVALUE, DebugLoc(), getSDVTList(MVT::Other)), V(v) {}
 
 public:
   /// getValue - return the contained Value.
@@ -1997,14 +2064,28 @@ public:
     return N->getOpcode() == ISD::SRCVALUE;
   }
 };
+  
+class MDNodeSDNode : public SDNode {
+  const MDNode *MD;
+  friend class SelectionDAG;
+  explicit MDNodeSDNode(const MDNode *md)
+  : SDNode(ISD::MDNODE_SDNODE, DebugLoc(), getSDVTList(MVT::Other)), MD(md) {}
+public:
+  
+  const MDNode *getMD() const { return MD; }
+  
+  static bool classof(const MDNodeSDNode *) { return true; }
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::MDNODE_SDNODE;
+  }
+};
 
 
 class RegisterSDNode : public SDNode {
   unsigned Reg;
   friend class SelectionDAG;
   RegisterSDNode(unsigned reg, EVT VT)
-    : SDNode(ISD::Register, DebugLoc::getUnknownLoc(),
-             getSDVTList(VT)), Reg(reg) {
+    : SDNode(ISD::Register, DebugLoc(), getSDVTList(VT)), Reg(reg) {
   }
 public:
 
@@ -2022,7 +2103,7 @@ class BlockAddressSDNode : public SDNode {
   friend class SelectionDAG;
   BlockAddressSDNode(unsigned NodeTy, EVT VT, BlockAddress *ba,
                      unsigned char Flags)
-    : SDNode(NodeTy, DebugLoc::getUnknownLoc(), getSDVTList(VT)),
+    : SDNode(NodeTy, DebugLoc(), getSDVTList(VT)),
              BA(ba), TargetFlags(Flags) {
   }
 public:
@@ -2036,18 +2117,18 @@ public:
   }
 };
 
-class LabelSDNode : public SDNode {
+class EHLabelSDNode : public SDNode {
   SDUse Chain;
-  unsigned LabelID;
+  MCSymbol *Label;
   friend class SelectionDAG;
-  LabelSDNode(unsigned NodeTy, DebugLoc dl, SDValue ch, unsigned id)
-    : SDNode(NodeTy, dl, getSDVTList(MVT::Other)), LabelID(id) {
+  EHLabelSDNode(DebugLoc dl, SDValue ch, MCSymbol *L)
+    : SDNode(ISD::EH_LABEL, dl, getSDVTList(MVT::Other)), Label(L) {
     InitOperands(&Chain, ch);
   }
 public:
-  unsigned getLabelID() const { return LabelID; }
+  MCSymbol *getLabel() const { return Label; }
 
-  static bool classof(const LabelSDNode *) { return true; }
+  static bool classof(const EHLabelSDNode *) { return true; }
   static bool classof(const SDNode *N) {
     return N->getOpcode() == ISD::EH_LABEL;
   }
@@ -2060,8 +2141,7 @@ class ExternalSymbolSDNode : public SDNode {
   friend class SelectionDAG;
   ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned char TF, EVT VT)
     : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
-             DebugLoc::getUnknownLoc(),
-             getSDVTList(VT)), Symbol(Sym), TargetFlags(TF) {
+             DebugLoc(), getSDVTList(VT)), Symbol(Sym), TargetFlags(TF) {
   }
 public:
 
@@ -2079,8 +2159,8 @@ class CondCodeSDNode : public SDNode {
   ISD::CondCode Condition;
   friend class SelectionDAG;
   explicit CondCodeSDNode(ISD::CondCode Cond)
-    : SDNode(ISD::CONDCODE, DebugLoc::getUnknownLoc(),
-             getSDVTList(MVT::Other)), Condition(Cond) {
+    : SDNode(ISD::CONDCODE, DebugLoc(), getSDVTList(MVT::Other)),
+      Condition(Cond) {
   }
 public:
 
@@ -2237,8 +2317,8 @@ class VTSDNode : public SDNode {
   EVT ValueType;
   friend class SelectionDAG;
   explicit VTSDNode(EVT VT)
-    : SDNode(ISD::VALUETYPE, DebugLoc::getUnknownLoc(),
-             getSDVTList(MVT::Other)), ValueType(VT) {
+    : SDNode(ISD::VALUETYPE, DebugLoc(), getSDVTList(MVT::Other)),
+      ValueType(VT) {
   }
 public: