diff options
Diffstat (limited to 'llvm/lib/CodeGen/LiveDebugVariables.cpp')
-rw-r--r-- | llvm/lib/CodeGen/LiveDebugVariables.cpp | 334 |
1 files changed, 185 insertions, 149 deletions
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp index 2cc547a6b741..158e873370b1 100644 --- a/llvm/lib/CodeGen/LiveDebugVariables.cpp +++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp @@ -96,44 +96,49 @@ LiveDebugVariables::LiveDebugVariables() : MachineFunctionPass(ID) { enum : unsigned { UndefLocNo = ~0U }; -/// Describes a location by number along with some flags about the original -/// usage of the location. -class DbgValueLocation { +/// Describes a debug variable value by location number and expression along +/// with some flags about the original usage of the location. +class DbgVariableValue { public: - DbgValueLocation(unsigned LocNo) - : LocNo(LocNo) { - static_assert(sizeof(*this) == sizeof(unsigned), "bad bitfield packing"); - assert(locNo() == LocNo && "location truncation"); + DbgVariableValue(unsigned LocNo, bool WasIndirect, + const DIExpression &Expression) + : LocNo(LocNo), WasIndirect(WasIndirect), Expression(&Expression) { + assert(getLocNo() == LocNo && "location truncation"); } - DbgValueLocation() : LocNo(0) {} + DbgVariableValue() : LocNo(0), WasIndirect(0) {} - unsigned locNo() const { + const DIExpression *getExpression() const { return Expression; } + unsigned getLocNo() const { // Fix up the undef location number, which gets truncated. return LocNo == INT_MAX ? UndefLocNo : LocNo; } - bool isUndef() const { return locNo() == UndefLocNo; } + bool getWasIndirect() const { return WasIndirect; } + bool isUndef() const { return getLocNo() == UndefLocNo; } - DbgValueLocation changeLocNo(unsigned NewLocNo) const { - return DbgValueLocation(NewLocNo); + DbgVariableValue changeLocNo(unsigned NewLocNo) const { + return DbgVariableValue(NewLocNo, WasIndirect, *Expression); } - friend inline bool operator==(const DbgValueLocation &LHS, - const DbgValueLocation &RHS) { - return LHS.LocNo == RHS.LocNo; + friend inline bool operator==(const DbgVariableValue &LHS, + const DbgVariableValue &RHS) { + return LHS.LocNo == RHS.LocNo && LHS.WasIndirect == RHS.WasIndirect && + LHS.Expression == RHS.Expression; } - friend inline bool operator!=(const DbgValueLocation &LHS, - const DbgValueLocation &RHS) { + friend inline bool operator!=(const DbgVariableValue &LHS, + const DbgVariableValue &RHS) { return !(LHS == RHS); } private: - unsigned LocNo; + unsigned LocNo : 31; + unsigned WasIndirect : 1; + const DIExpression *Expression = nullptr; }; -/// Map of where a user value is live, and its location. -using LocMap = IntervalMap<SlotIndex, DbgValueLocation, 4>; +/// Map of where a user value is live to that value. +using LocMap = IntervalMap<SlotIndex, DbgVariableValue, 4>; /// Map of stack slot offsets for spilled locations. /// Non-spilled locations are not added to the map. @@ -149,12 +154,12 @@ class LDVImpl; /// 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. +/// user values are related if they are held by the same virtual register. The +/// equivalence class is the transitive closure of that relation. class UserValue { const DILocalVariable *Variable; ///< The debug info variable we are part of. - const DIExpression *Expression; ///< Any complex address expression. + /// The part of the variable we describe. + const Optional<DIExpression::FragmentInfo> Fragment; DebugLoc dl; ///< The debug location for the variable. This is ///< used by dwarf writer to find lexical scope. UserValue *leader; ///< Equivalence class leader. @@ -166,23 +171,28 @@ class UserValue { /// Map of slot indices where this value is live. LocMap locInts; - /// Insert a DBG_VALUE into MBB at Idx for LocNo. + /// Set of interval start indexes that have been trimmed to the + /// lexical scope. + SmallSet<SlotIndex, 2> trimmedDefs; + + /// Insert a DBG_VALUE into MBB at Idx for DbgValue. void insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx, - SlotIndex StopIdx, DbgValueLocation Loc, bool Spilled, - unsigned SpillOffset, LiveIntervals &LIS, + SlotIndex StopIdx, DbgVariableValue DbgValue, + bool Spilled, unsigned SpillOffset, LiveIntervals &LIS, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI); /// Replace OldLocNo ranges with NewRegs ranges where NewRegs /// is live. Returns true if any changes were made. - bool splitLocation(unsigned OldLocNo, ArrayRef<unsigned> NewRegs, + bool splitLocation(unsigned OldLocNo, ArrayRef<Register> NewRegs, LiveIntervals &LIS); public: /// Create a new UserValue. - UserValue(const DILocalVariable *var, const DIExpression *expr, DebugLoc L, + UserValue(const DILocalVariable *var, + Optional<DIExpression::FragmentInfo> Fragment, DebugLoc L, LocMap::Allocator &alloc) - : Variable(var), Expression(expr), dl(std::move(L)), leader(this), + : Variable(var), Fragment(Fragment), dl(std::move(L)), leader(this), locInts(alloc) {} /// Get the leader of this value's equivalence class. @@ -196,14 +206,6 @@ public: /// Return the next UserValue in the equivalence class. UserValue *getNext() const { return next; } - /// Does this UserValue match the parameters? - bool match(const DILocalVariable *Var, const DIExpression *Expr, - const DILocation *IA) const { - // FIXME: The fragment should be part of the equivalence class, but not - // other things in the expression like stack values. - return Var == Variable && Expr == Expression && dl->getInlinedAt() == IA; - } - /// Merge equivalence classes. static UserValue *merge(UserValue *L1, UserValue *L2) { L2 = L2->getLeader(); @@ -261,33 +263,34 @@ public: void removeLocationIfUnused(unsigned LocNo) { // Bail out if LocNo still is used. for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I) { - DbgValueLocation Loc = I.value(); - if (Loc.locNo() == LocNo) + DbgVariableValue DbgValue = I.value(); + if (DbgValue.getLocNo() == LocNo) return; } // Remove the entry in the locations vector, and adjust all references to // location numbers above the removed entry. locations.erase(locations.begin() + LocNo); for (LocMap::iterator I = locInts.begin(); I.valid(); ++I) { - DbgValueLocation Loc = I.value(); - if (!Loc.isUndef() && Loc.locNo() > LocNo) - I.setValueUnchecked(Loc.changeLocNo(Loc.locNo() - 1)); + DbgVariableValue DbgValue = I.value(); + if (!DbgValue.isUndef() && DbgValue.getLocNo() > LocNo) + I.setValueUnchecked(DbgValue.changeLocNo(DbgValue.getLocNo() - 1)); } } /// Ensure that all virtual register locations are mapped. void mapVirtRegs(LDVImpl *LDV); - /// Add a definition point to this value. - void addDef(SlotIndex Idx, const MachineOperand &LocMO) { - DbgValueLocation Loc(getLocationNo(LocMO)); - // Add a singular (Idx,Idx) -> Loc mapping. + /// Add a definition point to this user value. + void addDef(SlotIndex Idx, const MachineOperand &LocMO, bool IsIndirect, + const DIExpression &Expr) { + DbgVariableValue DbgValue(getLocationNo(LocMO), IsIndirect, Expr); + // Add a singular (Idx,Idx) -> value mapping. LocMap::iterator I = locInts.find(Idx); if (!I.valid() || I.start() != Idx) - I.insert(Idx, Idx.getNextSlot(), Loc); + I.insert(Idx, Idx.getNextSlot(), DbgValue); else // A later DBG_VALUE at the same SlotIndex overrides the old location. - I.setValue(Loc); + I.setValue(DbgValue); } /// Extend the current definition as far as possible down. @@ -299,28 +302,27 @@ public: /// data-flow analysis to propagate them beyond basic block boundaries. /// /// \param Idx Starting point for the definition. - /// \param Loc Location number to propagate. + /// \param DbgValue value to propagate. /// \param LR Restrict liveness to where LR has the value VNI. May be null. /// \param VNI When LR is not null, this is the value to restrict to. /// \param [out] Kills Append end points of VNI's live range to Kills. /// \param LIS Live intervals analysis. - void extendDef(SlotIndex Idx, DbgValueLocation Loc, - LiveRange *LR, const VNInfo *VNI, - SmallVectorImpl<SlotIndex> *Kills, + void extendDef(SlotIndex Idx, DbgVariableValue DbgValue, LiveRange *LR, + const VNInfo *VNI, SmallVectorImpl<SlotIndex> *Kills, LiveIntervals &LIS); - /// The value in LI/LocNo may be copies to other registers. Determine if + /// The value in LI may be copies to other registers. Determine if /// any of the copies are available at the kill points, and add defs if /// possible. /// /// \param LI Scan for copies of the value in LI->reg. - /// \param LocNo Location number of LI->reg. - /// \param Kills Points where the range of LocNo could be extended. - /// \param [in,out] NewDefs Append (Idx, LocNo) of inserted defs here. + /// \param DbgValue Location number of LI->reg, and DIExpression. + /// \param Kills Points where the range of DbgValue could be extended. + /// \param [in,out] NewDefs Append (Idx, DbgValue) of inserted defs here. void addDefsFromCopies( - LiveInterval *LI, unsigned LocNo, + LiveInterval *LI, DbgVariableValue DbgValue, const SmallVectorImpl<SlotIndex> &Kills, - SmallVectorImpl<std::pair<SlotIndex, DbgValueLocation>> &NewDefs, + SmallVectorImpl<std::pair<SlotIndex, DbgVariableValue>> &NewDefs, MachineRegisterInfo &MRI, LiveIntervals &LIS); /// Compute the live intervals of all locations after collecting all their @@ -330,7 +332,7 @@ public: /// Replace OldReg ranges with NewRegs ranges where NewRegs is /// live. Returns true if any changes were made. - bool splitRegister(unsigned OldReg, ArrayRef<unsigned> NewRegs, + bool splitRegister(Register OldReg, ArrayRef<Register> NewRegs, LiveIntervals &LIS); /// Rewrite virtual register locations according to the provided virtual @@ -370,7 +372,7 @@ public: : Label(label), dl(std::move(L)), loc(Idx) {} /// Does this UserLabel match the parameters? - bool match(const DILabel *L, const DILocation *IA, + bool matches(const DILabel *L, const DILocation *IA, const SlotIndex Index) const { return Label == L && dl->getInlinedAt() == IA && loc == Index; } @@ -408,16 +410,17 @@ class LDVImpl { using VRMap = DenseMap<unsigned, UserValue *>; VRMap virtRegToEqClass; - /// Map user variable to eq class leader. - using UVMap = DenseMap<const DILocalVariable *, UserValue *>; + /// Map to find existing UserValue instances. + using UVMap = DenseMap<DebugVariable, UserValue *>; UVMap userVarMap; /// Find or create a UserValue. - UserValue *getUserValue(const DILocalVariable *Var, const DIExpression *Expr, + UserValue *getUserValue(const DILocalVariable *Var, + Optional<DIExpression::FragmentInfo> Fragment, const DebugLoc &DL); /// Find the EC leader for VirtReg or null. - UserValue *lookupVirtReg(unsigned VirtReg); + UserValue *lookupVirtReg(Register VirtReg); /// Add DBG_VALUE instruction to our maps. /// @@ -467,10 +470,10 @@ public: } /// Map virtual register to an equivalence class. - void mapVirtReg(unsigned VirtReg, UserValue *EC); + void mapVirtReg(Register VirtReg, UserValue *EC); /// Replace all references to OldReg with NewRegs. - void splitRegister(unsigned OldReg, ArrayRef<unsigned> NewRegs); + void splitRegister(Register OldReg, ArrayRef<Register> NewRegs); /// Recreate DBG_VALUE instruction from data structures. void emitDebugValues(VirtRegMap *VRM); @@ -537,7 +540,9 @@ void UserValue::print(raw_ostream &OS, const TargetRegisterInfo *TRI) { if (I.value().isUndef()) OS << "undef"; else { - OS << I.value().locNo(); + OS << I.value().getLocNo(); + if (I.value().getWasIndirect()) + OS << " ind"; } } for (unsigned i = 0, e = locations.size(); i != e; ++i) { @@ -574,30 +579,27 @@ void UserValue::mapVirtRegs(LDVImpl *LDV) { } UserValue *LDVImpl::getUserValue(const DILocalVariable *Var, - const DIExpression *Expr, const DebugLoc &DL) { - UserValue *&Leader = userVarMap[Var]; - if (Leader) { - UserValue *UV = Leader->getLeader(); - Leader = UV; - for (; UV; UV = UV->getNext()) - if (UV->match(Var, Expr, DL->getInlinedAt())) - return UV; + Optional<DIExpression::FragmentInfo> Fragment, + const DebugLoc &DL) { + // FIXME: Handle partially overlapping fragments. See + // https://reviews.llvm.org/D70121#1849741. + DebugVariable ID(Var, Fragment, DL->getInlinedAt()); + UserValue *&UV = userVarMap[ID]; + if (!UV) { + userValues.push_back( + std::make_unique<UserValue>(Var, Fragment, DL, allocator)); + UV = userValues.back().get(); } - - userValues.push_back( - std::make_unique<UserValue>(Var, Expr, DL, allocator)); - UserValue *UV = userValues.back().get(); - Leader = UserValue::merge(Leader, UV); return UV; } -void LDVImpl::mapVirtReg(unsigned VirtReg, UserValue *EC) { +void LDVImpl::mapVirtReg(Register VirtReg, UserValue *EC) { assert(Register::isVirtualRegister(VirtReg) && "Only map VirtRegs"); UserValue *&Leader = virtRegToEqClass[VirtReg]; Leader = UserValue::merge(Leader, EC); } -UserValue *LDVImpl::lookupVirtReg(unsigned VirtReg) { +UserValue *LDVImpl::lookupVirtReg(Register VirtReg) { if (UserValue *UV = virtRegToEqClass.lookup(VirtReg)) return UV->getLeader(); return nullptr; @@ -606,8 +608,8 @@ UserValue *LDVImpl::lookupVirtReg(unsigned VirtReg) { bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) { // DBG_VALUE loc, offset, variable if (MI.getNumOperands() != 4 || - !(MI.getOperand(1).isReg() || MI.getOperand(1).isImm()) || - !MI.getOperand(2).isMetadata()) { + !(MI.getDebugOffset().isReg() || MI.getDebugOffset().isImm()) || + !MI.getDebugVariableOp().isMetadata()) { LLVM_DEBUG(dbgs() << "Can't handle " << MI); return false; } @@ -620,9 +622,9 @@ bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) { // (and if the machine verifier is improved to catch this), then these checks // could be removed or replaced by asserts. bool Discard = false; - if (MI.getOperand(0).isReg() && - Register::isVirtualRegister(MI.getOperand(0).getReg())) { - const Register Reg = MI.getOperand(0).getReg(); + if (MI.getDebugOperand(0).isReg() && + Register::isVirtualRegister(MI.getDebugOperand(0).getReg())) { + const Register Reg = MI.getDebugOperand(0).getReg(); if (!LIS->hasInterval(Reg)) { // The DBG_VALUE is described by a virtual register that does not have a // live interval. Discard the DBG_VALUE. @@ -646,18 +648,19 @@ bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) { } // Get or create the UserValue for (variable,offset) here. - assert(!MI.getOperand(1).isImm() && "DBG_VALUE with indirect flag before " - "LiveDebugVariables"); + bool IsIndirect = MI.isDebugOffsetImm(); + if (IsIndirect) + assert(MI.getDebugOffset().getImm() == 0 && + "DBG_VALUE with nonzero offset"); const DILocalVariable *Var = MI.getDebugVariable(); const DIExpression *Expr = MI.getDebugExpression(); - UserValue *UV = - getUserValue(Var, Expr, MI.getDebugLoc()); + UserValue *UV = getUserValue(Var, Expr->getFragmentInfo(), MI.getDebugLoc()); if (!Discard) - UV->addDef(Idx, MI.getOperand(0)); + UV->addDef(Idx, MI.getDebugOperand(0), IsIndirect, *Expr); else { MachineOperand MO = MachineOperand::CreateReg(0U, false); MO.setIsDebug(); - UV->addDef(Idx, MO); + UV->addDef(Idx, MO, false, *Expr); } return true; } @@ -674,7 +677,7 @@ bool LDVImpl::handleDebugLabel(MachineInstr &MI, SlotIndex Idx) { const DebugLoc &DL = MI.getDebugLoc(); bool Found = false; for (auto const &L : userLabels) { - if (L->match(Label, DL->getInlinedAt(), Idx)) { + if (L->matches(Label, DL->getInlinedAt(), Idx)) { Found = true; break; } @@ -720,7 +723,7 @@ bool LDVImpl::collectDebugValues(MachineFunction &mf) { return Changed; } -void UserValue::extendDef(SlotIndex Idx, DbgValueLocation Loc, LiveRange *LR, +void UserValue::extendDef(SlotIndex Idx, DbgVariableValue DbgValue, LiveRange *LR, const VNInfo *VNI, SmallVectorImpl<SlotIndex> *Kills, LiveIntervals &LIS) { SlotIndex Start = Idx; @@ -747,7 +750,7 @@ void UserValue::extendDef(SlotIndex Idx, DbgValueLocation Loc, LiveRange *LR, if (I.valid() && I.start() <= Start) { // Stop when meeting a different location or an already extended interval. Start = Start.getNextSlot(); - if (I.value() != Loc || I.stop() != Start) + if (I.value() != DbgValue || I.stop() != Start) return; // This is a one-slot placeholder. Just skip it. ++I; @@ -761,13 +764,13 @@ void UserValue::extendDef(SlotIndex Idx, DbgValueLocation Loc, LiveRange *LR, Kills->push_back(Stop); if (Start < Stop) - I.insert(Start, Stop, Loc); + I.insert(Start, Stop, DbgValue); } void UserValue::addDefsFromCopies( - LiveInterval *LI, unsigned LocNo, + LiveInterval *LI, DbgVariableValue DbgValue, const SmallVectorImpl<SlotIndex> &Kills, - SmallVectorImpl<std::pair<SlotIndex, DbgValueLocation>> &NewDefs, + SmallVectorImpl<std::pair<SlotIndex, DbgVariableValue>> &NewDefs, MachineRegisterInfo &MRI, LiveIntervals &LIS) { if (Kills.empty()) return; @@ -791,11 +794,11 @@ void UserValue::addDefsFromCopies( if (!Register::isVirtualRegister(DstReg)) continue; - // Is LocNo extended to reach this copy? If not, another def may be blocking - // it, or we are looking at a wrong value of LI. + // Is the value extended to reach this copy? If not, another def may be + // blocking it, or we are looking at a wrong value of LI. SlotIndex Idx = LIS.getInstructionIndex(*MI); LocMap::iterator I = locInts.find(Idx.getRegSlot(true)); - if (!I.valid() || I.value().locNo() != LocNo) + if (!I.valid() || I.value() != DbgValue) continue; if (!LIS.hasInterval(DstReg)) @@ -829,9 +832,9 @@ void UserValue::addDefsFromCopies( MachineInstr *CopyMI = LIS.getInstructionFromIndex(DstVNI->def); assert(CopyMI && CopyMI->isCopy() && "Bad copy value"); unsigned LocNo = getLocationNo(CopyMI->getOperand(0)); - DbgValueLocation NewLoc(LocNo); - I.insert(Idx, Idx.getNextSlot(), NewLoc); - NewDefs.push_back(std::make_pair(Idx, NewLoc)); + DbgVariableValue NewValue = DbgValue.changeLocNo(LocNo); + I.insert(Idx, Idx.getNextSlot(), NewValue); + NewDefs.push_back(std::make_pair(Idx, NewValue)); break; } } @@ -840,7 +843,7 @@ void UserValue::addDefsFromCopies( void UserValue::computeIntervals(MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, LiveIntervals &LIS, LexicalScopes &LS) { - SmallVector<std::pair<SlotIndex, DbgValueLocation>, 16> Defs; + SmallVector<std::pair<SlotIndex, DbgVariableValue>, 16> Defs; // Collect all defs to be extended (Skipping undefs). for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I) @@ -850,11 +853,11 @@ void UserValue::computeIntervals(MachineRegisterInfo &MRI, // Extend all defs, and possibly add new ones along the way. for (unsigned i = 0; i != Defs.size(); ++i) { SlotIndex Idx = Defs[i].first; - DbgValueLocation Loc = Defs[i].second; - const MachineOperand &LocMO = locations[Loc.locNo()]; + DbgVariableValue DbgValue = Defs[i].second; + const MachineOperand &LocMO = locations[DbgValue.getLocNo()]; if (!LocMO.isReg()) { - extendDef(Idx, Loc, nullptr, nullptr, nullptr, LIS); + extendDef(Idx, DbgValue, nullptr, nullptr, nullptr, LIS); continue; } @@ -867,7 +870,7 @@ void UserValue::computeIntervals(MachineRegisterInfo &MRI, VNI = LI->getVNInfoAt(Idx); } SmallVector<SlotIndex, 16> Kills; - extendDef(Idx, Loc, LI, VNI, &Kills, LIS); + extendDef(Idx, DbgValue, LI, VNI, &Kills, LIS); // FIXME: Handle sub-registers in addDefsFromCopies. The problem is that // if the original location for example is %vreg0:sub_hi, and we find a // full register copy in addDefsFromCopies (at the moment it only handles @@ -877,7 +880,7 @@ void UserValue::computeIntervals(MachineRegisterInfo &MRI, // sub-register in that regclass). For now, simply skip handling copies if // a sub-register is involved. if (LI && !LocMO.getSubReg()) - addDefsFromCopies(LI, Loc.locNo(), Kills, Defs, MRI, LIS); + addDefsFromCopies(LI, DbgValue, Kills, Defs, MRI, LIS); continue; } @@ -910,11 +913,16 @@ void UserValue::computeIntervals(MachineRegisterInfo &MRI, SlotIndex RStart = LIS.getInstructionIndex(*Range.first); SlotIndex REnd = LIS.getInstructionIndex(*Range.second); + // Variable locations at the first instruction of a block should be + // based on the block's SlotIndex, not the first instruction's index. + if (Range.first == Range.first->getParent()->begin()) + RStart = LIS.getSlotIndexes()->getIndexBefore(*Range.first); + // At the start of each iteration I has been advanced so that // I.stop() >= PrevEnd. Check for overlap. if (PrevEnd && I.start() < PrevEnd) { SlotIndex IStop = I.stop(); - DbgValueLocation Loc = I.value(); + DbgVariableValue DbgValue = I.value(); // Stop overlaps previous end - trim the end of the interval to // the scope range. @@ -922,9 +930,10 @@ void UserValue::computeIntervals(MachineRegisterInfo &MRI, ++I; // If the interval also overlaps the start of the "next" (i.e. - // current) range create a new interval for the remainder + // current) range create a new interval for the remainder (which + // may be further trimmed). if (RStart < IStop) - I.insert(RStart, IStop, Loc); + I.insert(RStart, IStop, DbgValue); } // Advance I so that I.stop() >= RStart, and check for overlap. @@ -932,6 +941,13 @@ void UserValue::computeIntervals(MachineRegisterInfo &MRI, if (!I.valid()) return; + if (I.start() < RStart) { + // Interval start overlaps range - trim to the scope range. + I.setStartUnchecked(RStart); + // Remember that this interval was trimmed. + trimmedDefs.insert(RStart); + } + // The end of a lexical scope range is the last instruction in the // range. To convert to an interval we need the index of the // instruction after it. @@ -1014,7 +1030,7 @@ LiveDebugVariables::~LiveDebugVariables() { //===----------------------------------------------------------------------===// bool -UserValue::splitLocation(unsigned OldLocNo, ArrayRef<unsigned> NewRegs, +UserValue::splitLocation(unsigned OldLocNo, ArrayRef<Register> NewRegs, LiveIntervals& LIS) { LLVM_DEBUG({ dbgs() << "Splitting Loc" << OldLocNo << '\t'; @@ -1044,7 +1060,8 @@ UserValue::splitLocation(unsigned OldLocNo, ArrayRef<unsigned> NewRegs, break; // Now LII->end > LocMapI.start(). Do we have an overlap? - if (LocMapI.value().locNo() == OldLocNo && LII->start < LocMapI.stop()) { + if (LocMapI.value().getLocNo() == OldLocNo && + LII->start < LocMapI.stop()) { // Overlapping correct location. Allocate NewLocNo now. if (NewLocNo == UndefLocNo) { MachineOperand MO = MachineOperand::CreateReg(LI->reg, false); @@ -1054,8 +1071,8 @@ UserValue::splitLocation(unsigned OldLocNo, ArrayRef<unsigned> NewRegs, } SlotIndex LStart = LocMapI.start(); - SlotIndex LStop = LocMapI.stop(); - DbgValueLocation OldLoc = LocMapI.value(); + SlotIndex LStop = LocMapI.stop(); + DbgVariableValue OldDbgValue = LocMapI.value(); // Trim LocMapI down to the LII overlap. if (LStart < LII->start) @@ -1064,17 +1081,17 @@ UserValue::splitLocation(unsigned OldLocNo, ArrayRef<unsigned> NewRegs, LocMapI.setStopUnchecked(LII->end); // Change the value in the overlap. This may trigger coalescing. - LocMapI.setValue(OldLoc.changeLocNo(NewLocNo)); + LocMapI.setValue(OldDbgValue.changeLocNo(NewLocNo)); - // Re-insert any removed OldLocNo ranges. + // Re-insert any removed OldDbgValue ranges. if (LStart < LocMapI.start()) { - LocMapI.insert(LStart, LocMapI.start(), OldLoc); + LocMapI.insert(LStart, LocMapI.start(), OldDbgValue); ++LocMapI; assert(LocMapI.valid() && "Unexpected coalescing"); } if (LStop > LocMapI.stop()) { ++LocMapI; - LocMapI.insert(LII->end, LStop, OldLoc); + LocMapI.insert(LII->end, LStop, OldDbgValue); --LocMapI; } } @@ -1100,6 +1117,9 @@ UserValue::splitLocation(unsigned OldLocNo, ArrayRef<unsigned> NewRegs, // register to the spill slot). So for a while we can have locations that map // to virtual registers that have been removed from both the MachineFunction // and from LiveIntervals. + // + // We may also just be using the location for a value with a different + // expression. removeLocationIfUnused(OldLocNo); LLVM_DEBUG({ @@ -1110,7 +1130,7 @@ UserValue::splitLocation(unsigned OldLocNo, ArrayRef<unsigned> NewRegs, } bool -UserValue::splitRegister(unsigned OldReg, ArrayRef<unsigned> NewRegs, +UserValue::splitRegister(Register OldReg, ArrayRef<Register> NewRegs, LiveIntervals &LIS) { bool DidChange = false; // Split locations referring to OldReg. Iterate backwards so splitLocation can @@ -1125,7 +1145,7 @@ UserValue::splitRegister(unsigned OldReg, ArrayRef<unsigned> NewRegs, return DidChange; } -void LDVImpl::splitRegister(unsigned OldReg, ArrayRef<unsigned> NewRegs) { +void LDVImpl::splitRegister(Register OldReg, ArrayRef<Register> NewRegs) { bool DidChange = false; for (UserValue *UV = lookupVirtReg(OldReg); UV; UV = UV->getNext()) DidChange |= UV->splitRegister(OldReg, NewRegs, *LIS); @@ -1140,7 +1160,7 @@ void LDVImpl::splitRegister(unsigned OldReg, ArrayRef<unsigned> NewRegs) { } void LiveDebugVariables:: -splitRegister(unsigned OldReg, ArrayRef<unsigned> NewRegs, LiveIntervals &LIS) { +splitRegister(Register OldReg, ArrayRef<Register> NewRegs, LiveIntervals &LIS) { if (pImpl) static_cast<LDVImpl*>(pImpl)->splitRegister(OldReg, NewRegs); } @@ -1218,13 +1238,13 @@ void UserValue::rewriteLocations(VirtRegMap &VRM, const MachineFunction &MF, // DBG_VALUE intervals with different vregs that were allocated to the same // physical register. for (LocMap::iterator I = locInts.begin(); I.valid(); ++I) { - DbgValueLocation Loc = I.value(); + DbgVariableValue DbgValue = I.value(); // Undef values don't exist in locations (and thus not in LocNoMap either) // so skip over them. See getLocationNo(). - if (Loc.isUndef()) + if (DbgValue.isUndef()) continue; - unsigned NewLocNo = LocNoMap[Loc.locNo()]; - I.setValueUnchecked(Loc.changeLocNo(NewLocNo)); + unsigned NewLocNo = LocNoMap[DbgValue.getLocNo()]; + I.setValueUnchecked(DbgValue.changeLocNo(NewLocNo)); I.setStart(I.start()); } } @@ -1278,7 +1298,7 @@ findNextInsertLocation(MachineBasicBlock *MBB, } void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx, - SlotIndex StopIdx, DbgValueLocation Loc, + SlotIndex StopIdx, DbgVariableValue DbgValue, bool Spilled, unsigned SpillOffset, LiveIntervals &LIS, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI) { @@ -1288,12 +1308,14 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx, MachineBasicBlock::iterator I = findInsertLocation(MBB, StartIdx, LIS); // Undef values don't exist in locations so create new "noreg" register MOs // for them. See getLocationNo(). - MachineOperand MO = !Loc.isUndef() ? - locations[Loc.locNo()] : - MachineOperand::CreateReg(/* Reg */ 0, /* isDef */ false, /* isImp */ false, - /* isKill */ false, /* isDead */ false, - /* isUndef */ false, /* isEarlyClobber */ false, - /* SubReg */ 0, /* isDebug */ true); + MachineOperand MO = + !DbgValue.isUndef() + ? locations[DbgValue.getLocNo()] + : MachineOperand::CreateReg( + /* Reg */ 0, /* isDef */ false, /* isImp */ false, + /* isKill */ false, /* isDead */ false, + /* isUndef */ false, /* isEarlyClobber */ false, + /* SubReg */ 0, /* isDebug */ true); ++NumInsertedDebugValues; @@ -1305,15 +1327,22 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx, // original DBG_VALUE was indirect, we need to add DW_OP_deref to indicate // that the original virtual register was a pointer. Also, add the stack slot // offset for the spilled register to the expression. - const DIExpression *Expr = Expression; - if (Spilled) - Expr = DIExpression::prepend(Expr, DIExpression::ApplyOffset, SpillOffset); + const DIExpression *Expr = DbgValue.getExpression(); + uint8_t DIExprFlags = DIExpression::ApplyOffset; + bool IsIndirect = DbgValue.getWasIndirect(); + if (Spilled) { + if (IsIndirect) + DIExprFlags |= DIExpression::DerefAfter; + Expr = + DIExpression::prepend(Expr, DIExprFlags, SpillOffset); + IsIndirect = true; + } assert((!Spilled || MO.isFI()) && "a spilled location must be a frame index"); do { BuildMI(*MBB, I, getDebugLoc(), TII.get(TargetOpcode::DBG_VALUE), - Spilled, MO, Variable, Expr); + IsIndirect, MO, Variable, Expr); // Continue and insert DBG_VALUES after every redefinition of register // associated with the debug value within the range @@ -1339,19 +1368,26 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS, for (LocMap::const_iterator I = locInts.begin(); I.valid();) { SlotIndex Start = I.start(); SlotIndex Stop = I.stop(); - DbgValueLocation Loc = I.value(); - auto SpillIt = - !Loc.isUndef() ? SpillOffsets.find(Loc.locNo()) : SpillOffsets.end(); + DbgVariableValue DbgValue = I.value(); + auto SpillIt = !DbgValue.isUndef() ? SpillOffsets.find(DbgValue.getLocNo()) + : SpillOffsets.end(); bool Spilled = SpillIt != SpillOffsets.end(); unsigned SpillOffset = Spilled ? SpillIt->second : 0; - LLVM_DEBUG(dbgs() << "\t[" << Start << ';' << Stop << "):" << Loc.locNo()); + // If the interval start was trimmed to the lexical scope insert the + // DBG_VALUE at the previous index (otherwise it appears after the + // first instruction in the range). + if (trimmedDefs.count(Start)) + Start = Start.getPrevIndex(); + + LLVM_DEBUG(dbgs() << "\t[" << Start << ';' << Stop + << "):" << DbgValue.getLocNo()); MachineFunction::iterator MBB = LIS.getMBBFromIndex(Start)->getIterator(); SlotIndex MBBEnd = LIS.getMBBEndIdx(&*MBB); LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB) << '-' << MBBEnd); - insertDebugValue(&*MBB, Start, Stop, Loc, Spilled, SpillOffset, LIS, TII, - TRI); + insertDebugValue(&*MBB, Start, Stop, DbgValue, Spilled, SpillOffset, LIS, + TII, TRI); // This interval may span multiple basic blocks. // Insert a DBG_VALUE into each one. while (Stop > MBBEnd) { @@ -1361,8 +1397,8 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS, break; MBBEnd = LIS.getMBBEndIdx(&*MBB); LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB) << '-' << MBBEnd); - insertDebugValue(&*MBB, Start, Stop, Loc, Spilled, SpillOffset, LIS, TII, - TRI); + insertDebugValue(&*MBB, Start, Stop, DbgValue, Spilled, SpillOffset, LIS, + TII, TRI); } LLVM_DEBUG(dbgs() << '\n'); if (MBB == MFEnd) |