From bb7b23f5b79a7ca2aa62faa1a6078428af597234 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 30 Nov 2010 02:17:10 +0000 Subject: Stub out a new LiveDebugVariables pass. This analysis is going to run immediately after LiveIntervals. It will stay alive during register allocation and keep track of user variables mentioned in DBG_VALUE instructions. When the register allocator is moving values between registers and the stack, it is very hard to keep track of DBG_VALUE instructions. We usually get it wrong. This analysis maintains a data structure that makes it easy to update DBG_VALUE instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120385 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 lib/CodeGen/LiveDebugVariables.cpp (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp new file mode 100644 index 0000000..2ca0bee --- /dev/null +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -0,0 +1,50 @@ +//===- LiveDebugVariables.cpp - Tracking debug info variables -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the LiveDebugVariables analysis. +// +// Remove all DBG_VALUE instructions referencing virtual registers and replace +// them with a data structure tracking where live user variables are kept - in a +// virtual register or in a stack slot. +// +// Allow the data structure to be updated during register allocation when values +// are moved between registers and stack slots. Finally emit new DBG_VALUE +// instructions after register allocation is complete. +// +//===----------------------------------------------------------------------===// + +#include "LiveDebugVariables.h" +#include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Target/TargetMachine.h" + +using namespace llvm; + +char LiveDebugVariables::ID = 0; + +INITIALIZE_PASS_BEGIN(LiveDebugVariables, "livedebugvars", + "Debug Variable Analysis", false, false) +INITIALIZE_PASS_DEPENDENCY(LiveIntervals) +INITIALIZE_PASS_END(LiveDebugVariables, "livedebugvars", + "Debug Variable Analysis", false, false) + +void LiveDebugVariables::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequiredTransitive(); + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); +} + +LiveDebugVariables::LiveDebugVariables() : MachineFunctionPass(ID) { + initializeLiveDebugVariablesPass(*PassRegistry::getPassRegistry()); +} + +bool LiveDebugVariables::runOnMachineFunction(MachineFunction &mf) { + return false; +} -- cgit v1.1 From 0613516b16466a92c68d60734801221506c85e86 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 2 Dec 2010 00:37:37 +0000 Subject: Implement the first half of LiveDebugVariables. Scan the MachineFunction for DBG_VALUE instructions, and replace them with a data structure similar to LiveIntervals. The live range of a DBG_VALUE is determined by propagating it down the dominator tree until a new DBG_VALUE is found. When a DBG_VALUE lives in a register, its live range is confined to the live range of the register's value. LiveDebugVariables runs before coalescing, so DBG_VALUEs are not artificially extended when registers are joined. The missing half will recreate DBG_VALUE instructions from the intervals when register allocation is complete. The pass is disabled by default. It can be enabled with the temporary command line option -live-debug-variables. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120636 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 507 ++++++++++++++++++++++++++++++++++++- 1 file changed, 505 insertions(+), 2 deletions(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 2ca0bee..9a15a27 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -19,32 +19,535 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "livedebug" #include "LiveDebugVariables.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/Passes.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; +static cl::opt +EnableLDV("live-debug-variables", + cl::desc("Enable the live debug variables pass"), cl::Hidden); + char LiveDebugVariables::ID = 0; INITIALIZE_PASS_BEGIN(LiveDebugVariables, "livedebugvars", "Debug Variable Analysis", false, false) +INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) INITIALIZE_PASS_DEPENDENCY(LiveIntervals) INITIALIZE_PASS_END(LiveDebugVariables, "livedebugvars", "Debug Variable Analysis", false, false) void LiveDebugVariables::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); AU.addRequiredTransitive(); AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); } -LiveDebugVariables::LiveDebugVariables() : MachineFunctionPass(ID) { +LiveDebugVariables::LiveDebugVariables() : MachineFunctionPass(ID), pImpl(0) { initializeLiveDebugVariablesPass(*PassRegistry::getPassRegistry()); } +/// Location - All the different places a user value can reside. +/// Note that this includes immediate values that technically aren't locations. +namespace { +struct Location { + /// kind - What kind of location is this? + enum Kind { + locUndef = 0, + locImm = 0x80000000, + locFPImm + }; + /// Kind - One of the following: + /// 1. locUndef + /// 2. Register number (physical or virtual), data.SubIdx is the subreg index. + /// 3. ~Frame index, data.Offset is the offset. + /// 4. locImm, data.ImmVal is the constant integer value. + /// 5. locFPImm, data.CFP points to the floating point constant. + unsigned Kind; + + /// Data - Extra data about location. + union { + unsigned SubIdx; ///< For virtual registers. + int64_t Offset; ///< For frame indices. + int64_t ImmVal; ///< For locImm. + const ConstantFP *CFP; ///< For locFPImm. + } Data; + + Location(const MachineOperand &MO) { + switch(MO.getType()) { + case MachineOperand::MO_Register: + Kind = MO.getReg(); + Data.SubIdx = MO.getSubReg(); + return; + case MachineOperand::MO_Immediate: + Kind = locImm; + Data.ImmVal = MO.getImm(); + return; + case MachineOperand::MO_FPImmediate: + Kind = locFPImm; + Data.CFP = MO.getFPImm(); + return; + case MachineOperand::MO_FrameIndex: + Kind = ~MO.getIndex(); + // FIXME: MO_FrameIndex should support an offset. + Data.Offset = 0; + return; + default: + Kind = locUndef; + return; + } + } + + bool operator==(const Location &RHS) const { + if (Kind != RHS.Kind) + return false; + switch (Kind) { + case locUndef: + return true; + case locImm: + return Data.ImmVal == RHS.Data.ImmVal; + case locFPImm: + return Data.CFP == RHS.Data.CFP; + default: + if (isReg()) + return Data.SubIdx == RHS.Data.SubIdx; + else + return Data.Offset == RHS.Data.Offset; + } + } + + /// isUndef - is this the singleton undef? + bool isUndef() const { return Kind == locUndef; } + + /// isReg - is this a register location? + bool isReg() const { return Kind && Kind < locImm; } + + void print(raw_ostream&, const TargetRegisterInfo*); +}; +} + +/// LocMap - Map of where a user value is live, and its location. +typedef IntervalMap LocMap; + +/// UserValue - A user value is a part of a debug info user variable. +/// +/// A DBG_VALUE instruction notes that (a sub-register of) a virtual register +/// holds part of a user variable. The part is identified by a byte offset. +/// +/// UserValues are grouped into equivalence classes for easier searching. Two +/// user values are related if they refer to the same variable, or if they are +/// held by the same virtual register. The equivalence class is the transitive +/// closure of that relation. +namespace { +class UserValue { + const MDNode *variable; ///< The debug info variable we are part of. + unsigned offset; ///< Byte offset into variable. + + UserValue *leader; ///< Equivalence class leader. + UserValue *next; ///< Next value in equivalence class, or null. + + /// Numbered locations referenced by locmap. + SmallVector locations; + + /// Map of slot indices where this value is live. + LocMap locInts; + +public: + /// UserValue - Create a new UserValue. + UserValue(const MDNode *var, unsigned o, LocMap::Allocator &alloc) + : variable(var), offset(o), leader(this), next(0), locInts(alloc) + {} + + /// getLeader - Get the leader of this value's equivalence class. + UserValue *getLeader() { + UserValue *l = leader; + while (l != l->leader) + l = l->leader; + return leader = l; + } + + /// getNext - Return the next UserValue in the equivalence class. + UserValue *getNext() const { return next; } + + /// match - Does this UserValue match the aprameters? + bool match(const MDNode *Var, unsigned Offset) const { + return Var == variable && Offset == offset; + } + + /// merge - Merge equivalence classes. + static UserValue *merge(UserValue *L1, UserValue *L2) { + L2 = L2->getLeader(); + if (!L1) + return L2; + L1 = L1->getLeader(); + if (L1 == L2) + return L1; + // Splice L2 before L1's members. + UserValue *End = L2; + while (End->next) + End->leader = L1, End = End->next; + End->leader = L1; + End->next = L1->next; + L1->next = L2; + return L1; + } + + /// getLocationNo - Return the location number that matches Loc. + unsigned getLocationNo(Location Loc) { + if (Loc.isUndef()) + return ~0u; + unsigned n = std::find(locations.begin(), locations.end(), Loc) - + locations.begin(); + if (n == locations.size()) + locations.push_back(Loc); + return n; + } + + /// addDef - Add a definition point to this value. + void addDef(SlotIndex Idx, const MachineOperand &LocMO) { + // Add a singular (Idx,Idx) -> Loc mapping. + LocMap::iterator I = locInts.find(Idx); + if (!I.valid() || I.start() != Idx) + I.insert(Idx, Idx.getNextSlot(), getLocationNo(LocMO)); + } + + /// extendDef - Extend the current definition as far as possible down the + /// dominator tree. Stop when meeting an existing def or when leaving the live + /// range of VNI. + /// @param Idx Starting point for the definition. + /// @param LocNo Location number to propagate. + /// @param LI Restrict liveness to where LI has the value VNI. May be null. + /// @param VNI When LI is not null, this is the value to restrict to. + /// @param LIS Live intervals analysis. + /// @param MDT Dominator tree. + void extendDef(SlotIndex Idx, unsigned LocNo, + LiveInterval *LI, const VNInfo *VNI, + LiveIntervals &LIS, MachineDominatorTree &MDT); + + /// computeIntervals - Compute the live intervals of all locations after + /// collecting all their def points. + void computeIntervals(LiveIntervals &LIS, MachineDominatorTree &MDT); + + void print(raw_ostream&, const TargetRegisterInfo*); +}; +} // namespace + +/// LDVImpl - Implementation of the LiveDebugVariables pass. +namespace { +class LDVImpl { + LiveDebugVariables &pass; + LocMap::Allocator allocator; + MachineFunction *MF; + LiveIntervals *LIS; + MachineDominatorTree *MDT; + const TargetRegisterInfo *TRI; + + /// userValues - All allocated UserValue instances. + SmallVector userValues; + + /// Map virtual register to eq class leader. + typedef DenseMap VRMap; + VRMap virtRegMap; + + /// Map user variable to eq class leader. + typedef DenseMap UVMap; + UVMap userVarMap; + + /// getUserValue - Find or create a UserValue. + UserValue *getUserValue(const MDNode *Var, unsigned Offset); + + /// mapVirtReg - Map virtual register to an equivalence class. + void mapVirtReg(unsigned VirtReg, UserValue *EC); + + /// handleDebugValue - Add DBG_VALUE instruction to our maps. + /// @param MI DBG_VALUE instruction + /// @param Idx Last valid SLotIndex before instruction. + /// @return True if the DBG_VALUE instruction should be deleted. + bool handleDebugValue(MachineInstr *MI, SlotIndex Idx); + + /// collectDebugValues - Collect and erase all DBG_VALUE instructions, adding + /// a UserValue def for each instruction. + /// @param mf MachineFunction to be scanned. + /// @return True if any debug values were found. + bool collectDebugValues(MachineFunction &mf); + + /// computeIntervals - Compute the live intervals of all user values after + /// collecting all their def points. + void computeIntervals(); + +public: + LDVImpl(LiveDebugVariables *ps) : pass(*ps) {} + bool runOnMachineFunction(MachineFunction &mf); + + /// clear - Relase all memory. + void clear() { + DeleteContainerPointers(userValues); + userValues.clear(); + virtRegMap.clear(); + userVarMap.clear(); + } + + void print(raw_ostream&); +}; +} // namespace + +void Location::print(raw_ostream &OS, const TargetRegisterInfo *TRI) { + switch (Kind) { + case locUndef: + OS << "undef"; + return; + case locImm: + OS << "int:" << Data.ImmVal; + return; + case locFPImm: + OS << "fp:" << Data.CFP->getValueAPF().convertToDouble(); + return; + default: + if (isReg()) { + if (TargetRegisterInfo::isVirtualRegister(Kind)) { + OS << "%reg" << Kind; + if (Data.SubIdx) + OS << ':' << TRI->getSubRegIndexName(Data.SubIdx); + } else + OS << '%' << TRI->getName(Kind); + } else { + OS << "fi#" << ~Kind; + if (Data.Offset) + OS << '+' << Data.Offset; + } + return; + } +} + +void UserValue::print(raw_ostream &OS, const TargetRegisterInfo *TRI) { + if (const MDString *MDS = dyn_cast(variable->getOperand(2))) + OS << "!\"" << MDS->getString() << "\"\t"; + if (offset) + OS << '+' << offset; + for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I) { + OS << " [" << I.start() << ';' << I.stop() << "):"; + if (I.value() == ~0u) + OS << "undef"; + else + OS << I.value(); + } + for (unsigned i = 0, e = locations.size(); i != e; ++i) { + OS << " Loc" << i << '='; + locations[i].print(OS, TRI); + } + OS << '\n'; +} + +void LDVImpl::print(raw_ostream &OS) { + OS << "********** DEBUG VARIABLES **********\n"; + for (unsigned i = 0, e = userValues.size(); i != e; ++i) + userValues[i]->print(OS, TRI); +} + +UserValue *LDVImpl::getUserValue(const MDNode *Var, unsigned Offset) { + UserValue *&Leader = userVarMap[Var]; + if (Leader) { + UserValue *UV = Leader->getLeader(); + Leader = UV; + for (; UV; UV = UV->getNext()) + if (UV->match(Var, Offset)) + return UV; + } + + UserValue *UV = new UserValue(Var, Offset, allocator); + userValues.push_back(UV); + Leader = UserValue::merge(Leader, UV); + return UV; +} + +void LDVImpl::mapVirtReg(unsigned VirtReg, UserValue *EC) { + assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && "Only map VirtRegs"); + UserValue *&Leader = virtRegMap[VirtReg]; + Leader = UserValue::merge(Leader, EC); +} + +bool LDVImpl::handleDebugValue(MachineInstr *MI, SlotIndex Idx) { + // DBG_VALUE loc, offset, variable + if (MI->getNumOperands() != 3 || + !MI->getOperand(1).isImm() || !MI->getOperand(2).isMetadata()) { + DEBUG(dbgs() << "Can't handle " << *MI); + return false; + } + + // Get or create the UserValue for (variable,offset). + unsigned Offset = MI->getOperand(1).getImm(); + const MDNode *Var = MI->getOperand(2).getMetadata(); + UserValue *UV = getUserValue(Var, Offset); + + // If the location is a virtual register, make sure it is mapped. + if (MI->getOperand(0).isReg()) { + unsigned Reg = MI->getOperand(0).getReg(); + if (Reg && TargetRegisterInfo::isVirtualRegister(Reg)) + mapVirtReg(Reg, UV); + } + + UV->addDef(Idx, MI->getOperand(0)); + return true; +} + +bool LDVImpl::collectDebugValues(MachineFunction &mf) { + bool Changed = false; + for (MachineFunction::iterator MFI = mf.begin(), MFE = mf.end(); MFI != MFE; + ++MFI) { + MachineBasicBlock *MBB = MFI; + for (MachineBasicBlock::iterator MBBI = MBB->begin(), MBBE = MBB->end(); + MBBI != MBBE;) { + if (!MBBI->isDebugValue()) { + ++MBBI; + continue; + } + // DBG_VALUE has no slot index, use the previous instruction instead. + SlotIndex Idx = MBBI == MBB->begin() ? + LIS->getMBBStartIdx(MBB) : + LIS->getInstructionIndex(llvm::prior(MBBI)).getDefIndex(); + // Handle consecutive DBG_VALUE instructions with the same slot index. + do { + if (handleDebugValue(MBBI, Idx)) { + MBBI = MBB->erase(MBBI); + Changed = true; + } else + ++MBBI; + } while (MBBI != MBBE && MBBI->isDebugValue()); + } + } + return Changed; +} + +void UserValue::extendDef(SlotIndex Idx, unsigned LocNo, + LiveInterval *LI, const VNInfo *VNI, + LiveIntervals &LIS, MachineDominatorTree &MDT) { + SmallVector Todo; + Todo.push_back(Idx); + + do { + SlotIndex Start = Todo.pop_back_val(); + MachineBasicBlock *MBB = LIS.getMBBFromIndex(Start); + SlotIndex Stop = LIS.getMBBEndIdx(MBB); + LocMap::iterator I = locInts.find(Idx); + + // Limit to VNI's live range. + bool ToEnd = true; + if (LI && VNI) { + LiveRange *Range = LI->getLiveRangeContaining(Start); + if (!Range || Range->valno != VNI) + continue; + if (Range->end < Stop) + Stop = Range->end, ToEnd = false; + } + + // There could already be a short def at Start. + if (I.valid() && I.start() <= Start) { + // Stop when meeting a different location or an already extended interval. + Start = Start.getNextSlot(); + if (I.value() != LocNo || I.stop() != Start) + continue; + // This is a one-slot placeholder. Just skip it. + ++I; + } + + // Limited by the next def. + if (I.valid() && I.start() < Stop) + Stop = I.start(), ToEnd = false; + + if (Start >= Stop) + continue; + + I.insert(Start, Stop, LocNo); + + // If we extended to the MBB end, propagate down the dominator tree. + if (!ToEnd) + continue; + const std::vector &Children = + MDT.getNode(MBB)->getChildren(); + for (unsigned i = 0, e = Children.size(); i != e; ++i) + Todo.push_back(LIS.getMBBStartIdx(Children[i]->getBlock())); + } while (!Todo.empty()); +} + +void +UserValue::computeIntervals(LiveIntervals &LIS, MachineDominatorTree &MDT) { + SmallVector, 16> Defs; + + // Collect all defs to be extended (Skipping undefs). + for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I) + if (I.value() != ~0u) + Defs.push_back(std::make_pair(I.start(), I.value())); + + for (unsigned i = 0, e = Defs.size(); i != e; ++i) { + SlotIndex Idx = Defs[i].first; + unsigned LocNo = Defs[i].second; + const Location &Loc = locations[LocNo]; + + // Register locations are constrained to where the register value is live. + if (Loc.isReg() && LIS.hasInterval(Loc.Kind)) { + LiveInterval *LI = &LIS.getInterval(Loc.Kind); + const VNInfo *VNI = LI->getVNInfoAt(Idx); + extendDef(Idx, LocNo, LI, VNI, LIS, MDT); + } else + extendDef(Idx, LocNo, 0, 0, LIS, MDT); + } + + // Finally, erase all the undefs. + for (LocMap::iterator I = locInts.begin(); I.valid();) + if (I.value() == ~0u) + I.erase(); + else + ++I; +} + +void LDVImpl::computeIntervals() { + for (unsigned i = 0, e = userValues.size(); i != e; ++i) + userValues[i]->computeIntervals(*LIS, *MDT); +} + +bool LDVImpl::runOnMachineFunction(MachineFunction &mf) { + MF = &mf; + LIS = &pass.getAnalysis(); + MDT = &pass.getAnalysis(); + TRI = mf.getTarget().getRegisterInfo(); + clear(); + DEBUG(dbgs() << "********** COMPUTING LIVE DEBUG VARIABLES: " + << ((Value*)mf.getFunction())->getName() + << " **********\n"); + + bool Changed = collectDebugValues(mf); + computeIntervals(); + DEBUG(print(dbgs())); + return Changed; +} + bool LiveDebugVariables::runOnMachineFunction(MachineFunction &mf) { - return false; + if (!EnableLDV) + return false; + if (!pImpl) + pImpl = new LDVImpl(this); + return static_cast(pImpl)->runOnMachineFunction(mf); +} + +void LiveDebugVariables::releaseMemory() { + if (pImpl) + static_cast(pImpl)->clear(); +} + +LiveDebugVariables::~LiveDebugVariables() { + if (pImpl) + delete static_cast(pImpl); } -- cgit v1.1 From 30e2128a731e5a0bcac45a6a79a03bdedce68a0a Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 2 Dec 2010 18:15:44 +0000 Subject: Update LiveDebugVariables during coalescing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120720 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 49 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 9a15a27..4b428f6 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -241,6 +241,10 @@ public: /// collecting all their def points. void computeIntervals(LiveIntervals &LIS, MachineDominatorTree &MDT); + /// renameRegister - Update locations to rewrite OldReg as NewReg:SubIdx. + void renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx, + const TargetRegisterInfo *TRI); + void print(raw_ostream&, const TargetRegisterInfo*); }; } // namespace @@ -269,6 +273,9 @@ class LDVImpl { /// getUserValue - Find or create a UserValue. UserValue *getUserValue(const MDNode *Var, unsigned Offset); + /// lookupVirtReg - Find the EC leader for VirtReg or null. + UserValue *lookupVirtReg(unsigned VirtReg); + /// mapVirtReg - Map virtual register to an equivalence class. void mapVirtReg(unsigned VirtReg, UserValue *EC); @@ -300,6 +307,9 @@ public: userVarMap.clear(); } + /// renameRegister - Replace all references to OldReg wiht NewReg:SubIdx. + void renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx); + void print(raw_ostream&); }; } // namespace @@ -379,6 +389,12 @@ void LDVImpl::mapVirtReg(unsigned VirtReg, UserValue *EC) { Leader = UserValue::merge(Leader, EC); } +UserValue *LDVImpl::lookupVirtReg(unsigned VirtReg) { + if (UserValue *UV = virtRegMap.lookup(VirtReg)) + return UV->getLeader(); + return 0; +} + bool LDVImpl::handleDebugValue(MachineInstr *MI, SlotIndex Idx) { // DBG_VALUE loc, offset, variable if (MI->getNumOperands() != 3 || @@ -551,3 +567,36 @@ LiveDebugVariables::~LiveDebugVariables() { if (pImpl) delete static_cast(pImpl); } + +void UserValue:: +renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx, + const TargetRegisterInfo *TRI) { + for (unsigned i = 0, e = locations.size(); i != e; ++i) { + Location &Loc = locations[i]; + if (Loc.Kind != OldReg) + continue; + Loc.Kind = NewReg; + if (SubIdx && Loc.Data.SubIdx) + Loc.Data.SubIdx = TRI->composeSubRegIndices(SubIdx, Loc.Data.SubIdx); + } +} + +void LDVImpl:: +renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx) { + for (UserValue *UV = lookupVirtReg(OldReg); UV; UV = UV->getNext()) + UV->renameRegister(OldReg, NewReg, SubIdx, TRI); +} + +void LiveDebugVariables:: +renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx) { + if (pImpl) + static_cast(pImpl)->renameRegister(OldReg, NewReg, SubIdx); +} + +#ifndef NDEBUG +void LiveDebugVariables::dump() { + if (pImpl) + static_cast(pImpl)->print(dbgs()); +} +#endif + -- cgit v1.1 From 8d2584a1d9ab56d35884d035e4da6146b4d7391f Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 3 Dec 2010 21:47:08 +0000 Subject: Also update virtRegMap when renaming virtual registers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120841 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 4b428f6..73083c7 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -583,8 +583,18 @@ renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx, void LDVImpl:: renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx) { - for (UserValue *UV = lookupVirtReg(OldReg); UV; UV = UV->getNext()) + UserValue *UV = lookupVirtReg(OldReg); + if (!UV) + return; + + if (TargetRegisterInfo::isVirtualRegister(NewReg)) + mapVirtReg(NewReg, UV); + virtRegMap.erase(OldReg); + + do { UV->renameRegister(OldReg, NewReg, SubIdx, TRI); + UV = UV->getNext(); + } while (UV); } void LiveDebugVariables:: -- cgit v1.1 From 42acf069c9e46395a2fa230ed6b89b402828e3d5 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 3 Dec 2010 21:47:10 +0000 Subject: Emit DBG_VALUE instructions from LiveDebugVariables. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120842 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 182 ++++++++++++++++++++++++++++++++++++- 1 file changed, 181 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 73083c7..4f48d76 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) -- cgit v1.1 From 5daec2215bdb6f484956362d81e5923bb2bffd58 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 3 Dec 2010 22:25:07 +0000 Subject: Coalesce debug locations when possible, causing less DBG_VALUE instructions to be emitted. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120845 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 4f48d76..588a24c 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -188,6 +188,11 @@ class UserValue { /// Map of slot indices where this value is live. LocMap locInts; + /// coalesceLocation - After LocNo was changed, check if it has become + /// identical to another location, and coalesce them. This may cause LocNo or + /// a later location to be erased, but no earlier location will be erased. + void coalesceLocation(unsigned LocNo); + /// insertDebugValue - Insert a DBG_VALUE into MBB at Idx for LocNo. void insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, unsigned LocNo, LiveIntervals &LIS, const TargetInstrInfo &TII); @@ -409,6 +414,30 @@ void LDVImpl::print(raw_ostream &OS) { userValues[i]->print(OS, TRI); } +void UserValue::coalesceLocation(unsigned LocNo) { + unsigned KeepLoc = std::find(locations.begin(), locations.begin() + LocNo, + locations[LocNo]) - locations.begin(); + unsigned EraseLoc = LocNo; + if (KeepLoc == LocNo) { + EraseLoc = std::find(locations.begin() + LocNo + 1, locations.end(), + locations[LocNo]) - locations.begin(); + // No matches. + if (EraseLoc == locations.size()) + return; + } + assert(KeepLoc < EraseLoc); + locations.erase(locations.begin() + EraseLoc); + + // Rewrite values. + for (LocMap::iterator I = locInts.begin(); I.valid(); ++I) { + unsigned v = I.value(); + if (v == EraseLoc) + I.setValue(KeepLoc); // Coalesce when possible. + else if (v > EraseLoc) + I.setValueUnchecked(v-1); // Avoid coalescing with untransformed values. + } +} + UserValue *LDVImpl::getUserValue(const MDNode *Var, unsigned Offset) { UserValue *&Leader = userVarMap[Var]; if (Leader) { @@ -613,13 +642,15 @@ LiveDebugVariables::~LiveDebugVariables() { void UserValue:: renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx, const TargetRegisterInfo *TRI) { - for (unsigned i = 0, e = locations.size(); i != e; ++i) { - Location &Loc = locations[i]; + for (unsigned i = locations.size(); i; --i) { + unsigned LocNo = i - 1; + Location &Loc = locations[LocNo]; if (Loc.Kind != OldReg) continue; Loc.Kind = NewReg; if (SubIdx && Loc.Data.SubIdx) Loc.Data.SubIdx = TRI->composeSubRegIndices(SubIdx, Loc.Data.SubIdx); + coalesceLocation(LocNo); } } @@ -668,6 +699,7 @@ UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI) { } else { Loc.Kind = Location::locUndef; } + coalesceLocation(LocNo); } DEBUG(print(dbgs(), &TRI)); } -- cgit v1.1 From 6ed4c6af97db8b2bbfd6b54dd2a58f16cf0c592b Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 3 Dec 2010 22:25:09 +0000 Subject: Rename virtRegMap to avoid confusion with the VirtRegMap that it isn't. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120846 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 588a24c..baedfc3 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -308,7 +308,7 @@ class LDVImpl { /// Map virtual register to eq class leader. typedef DenseMap VRMap; - VRMap virtRegMap; + VRMap virtRegToEqClass; /// Map user variable to eq class leader. typedef DenseMap UVMap; @@ -347,7 +347,7 @@ public: void clear() { DeleteContainerPointers(userValues); userValues.clear(); - virtRegMap.clear(); + virtRegToEqClass.clear(); userVarMap.clear(); } @@ -456,12 +456,12 @@ UserValue *LDVImpl::getUserValue(const MDNode *Var, unsigned Offset) { void LDVImpl::mapVirtReg(unsigned VirtReg, UserValue *EC) { assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && "Only map VirtRegs"); - UserValue *&Leader = virtRegMap[VirtReg]; + UserValue *&Leader = virtRegToEqClass[VirtReg]; Leader = UserValue::merge(Leader, EC); } UserValue *LDVImpl::lookupVirtReg(unsigned VirtReg) { - if (UserValue *UV = virtRegMap.lookup(VirtReg)) + if (UserValue *UV = virtRegToEqClass.lookup(VirtReg)) return UV->getLeader(); return 0; } @@ -662,7 +662,7 @@ renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx) { if (TargetRegisterInfo::isVirtualRegister(NewReg)) mapVirtReg(NewReg, UV); - virtRegMap.erase(OldReg); + virtRegToEqClass.erase(OldReg); do { UV->renameRegister(OldReg, NewReg, SubIdx, TRI); -- cgit v1.1 From 1dea232624c246341a5a98e0d481ba89f854012c Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 7 Jan 2011 21:30:41 +0000 Subject: Appropriately truncate debug info range in dwarf output. Enable live debug variables pass. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123032 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index baedfc3..2b6a54e 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -39,10 +39,6 @@ using namespace llvm; -static cl::opt -EnableLDV("live-debug-variables", - cl::desc("Enable the live debug variables pass"), cl::Hidden); - char LiveDebugVariables::ID = 0; INITIALIZE_PASS_BEGIN(LiveDebugVariables, "livedebugvars", @@ -622,8 +618,6 @@ bool LDVImpl::runOnMachineFunction(MachineFunction &mf) { } bool LiveDebugVariables::runOnMachineFunction(MachineFunction &mf) { - if (!EnableLDV) - return false; if (!pImpl) pImpl = new LDVImpl(this); return static_cast(pImpl)->runOnMachineFunction(mf); -- cgit v1.1 From 51a666f0e50a34b74212db9c5814153c885153a5 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 7 Jan 2011 22:33:41 +0000 Subject: Speculatively revert r123032. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123039 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 2b6a54e..baedfc3 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -39,6 +39,10 @@ using namespace llvm; +static cl::opt +EnableLDV("live-debug-variables", + cl::desc("Enable the live debug variables pass"), cl::Hidden); + char LiveDebugVariables::ID = 0; INITIALIZE_PASS_BEGIN(LiveDebugVariables, "livedebugvars", @@ -618,6 +622,8 @@ bool LDVImpl::runOnMachineFunction(MachineFunction &mf) { } bool LiveDebugVariables::runOnMachineFunction(MachineFunction &mf) { + if (!EnableLDV) + return false; if (!pImpl) pImpl = new LDVImpl(this); return static_cast(pImpl)->runOnMachineFunction(mf); -- cgit v1.1 From 4314268128be6d54c9a7f0709680e5a5b40f3ab3 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Sun, 9 Jan 2011 03:05:53 +0000 Subject: Replace TargetRegisterInfo::printReg with a PrintReg class that also works without a TRI instance. Print virtual registers numbered from 0 instead of the arbitrary FirstVirtualRegister. The first virtual register is printed as %vreg0. TRI::NoRegister is printed as %noreg. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123107 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index baedfc3..98c6dea 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -374,12 +374,7 @@ void Location::print(raw_ostream &OS, const TargetRegisterInfo *TRI) { return; default: if (isReg()) { - if (TargetRegisterInfo::isVirtualRegister(Kind)) { - OS << "%reg" << Kind; - if (Data.SubIdx) - OS << ':' << TRI->getSubRegIndexName(Data.SubIdx); - } else - OS << '%' << TRI->getName(Kind); + OS << PrintReg(Kind, TRI, Data.SubIdx); } else { OS << "fi#" << ~Kind; if (Data.Offset) -- cgit v1.1 From 0804ead404d694b35e9c55ccbf43f99cd394e487 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Sun, 9 Jan 2011 05:33:21 +0000 Subject: Simplify LiveDebugVariables by storing MachineOperand copies locations instead of using a Location class with the same information. When making a copy of a MachineOperand that was already stored in a MachineInstr, it is necessary to clear the parent pointer on the copy. Otherwise the register use-def lists become inconsistent. Add MachineOperand::clearParent() to do that. An alternative would be a custom MachineOperand copy constructor that cleared ParentMI. I didn't want to do that because of the performance impact. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123109 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 217 ++++++++----------------------------- 1 file changed, 48 insertions(+), 169 deletions(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 98c6dea..ac95e73 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -63,105 +63,6 @@ LiveDebugVariables::LiveDebugVariables() : MachineFunctionPass(ID), pImpl(0) { initializeLiveDebugVariablesPass(*PassRegistry::getPassRegistry()); } -/// Location - All the different places a user value can reside. -/// Note that this includes immediate values that technically aren't locations. -namespace { -struct Location { - /// kind - What kind of location is this? - enum Kind { - locUndef = 0, - locImm = 0x80000000, - locFPImm - }; - /// Kind - One of the following: - /// 1. locUndef - /// 2. Register number (physical or virtual), data.SubIdx is the subreg index. - /// 3. ~Frame index, data.Offset is the offset. - /// 4. locImm, data.ImmVal is the constant integer value. - /// 5. locFPImm, data.CFP points to the floating point constant. - unsigned Kind; - - /// Data - Extra data about location. - union { - unsigned SubIdx; ///< For virtual registers. - int64_t Offset; ///< For frame indices. - int64_t ImmVal; ///< For locImm. - const ConstantFP *CFP; ///< For locFPImm. - } Data; - - Location(const MachineOperand &MO) { - switch(MO.getType()) { - case MachineOperand::MO_Register: - Kind = MO.getReg(); - Data.SubIdx = MO.getSubReg(); - return; - case MachineOperand::MO_Immediate: - Kind = locImm; - Data.ImmVal = MO.getImm(); - return; - case MachineOperand::MO_FPImmediate: - Kind = locFPImm; - Data.CFP = MO.getFPImm(); - return; - case MachineOperand::MO_FrameIndex: - Kind = ~MO.getIndex(); - // FIXME: MO_FrameIndex should support an offset. - Data.Offset = 0; - return; - default: - Kind = locUndef; - return; - } - } - - /// 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; - switch (Kind) { - case locUndef: - return true; - case locImm: - return Data.ImmVal == RHS.Data.ImmVal; - case locFPImm: - return Data.CFP == RHS.Data.CFP; - default: - if (isReg()) - return Data.SubIdx == RHS.Data.SubIdx; - else - return Data.Offset == RHS.Data.Offset; - } - } - - /// isUndef - is this the singleton undef? - bool isUndef() const { return Kind == locUndef; } - - /// 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*); -}; -} - /// LocMap - Map of where a user value is live, and its location. typedef IntervalMap LocMap; @@ -183,7 +84,7 @@ class UserValue { UserValue *next; ///< Next value in equivalence class, or null. /// Numbered locations referenced by locmap. - SmallVector locations; + SmallVector locations; /// Map of slot indices where this value is live. LocMap locInts; @@ -242,14 +143,16 @@ public: } /// getLocationNo - Return the location number that matches Loc. - unsigned getLocationNo(Location Loc) { - if (Loc.isUndef()) + unsigned getLocationNo(const MachineOperand &LocMO) { + if (LocMO.isReg() && LocMO.getReg() == 0) return ~0u; - unsigned n = std::find(locations.begin(), locations.end(), Loc) - - locations.begin(); - if (n == locations.size()) - locations.push_back(Loc); - return n; + for (unsigned i = 0, e = locations.size(); i != e; ++i) + if (LocMO.isIdenticalTo(locations[i])) + return i; + locations.push_back(LocMO); + // We are storing a MachineOperand outside a MachineInstr. + locations.back().clearParent(); + return locations.size() - 1; } /// addDef - Add a definition point to this value. @@ -361,29 +264,6 @@ public: }; } // namespace -void Location::print(raw_ostream &OS, const TargetRegisterInfo *TRI) { - switch (Kind) { - case locUndef: - OS << "undef"; - return; - case locImm: - OS << "int:" << Data.ImmVal; - return; - case locFPImm: - OS << "fp:" << Data.CFP->getValueAPF().convertToDouble(); - return; - default: - if (isReg()) { - OS << PrintReg(Kind, TRI, Data.SubIdx); - } else { - OS << "fi#" << ~Kind; - if (Data.Offset) - OS << '+' << Data.Offset; - } - return; - } -} - void UserValue::print(raw_ostream &OS, const TargetRegisterInfo *TRI) { if (const MDString *MDS = dyn_cast(variable->getOperand(2))) OS << "!\"" << MDS->getString() << "\"\t"; @@ -396,10 +276,8 @@ void UserValue::print(raw_ostream &OS, const TargetRegisterInfo *TRI) { else OS << I.value(); } - for (unsigned i = 0, e = locations.size(); i != e; ++i) { - OS << " Loc" << i << '='; - locations[i].print(OS, TRI); - } + for (unsigned i = 0, e = locations.size(); i != e; ++i) + OS << " Loc" << i << '=' << locations[i]; OS << '\n'; } @@ -410,17 +288,21 @@ void LDVImpl::print(raw_ostream &OS) { } void UserValue::coalesceLocation(unsigned LocNo) { - unsigned KeepLoc = std::find(locations.begin(), locations.begin() + LocNo, - locations[LocNo]) - locations.begin(); - unsigned EraseLoc = LocNo; - if (KeepLoc == LocNo) { - EraseLoc = std::find(locations.begin() + LocNo + 1, locations.end(), - locations[LocNo]) - locations.begin(); - // No matches. - if (EraseLoc == locations.size()) - return; + unsigned KeepLoc = 0; + for (unsigned e = locations.size(); KeepLoc != e; ++KeepLoc) { + if (KeepLoc == LocNo) + continue; + if (locations[KeepLoc].isIdenticalTo(locations[LocNo])) + break; } - assert(KeepLoc < EraseLoc); + // No matches. + if (KeepLoc == locations.size()) + return; + + // Keep the smaller location, erase the larger one. + unsigned EraseLoc = LocNo; + if (KeepLoc > EraseLoc) + std::swap(KeepLoc, EraseLoc); locations.erase(locations.begin() + EraseLoc); // Rewrite values. @@ -576,11 +458,11 @@ UserValue::computeIntervals(LiveIntervals &LIS, MachineDominatorTree &MDT) { for (unsigned i = 0, e = Defs.size(); i != e; ++i) { SlotIndex Idx = Defs[i].first; unsigned LocNo = Defs[i].second; - const Location &Loc = locations[LocNo]; + const MachineOperand &Loc = locations[LocNo]; // Register locations are constrained to where the register value is live. - if (Loc.isReg() && LIS.hasInterval(Loc.Kind)) { - LiveInterval *LI = &LIS.getInterval(Loc.Kind); + if (Loc.isReg() && LIS.hasInterval(Loc.getReg())) { + LiveInterval *LI = &LIS.getInterval(Loc.getReg()); const VNInfo *VNI = LI->getVNInfoAt(Idx); extendDef(Idx, LocNo, LI, VNI, LIS, MDT); } else @@ -639,12 +521,13 @@ renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx, const TargetRegisterInfo *TRI) { for (unsigned i = locations.size(); i; --i) { unsigned LocNo = i - 1; - Location &Loc = locations[LocNo]; - if (Loc.Kind != OldReg) + MachineOperand &Loc = locations[LocNo]; + if (!Loc.isReg() || Loc.getReg() != OldReg) continue; - Loc.Kind = NewReg; - if (SubIdx && Loc.Data.SubIdx) - Loc.Data.SubIdx = TRI->composeSubRegIndices(SubIdx, Loc.Data.SubIdx); + if (TargetRegisterInfo::isPhysicalRegister(NewReg)) + Loc.substPhysReg(NewReg, *TRI); + else + Loc.substVirtReg(NewReg, SubIdx, *TRI); coalesceLocation(LocNo); } } @@ -676,23 +559,20 @@ 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]; + MachineOperand &Loc = locations[LocNo]; // Only virtual registers are rewritten. - if (!Loc.isReg() || !TargetRegisterInfo::isVirtualRegister(Loc.Kind)) + if (!Loc.isReg() || !Loc.getReg() || + !TargetRegisterInfo::isVirtualRegister(Loc.getReg())) continue; - unsigned VirtReg = Loc.Kind; + unsigned VirtReg = Loc.getReg(); 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; + Loc.substPhysReg(VRM.getPhys(VirtReg), TRI); } 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; + Loc = MachineOperand::CreateFI(VRM.getStackSlot(VirtReg)); } else { - Loc.Kind = Location::locUndef; + Loc.setReg(0); + Loc.setSubReg(0); } coalesceLocation(LocNo); } @@ -730,21 +610,20 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, const TargetInstrInfo &TII) { DebugLoc DL; MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, DL, LIS); - Location &Loc = locations[LocNo]; + MachineOperand &Loc = locations[LocNo]; // Frame index locations may require a target callback. - if (Loc.isFrameIndex()) { + if (Loc.isFI()) { MachineInstr *MI = TII.emitFrameIndexDebugValue(*MBB->getParent(), - Loc.getFrameIndex(), - offset, variable, DL); + Loc.getIndex(), 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); + BuildMI(*MBB, I, DL, TII.get(TargetOpcode::DBG_VALUE)) + .addOperand(Loc).addImm(offset).addMetadata(variable); } void UserValue::insertDebugKill(MachineBasicBlock *MBB, SlotIndex Idx, -- cgit v1.1 From c9df025e33ac435adb3b3318d237c36ca7cec659 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Mon, 10 Jan 2011 02:58:51 +0000 Subject: Simplify a bunch of isVirtualRegister() and isPhysicalRegister() logic. These functions not longer assert when passed 0, but simply return false instead. No functional change intended. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123155 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index ac95e73..da4b017 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -359,7 +359,7 @@ bool LDVImpl::handleDebugValue(MachineInstr *MI, SlotIndex Idx) { // If the location is a virtual register, make sure it is mapped. if (MI->getOperand(0).isReg()) { unsigned Reg = MI->getOperand(0).getReg(); - if (Reg && TargetRegisterInfo::isVirtualRegister(Reg)) + if (TargetRegisterInfo::isVirtualRegister(Reg)) mapVirtReg(Reg, UV); } -- cgit v1.1 From b08773749a42a8c68afca96360b6e361147779b4 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 11 Jan 2011 22:11:16 +0000 Subject: Don't insert DBG_VALUE instructions after the first terminator. For one, MachineBasicBlock::getFirstTerminator() doesn't understand what is happening, and it also makes sense to have all control flow run through the DBG_VALUE. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123277 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index da4b017..9a67a63 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -587,6 +587,13 @@ findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, DebugLoc &DL, SlotIndex Start = LIS.getMBBStartIdx(MBB); Idx = Idx.getBaseIndex(); + // Don't insert anything after the first terminator. + MachineBasicBlock::iterator Term = MBB->getFirstTerminator(); + if (Term != MBB->end() && Idx >= LIS.getInstructionIndex(Term)) { + DL = Term->getDebugLoc(); + return Term; + } + // Try to find an insert location by going backwards from Idx. MachineInstr *MI; while (!(MI = LIS.getInstructionFromIndex(Idx))) { -- cgit v1.1 From a518ccc26a0e01d93a58e305f7c19c42fa640bb9 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 11 Jan 2011 22:45:28 +0000 Subject: Enable LiveDebugVariables by default. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123282 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 9a67a63..1349bf5 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -40,7 +40,7 @@ using namespace llvm; static cl::opt -EnableLDV("live-debug-variables", +EnableLDV("live-debug-variables", cl::init(true), cl::desc("Enable the live debug variables pass"), cl::Hidden); char LiveDebugVariables::ID = 0; -- cgit v1.1 From 2df5458535c54c1e214da65191ef86c38b57da39 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 11 Jan 2011 23:20:33 +0000 Subject: The world is not ready for LiveDebugVariables yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123290 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 1349bf5..9a67a63 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -40,7 +40,7 @@ using namespace llvm; static cl::opt -EnableLDV("live-debug-variables", cl::init(true), +EnableLDV("live-debug-variables", cl::desc("Enable the live debug variables pass"), cl::Hidden); char LiveDebugVariables::ID = 0; -- cgit v1.1 From f203627f21614cbef9526aa791b3e7b0493d1e41 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 12 Jan 2011 22:37:49 +0000 Subject: Sometimes, old virtual registers can linger on DBG_VALUE instructions. Make sure we don't crash in that case, but simply turn them into %noreg instead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123335 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 9a67a63..1e2dba2 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -565,7 +565,8 @@ UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI) { !TargetRegisterInfo::isVirtualRegister(Loc.getReg())) continue; unsigned VirtReg = Loc.getReg(); - if (VRM.isAssignedReg(VirtReg)) { + if (VRM.isAssignedReg(VirtReg) && + TargetRegisterInfo::isPhysicalRegister(VRM.getPhys(VirtReg))) { Loc.substPhysReg(VRM.getPhys(VirtReg), TRI); } else if (VRM.getStackSlot(VirtReg) != VirtRegMap::NO_STACK_SLOT) { // FIXME: Translate SubIdx to a stackslot offset. -- cgit v1.1 From 12a40314a91511b65bc83782fd5a3e981331adb1 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 12 Jan 2011 23:14:04 +0000 Subject: Fix braino in dominator tree walk. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123338 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 1e2dba2..fc6275f 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -405,7 +405,7 @@ void UserValue::extendDef(SlotIndex Idx, unsigned LocNo, SlotIndex Start = Todo.pop_back_val(); MachineBasicBlock *MBB = LIS.getMBBFromIndex(Start); SlotIndex Stop = LIS.getMBBEndIdx(MBB); - LocMap::iterator I = locInts.find(Idx); + LocMap::iterator I = locInts.find(Start); // Limit to VNI's live range. bool ToEnd = true; -- cgit v1.1 From f0704d28f34b872f949ef8030651c7159ff6f32f Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 12 Jan 2011 23:14:07 +0000 Subject: Don't emit a DBG_VALUE for a spill slot that the rewriter decided not to use after all. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123339 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index fc6275f..b2aaa8e 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -568,7 +568,8 @@ UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI) { if (VRM.isAssignedReg(VirtReg) && TargetRegisterInfo::isPhysicalRegister(VRM.getPhys(VirtReg))) { Loc.substPhysReg(VRM.getPhys(VirtReg), TRI); - } else if (VRM.getStackSlot(VirtReg) != VirtRegMap::NO_STACK_SLOT) { + } else if (VRM.getStackSlot(VirtReg) != VirtRegMap::NO_STACK_SLOT && + VRM.isSpillSlotUsed(VRM.getStackSlot(VirtReg))) { // FIXME: Translate SubIdx to a stackslot offset. Loc = MachineOperand::CreateFI(VRM.getStackSlot(VirtReg)); } else { -- cgit v1.1 From 25dc2268a5aedcb5da57f065dbdb40d790b11bc0 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 12 Jan 2011 23:36:21 +0000 Subject: Try again enabling LiveDebugVariables. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123342 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index b2aaa8e..1eab6bb 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -40,7 +40,7 @@ using namespace llvm; static cl::opt -EnableLDV("live-debug-variables", +EnableLDV("live-debug-variables", cl::init(true), cl::desc("Enable the live debug variables pass"), cl::Hidden); char LiveDebugVariables::ID = 0; -- cgit v1.1 From a6ada9f725b0015c419a7ef661e833f9e9b26ff8 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 13 Jan 2011 21:28:55 +0000 Subject: Temporary workaround for an i386 crash in LiveDebugVariables. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123400 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 1eab6bb..5e8e309 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -591,7 +591,8 @@ findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, DebugLoc &DL, // Don't insert anything after the first terminator. MachineBasicBlock::iterator Term = MBB->getFirstTerminator(); - if (Term != MBB->end() && Idx >= LIS.getInstructionIndex(Term)) { + if (Term != MBB->end() && !LIS.isNotInMIMap(Term) && + Idx >= LIS.getInstructionIndex(Term)) { DL = Term->getDebugLoc(); return Term; } -- cgit v1.1 From eea666f216ad3a8f8cd88a969176f86add7228f3 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 13 Jan 2011 23:35:53 +0000 Subject: Better terminator avoidance. This approach also works when the terminator doesn't have a slot index. (Which can happen??) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123413 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 5e8e309..38b270d 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -589,14 +589,6 @@ findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, DebugLoc &DL, SlotIndex Start = LIS.getMBBStartIdx(MBB); Idx = Idx.getBaseIndex(); - // Don't insert anything after the first terminator. - MachineBasicBlock::iterator Term = MBB->getFirstTerminator(); - if (Term != MBB->end() && !LIS.isNotInMIMap(Term) && - Idx >= LIS.getInstructionIndex(Term)) { - DL = Term->getDebugLoc(); - return Term; - } - // Try to find an insert location by going backwards from Idx. MachineInstr *MI; while (!(MI = LIS.getInstructionFromIndex(Idx))) { @@ -611,7 +603,9 @@ findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, DebugLoc &DL, } // We found an instruction. The insert point is after the instr. DL = MI->getDebugLoc(); - return llvm::next(MachineBasicBlock::iterator(MI)); + // Don't insert anything after the first terminator, though. + return MI->getDesc().isTerminator() ? MBB->getFirstTerminator() : + llvm::next(MachineBasicBlock::iterator(MI)); } void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, -- cgit v1.1 From f827cd717b63fd3f1d9ad16e69087c65e9af8c82 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 4 Feb 2011 01:43:25 +0000 Subject: DebugLoc associated with a machine instruction is used to emit location entries. DebugLoc associated with a DBG_VALUE is used to identify lexical scope of the variable. After register allocation, while inserting DBG_VALUE remember original debug location for the first instruction and reuse it, otherwise dwarf writer may be mislead in identifying the variable's scope. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124845 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveDebugVariables.cpp | 49 ++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 20 deletions(-) (limited to 'lib/CodeGen/LiveDebugVariables.cpp') diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 38b270d..853ec1a 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -79,7 +79,8 @@ namespace { class UserValue { const MDNode *variable; ///< The debug info variable we are part of. unsigned offset; ///< Byte offset into variable. - + DebugLoc dl; ///< The debug location for the variable. This is + ///< used by dwarf writer to find lexical scope. UserValue *leader; ///< Equivalence class leader. UserValue *next; ///< Next value in equivalence class, or null. @@ -104,8 +105,9 @@ class UserValue { public: /// UserValue - Create a new UserValue. - UserValue(const MDNode *var, unsigned o, LocMap::Allocator &alloc) - : variable(var), offset(o), leader(this), next(0), locInts(alloc) + UserValue(const MDNode *var, unsigned o, DebugLoc L, + LocMap::Allocator &alloc) + : variable(var), offset(o), dl(L), leader(this), next(0), locInts(alloc) {} /// getLeader - Get the leader of this value's equivalence class. @@ -192,6 +194,11 @@ public: void emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS, const TargetInstrInfo &TRI); + /// findDebugLoc - Return DebugLoc used for this DBG_VALUE instruction. A + /// variable may have more than one corresponding DBG_VALUE instructions. + /// Only first one needs DebugLoc to identify variable's lexical scope + /// in source file. + DebugLoc findDebugLoc(); void print(raw_ostream&, const TargetRegisterInfo*); }; } // namespace @@ -218,7 +225,7 @@ class LDVImpl { UVMap userVarMap; /// getUserValue - Find or create a UserValue. - UserValue *getUserValue(const MDNode *Var, unsigned Offset); + UserValue *getUserValue(const MDNode *Var, unsigned Offset, DebugLoc DL); /// lookupVirtReg - Find the EC leader for VirtReg or null. UserValue *lookupVirtReg(unsigned VirtReg); @@ -315,7 +322,8 @@ void UserValue::coalesceLocation(unsigned LocNo) { } } -UserValue *LDVImpl::getUserValue(const MDNode *Var, unsigned Offset) { +UserValue *LDVImpl::getUserValue(const MDNode *Var, unsigned Offset, + DebugLoc DL) { UserValue *&Leader = userVarMap[Var]; if (Leader) { UserValue *UV = Leader->getLeader(); @@ -325,7 +333,7 @@ UserValue *LDVImpl::getUserValue(const MDNode *Var, unsigned Offset) { return UV; } - UserValue *UV = new UserValue(Var, Offset, allocator); + UserValue *UV = new UserValue(Var, Offset, DL, allocator); userValues.push_back(UV); Leader = UserValue::merge(Leader, UV); return UV; @@ -354,7 +362,7 @@ bool LDVImpl::handleDebugValue(MachineInstr *MI, SlotIndex Idx) { // Get or create the UserValue for (variable,offset). unsigned Offset = MI->getOperand(1).getImm(); const MDNode *Var = MI->getOperand(2).getMetadata(); - UserValue *UV = getUserValue(Var, Offset); + UserValue *UV = getUserValue(Var, Offset, MI->getDebugLoc()); // If the location is a virtual register, make sure it is mapped. if (MI->getOperand(0).isReg()) { @@ -581,10 +589,10 @@ UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI) { DEBUG(print(dbgs(), &TRI)); } -/// findInsertLocation - Find an iterator and DebugLoc for inserting a DBG_VALUE +/// findInsertLocation - Find an iterator for inserting a DBG_VALUE /// instruction. static MachineBasicBlock::iterator -findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, DebugLoc &DL, +findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, LiveIntervals &LIS) { SlotIndex Start = LIS.getMBBStartIdx(MBB); Idx = Idx.getBaseIndex(); @@ -595,46 +603,47 @@ findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, DebugLoc &DL, // 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(); + // Don't insert anything after the first terminator, though. return MI->getDesc().isTerminator() ? MBB->getFirstTerminator() : llvm::next(MachineBasicBlock::iterator(MI)); } +DebugLoc UserValue::findDebugLoc() { + DebugLoc D = dl; + dl = DebugLoc(); + return D; +} void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, unsigned LocNo, LiveIntervals &LIS, const TargetInstrInfo &TII) { - DebugLoc DL; - MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, DL, LIS); + MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, LIS); MachineOperand &Loc = locations[LocNo]; // Frame index locations may require a target callback. if (Loc.isFI()) { MachineInstr *MI = TII.emitFrameIndexDebugValue(*MBB->getParent(), - Loc.getIndex(), offset, variable, DL); + Loc.getIndex(), offset, variable, + findDebugLoc()); if (MI) { MBB->insert(I, MI); return; } } // This is not a frame index, or the target is happy with a standard FI. - BuildMI(*MBB, I, DL, TII.get(TargetOpcode::DBG_VALUE)) + BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE)) .addOperand(Loc).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) + MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, LIS); + BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE)).addReg(0) .addImm(offset).addMetadata(variable); } -- cgit v1.1