diff options
Diffstat (limited to 'lib/CodeGen/LiveDebugVariables.cpp')
| -rw-r--r-- | lib/CodeGen/LiveDebugVariables.cpp | 181 | 
1 files changed, 138 insertions, 43 deletions
diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index d0d889782a35..656ec7d4bdfd 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -1,9 +1,8 @@  //===- 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception  //  //===----------------------------------------------------------------------===//  // @@ -23,6 +22,7 @@  #include "llvm/ADT/ArrayRef.h"  #include "llvm/ADT/DenseMap.h"  #include "llvm/ADT/IntervalMap.h" +#include "llvm/ADT/MapVector.h"  #include "llvm/ADT/STLExtras.h"  #include "llvm/ADT/SmallSet.h"  #include "llvm/ADT/SmallVector.h" @@ -71,6 +71,7 @@ EnableLDV("live-debug-variables", cl::init(true),            cl::desc("Enable the live debug variables pass"), cl::Hidden);  STATISTIC(NumInsertedDebugValues, "Number of DBG_VALUEs inserted"); +STATISTIC(NumInsertedDebugLabels, "Number of DBG_LABELs inserted");  char LiveDebugVariables::ID = 0; @@ -166,10 +167,6 @@ class UserValue {    /// Map of slot indices where this value is live.    LocMap locInts; -  /// 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 LocNo.    void insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,                          SlotIndex StopIdx, DbgValueLocation Loc, bool Spilled, @@ -339,6 +336,37 @@ public:    void print(raw_ostream &, const TargetRegisterInfo *);  }; +/// A user label is a part of a debug info user label. +class UserLabel { +  const DILabel *Label; ///< The debug info label we are part of. +  DebugLoc dl;          ///< The debug location for the label. This is +                        ///< used by dwarf writer to find lexical scope. +  SlotIndex loc;        ///< Slot used by the debug label. + +  /// Insert a DBG_LABEL into MBB at Idx. +  void insertDebugLabel(MachineBasicBlock *MBB, SlotIndex Idx, +                        LiveIntervals &LIS, const TargetInstrInfo &TII); + +public: +  /// Create a new UserLabel. +  UserLabel(const DILabel *label, DebugLoc L, SlotIndex Idx) +      : Label(label), dl(std::move(L)), loc(Idx) {} + +  /// Does this UserLabel match the parameters? +  bool match(const DILabel *L, const DILocation *IA, +             const SlotIndex Index) const { +    return Label == L && dl->getInlinedAt() == IA && loc == Index; +  } + +  /// Recreate DBG_LABEL instruction from data structures. +  void emitDebugLabel(LiveIntervals &LIS, const TargetInstrInfo &TII); + +  /// Return DebugLoc of this UserLabel. +  DebugLoc getDebugLoc() { return dl; } + +  void print(raw_ostream &, const TargetRegisterInfo *); +}; +  /// Implementation of the LiveDebugVariables pass.  class LDVImpl {    LiveDebugVariables &pass; @@ -356,6 +384,9 @@ class LDVImpl {    /// All allocated UserValue instances.    SmallVector<std::unique_ptr<UserValue>, 8> userValues; +  /// All allocated UserLabel instances. +  SmallVector<std::unique_ptr<UserLabel>, 2> userLabels; +    /// Map virtual register to eq class leader.    using VRMap = DenseMap<unsigned, UserValue *>;    VRMap virtRegToEqClass; @@ -379,6 +410,14 @@ class LDVImpl {    /// \returns True if the DBG_VALUE instruction should be deleted.    bool handleDebugValue(MachineInstr &MI, SlotIndex Idx); +  /// Add DBG_LABEL instruction to UserLabel. +  /// +  /// \param MI DBG_LABEL instruction +  /// \param Idx Last valid SlotIndex before instruction. +  /// +  /// \returns True if the DBG_LABEL instruction should be deleted. +  bool handleDebugLabel(MachineInstr &MI, SlotIndex Idx); +    /// Collect and erase all DBG_VALUE instructions, adding a UserValue def    /// for each instruction.    /// @@ -400,6 +439,7 @@ public:    void clear() {      MF = nullptr;      userValues.clear(); +    userLabels.clear();      virtRegToEqClass.clear();      userVarMap.clear();      // Make sure we call emitDebugValues if the machine function was modified. @@ -445,13 +485,23 @@ static void printDebugLoc(const DebugLoc &DL, raw_ostream &CommentOS,    CommentOS << " ]";  } -static void printExtendedName(raw_ostream &OS, const DILocalVariable *V, +static void printExtendedName(raw_ostream &OS, const DINode *Node,                                const DILocation *DL) { -  const LLVMContext &Ctx = V->getContext(); -  StringRef Res = V->getName(); +  const LLVMContext &Ctx = Node->getContext(); +  StringRef Res; +  unsigned Line; +  if (const auto *V = dyn_cast<const DILocalVariable>(Node)) { +    Res = V->getName(); +    Line = V->getLine(); +  } else if (const auto *L = dyn_cast<const DILabel>(Node)) { +    Res = L->getName(); +    Line = L->getLine(); +  } +    if (!Res.empty()) -    OS << Res << "," << V->getLine(); -  if (auto *InlinedAt = DL->getInlinedAt()) { +    OS << Res << "," << Line; +  auto *InlinedAt = DL ? DL->getInlinedAt() : nullptr; +  if (InlinedAt) {      if (DebugLoc InlinedAtDL = InlinedAt) {        OS << " @[";        printDebugLoc(InlinedAtDL, OS, Ctx); @@ -461,9 +511,8 @@ static void printExtendedName(raw_ostream &OS, const DILocalVariable *V,  }  void UserValue::print(raw_ostream &OS, const TargetRegisterInfo *TRI) { -  auto *DV = cast<DILocalVariable>(Variable);    OS << "!\""; -  printExtendedName(OS, DV, dl); +  printExtendedName(OS, Variable, dl);    OS << "\"\t";    for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I) { @@ -483,10 +532,22 @@ void UserValue::print(raw_ostream &OS, const TargetRegisterInfo *TRI) {    OS << '\n';  } +void UserLabel::print(raw_ostream &OS, const TargetRegisterInfo *TRI) { +  OS << "!\""; +  printExtendedName(OS, Label, dl); + +  OS << "\"\t"; +  OS << loc; +  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); +  for (auto &userValue : userValues) +    userValue->print(OS, TRI); +  OS << "********** DEBUG LABELS **********\n"; +  for (auto &userLabel : userLabels) +    userLabel->print(OS, TRI);  }  #endif @@ -556,7 +617,7 @@ bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) {      } else {        // The DBG_VALUE is only valid if either Reg is live out from Idx, or Reg        // is defined dead at Idx (where Idx is the slot index for the instruction -      // preceeding the DBG_VALUE). +      // preceding the DBG_VALUE).        const LiveInterval &LI = LIS->getInterval(Reg);        LiveQueryResult LRQ = LI.Query(Idx);        if (!LRQ.valueOutOrDead()) { @@ -587,6 +648,29 @@ bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) {    return true;  } +bool LDVImpl::handleDebugLabel(MachineInstr &MI, SlotIndex Idx) { +  // DBG_LABEL label +  if (MI.getNumOperands() != 1 || !MI.getOperand(0).isMetadata()) { +    LLVM_DEBUG(dbgs() << "Can't handle " << MI); +    return false; +  } + +  // Get or create the UserLabel for label here. +  const DILabel *Label = MI.getDebugLabel(); +  const DebugLoc &DL = MI.getDebugLoc(); +  bool Found = false; +  for (auto const &L : userLabels) { +    if (L->match(Label, DL->getInlinedAt(), Idx)) { +      Found = true; +      break; +    } +  } +  if (!Found) +    userLabels.push_back(llvm::make_unique<UserLabel>(Label, DL, Idx)); + +  return true; +} +  bool LDVImpl::collectDebugValues(MachineFunction &mf) {    bool Changed = false;    for (MachineFunction::iterator MFI = mf.begin(), MFE = mf.end(); MFI != MFE; @@ -610,7 +694,8 @@ bool LDVImpl::collectDebugValues(MachineFunction &mf) {        do {          // Only handle DBG_VALUE in handleDebugValue(). Skip all other          // kinds of debug instructions. -        if (MBBI->isDebugValue() && handleDebugValue(*MBBI, Idx)) { +        if ((MBBI->isDebugValue() && handleDebugValue(*MBBI, Idx)) || +            (MBBI->isDebugLabel() && handleDebugLabel(*MBBI, Idx))) {            MBBI = MBB->erase(MBBI);            Changed = true;          } else @@ -655,10 +740,8 @@ void UserValue::extendDef(SlotIndex Idx, DbgValueLocation Loc, LiveRange *LR,    }    // Limited by the next def. -  if (I.valid() && I.start() < Stop) { +  if (I.valid() && I.start() < Stop)      Stop = I.start(); -    ToEnd = false; -  }    // Limited by VNI's live range.    else if (!ToEnd && Kills)      Kills->push_back(Stop); @@ -826,8 +909,7 @@ 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 (which -      // may be further trimmed). +      // current) range create a new interval for the remainder        if (RStart < IStop)          I.insert(RStart, IStop, Loc);      } @@ -837,13 +919,6 @@ 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. @@ -1227,11 +1302,13 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,    // 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; +  uint8_t DIExprFlags = DIExpression::ApplyOffset;    bool IsIndirect = Loc.wasIndirect();    if (Spilled) { -    auto Deref = IsIndirect ? DIExpression::WithDeref : DIExpression::NoDeref; +    if (IsIndirect) +      DIExprFlags |= DIExpression::DerefAfter;      Expr = -        DIExpression::prepend(Expr, DIExpression::NoDeref, SpillOffset, Deref); +        DIExpression::prepend(Expr, DIExprFlags, SpillOffset);      IsIndirect = true;    } @@ -1247,6 +1324,15 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,    } while (I != MBB->end());  } +void UserLabel::insertDebugLabel(MachineBasicBlock *MBB, SlotIndex Idx, +                                 LiveIntervals &LIS, +                                 const TargetInstrInfo &TII) { +  MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, LIS); +  ++NumInsertedDebugLabels; +  BuildMI(*MBB, I, getDebugLoc(), TII.get(TargetOpcode::DBG_LABEL)) +      .addMetadata(Label); +} +  void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,                                  const TargetInstrInfo &TII,                                  const TargetRegisterInfo &TRI, @@ -1262,12 +1348,6 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,      bool Spilled = SpillIt != SpillOffsets.end();      unsigned SpillOffset = Spilled ? SpillIt->second : 0; -    // 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 << "):" << Loc.locNo());      MachineFunction::iterator MBB = LIS.getMBBFromIndex(Start)->getIterator();      SlotIndex MBBEnd = LIS.getMBBEndIdx(&*MBB); @@ -1295,16 +1375,31 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,    }  } +void UserLabel::emitDebugLabel(LiveIntervals &LIS, const TargetInstrInfo &TII) { +  LLVM_DEBUG(dbgs() << "\t" << loc); +  MachineFunction::iterator MBB = LIS.getMBBFromIndex(loc)->getIterator(); + +  LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB)); +  insertDebugLabel(&*MBB, loc, LIS, TII); + +  LLVM_DEBUG(dbgs() << '\n'); +} +  void LDVImpl::emitDebugValues(VirtRegMap *VRM) {    LLVM_DEBUG(dbgs() << "********** EMITTING LIVE DEBUG VARIABLES **********\n");    if (!MF)      return;    const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();    SpillOffsetMap SpillOffsets; -  for (unsigned i = 0, e = userValues.size(); i != e; ++i) { -    LLVM_DEBUG(userValues[i]->print(dbgs(), TRI)); -    userValues[i]->rewriteLocations(*VRM, *MF, *TII, *TRI, SpillOffsets); -    userValues[i]->emitDebugValues(VRM, *LIS, *TII, *TRI, SpillOffsets); +  for (auto &userValue : userValues) { +    LLVM_DEBUG(userValue->print(dbgs(), TRI)); +    userValue->rewriteLocations(*VRM, *MF, *TII, *TRI, SpillOffsets); +    userValue->emitDebugValues(VRM, *LIS, *TII, *TRI, SpillOffsets); +  } +  LLVM_DEBUG(dbgs() << "********** EMITTING LIVE DEBUG LABELS **********\n"); +  for (auto &userLabel : userLabels) { +    LLVM_DEBUG(userLabel->print(dbgs(), TRI)); +    userLabel->emitDebugLabel(*LIS, *TII);    }    EmitDone = true;  }  | 
