From: Jakob Stoklund Olesen Date: Fri, 3 Dec 2010 21:47:10 +0000 (+0000) Subject: Emit DBG_VALUE instructions from LiveDebugVariables. X-Git-Tag: android-x86-6.0-r1~1002^2~2620 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=42acf069c9e46395a2fa230ed6b89b402828e3d5;p=android-x86%2Fexternal-llvm.git Emit DBG_VALUE instructions from LiveDebugVariables. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120842 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 73083c77157..4f48d766aef 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -21,16 +21,19 @@ #define DEBUG_TYPE "livedebug" #include "LiveDebugVariables.h" +#include "VirtRegMap.h" #include "llvm/Constants.h" #include "llvm/Metadata.h" #include "llvm/Value.h" #include "llvm/ADT/IntervalMap.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" -#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" @@ -111,6 +114,21 @@ struct Location { } } + /// addOperand - Add this location as a machine operand to MI. + MachineInstrBuilder addOperand(MachineInstrBuilder MI) const { + switch (Kind) { + case locImm: + return MI.addImm(Data.ImmVal); + case locFPImm: + return MI.addFPImm(Data.CFP); + default: + if (isFrameIndex()) + return MI.addFrameIndex(getFrameIndex()); + else + return MI.addReg(Kind); // reg and undef. + } + } + bool operator==(const Location &RHS) const { if (Kind != RHS.Kind) return false; @@ -135,6 +153,11 @@ struct Location { /// isReg - is this a register location? bool isReg() const { return Kind && Kind < locImm; } + /// isFrameIndex - is this a frame index location? + bool isFrameIndex() const { return Kind > locFPImm; } + + int getFrameIndex() const { return ~Kind; } + void print(raw_ostream&, const TargetRegisterInfo*); }; } @@ -165,6 +188,14 @@ class UserValue { /// Map of slot indices where this value is live. LocMap locInts; + /// insertDebugValue - Insert a DBG_VALUE into MBB at Idx for LocNo. + void insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, unsigned LocNo, + LiveIntervals &LIS, const TargetInstrInfo &TII); + + /// insertDebugKill - Insert an undef DBG_VALUE into MBB at Idx. + void insertDebugKill(MachineBasicBlock *MBB, SlotIndex Idx, + LiveIntervals &LIS, const TargetInstrInfo &TII); + public: /// UserValue - Create a new UserValue. UserValue(const MDNode *var, unsigned o, LocMap::Allocator &alloc) @@ -245,6 +276,14 @@ public: void renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx, const TargetRegisterInfo *TRI); + /// rewriteLocations - Rewrite virtual register locations according to the + /// provided virtual register map. + void rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI); + + /// emitDebugVariables - Recreate DBG_VALUE instruction from data structures. + void emitDebugValues(VirtRegMap *VRM, + LiveIntervals &LIS, const TargetInstrInfo &TRI); + void print(raw_ostream&, const TargetRegisterInfo*); }; } // namespace @@ -310,6 +349,9 @@ public: /// renameRegister - Replace all references to OldReg wiht NewReg:SubIdx. void renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx); + /// emitDebugVariables - Recreate DBG_VALUE instruction from data structures. + void emitDebugValues(VirtRegMap *VRM); + void print(raw_ostream&); }; } // namespace @@ -603,6 +645,144 @@ renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx) { static_cast(pImpl)->renameRegister(OldReg, NewReg, SubIdx); } +void +UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI) { + // Iterate over locations in reverse makes it easier to handle coalescing. + for (unsigned i = locations.size(); i ; --i) { + unsigned LocNo = i-1; + Location &Loc = locations[LocNo]; + // Only virtual registers are rewritten. + if (!Loc.isReg() || !TargetRegisterInfo::isVirtualRegister(Loc.Kind)) + continue; + unsigned VirtReg = Loc.Kind; + if (VRM.isAssignedReg(VirtReg)) { + unsigned PhysReg = VRM.getPhys(VirtReg); + if (Loc.Data.SubIdx) + PhysReg = TRI.getSubReg(PhysReg, Loc.Data.SubIdx); + Loc.Kind = PhysReg; + Loc.Data.SubIdx = 0; + } else if (VRM.getStackSlot(VirtReg) != VirtRegMap::NO_STACK_SLOT) { + Loc.Kind = ~VRM.getStackSlot(VirtReg); + // FIXME: Translate SubIdx to a stackslot offset. + Loc.Data.Offset = 0; + } else { + Loc.Kind = Location::locUndef; + } + } + DEBUG(print(dbgs(), &TRI)); +} + +/// findInsertLocation - Find an iterator and DebugLoc for inserting a DBG_VALUE +/// instruction. +static MachineBasicBlock::iterator +findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, DebugLoc &DL, + LiveIntervals &LIS) { + SlotIndex Start = LIS.getMBBStartIdx(MBB); + Idx = Idx.getBaseIndex(); + + // Try to find an insert location by going backwards from Idx. + MachineInstr *MI; + while (!(MI = LIS.getInstructionFromIndex(Idx))) { + // We've reached the beginning of MBB. + if (Idx == Start) { + MachineBasicBlock::iterator I = MBB->SkipPHIsAndLabels(MBB->begin()); + if (I != MBB->end()) + DL = I->getDebugLoc(); + return I; + } + Idx = Idx.getPrevIndex(); + } + // We found an instruction. The insert point is after the instr. + DL = MI->getDebugLoc(); + return llvm::next(MachineBasicBlock::iterator(MI)); +} + +void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, + unsigned LocNo, + LiveIntervals &LIS, + const TargetInstrInfo &TII) { + DebugLoc DL; + MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, DL, LIS); + Location &Loc = locations[LocNo]; + + // Frame index locations may require a target callback. + if (Loc.isFrameIndex()) { + MachineInstr *MI = TII.emitFrameIndexDebugValue(*MBB->getParent(), + Loc.getFrameIndex(), + offset, variable, DL); + if (MI) { + MBB->insert(I, MI); + return; + } + } + // This is not a frame index, or the target is happy with a standard FI. + Loc.addOperand(BuildMI(*MBB, I, DL, TII.get(TargetOpcode::DBG_VALUE))) + .addImm(offset).addMetadata(variable); +} + +void UserValue::insertDebugKill(MachineBasicBlock *MBB, SlotIndex Idx, + LiveIntervals &LIS, const TargetInstrInfo &TII) { + DebugLoc DL; + MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, DL, LIS); + BuildMI(*MBB, I, DL, TII.get(TargetOpcode::DBG_VALUE)).addReg(0) + .addImm(offset).addMetadata(variable); +} + +void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS, + const TargetInstrInfo &TII) { + MachineFunction::iterator MFEnd = VRM->getMachineFunction().end(); + + for (LocMap::const_iterator I = locInts.begin(); I.valid();) { + SlotIndex Start = I.start(); + SlotIndex Stop = I.stop(); + unsigned LocNo = I.value(); + DEBUG(dbgs() << "\t[" << Start << ';' << Stop << "):" << LocNo); + MachineFunction::iterator MBB = LIS.getMBBFromIndex(Start); + SlotIndex MBBEnd = LIS.getMBBEndIdx(MBB); + + DEBUG(dbgs() << " BB#" << MBB->getNumber() << '-' << MBBEnd); + insertDebugValue(MBB, Start, LocNo, LIS, TII); + + // This interval may span multiple basic blocks. + // Insert a DBG_VALUE into each one. + while(Stop > MBBEnd) { + // Move to the next block. + Start = MBBEnd; + if (++MBB == MFEnd) + break; + MBBEnd = LIS.getMBBEndIdx(MBB); + DEBUG(dbgs() << " BB#" << MBB->getNumber() << '-' << MBBEnd); + insertDebugValue(MBB, Start, LocNo, LIS, TII); + } + DEBUG(dbgs() << '\n'); + if (MBB == MFEnd) + break; + + ++I; + if (Stop == MBBEnd) + continue; + // The current interval ends before MBB. + // Insert a kill if there is a gap. + if (!I.valid() || I.start() > Stop) + insertDebugKill(MBB, Stop, LIS, TII); + } +} + +void LDVImpl::emitDebugValues(VirtRegMap *VRM) { + DEBUG(dbgs() << "********** EMITTING LIVE DEBUG VARIABLES **********\n"); + const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); + for (unsigned i = 0, e = userValues.size(); i != e; ++i) { + userValues[i]->rewriteLocations(*VRM, *TRI); + userValues[i]->emitDebugValues(VRM, *LIS, *TII); + } +} + +void LiveDebugVariables::emitDebugValues(VirtRegMap *VRM) { + if (pImpl) + static_cast(pImpl)->emitDebugValues(VRM); +} + + #ifndef NDEBUG void LiveDebugVariables::dump() { if (pImpl) diff --git a/lib/CodeGen/LiveDebugVariables.h b/lib/CodeGen/LiveDebugVariables.h index a69b974fe37..a6e40a19845 100644 --- a/lib/CodeGen/LiveDebugVariables.h +++ b/lib/CodeGen/LiveDebugVariables.h @@ -25,6 +25,8 @@ namespace llvm { +class VirtRegMap; + class LiveDebugVariables : public MachineFunctionPass { void *pImpl; public: @@ -42,7 +44,8 @@ public: /// emitDebugValues - Emit new DBG_VALUE instructions reflecting the changes /// that happened during register allocation. - void emitDebugValues(); + /// @param VRM Rename virtual registers according to map. + void emitDebugValues(VirtRegMap *VRM); /// dump - Print data structures to dbgs(). void dump(); diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp index ac5143b7c69..0875257550b 100644 --- a/lib/CodeGen/RegAllocLinearScan.cpp +++ b/lib/CodeGen/RegAllocLinearScan.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "regalloc" +#include "LiveDebugVariables.h" #include "VirtRegMap.h" #include "VirtRegRewriter.h" #include "Spiller.h" @@ -91,6 +92,7 @@ namespace { struct RALinScan : public MachineFunctionPass { static char ID; RALinScan() : MachineFunctionPass(ID) { + initializeLiveDebugVariablesPass(*PassRegistry::getPassRegistry()); initializeLiveIntervalsPass(*PassRegistry::getPassRegistry()); initializeStrongPHIEliminationPass(*PassRegistry::getPassRegistry()); initializeRegisterCoalescerAnalysisGroup( @@ -212,6 +214,8 @@ namespace { AU.addPreserved(); AU.addRequired(); AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); AU.addRequiredID(MachineDominatorsID); AU.addPreservedID(MachineDominatorsID); MachineFunctionPass::getAnalysisUsage(AU); @@ -532,6 +536,9 @@ bool RALinScan::runOnMachineFunction(MachineFunction &fn) { // Rewrite spill code and update the PhysRegsUsed set. rewriter_->runOnMachineFunction(*mf_, *vrm_, li_); + // Write out new DBG_VALUE instructions. + getAnalysis().emitDebugValues(vrm_); + assert(unhandled_.empty() && "Unhandled live intervals remain!"); finalizeRegUses();