Add DebugLoc-aware constructors for SDNode derived
[oota-llvm.git] / include / llvm / CodeGen / SelectionDAGNodes.h
index 7a5cd3b43eed39e5295cdd95dd84662ff23bb2c0..89dea1bf0f9e5eeaa29df108d0b051e708cd5e5a 100644 (file)
@@ -30,6 +30,7 @@
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/RecyclingAllocator.h"
 #include "llvm/Support/DataTypes.h"
+#include "llvm/CodeGen/DebugLoc.h"
 #include <cassert>
 
 namespace llvm {
@@ -62,6 +63,13 @@ namespace ISD {
   /// ISD::NodeType enum - This enum defines all of the operators valid in a
   /// SelectionDAG.
   ///
+  /// These are sometimes called the target-independent operators; targets
+  /// may also define target-dependent operators. For example, on x86, these
+  /// are the enum values in the X86ISD namespace. Targets should aim to use
+  /// target-independent operators to model their instruction sets as much
+  /// as possible, and only use target-dependent operators when they have
+  /// special requirements.
+  ///
   enum NodeType {
     // DELETED_NODE - This is an illegal flag value that is used to catch
     // errors.  This opcode is not a legal opcode for any node.
@@ -901,6 +909,7 @@ public:
   inline bool isTargetOpcode() const;
   inline bool isMachineOpcode() const;
   inline unsigned getMachineOpcode() const;
+  inline const DebugLoc getDebugLoc() const;
 
   
   /// reachesChainWithoutSideEffects - Return true if this operand (which must
@@ -1077,6 +1086,9 @@ private:
   /// NodeId - Unique id per SDNode in the DAG.
   int NodeId;
 
+  /// debugLoc - source line information.
+  DebugLoc debugLoc;
+
   /// OperandList - The values that are used by this operation.
   ///
   SDUse *OperandList;
@@ -1146,6 +1158,13 @@ public:
   /// setNodeId - Set unique node id.
   void setNodeId(int Id) { NodeId = Id; }
 
+  /// getDebugLoc - Return the source location info.
+  const DebugLoc getDebugLoc() const { return debugLoc; }
+
+  /// setDebugLoc - Set source location info.  Try to avoid this, putting
+  /// it in the constructor is preferable.
+  void setDebugLoc(const DebugLoc dl) { debugLoc = dl; }
+
   /// use_iterator - This class provides iterator support for SDUse
   /// operands that use a specific SDNode. 
   class use_iterator
@@ -1326,9 +1345,11 @@ protected:
     return Ret;
   }
 
+  /// The constructors that supply DebugLoc explicitly should be preferred
+  /// for new code.
   SDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps)
     : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0),
-      NodeId(-1),
+      NodeId(-1), debugLoc(DebugLoc::getUnknownLoc()),
       OperandList(NumOps ? new SDUse[NumOps] : 0),
       ValueList(VTs.VTs),
       NumOperands(NumOps), NumValues(VTs.NumVTs),
@@ -1343,8 +1364,33 @@ protected:
   /// set later with InitOperands.
   SDNode(unsigned Opc, SDVTList VTs)
     : NodeType(Opc), OperandsNeedDelete(false), SubclassData(0),
-      NodeId(-1), OperandList(0), ValueList(VTs.VTs),
-      NumOperands(0), NumValues(VTs.NumVTs),
+      NodeId(-1), debugLoc(DebugLoc::getUnknownLoc()), OperandList(0), 
+      ValueList(VTs.VTs), NumOperands(0), NumValues(VTs.NumVTs),
+      UseList(NULL) {}
+
+  /// The next two constructors specify DebugLoc explicitly; the intent
+  /// is that they will replace the above two over time, and eventually
+  /// the ones above can be removed.
+  SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs, const SDValue *Ops, 
+         unsigned NumOps)
+    : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0),
+      NodeId(-1), debugLoc(dl),
+      OperandList(NumOps ? new SDUse[NumOps] : 0),
+      ValueList(VTs.VTs),
+      NumOperands(NumOps), NumValues(VTs.NumVTs),
+      UseList(NULL) {
+    for (unsigned i = 0; i != NumOps; ++i) {
+      OperandList[i].setUser(this);
+      OperandList[i].setInitial(Ops[i]);
+    }
+  }
+
+  /// 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), debugLoc(dl), OperandList(0),
+      ValueList(VTs.VTs), NumOperands(0), NumValues(VTs.NumVTs),
       UseList(NULL) {}
   
   /// InitOperands - Initialize the operands list of this with 1 operand.
@@ -1441,6 +1487,9 @@ inline bool SDValue::use_empty() const {
 inline bool SDValue::hasOneUse() const {
   return Node->hasNUsesOfValue(1, ResNo);
 }
+inline const DebugLoc SDValue::getDebugLoc() const {
+  return Node->getDebugLoc();
+}
 
 // Define inline functions from the SDUse class.
 
@@ -1470,6 +1519,10 @@ public:
     : SDNode(Opc, VTs) {
     InitOperands(&Op, X);
   }
+  UnarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X)
+    : SDNode(Opc, dl, VTs) {
+    InitOperands(&Op, X);
+  }
 };
 
 /// BinarySDNode - This class is used for two-operand SDNodes.  This is solely
@@ -1481,6 +1534,10 @@ public:
     : SDNode(Opc, VTs) {
     InitOperands(Ops, X, Y);
   }
+  BinarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y)
+    : SDNode(Opc, dl, VTs) {
+    InitOperands(Ops, X, Y);
+  }
 };
 
 /// TernarySDNode - This class is used for three-operand SDNodes. This is solely
@@ -1493,6 +1550,11 @@ public:
     : SDNode(Opc, VTs) {
     InitOperands(Ops, X, Y, Z);
   }
