Skip to content

Commit d6b2cdf

Browse files
committed
[DebugInfo] Generate DWARF debug information for labels.
There are two forms for label debug information in DWARF format. 1. Labels in a non-inlined function: DW_TAG_label DW_AT_name DW_AT_decl_file DW_AT_decl_line DW_AT_low_pc 2. Labels in an inlined function: DW_TAG_label DW_AT_abstract_origin DW_AT_low_pc We will collect label information from DBG_LABEL. Before every DBG_LABEL, we will generate a temporary symbol to denote the location of the label. The symbol could be used to get DW_AT_low_pc afterwards. So, we create a mapping between 'inlined label' and DBG_LABEL MachineInstr in DebugHandlerBase. The DBG_LABEL in the mapping is used to query the symbol before it. The AbstractLabels in DwarfCompileUnit is used to process labels in inlined functions. We also keep a mapping between scope and labels in DwarfFile to help to generate correct tree structure of DIEs. Differential Revision: https://reviews.llvm.org/D45556 Patch by Hsiangkai Wang. llvm-svn: 337799
1 parent b7f19e6 commit d6b2cdf

18 files changed

+514
-152
lines changed

llvm/include/llvm/IR/InstVisitor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ class InstVisitor {
213213
// Handle the special instrinsic instruction classes.
214214
RetTy visitDbgDeclareInst(DbgDeclareInst &I) { DELEGATE(DbgInfoIntrinsic);}
215215
RetTy visitDbgValueInst(DbgValueInst &I) { DELEGATE(DbgInfoIntrinsic);}
216-
RetTy visitDbgLabelInst(DbgLabelInst &I) { DELEGATE(DbgInfoIntrinsic);}
216+
RetTy visitDbgLabelInst(DbgLabelInst &I) { DELEGATE(IntrinsicInst);}
217217
RetTy visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) { DELEGATE(IntrinsicInst); }
218218
RetTy visitMemSetInst(MemSetInst &I) { DELEGATE(MemIntrinsic); }
219219
RetTy visitMemCpyInst(MemCpyInst &I) { DELEGATE(MemTransferInst); }

llvm/include/llvm/IR/IntrinsicInst.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ namespace llvm {
104104
case Intrinsic::dbg_declare:
105105
case Intrinsic::dbg_value:
106106
case Intrinsic::dbg_addr:
107-
case Intrinsic::dbg_label:
108107
return true;
109108
default: return false;
110109
}
@@ -165,7 +164,7 @@ namespace llvm {
165164
};
166165

