Progress towards shepherding debug info through SelectionDAG.
No functional effect yet.  This is still evolving and should
not be viewed as final.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98195 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 625de11..e6ad363 100644
--- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -508,6 +508,7 @@
     return;
   if (!sd)
     return;
+  assert(sd->getKind() == SDDbgValue::SD);
   unsigned VReg = getVR(SDValue(sd->getSDNode(), sd->getResNo()), VRBaseMap);
   const TargetInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
   DebugLoc DL = sd->getDebugLoc();
@@ -524,26 +525,46 @@
   MBB->insert(InsertPos, MI);
 }
 
-/// EmitDbgValue - Generate constant debug info.  No SDNode is involved.
+/// EmitDbgValue - Generate debug info that does not refer to a SDNode.
 void
-InstrEmitter::EmitDbgValue(SDDbgValue *sd) {
+InstrEmitter::EmitDbgValue(SDDbgValue *sd,
+                         DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
   if (!sd)
     return;
   const TargetInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
+  uint64_t Offset = sd->getOffset();
+  MDNode* mdPtr = sd->getMDPtr();
+  SDDbgValue::DbgValueKind kind = sd->getKind();
   DebugLoc DL = sd->getDebugLoc();
-  MachineInstr *MI;
-  Value *V = sd->getConst();
-  if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
-    MI = BuildMI(*MF, DL, II).addImm(CI->getZExtValue()).
-                                   addImm(sd->getOffset()).
-                                   addMetadata(sd->getMDPtr());
-  } else if (ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
-    MI = BuildMI(*MF, DL, II).addFPImm(CF).addImm(sd->getOffset()).
-                                   addMetadata(sd->getMDPtr());
+  MachineInstr* MI;
+  if (kind == SDDbgValue::CNST) {
+    Value *V = sd->getConst();
+    if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+      MI = BuildMI(*MF, DL, II).addImm(CI->getZExtValue()).
+                                     addImm(Offset).addMetadata(mdPtr);
+    } else if (ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
+      MI = BuildMI(*MF, DL, II).addFPImm(CF).
+                                     addImm(Offset).addMetadata(mdPtr);
+    } else {
+      // Could be an Undef.  In any case insert an Undef so we can see what we
+      // dropped.
+      MI = BuildMI(*MF, DL, II).addReg(0U).
+                                       addImm(Offset).addMetadata(mdPtr);
+    }
+  } else if (kind == SDDbgValue::FX) {
+    unsigned FrameIx = sd->getFrameIx();
+    // Stack address; this needs to be lowered in target-dependent fashion.
+    // FIXME test that the target supports this somehow; if not emit Undef.
+    // Create a pseudo for EmitInstrWithCustomInserter's consumption.
+    MI = BuildMI(*MF, DL, II).addImm(FrameIx).
+                                   addImm(Offset).addMetadata(mdPtr);
+    MBB = TLI->EmitInstrWithCustomInserter(MI, MBB, EM);
+    InsertPos = MBB->end();
+    return;
   } else {
     // Insert an Undef so we can see what we dropped.
-    MI = BuildMI(*MF, DL, II).addReg(0U).addImm(sd->getOffset()).
-                                    addMetadata(sd->getMDPtr());
+    MI = BuildMI(*MF, DL, II).addReg(0U).
+                                     addImm(Offset).addMetadata(mdPtr);
   }
   MBB->insert(InsertPos, MI);
 }
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.h b/lib/CodeGen/SelectionDAG/InstrEmitter.h
index 4fe9f19..eefcd73 100644
--- a/lib/CodeGen/SelectionDAG/InstrEmitter.h
+++ b/lib/CodeGen/SelectionDAG/InstrEmitter.h
@@ -106,7 +106,8 @@
 
 
   /// EmitDbgValue - Generate a constant DBG_VALUE.  No node is involved.
-  void EmitDbgValue(SDDbgValue* sd);
+  void EmitDbgValue(SDDbgValue* sd,
+                DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM);
 
   /// EmitNode - Generate machine code for a node and needed dependencies.
   ///
