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
This commit is contained in:
Dale Johannesen
2010-03-10 22:13:47 +00:00
parent 6663670359
commit bfdf7f3852
10 changed files with 276 additions and 40 deletions
+45 -1
View File
@@ -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;
}