+  TernarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y,
+                SDValue Z)
+    : SDNode(Opc, dl, VTs) {
+    InitOperands(Ops, X, Y, Z);
+  }
 };
 
 
@@ -1542,6 +1604,14 @@ public:
             MVT MemoryVT, const Value *srcValue, int SVOff,
             unsigned alignment, bool isvolatile);
 
+  MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, MVT MemoryVT,
+            const Value *srcValue, int SVOff,
+            unsigned alignment, bool isvolatile);
+
+  MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, const SDValue *Ops, 
+            unsigned NumOps, MVT MemoryVT, const Value *srcValue, int SVOff,
+            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; }
@@ -1620,6 +1690,21 @@ public:
                 Align, /*isVolatile=*/true) {
     InitOperands(Ops, Chain, Ptr, Val);
   }
+  AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, MVT MemVT,
+               SDValue Chain, SDValue Ptr,
+               SDValue Cmp, SDValue Swp, const Value* SrcVal,
+               unsigned Align=0)
+    : MemSDNode(Opc, dl, VTL, MemVT, SrcVal, /*SVOffset=*/0,
+                Align, /*isVolatile=*/true) {
+    InitOperands(Ops, Chain, Ptr, Cmp, Swp);
+  }
+  AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, MVT MemVT,
+               SDValue Chain, SDValue Ptr, 
+               SDValue Val, const Value* SrcVal, unsigned Align=0)
+    : MemSDNode(Opc, dl, VTL, MemVT, SrcVal, /*SVOffset=*/0,
+                Align, /*isVolatile=*/true) {
+    InitOperands(Ops, Chain, Ptr, Val);
+  }
   
   const SDValue &getBasePtr() const { return getOperand(1); }
   const SDValue &getVal() const { return getOperand(2); }
@@ -1661,6 +1746,13 @@ public:
     : MemSDNode(Opc, VTs, Ops, NumOps, MemoryVT, srcValue, SVO, Align, Vol),
       ReadMem(ReadMem), WriteMem(WriteMem) {
   }
+  MemIntrinsicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs,
+                     const SDValue *Ops, unsigned NumOps,
+                     MVT MemoryVT, const Value *srcValue, int SVO,
+                     unsigned Align, bool Vol, bool ReadMem, bool WriteMem)
+    : MemSDNode(Opc, dl, VTs, Ops, NumOps, MemoryVT, srcValue, SVO, Align, Vol),
+      ReadMem(ReadMem), WriteMem(WriteMem) {
+  }
 
   bool readMem() const { return ReadMem; }
   bool writeMem() const { return WriteMem; }
@@ -1879,6 +1971,9 @@ protected:
   explicit BasicBlockSDNode(MachineBasicBlock *mbb)
     : SDNode(ISD::BasicBlock, getSDVTList(MVT::Other)), MBB(mbb) {
   }
+  explicit BasicBlockSDNode(MachineBasicBlock *mbb, DebugLoc dl)
+    : SDNode(ISD::BasicBlock, dl, getSDVTList(MVT::Other)), MBB(mbb) {
+  }
 public:
 
   MachineBasicBlock *getBasicBlock() const { return MBB; }
@@ -1988,6 +2083,10 @@ protected:
     : SDNode(NodeTy, getSDVTList(MVT::Other)), LabelID(id) {
     InitOperands(&Chain, ch);
   }
+  LabelSDNode(unsigned NodeTy, DebugLoc dl, SDValue ch, unsigned id)
+    : SDNode(NodeTy, dl, getSDVTList(MVT::Other)), LabelID(id) {
+    InitOperands(&Chain, ch);
+  }
 public:
   unsigned getLabelID() const { return LabelID; }
 
@@ -2006,6 +2105,10 @@ protected:
     : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
              getSDVTList(VT)), Symbol(Sym) {
   }
+  ExternalSymbolSDNode(bool isTarget, DebugLoc dl, const char *Sym, MVT VT)
+    : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, dl,
+             getSDVTList(VT)), Symbol(Sym) {
+  }
 public:
 
   const char *getSymbol() const { return Symbol; }
@@ -2172,6 +2275,12 @@ protected:
     : SDNode(ISD::CALL, VTs, Operands, numOperands),
       CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall),
       Inreg(isinreg) {}
+  CallSDNode(unsigned cc, DebugLoc dl, bool isvararg, bool istailcall, 
+             bool isinreg, SDVTList VTs, const SDValue *Operands, 
+             unsigned numOperands)
+    : SDNode(ISD::CALL, dl, VTs, Operands, numOperands),
+      CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall),
+      Inreg(isinreg) {}
 public:
   unsigned getCallingConv() const { return CallingConv; }
   unsigned isVarArg() const { return IsVarArg; }
@@ -2246,6 +2355,16 @@ public:
     assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) &&
            "Only indexed loads and stores have a non-undef offset operand");
   }
+  LSBaseSDNode(ISD::NodeType NodeTy, DebugLoc dl, SDValue *Operands, 
+               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");
+    assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) &&
+           "Only indexed loads and stores have a non-undef offset operand");
+  }
 
   const SDValue &getOffset() const {
     return getOperand(getOpcode() == ISD::LOAD ? 2 : 3);
@@ -2282,6 +2401,13 @@ protected:
                    VTs, AM, LVT, SV, O, Align, Vol) {
     SubclassData |= (unsigned short)ETy << 3;
   }
+  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;
+  }
 public:
 
   /// getExtensionType - Return whether this is a plain node,
@@ -2311,6 +2437,13 @@ protected:
                    VTs, AM, SVT, SV, O, Align, Vol) {
     SubclassData |= (unsigned short)isTrunc << 3;
   }
+  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;
+  }
 public:
 
   /// isTruncatingStore - Return true if the op does a truncation before store.