diff --git a/lib/CodeGen/SelectionDAG/SDDbgValue.h b/lib/CodeGen/SelectionDAG/SDDbgValue.h
index d43a044..1b7ba18 100644
--- a/lib/CodeGen/SelectionDAG/SDDbgValue.h
+++ b/lib/CodeGen/SelectionDAG/SDDbgValue.h
@@ -28,9 +28,22 @@
 /// We do not use SDValue here to avoid including its header.
 
 class SDDbgValue {
-  SDNode *Node;           // valid for non-constants
-  unsigned ResNo;         // valid for non-constants
-  Value *Const;           // valid for constants
+public:
+  enum DbgValueKind {
+    SD = 0,
+    CNST = 1,
+    FX = 2
+  };
+private:
+  enum DbgValueKind kind;
+  union {
+    struct {
+      SDNode *Node;         // valid for non-constants
+      unsigned ResNo;       // valid for non-constants
+    } s;
+    Value *Const;           // valid for constants
+    unsigned FrameIx;       // valid for stack objects
+  } u;
   MDNode *mdPtr;
   uint64_t Offset;
   DebugLoc DL;
@@ -38,24 +51,43 @@
 public:
   // Constructor for non-constants.
   SDDbgValue(MDNode *mdP, SDNode *N, unsigned R, uint64_t off, DebugLoc dl,
-             unsigned O) :
-    Node(N), ResNo(R), Const(0), mdPtr(mdP), Offset(off), DL(dl), Order(O) {}
+             unsigned O) : mdPtr(mdP), Offset(off), DL(dl), Order(O) {
+    kind = SD;
+    u.s.Node = N;
+    u.s.ResNo = R;
+  }
 
   // Constructor for constants.
   SDDbgValue(MDNode *mdP, Value *C, uint64_t off, DebugLoc dl, unsigned O) : 
-    Node(0), ResNo(0), Const(C), mdPtr(mdP), Offset(off), DL(dl), Order(O) {}
+    mdPtr(mdP), Offset(off), DL(dl), Order(O) {
+    kind = CNST;
+    u.Const = C;
+  }
+
+  // Constructor for frame indices.
+  SDDbgValue(MDNode *mdP, unsigned FI, uint64_t off, DebugLoc dl, unsigned O) : 
+    mdPtr(mdP), Offset(off), DL(dl), Order(O) {
+    kind = FX;
+    u.FrameIx = FI;
+  }
+
+  // Returns the kind.
+  DbgValueKind getKind() { return kind; }
 
   // Returns the MDNode pointer.
   MDNode *getMDPtr() { return mdPtr; }
 
-  // Returns the SDNode* (valid for non-constants only).
-  SDNode *getSDNode() { assert (!Const); return Node; }
+  // Returns the SDNode* for a register ref
+  SDNode *getSDNode() { assert (kind==SD); return u.s.Node; }
 
-  // Returns the ResNo (valid for non-constants only).
-  unsigned getResNo() { assert (!Const); return ResNo; }
+  // Returns the ResNo for a register ref
+  unsigned getResNo() { assert (kind==SD); return u.s.ResNo; }
 
-  // Returns the Value* for a constant (invalid for non-constants).
-  Value *getConst() { assert (!Node); return Const; }
+  // Returns the Value* for a constant
+  Value *getConst() { assert (kind==CNST); return u.Const; }
+
+  // Returns the FrameIx for a stack object
+  unsigned getFrameIx() { assert (kind==FX); return u.FrameIx; }
 
   // Returns the offset.
   uint64_t getOffset() { return Offset; }
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
index 06e7b8c..4ace1b7 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "pre-RA-sched"
+#include "SDDbgValue.h"
 #include "ScheduleDAGSDNodes.h"
 #include "InstrEmitter.h"
 #include "llvm/CodeGen/SelectionDAG.h"
@@ -412,6 +413,14 @@
   InstrEmitter Emitter(BB, InsertPos);
   DenseMap<SDValue, unsigned> VRBaseMap;
   DenseMap<SUnit*, unsigned> CopyVRBaseMap;