167166
/// This represents the llvm.dbg.label instruction.
168-
class DbgLabelInst : public DbgInfoIntrinsic {
167+
class DbgLabelInst : public IntrinsicInst {
169168
public:
170169
DILabel *getLabel() const {
171170
return cast<DILabel>(getRawVariable());

llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ add_llvm_library(LLVMAsmPrinter
55
AsmPrinter.cpp
66
AsmPrinterDwarf.cpp
77
AsmPrinterInlineAsm.cpp
8-
DbgValueHistoryCalculator.cpp
8+
DbgEntityHistoryCalculator.cpp
99
DebugHandlerBase.cpp
1010
DebugLocStream.cpp
1111
DIE.cpp

llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
1515
#define LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
1616

17-
#include "DbgValueHistoryCalculator.h"
17+
#include "DbgEntityHistoryCalculator.h"
1818
#include "DebugHandlerBase.h"
1919
#include "llvm/ADT/ArrayRef.h"
2020
#include "llvm/ADT/DenseMap.h"

llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp renamed to llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp --------------===//
1+
//===- llvm/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp -------------===//
22
//
33
// The LLVM Compiler Infrastructure
44
//
@@ -7,7 +7,7 @@
77
//
88
//===----------------------------------------------------------------------===//
99

10-
#include "DbgValueHistoryCalculator.h"
10+
#include "DbgEntityHistoryCalculator.h"
1111
#include "llvm/ADT/BitVector.h"
1212
#include "llvm/ADT/STLExtras.h"
1313
#include "llvm/ADT/SmallVector.h"
@@ -78,11 +78,17 @@ unsigned DbgValueHistoryMap::getRegisterForVar(InlinedVariable Var) const {
7878
return isDescribedByReg(*Ranges.back().first);
7979
}
8080

81+
void DbgLabelInstrMap::addInstr(InlinedLabel Label, const MachineInstr &MI) {
82+
assert(MI.isDebugLabel() && "not a DBG_LABEL");
83+
LabelInstr[Label] = &MI;
84+
}
85+
8186
namespace {
8287

8388
// Maps physreg numbers to the variables they describe.
8489
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
8590
using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedVariable, 1>>;
91+
using InlinedLabel = DbgLabelInstrMap::InlinedLabel;
8692

8793
} // end anonymous namespace
8894

@@ -187,9 +193,10 @@ static void collectChangingRegs(const MachineFunction *MF,
187193
}
188194
}
189195

190-
void llvm::calculateDbgValueHistory(const MachineFunction *MF,
191-
const TargetRegisterInfo *TRI,
192-
DbgValueHistoryMap &Result) {
196+
void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
197+
const TargetRegisterInfo *TRI,
198+
DbgValueHistoryMap &DbgValues,
199+
DbgLabelInstrMap &DbgLabels) {
193200
BitVector ChangingRegs(TRI->getNumRegs());
194201
collectChangingRegs(MF, TRI, ChangingRegs);
195202

@@ -210,14 +217,14 @@ void llvm::calculateDbgValueHistory(const MachineFunction *MF,
210217
// If this is a virtual register, only clobber it since it doesn't
211218
// have aliases.
212219
if (TRI->isVirtualRegister(MO.getReg()))
213-
clobberRegisterUses(RegVars, MO.getReg(), Result, MI);
220+
clobberRegisterUses(RegVars, MO.getReg(), DbgValues, MI);
214221
// If this is a register def operand, it may end a debug value
215222
// range.
216223
else {
217224
for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
218225
++AI)
219226
if (ChangingRegs.test(*AI))
220-
clobberRegisterUses(RegVars, *AI, Result, MI);
227+
clobberRegisterUses(RegVars, *AI, DbgValues, MI);
221228
}
222229
} else if (MO.isRegMask()) {
223230
// If this is a register mask operand, clobber all debug values in
@@ -226,34 +233,42 @@ void llvm::calculateDbgValueHistory(const MachineFunction *MF,
226233
// Don't consider SP to be clobbered by register masks.
227234
if (unsigned(I) != SP && TRI->isPhysicalRegister(I) &&
228235
MO.clobbersPhysReg(I)) {
229-
clobberRegisterUses(RegVars, I, Result, MI);
236+
clobberRegisterUses(RegVars, I, DbgValues, MI);
230237
}
231238
}
232239
}
233240
}
234241
continue;
235242
}
236243

237-
// Skip DBG_LABEL instructions.
238-
if (MI.isDebugLabel())
239-
continue;
240-
241-
assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!");
242-
// Use the base variable (without any DW_OP_piece expressions)
243-
// as index into History. The full variables including the
244-
// piece expressions are attached to the MI.
245-
const DILocalVariable *RawVar = MI.getDebugVariable();
246-
assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
247-
"Expected inlined-at fields to agree");
248-
InlinedVariable Var(RawVar, MI.getDebugLoc()->getInlinedAt());
249-
250-
if (unsigned PrevReg = Result.getRegisterForVar(Var))
251-
dropRegDescribedVar(RegVars, PrevReg, Var);
252-
253-
Result.startInstrRange(Var, MI);
254-
255-
if (unsigned NewReg = isDescribedByReg(MI))
256-
addRegDescribedVar(RegVars, NewReg, Var);
244+
if (MI.isDebugValue()) {
245+
assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!");
246+
// Use the base variable (without any DW_OP_piece expressions)
247+
// as index into History. The full variables including the
248+
// piece expressions are attached to the MI.
249+
const DILocalVariable *RawVar = MI.getDebugVariable();
250+
assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
251+
"Expected inlined-at fields to agree");
252+
InlinedVariable Var(RawVar, MI.getDebugLoc()->getInlinedAt());
253+
254+
if (unsigned PrevReg = DbgValues.getRegisterForVar(Var))
255+
dropRegDescribedVar(RegVars, PrevReg, Var);
256+
257+
DbgValues.startInstrRange(Var, MI);
258+
259+
if (unsigned NewReg = isDescribedByReg(MI))
260+
addRegDescribedVar(RegVars, NewReg, Var);
261+
} else if (MI.isDebugLabel()) {
262+
assert(MI.getNumOperands() == 1 && "Invalid DBG_LABEL instruction!");
263+
const DILabel *RawLabel = MI.getDebugLabel();
264+
assert(RawLabel->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
265+
"Expected inlined-at fields to agree");
266+
// When collecting debug information for labels, there is no MCSymbol
267+
// generated for it. So, we keep MachineInstr in DbgLabels in order
268+
// to query MCSymbol afterward.
269+
InlinedLabel L(RawLabel, MI.getDebugLoc()->getInlinedAt());
270+
DbgLabels.addInstr(L, MI);
271+
}
257272
}
258273

