diff options
author | Dale Johannesen <dalej@apple.com> | 2010-03-10 22:13:47 +0000 |
---|---|---|
committer | Dale Johannesen <dalej@apple.com> | 2010-03-10 22:13:47 +0000 |
commit | bfdf7f38523bd38ae0538861a2bfd8bdc46e5c33 (patch) | |
tree | 93ff5897edbba90849c2d923a1a23eabb835689f /lib/CodeGen | |
parent | 6663670359428183427b7601f3eb9916c08e6068 (diff) |
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
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/ScheduleDAGInstrs.cpp | 46 | ||||
-rw-r--r-- | lib/CodeGen/ScheduleDAGInstrs.h | 4 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/InstrEmitter.cpp | 47 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/InstrEmitter.h | 3 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SDDbgValue.h | 56 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp | 19 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 29 |
7 files changed, 176 insertions, 28 deletions
diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp index badf34e66c..e532ade5f6 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<const Value *, SUnit *> AliasMemDefs, NonAliasMemDefs; std::map<const Value *, std::vector<SUnit *> > AliasMemUses, NonAliasMemUses; + // Keep track of dangling debug references to registers. + std::pair<MachineInstr*, unsigned> + 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<TargetSubtarget>(); 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<SUnit *> &UseList = Uses[Reg]; std::vector<SUnit *> &DefList = Defs[Reg]; // Optionally add output and anti dependencies. For anti @@ -555,6 +582,14 @@ EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*> *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<MachineBasicBlock*, MachineBasicBlock*> *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 366c3a859d..c9b44de85e 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<SUnit *> Defs[TargetRegisterInfo::FirstVirtualRegister]; std::vector<SUnit *> Uses[TargetRegisterInfo::FirstVirtualRegister]; + + /// DbgValueVec - Remember DBG_VALUEs that refer to a particular + /// register. + std::vector<MachineInstr *>DbgValueVec; /// 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 625de11432..e6ad363050 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<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 4fe9f19cc9..eefcd73e6e 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<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 d43a0447a6..1b7ba18afe 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 for a register ref + unsigned getResNo() { assert (kind==SD); return u.s.ResNo; } - // Returns the ResNo (valid for non-constants only). - unsigned getResNo() { assert (!Const); return ResNo; } + // Returns the Value* for a constant + Value *getConst() { assert (kind==CNST); return u.Const; } - // Returns the Value* for a constant (invalid for non-constants). - Value *getConst() { assert (!Node); return 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 06e7b8c905..4ace1b74bd 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<MachineBasicBlock*, MachineBasicBlock*> *EM) { 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 @@ EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*> *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 746d4e2e1a..58a475c0a8 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() << ']'; } |