+
+  // For now, any constant debug info nodes go at the beginning.
+  for (SDDbgInfo::ConstDbgIterator I = DAG->DbgConstBegin(),
+       E = DAG->DbgConstEnd(); I!=E; I++) {
+    Emitter.EmitDbgValue(*I, EM);
+    delete *I;
+  }
+
   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
     SUnit *SU = Sequence[i];
     if (!SU) {
@@ -435,10 +444,20 @@
     while (!FlaggedNodes.empty()) {
       Emitter.EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, SU->isCloned,
                        VRBaseMap, EM);
+      if (FlaggedNodes.back()->getHasDebugValue())
+        if (SDDbgValue *sd = DAG->GetDbgInfo(FlaggedNodes.back())) {
+          Emitter.EmitDbgValue(FlaggedNodes.back(), VRBaseMap, sd);
+          delete sd;
+        }
       FlaggedNodes.pop_back();
     }
     Emitter.EmitNode(SU->getNode(), SU->OrigNode != SU, SU->isCloned,
                      VRBaseMap, EM);
+    if (SU->getNode()->getHasDebugValue())
+      if (SDDbgValue *sd = DAG->GetDbgInfo(SU->getNode())) {
+        Emitter.EmitDbgValue(SU->getNode(), VRBaseMap, sd);
+        delete sd;
+      }
   }
 
   BB = Emitter.getBlock();
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 746d4e2..58a475c 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -13,6 +13,7 @@
 
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "SDNodeOrdering.h"
+#include "SDDbgValue.h"
 #include "llvm/Constants.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/Function.h"
@@ -596,6 +597,9 @@
 
   // Remove the ordering of this node.
   Ordering->remove(N);
+
+  // And its entry in the debug info table, if any.
+  DbgInfo->remove(N);
 }
 
 /// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that
@@ -793,6 +797,7 @@
     Root(getEntryNode()), Ordering(0) {
   AllNodes.push_back(&EntryNode);
   Ordering = new SDNodeOrdering();
+  DbgInfo = new SDDbgInfo();
 }
 
 void SelectionDAG::init(MachineFunction &mf, MachineModuleInfo *mmi,
@@ -806,6 +811,7 @@
 SelectionDAG::~SelectionDAG() {
   allnodes_clear();
   delete Ordering;
+  delete DbgInfo;
 }
 
 void SelectionDAG::allnodes_clear() {
@@ -833,6 +839,8 @@
   Root = getEntryNode();
   delete Ordering;
   Ordering = new SDNodeOrdering();
+  delete DbgInfo;
+  DbgInfo = new SDDbgInfo();
 }
 
 SDValue SelectionDAG::getSExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT) {
@@ -5264,6 +5272,25 @@
   return Ordering->getOrder(SD);
 }
 
+/// AssignDbgInfo - Assign debug info to the SDNode.
+void SelectionDAG::AssignDbgInfo(SDNode* SD, SDDbgValue* db) {
+  assert(SD && "Trying to assign dbg info to a null node!");
+  DbgInfo->add(SD, db);
+  SD->setHasDebugValue(true);
+}
+
+/// RememberDbgInfo - Remember debug info which is not assigned to an SDNode.
+void SelectionDAG::RememberDbgInfo(SDDbgValue* db) {
+  DbgInfo->add(db);
+}
+
+/// GetDbgInfo - Get the debug info, if any, for the SDNode.
+SDDbgValue* SelectionDAG::GetDbgInfo(const SDNode *SD) {
+  assert(SD && "Trying to get the order of a null node!");
+  if (SD->getHasDebugValue())
+    return DbgInfo->getSDDbgValue(SD);
+  return 0;
+}
 
 //===----------------------------------------------------------------------===//
 //                              SDNode Class
@@ -5911,7 +5938,7 @@
   if (G)
     if (unsigned Order = G->GetOrdering(this))
       OS << " [ORD=" << Order << ']';
-  
+
   if (getNodeId() != -1)
     OS << " [ID=" << getNodeId() << ']';
 }