259274
// Make sure locations for register-described variables are valid only
@@ -264,7 +279,7 @@ void llvm::calculateDbgValueHistory(const MachineFunction *MF,
264279
auto CurElem = I++; // CurElem can be erased below.
265280
if (TRI->isVirtualRegister(CurElem->first) ||
266281
ChangingRegs.test(CurElem->first))
267-
clobberRegisterUses(RegVars, CurElem, Result, MBB.back());
282+
clobberRegisterUses(RegVars, CurElem, DbgValues, MBB.back());
268283
}
269284
}
270285
}

llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h renamed to llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.h

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h ------*- C++ -*-===//
1+
//===- llvm/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.h -----*- C++ -*-===//
22
//
33
// The LLVM Compiler Infrastructure
44
//
@@ -58,9 +58,30 @@ class DbgValueHistoryMap {
5858
#endif
5959
};
6060

61-
void calculateDbgValueHistory(const MachineFunction *MF,
62-
const TargetRegisterInfo *TRI,
63-
DbgValueHistoryMap &Result);
61+
/// For each inlined instance of a source-level label, keep the corresponding
62+
/// DBG_LABEL instruction. The DBG_LABEL instruction could be used to generate
63+
/// a temporary (assembler) label before it.
64+
class DbgLabelInstrMap {
65+
public:
66+
using InlinedLabel = std::pair<const DILabel *, const DILocation *>;
67+
using InstrMap = MapVector<InlinedLabel, const MachineInstr *>;
68+
69+
private:
70+
InstrMap LabelInstr;
71+
72+
public:
73+
void addInstr(InlinedLabel Label, const MachineInstr &MI);
74+
75+
bool empty() const { return LabelInstr.empty(); }
76+
void clear() { LabelInstr.clear(); }
77+
InstrMap::const_iterator begin() const { return LabelInstr.begin(); }
78+
InstrMap::const_iterator end() const { return LabelInstr.end(); }
79+
};
80+
81+
void calculateDbgEntityHistory(const MachineFunction *MF,
82+
const TargetRegisterInfo *TRI,
83+
DbgValueHistoryMap &DbgValues,
84+
DbgLabelInstrMap &DbgLabels);
6485

6586
} // end namespace llvm
6687

llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,9 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
190190

191191
// Calculate history for local variables.
192192
assert(DbgValues.empty() && "DbgValues map wasn't cleaned!");
193-
calculateDbgValueHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
194-
DbgValues);
193+
assert(DbgLabels.empty() && "DbgLabels map wasn't cleaned!");
194+
calculateDbgEntityHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
195+
DbgValues, DbgLabels);
195196
LLVM_DEBUG(DbgValues.dump());
196197

197198
// Request labels for the full history.
@@ -229,6 +230,12 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
229230
}
230231
}
231232

233+
// Ensure there is a symbol before DBG_LABEL.
234+
for (const auto &I : DbgLabels) {
235+
const MachineInstr *MI = I.second;
236+
requestLabelBeforeInsn(MI);
237+
}
238+
232239
PrevInstLoc = DebugLoc();
233240
PrevLabel = Asm->getFunctionBegin();
234241
beginFunctionImpl(MF);
@@ -296,6 +303,7 @@ void DebugHandlerBase::endFunction(const MachineFunction *MF) {
296303
if (hasDebugInfo(MMI, MF))
297304
endFunctionImpl(MF);
298305
DbgValues.clear();
306+
DbgLabels.clear();
299307
LabelsBeforeInsn.clear();
300308
LabelsAfterInsn.clear();
301309
}

llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGHANDLERBASE_H
1717

1818
#include "AsmPrinterHandler.h"
19-
#include "DbgValueHistoryCalculator.h"
19+
#include "DbgEntityHistoryCalculator.h"
2020
#include "llvm/ADT/Optional.h"
2121
#include "llvm/CodeGen/LexicalScopes.h"
2222
#include "llvm/CodeGen/MachineInstr.h"
@@ -82,6 +82,9 @@ class DebugHandlerBase : public AsmPrinterHandler {
8282
/// variable. Variables are listed in order of appearance.
8383
DbgValueHistoryMap DbgValues;
8484

85+
/// Mapping of inlined labels and DBG_LABEL machine instruction.
86+
DbgLabelInstrMap DbgLabels;
87+
8588
/// Maps instruction with label emitted before instruction.
8689
/// FIXME: Make this private from DwarfDebug, we have the necessary accessors
8790
/// for it.

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,18 @@ DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {
502502
return D;
503503
}
504504

505+
DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL,
506+
const LexicalScope &Scope) {
507+
auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag());
508+
insertDIE(DL.getLabel(), LabelDie);
509+
DL.setDIE(*LabelDie);
510+
511+
if (Scope.isAbstractScope())
512+
applyLabelAttributes(DL, *LabelDie);
513+
514+
return LabelDie;
515+
}
516+
505517
DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
506518
bool Abstract) {
507519
// Define variable debug information entry.
@@ -692,6 +704,9 @@ DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope,
692704
if (HasNonScopeChildren)
693705
*HasNonScopeChildren = !Children.empty();
694706

707+
for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))
708+
Children.push_back(constructLabelDIE(*DL, *Scope));
709+
695710
for (LexicalScope *LS : Scope->getChildren())
696711
constructScopeDIE(LS, Children);
697712

