LLVM  9.0.0svn
DbgEntityHistoryCalculator.cpp
Go to the documentation of this file.
1 //===- llvm/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "llvm/ADT/BitVector.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/SmallSet.h"
13 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/IR/DebugLoc.h"
23 #include "llvm/MC/MCRegisterInfo.h"
24 #include "llvm/Support/Debug.h"
26 #include <cassert>
27 #include <map>
28 #include <utility>
29 
30 using namespace llvm;
31 
32 #define DEBUG_TYPE "dwarfdebug"
33 
34 namespace {
35 using EntryIndex = DbgValueHistoryMap::EntryIndex;
36 }
37 
38 // If @MI is a DBG_VALUE with debug value described by a
39 // defined register, returns the number of this register.
40 // In the other case, returns 0.
41 static unsigned isDescribedByReg(const MachineInstr &MI) {
42  assert(MI.isDebugValue());
43  assert(MI.getNumOperands() == 4);
44  // If location of variable is described using a register (directly or
45  // indirectly), this register is always a first operand.
46  return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0;
47 }
48 
50  const MachineInstr &MI,
51  EntryIndex &NewIndex) {
52  // Instruction range should start with a DBG_VALUE instruction for the
53  // variable.
54  assert(MI.isDebugValue() && "not a DBG_VALUE");
55  auto &Entries = VarEntries[Var];
56  if (!Entries.empty() && Entries.back().isDbgValue() &&
57  !Entries.back().isClosed() &&
58  Entries.back().getInstr()->isIdenticalTo(MI)) {
59  LLVM_DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n"
60  << "\t" << Entries.back().getInstr() << "\t" << MI
61  << "\n");
62  return false;
63  }
64  Entries.emplace_back(&MI, Entry::DbgValue);
65  NewIndex = Entries.size() - 1;
66  return true;
67 }
68 
70  const MachineInstr &MI) {
71  auto &Entries = VarEntries[Var];
72  // If an instruction clobbers multiple registers that the variable is
73  // described by, then we may have already created a clobbering instruction.
74  if (Entries.back().isClobber() && Entries.back().getInstr() == &MI)
75  return Entries.size() - 1;
76  Entries.emplace_back(&MI, Entry::Clobber);
77  return Entries.size() - 1;
78 }
79 
81  // For now, instruction ranges are not allowed to cross basic block
82  // boundaries.
83  assert(isDbgValue() && "Setting end index for non-debug value");
84  assert(!isClosed() && "End index has already been set");
85  EndIndex = Index;
86 }
87 
89  assert(MI.isDebugLabel() && "not a DBG_LABEL");
90  LabelInstr[Label] = &MI;
91 }
92 
93 namespace {
94 
95 // Maps physreg numbers to the variables they describe.
97 using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedEntity, 1>>;
98 
99 // Keeps track of the debug value entries that are currently live for each
100 // inlined entity. As the history map entries are stored in a SmallVector, they
101 // may be moved at insertion of new entries, so store indices rather than
102 // pointers.
103 using DbgValueEntriesMap = std::map<InlinedEntity, SmallSet<EntryIndex, 1>>;
104 
105 } // end anonymous namespace
106 
107 // Claim that @Var is not described by @RegNo anymore.
108 static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
109  InlinedEntity Var) {
110  const auto &I = RegVars.find(RegNo);
111  assert(RegNo != 0U && I != RegVars.end());
112  auto &VarSet = I->second;
113  const auto &VarPos = llvm::find(VarSet, Var);
114  assert(VarPos != VarSet.end());
115  VarSet.erase(VarPos);
116  // Don't keep empty sets in a map to keep it as small as possible.
117  if (VarSet.empty())
118  RegVars.erase(I);
119 }
120 
121 // Claim that @Var is now described by @RegNo.
122 static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
123  InlinedEntity Var) {
124  assert(RegNo != 0U);
125  auto &VarSet = RegVars[RegNo];
126  assert(!is_contained(VarSet, Var));
127  VarSet.push_back(Var);
128 }
129 
130 /// Create a clobbering entry and end all open debug value entries
131 /// for \p Var that are described by \p RegNo using that entry.
132 static void clobberRegEntries(InlinedEntity Var, unsigned RegNo,
133  const MachineInstr &ClobberingInstr,
134  DbgValueEntriesMap &LiveEntries,
135  DbgValueHistoryMap &HistMap) {
136  EntryIndex ClobberIndex = HistMap.startClobber(Var, ClobberingInstr);
137 
138  // Close all entries whose values are described by the register.
139  SmallVector<EntryIndex, 4> IndicesToErase;
140  for (auto Index : LiveEntries[Var]) {
141  auto &Entry = HistMap.getEntry(Var, Index);
142  assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries");
143  if (isDescribedByReg(*Entry.getInstr()) == RegNo) {
144  IndicesToErase.push_back(Index);
145  Entry.endEntry(ClobberIndex);
146  }
147  }
148 
149  // Drop all entries that have ended.
150  for (auto Index : IndicesToErase)
151  LiveEntries[Var].erase(Index);
152 }
153 
154 /// Add a new debug value for \p Var. Closes all overlapping debug values.
155 static void handleNewDebugValue(InlinedEntity Var, const MachineInstr &DV,
156  RegDescribedVarsMap &RegVars,
157  DbgValueEntriesMap &LiveEntries,
158  DbgValueHistoryMap &HistMap) {
159  EntryIndex NewIndex;
160  if (HistMap.startDbgValue(Var, DV, NewIndex)) {
162 
163  // If we have created a new debug value entry, close all preceding
164  // live entries that overlap.
165  SmallVector<EntryIndex, 4> IndicesToErase;
166  const DIExpression *DIExpr = DV.getDebugExpression();
167  for (auto Index : LiveEntries[Var]) {
168  auto &Entry = HistMap.getEntry(Var, Index);
169  assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries");
170  const MachineInstr &DV = *Entry.getInstr();
171  bool Overlaps = DIExpr->fragmentsOverlap(DV.getDebugExpression());
172  if (Overlaps) {
173  IndicesToErase.push_back(Index);
174  Entry.endEntry(NewIndex);
175  }
176  if (unsigned Reg = isDescribedByReg(DV))
177  TrackedRegs[Reg] |= !Overlaps;
178  }
179 
180  // If the new debug value is described by a register, add tracking of
181  // that register if it is not already tracked.
182  if (unsigned NewReg = isDescribedByReg(DV)) {
183  if (!TrackedRegs.count(NewReg))
184  addRegDescribedVar(RegVars, NewReg, Var);
185  LiveEntries[Var].insert(NewIndex);
186  TrackedRegs[NewReg] = true;
187  }
188 
189  // Drop tracking of registers that are no longer used.
190  for (auto I : TrackedRegs)
191  if (!I.second)
192  dropRegDescribedVar(RegVars, I.first, Var);
193 
194  // Drop all entries that have ended, and mark the new entry as live.
195  for (auto Index : IndicesToErase)
196  LiveEntries[Var].erase(Index);
197  LiveEntries[Var].insert(NewIndex);
198  }
199 }
200 
201 // Terminate the location range for variables described by register at
202 // @I by inserting @ClobberingInstr to their history.
203 static void clobberRegisterUses(RegDescribedVarsMap &RegVars,
204  RegDescribedVarsMap::iterator I,
205  DbgValueHistoryMap &HistMap,
206  DbgValueEntriesMap &LiveEntries,
207  const MachineInstr &ClobberingInstr) {
208  // Iterate over all variables described by this register and add this
209  // instruction to their history, clobbering it.
210  for (const auto &Var : I->second)
211  clobberRegEntries(Var, I->first, ClobberingInstr, LiveEntries, HistMap);
212  RegVars.erase(I);
213 }
214 
215 // Terminate the location range for variables described by register
216 // @RegNo by inserting @ClobberingInstr to their history.
217 static void clobberRegisterUses(RegDescribedVarsMap &RegVars, unsigned RegNo,
218  DbgValueHistoryMap &HistMap,
219  DbgValueEntriesMap &LiveEntries,
220  const MachineInstr &ClobberingInstr) {
221  const auto &I = RegVars.find(RegNo);
222  if (I == RegVars.end())
223  return;
224  clobberRegisterUses(RegVars, I, HistMap, LiveEntries, ClobberingInstr);
225 }
226 
228  const TargetRegisterInfo *TRI,
229  DbgValueHistoryMap &DbgValues,
230  DbgLabelInstrMap &DbgLabels) {
231  const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
232  unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
233  unsigned FrameReg = TRI->getFrameRegister(*MF);
234  RegDescribedVarsMap RegVars;
235  DbgValueEntriesMap LiveEntries;
236  for (const auto &MBB : *MF) {
237  for (const auto &MI : MBB) {
238  if (MI.isDebugValue()) {
239  assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!");
240  // Use the base variable (without any DW_OP_piece expressions)
241  // as index into History. The full variables including the
242  // piece expressions are attached to the MI.
243  const DILocalVariable *RawVar = MI.getDebugVariable();
244  assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
245  "Expected inlined-at fields to agree");
246  InlinedEntity Var(RawVar, MI.getDebugLoc()->getInlinedAt());
247 
248  handleNewDebugValue(Var, MI, RegVars, LiveEntries, DbgValues);
249  } else if (MI.isDebugLabel()) {
250  assert(MI.getNumOperands() == 1 && "Invalid DBG_LABEL instruction!");
251  const DILabel *RawLabel = MI.getDebugLabel();
252  assert(RawLabel->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
253  "Expected inlined-at fields to agree");
254  // When collecting debug information for labels, there is no MCSymbol
255  // generated for it. So, we keep MachineInstr in DbgLabels in order
256  // to query MCSymbol afterward.
257  InlinedEntity L(RawLabel, MI.getDebugLoc()->getInlinedAt());
258  DbgLabels.addInstr(L, MI);
259  }
260 
261  if (MI.isDebugInstr())
262  continue;
263 
264  // Not a DBG_VALUE instruction. It may clobber registers which describe
265  // some variables.
266  for (const MachineOperand &MO : MI.operands()) {
267  if (MO.isReg() && MO.isDef() && MO.getReg()) {
268  // Ignore call instructions that claim to clobber SP. The AArch64
269  // backend does this for aggregate function arguments.
270  if (MI.isCall() && MO.getReg() == SP)
271  continue;
272  // If this is a virtual register, only clobber it since it doesn't
273  // have aliases.
274  if (TRI->isVirtualRegister(MO.getReg()))
275  clobberRegisterUses(RegVars, MO.getReg(), DbgValues, LiveEntries,
276  MI);
277  // If this is a register def operand, it may end a debug value
278  // range. Ignore frame-register defs in the epilogue and prologue,
279  // we expect debuggers to understand that stack-locations are
280  // invalid outside of the function body.
281  else if (MO.getReg() != FrameReg ||
282  (!MI.getFlag(MachineInstr::FrameDestroy) &&
283  !MI.getFlag(MachineInstr::FrameSetup))) {
284  for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
285  ++AI)
286  clobberRegisterUses(RegVars, *AI, DbgValues, LiveEntries, MI);
287  }
288  } else if (MO.isRegMask()) {
289  // If this is a register mask operand, clobber all debug values in
290  // non-CSRs.
291  SmallVector<unsigned, 32> RegsToClobber;
292  // Don't consider SP to be clobbered by register masks.
293  for (auto It : RegVars) {
294  unsigned int Reg = It.first;
295  if (Reg != SP && TRI->isPhysicalRegister(Reg) &&
296  MO.clobbersPhysReg(Reg))
297  RegsToClobber.push_back(Reg);
298  }
299 
300  for (unsigned Reg : RegsToClobber) {
301  clobberRegisterUses(RegVars, Reg, DbgValues, LiveEntries, MI);
302  }
303  }
304  } // End MO loop.
305  } // End instr loop.
306 
307  // Make sure locations for all variables are valid only until the end of
308  // the basic block (unless it's the last basic block, in which case let
309  // their liveness run off to the end of the function).
310  if (!MBB.empty() && &MBB != &MF->back()) {
311  // Iterate over all variables that have open debug values.
312  for (auto &Pair : LiveEntries) {
313  if (Pair.second.empty())
314  continue;
315 
316  // Create a clobbering entry.
317  EntryIndex ClobIdx = DbgValues.startClobber(Pair.first, MBB.back());
318 
319  // End all entries.
320  for (EntryIndex Idx : Pair.second) {
321  DbgValueHistoryMap::Entry &Ent = DbgValues.getEntry(Pair.first, Idx);
322  assert(Ent.isDbgValue() && !Ent.isClosed());
323  Ent.endEntry(ClobIdx);
324  }
325  }
326 
327  LiveEntries.clear();
328  RegVars.clear();
329  }
330  }
331 }
332 
333 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
335  dbgs() << "DbgValueHistoryMap:\n";
336  for (const auto &VarRangePair : *this) {
337  const InlinedEntity &Var = VarRangePair.first;
338  const Entries &Entries = VarRangePair.second;
339 
340  const DILocalVariable *LocalVar = cast<DILocalVariable>(Var.first);
341  const DILocation *Location = Var.second;
342 
343  dbgs() << " - " << LocalVar->getName() << " at ";
344 
345  if (Location)
346  dbgs() << Location->getFilename() << ":" << Location->getLine() << ":"
347  << Location->getColumn();
348  else
349  dbgs() << "<unknown location>";
350 
351  dbgs() << " --\n";
352 
353  for (const auto &E : enumerate(Entries)) {
354  const auto &Entry = E.value();
355  dbgs() << " Entry[" << E.index() << "]: ";
356  if (Entry.isDbgValue())
357  dbgs() << "Debug value\n";
358  else
359  dbgs() << "Clobber\n";
360  dbgs() << " Instr: " << *Entry.getInstr();
361  if (Entry.isDbgValue()) {
362  if (Entry.getEndIndex() == NoEntry)
363  dbgs() << " - Valid until end of function\n";
364  else
365  dbgs() << " - Closed by Entry[" << Entry.getEndIndex() << "]\n";
366  }
367  dbgs() << "\n";
368  }
369  }
370 }
371 #endif
For each inlined instance of a source-level label, keep the corresponding DBG_LABEL instruction...
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:641
bool isDebugLabel() const
static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, InlinedEntity Var)
static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B)
Check if fragments overlap between a pair of FragmentInfos.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Definition: Compiler.h:473
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned Reg
virtual const TargetLowering * getTargetLowering() const
unsigned const TargetRegisterInfo * TRI
For each user variable, keep a list of instruction ranges where this variable is accessible.
void calculateDbgEntityHistory(const MachineFunction *MF, const TargetRegisterInfo *TRI, DbgValueHistoryMap &DbgValues, DbgLabelInstrMap &DbgLabels)
std::pair< const DINode *, const DILocation * > InlinedEntity
StringRef getName() const
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:413
static void clobberRegEntries(InlinedEntity Var, unsigned RegNo, const MachineInstr &ClobberingInstr, DbgValueEntriesMap &LiveEntries, DbgValueHistoryMap &HistMap)
Create a clobbering entry and end all open debug value entries for Var that are described by RegNo us...
static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, InlinedEntity Var)
virtual unsigned getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
size_t EntryIndex
Index in the entry vector.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Debug location.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Specifies a change in a variable&#39;s debug value history.
MCRegAliasIterator enumerates all registers aliasing Reg.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
size_t size() const
Definition: SmallVector.h:52
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1213
static unsigned isDescribedByReg(const MachineInstr &MI)
const DIExpression * getDebugExpression() const
Return the complex address expression referenced by this DBG_VALUE instruction.
std::pair< const DINode *, const DILocation * > InlinedEntity
void addInstr(InlinedEntity Label, const MachineInstr &MI)
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
DWARF expression.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
static cl::opt< bool > NoEntry("spp-no-entry", cl::Hidden, cl::init(false))
Representation of each machine instruction.
Definition: MachineInstr.h:63
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
#define I(x, y, z)
Definition: MD5.cpp:58
Entry & getEntry(InlinedEntity Var, EntryIndex Index)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:171
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
static void clobberRegisterUses(RegDescribedVarsMap &RegVars, RegDescribedVarsMap::iterator I, DbgValueHistoryMap &HistMap, DbgValueEntriesMap &LiveEntries, const MachineInstr &ClobberingInstr)
IRTranslator LLVM IR MI
const MachineInstr * getInstr() const
#define LLVM_DEBUG(X)
Definition: Debug.h:122
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:415
bool startDbgValue(InlinedEntity Var, const MachineInstr &MI, EntryIndex &NewIndex)
LLVM_DUMP_METHOD void dump() const
EntryIndex startClobber(InlinedEntity Var, const MachineInstr &MI)
detail::enumerator< R > enumerate(R &&TheRange)
Given an input range, returns a new range whose values are are pair (A,B) such that A is the 0-based ...
Definition: STLExtras.h:1578
This file describes how to lower LLVM code to machine code.
static void handleNewDebugValue(InlinedEntity Var, const MachineInstr &DV, RegDescribedVarsMap &RegVars, DbgValueEntriesMap &LiveEntries, DbgValueHistoryMap &HistMap)
Add a new debug value for Var. Closes all overlapping debug values.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1251