diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 955965bccfa..81e9ab31529 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -227,6 +227,7 @@ namespace llvm { private: SDNode *Node; // Representative node. MachineInstr *Instr; // Alternatively, a MachineInstr. + MachineInstr *DbgInstr; // A dbg_value referencing this. public: SUnit *OrigNode; // If not this, the node from which // this node was cloned. @@ -269,10 +270,10 @@ namespace llvm { /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent /// an SDNode and any nodes flagged to it. SUnit(SDNode *node, unsigned nodenum) - : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), - Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), - isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), - hasPhysRegClobbers(false), + : Node(node), Instr(0), DbgInstr(0), OrigNode(0), NodeNum(nodenum), + NodeQueueId(0), Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), + NumSuccsLeft(0), isTwoAddress(false), isCommutable(false), + hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), isAvailable(false), isScheduled(false), isScheduleHigh(false), isCloned(false), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), @@ -281,10 +282,10 @@ namespace llvm { /// SUnit - Construct an SUnit for post-regalloc scheduling to represent /// a MachineInstr. SUnit(MachineInstr *instr, unsigned nodenum) - : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), - Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), - isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), - hasPhysRegClobbers(false), + : Node(0), Instr(instr), DbgInstr(0), OrigNode(0), NodeNum(nodenum), + NodeQueueId(0), Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), + NumSuccsLeft(0), isTwoAddress(false), isCommutable(false), + hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), isAvailable(false), isScheduled(false), isScheduleHigh(false), isCloned(false), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), @@ -292,10 +293,10 @@ namespace llvm { /// SUnit - Construct a placeholder SUnit. SUnit() - : Node(0), Instr(0), OrigNode(0), NodeNum(~0u), NodeQueueId(0), - Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), - isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), - hasPhysRegClobbers(false), + : Node(0), Instr(0), DbgInstr(0), OrigNode(0), NodeNum(~0u), + NodeQueueId(0), Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), + NumSuccsLeft(0), isTwoAddress(false), isCommutable(false), + hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), isAvailable(false), isScheduled(false), isScheduleHigh(false), isCloned(false), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), @@ -329,6 +330,20 @@ namespace llvm { return Instr; } + /// setDbgInstr - Assign the debug instruction for the SUnit. + /// This may be used during post-regalloc scheduling. + void setDbgInstr(MachineInstr *MI) { + assert(!Node && "Setting debug MachineInstr of SUnit with SDNode!"); + DbgInstr = MI; + } + + /// getDbgInstr - Return the debug MachineInstr for this SUnit. + /// This may be used during post-regalloc scheduling. + MachineInstr *getDbgInstr() const { + assert(!Node && "Reading debug MachineInstr of SUnit with SDNode!"); + return DbgInstr; + } + /// addPred - This adds the specified edge as a pred of the current node if /// not already. It also adds the current node as a successor of the /// specified node. diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index ad01e89b3c6..714addb129f 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -35,6 +35,7 @@ class MachineConstantPoolValue; class MachineFunction; class MachineModuleInfo; class SDNodeOrdering; +class SDDbgValue; class TargetLowering; template<> struct ilist_traits : public ilist_default_traits { @@ -57,6 +58,46 @@ private: static void createNode(const SDNode &); }; +/// SDDbgInfo - Keeps track of dbg_value information through SDISel. We do +/// not build SDNodes for these so as not to perturb the generated code; +/// instead the info is kept off to the side in this structure. SDNodes may +/// have an associated dbg_value entry in DbgValMap. Debug info that is not +/// associated with any SDNode is held in DbgConstMap. It is possible for +/// optimizations to change a variable to a constant, in which case the +/// corresponding debug info is moved from the variable to the constant table +/// (NYI). +class SDDbgInfo { + DenseMap DbgVblMap; + SmallVector DbgConstMap; + + void operator=(const SDDbgInfo&); // Do not implement. + SDDbgInfo(const SDDbgInfo&); // Do not implement. +public: + SDDbgInfo() {} + + void add(const SDNode *Node, SDDbgValue *V) { + DbgVblMap[Node] = V; + } + void add(SDDbgValue *V) { DbgConstMap.push_back(V); } + void remove(const SDNode *Node) { + DenseMap::iterator Itr = + DbgVblMap.find(Node); + if (Itr != DbgVblMap.end()) + DbgVblMap.erase(Itr); + } + // No need to remove a constant. + void clear() { + DbgVblMap.clear(); + DbgConstMap.clear(); + } + SDDbgValue *getSDDbgValue(const SDNode *Node) { + return DbgVblMap[Node]; + } + typedef SmallVector::iterator ConstDbgIterator; + ConstDbgIterator DbgConstBegin() { return DbgConstMap.begin(); } + ConstDbgIterator DbgConstEnd() { return DbgConstMap.end(); } +}; + enum CombineLevel { Unrestricted, // Combine may create illegal operations and illegal types. NoIllegalTypes, // Combine may create illegal operations but no illegal types. @@ -119,6 +160,9 @@ class SelectionDAG { /// the ordering of the original LLVM instructions. SDNodeOrdering *Ordering; + /// DbgInfo - Tracks dbg_value information through SDISel. + SDDbgInfo *DbgInfo; + /// VerifyNode - Sanity check the given node. Aborts if it is invalid. void VerifyNode(SDNode *N); @@ -828,6 +872,20 @@ public: /// GetOrdering - Get the order for the SDNode. unsigned GetOrdering(const SDNode *SD) const; + /// AssignDbgInfo - Assign debug info to the SDNode. + void AssignDbgInfo(SDNode *SD, SDDbgValue *db); + + /// RememberDbgInfo - Remember debug info with no associated SDNode. + void RememberDbgInfo(SDDbgValue *db); + + /// GetDbgInfo - Get the debug info for the SDNode. + SDDbgValue *GetDbgInfo(const SDNode* SD); + + SDDbgInfo::ConstDbgIterator DbgConstBegin() { + return DbgInfo->DbgConstBegin(); + } + SDDbgInfo::ConstDbgIterator DbgConstEnd() { return DbgInfo->DbgConstEnd(); } + void dump() const; /// CreateStackTemporary - Create a stack temporary, suitable for holding the diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp index badf34e66cc..e532ade5f68 100644 --- a/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -34,6 +34,7 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf, const MachineDominatorTree &mdt) : ScheduleDAG(mf), MLI(mli), MDT(mdt), LoopRegs(MLI, MDT) { MFI = mf.getFrameInfo(); + DbgValueVec.clear(); } /// Run - perform scheduling. @@ -157,6 +158,10 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) { std::map AliasMemDefs, NonAliasMemDefs; std::map > AliasMemUses, NonAliasMemUses; + // Keep track of dangling debug references to registers. + std::pair + DanglingDebugValue[TargetRegisterInfo::FirstVirtualRegister]; + // Check to see if the scheduler cares about latencies. bool UnitLatencies = ForceUnitLatencies(); @@ -164,10 +169,25 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) { const TargetSubtarget &ST = TM.getSubtarget(); unsigned SpecialAddressLatency = ST.getSpecialAddressLatency(); + // Remove any stale debug info; sometimes BuildSchedGraph is called again + // without emitting the info from the previous call. + DbgValueVec.clear(); + std::memset(DanglingDebugValue, 0, sizeof(DanglingDebugValue)); + // Walk the list of instructions, from bottom moving up. for (MachineBasicBlock::iterator MII = InsertPos, MIE = Begin; MII != MIE; --MII) { MachineInstr *MI = prior(MII); + // DBG_VALUE does not have SUnit's built, so just remember these for later + // reinsertion. + if (MI->isDebugValue()) { + if (MI->getNumOperands()==3 && MI->getOperand(0).isReg() && + MI->getOperand(0).getReg()) + DanglingDebugValue[MI->getOperand(0).getReg()] = + std::make_pair(MI, DbgValueVec.size()); + DbgValueVec.push_back(MI); + continue; + } const TargetInstrDesc &TID = MI->getDesc(); assert(!TID.isTerminator() && !MI->isLabel() && "Cannot schedule terminators or labels!"); @@ -188,6 +208,13 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) { if (Reg == 0) continue; assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!"); + + if (MO.isDef() && DanglingDebugValue[Reg].first!=0) { + SU->setDbgInstr(DanglingDebugValue[Reg].first); + DbgValueVec[DanglingDebugValue[Reg].second] = 0; + DanglingDebugValue[Reg] = std::make_pair((MachineInstr*)0, 0); + } + std::vector &UseList = Uses[Reg]; std::vector &DefList = Defs[Reg]; // Optionally add output and anti dependencies. For anti @@ -555,6 +582,14 @@ EmitSchedule(DenseMap *EM) { BB->remove(I); } + // First reinsert any remaining debug_values; these are either constants, + // or refer to live-in registers. The beginning of the block is the right + // place for the latter. The former might reasonably be placed elsewhere + // using some kind of ordering algorithm, but right now it doesn't matter. + for (int i = DbgValueVec.size()-1; i>=0; --i) + if (DbgValueVec[i]) + BB->insert(InsertPos, DbgValueVec[i]); + // Then re-insert them according to the given schedule. for (unsigned i = 0, e = Sequence.size(); i != e; i++) { SUnit *SU = Sequence[i]; @@ -565,12 +600,21 @@ EmitSchedule(DenseMap *EM) { } BB->insert(InsertPos, SU->getInstr()); + if (SU->getDbgInstr()) + BB->insert(InsertPos, SU->getDbgInstr()); } // Update the Begin iterator, as the first instruction in the block // may have been scheduled later. - if (!Sequence.empty()) + if (!DbgValueVec.empty()) { + for (int i = DbgValueVec.size()-1; i>=0; --i) + if (DbgValueVec[i]!=0) { + Begin = DbgValueVec[DbgValueVec.size()-1]; + break; + } + } else if (!Sequence.empty()) Begin = Sequence[0]->getInstr(); + DbgValueVec.clear(); return BB; } diff --git a/lib/CodeGen/ScheduleDAGInstrs.h b/lib/CodeGen/ScheduleDAGInstrs.h index 366c3a859d6..c9b44de85ec 100644 --- a/lib/CodeGen/ScheduleDAGInstrs.h +++ b/lib/CodeGen/ScheduleDAGInstrs.h @@ -106,6 +106,10 @@ namespace llvm { /// initialized and destructed for each block. std::vector Defs[TargetRegisterInfo::FirstVirtualRegister]; std::vector Uses[TargetRegisterInfo::FirstVirtualRegister]; + + /// DbgValueVec - Remember DBG_VALUEs that refer to a particular + /// register. + std::vectorDbgValueVec; /// PendingLoads - Remember where unknown loads are after the most recent /// unknown store, as we iterate. As with Defs and Uses, this is here diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index 625de114329..e6ad3630508 100644 --- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -508,6 +508,7 @@ InstrEmitter::EmitDbgValue(SDNode *Node, 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 @@ InstrEmitter::EmitDbgValue(SDNode *Node, 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 *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(V)) { - MI = BuildMI(*MF, DL, II).addImm(CI->getZExtValue()). - addImm(sd->getOffset()). - addMetadata(sd->getMDPtr()); - } else if (ConstantFP *CF = dyn_cast(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(V)) { + MI = BuildMI(*MF, DL, II).addImm(CI->getZExtValue()). + addImm(Offset).addMetadata(mdPtr); + } else if (ConstantFP *CF = dyn_cast(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 4fe9f19cc90..eefcd73e6e9 100644 --- a/lib/CodeGen/SelectionDAG/InstrEmitter.h +++ b/lib/CodeGen/SelectionDAG/InstrEmitter.h @@ -106,7 +106,8 @@ public: /// EmitDbgValue - Generate a constant DBG_VALUE. No node is involved. - void EmitDbgValue(SDDbgValue* sd); + void EmitDbgValue(SDDbgValue* sd, + DenseMap *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 d43a0447a6c..1b7ba18afea 100644 --- a/lib/CodeGen/SelectionDAG/SDDbgValue.h +++ b/lib/CodeGen/SelectionDAG/SDDbgValue.h @@ -28,9 +28,22 @@ class Value; /// 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 @@ class SDDbgValue { 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 06e7b8c905a..4ace1b74bd7 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 @@ EmitSchedule(DenseMap *EM) { InstrEmitter Emitter(BB, InsertPos); DenseMap VRBaseMap; DenseMap 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 @@ EmitSchedule(DenseMap *EM) { 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 746d4e2e1a5..58a475c0a87 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 @@ void SelectionDAG::DeallocateNode(SDNode *N) { // 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 @@ SelectionDAG::SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli) 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 @@ void SelectionDAG::init(MachineFunction &mf, MachineModuleInfo *mmi, SelectionDAG::~SelectionDAG() { allnodes_clear(); delete Ordering; + delete DbgInfo; } void SelectionDAG::allnodes_clear() { @@ -833,6 +839,8 @@ void SelectionDAG::clear() { 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 @@ unsigned SelectionDAG::GetOrdering(const SDNode *SD) const { 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 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const { if (G) if (unsigned Order = G->GetOrdering(this)) OS << " [ORD=" << Order << ']'; - + if (getNodeId() != -1) OS << " [ID=" << getNodeId() << ']'; } diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 0cfcbb6f86e..1416a6d8df2 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -8521,6 +8521,21 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. return BB; } + // DBG_VALUE. Only the frame index case is done here. + case X86::DBG_VALUE: { + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc DL = MI->getDebugLoc(); + X86AddressMode AM; + MachineFunction *F = BB->getParent(); + AM.BaseType = X86AddressMode::FrameIndexBase; + AM.Base.FrameIndex = MI->getOperand(0).getImm(); + addFullAddress(BuildMI(BB, DL, TII->get(X86::DBG_VALUE)), AM). + addImm(MI->getOperand(1).getImm()). + addMetadata(MI->getOperand(2).getMetadata()); + F->DeleteMachineInstr(MI); // Remove pseudo. + return BB; + } + // String/text processing lowering. case X86::PCMPISTRM128REG: return EmitPCMP(MI, BB, 3, false /* in-mem */);