@@ -817,40 +832,52 @@ void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
817832
}
818833
}
819834

820-
void DwarfCompileUnit::finishVariableDefinition(const DbgVariable &Var) {
821-
DbgVariable *AbsVar = getExistingAbstractVariable(
822-
InlinedVariable(Var.getVariable(), Var.getInlinedAt()));
823-
auto *VariableDie = Var.getDIE();
824-
if (AbsVar && AbsVar->getDIE()) {
825-
addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin,
826-
*AbsVar->getDIE());
827-
} else
828-
applyVariableAttributes(Var, *VariableDie);
829-
}
835+
void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
836+
DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity());
830837

831-
DbgVariable *DwarfCompileUnit::getExistingAbstractVariable(InlinedVariable IV) {
832-
const DILocalVariable *Cleansed;
833-
return getExistingAbstractVariable(IV, Cleansed);
838+
auto *Die = Entity->getDIE();
839+
/// Label may be used to generate DW_AT_low_pc, so put it outside
840+
/// if/else block.
841+
const DbgLabel *Label = nullptr;
842+
if (AbsEntity && AbsEntity->getDIE()) {
843+
addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());
844+
Label = dyn_cast<const DbgLabel>(Entity);
845+
} else {
846+
if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity))
847+
applyVariableAttributes(*Var, *Die);
848+
else if ((Label = dyn_cast<const DbgLabel>(Entity)))
849+
applyLabelAttributes(*Label, *Die);
850+
else
851+
llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");
852+
}
853+
854+
if (Label) {
855+
const MCSymbol *Sym = Label->getSymbol();
856+
addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);
857+
}
834858
}
835859

836-
// Find abstract variable, if any, associated with Var.
837-
DbgVariable *DwarfCompileUnit::getExistingAbstractVariable(
838-
InlinedVariable IV, const DILocalVariable *&Cleansed) {
839-
// More then one inlined variable corresponds to one abstract variable.
840-
Cleansed = IV.first;
841-
auto &AbstractVariables = getAbstractVariables();
842-
auto I = AbstractVariables.find(Cleansed);
843-
if (I != AbstractVariables.end())
860+
DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {
861+
auto &AbstractEntities = getAbstractEntities();
862+
auto I = AbstractEntities.find(Node);
863+
if (I != AbstractEntities.end())
844864
return I->second.get();
845865
return nullptr;
846866
}
847867

848-
void DwarfCompileUnit::createAbstractVariable(const DILocalVariable *Var,
849-
LexicalScope *Scope) {
868+
void DwarfCompileUnit::createAbstractEntity(const DINode *Node,
869+
LexicalScope *Scope) {
850870
assert(Scope && Scope->isAbstractScope());
851-
auto AbsDbgVariable = llvm::make_unique<DbgVariable>(Var, /* IA */ nullptr);
852-
DU->addScopeVariable(Scope, AbsDbgVariable.get());
853-
getAbstractVariables()[Var] = std::move(AbsDbgVariable);
871+
auto &Entity = getAbstractEntities()[Node];
872+
if (isa<const DILocalVariable>(Node)) {
873+
Entity = llvm::make_unique<DbgVariable>(
874+
cast<const DILocalVariable>(Node), nullptr /* IA */);;
875+
DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get()));
876+
} else if (isa<const DILabel>(Node)) {
877+
Entity = llvm::make_unique<DbgLabel>(
878+
cast<const DILabel>(Node), nullptr /* IA */);
879+
DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get()));
880+
}
854881
}
855882

856883
void DwarfCompileUnit::emitHeader(bool UseOffsets) {
@@ -1005,6 +1032,15 @@ void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var,
10051032
addFlag(VariableDie, dwarf::DW_AT_artificial);
10061033
}
10071034

1035+
void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label,
1036+
DIE &LabelDie) {
1037+
StringRef Name = Label.getName();
1038+
if (!Name.empty())
1039+
addString(LabelDie, dwarf::DW_AT_name, Name);
1040+
const auto *DILabel = Label.getLabel();
1041+
addSourceLine(LabelDie, DILabel);
1042+
}
1043+
10081044
/// Add a Dwarf expression attribute data and value.
10091045
void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
10101046
const MCExpr *Expr) {

0 commit comments

Comments
 (0)