diff options
author | Shiva Chen <shiva0217@gmail.com> | 2018-07-24 02:22:55 +0000 |
---|---|---|
committer | Shiva Chen <shiva0217@gmail.com> | 2018-07-24 02:22:55 +0000 |
commit | d6b2cdf9d4053ade22ad58379df7d12389ba3d1b (patch) | |
tree | 802f38b9edce3762f105845980436dc48fd74af0 /llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | |
parent | b7f19e6d1e7be2f0607d401b166b5e5355bd3dd1 (diff) | |
download | bcm5719-llvm-d6b2cdf9d4053ade22ad58379df7d12389ba3d1b.tar.gz bcm5719-llvm-d6b2cdf9d4053ade22ad58379df7d12389ba3d1b.zip |
[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
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 88 |
1 files changed, 62 insertions, 26 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index cf941a920c5..b77a9214342 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -502,6 +502,18 @@ DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) { return D; } +DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL, + const LexicalScope &Scope) { + auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag()); + insertDIE(DL.getLabel(), LabelDie); + DL.setDIE(*LabelDie); + + if (Scope.isAbstractScope()) + applyLabelAttributes(DL, *LabelDie); + + return LabelDie; +} + DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, bool Abstract) { // Define variable debug information entry. @@ -692,6 +704,9 @@ DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope, if (HasNonScopeChildren) *HasNonScopeChildren = !Children.empty(); + for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope)) + Children.push_back(constructLabelDIE(*DL, *Scope)); + for (LexicalScope *LS : Scope->getChildren()) constructScopeDIE(LS, Children); @@ -817,40 +832,52 @@ void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) { } } -void DwarfCompileUnit::finishVariableDefinition(const DbgVariable &Var) { - DbgVariable *AbsVar = getExistingAbstractVariable( - InlinedVariable(Var.getVariable(), Var.getInlinedAt())); - auto *VariableDie = Var.getDIE(); - if (AbsVar && AbsVar->getDIE()) { - addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin, - *AbsVar->getDIE()); - } else - applyVariableAttributes(Var, *VariableDie); -} +void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) { + DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity()); -DbgVariable *DwarfCompileUnit::getExistingAbstractVariable(InlinedVariable IV) { - const DILocalVariable *Cleansed; - return getExistingAbstractVariable(IV, Cleansed); + auto *Die = Entity->getDIE(); + /// Label may be used to generate DW_AT_low_pc, so put it outside + /// if/else block. + const DbgLabel *Label = nullptr; + if (AbsEntity && AbsEntity->getDIE()) { + addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE()); + Label = dyn_cast<const DbgLabel>(Entity); + } else { + if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity)) + applyVariableAttributes(*Var, *Die); + else if ((Label = dyn_cast<const DbgLabel>(Entity))) + applyLabelAttributes(*Label, *Die); + else + llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel."); + } + + if (Label) { + const MCSymbol *Sym = Label->getSymbol(); + addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym); + } } -// Find abstract variable, if any, associated with Var. -DbgVariable *DwarfCompileUnit::getExistingAbstractVariable( - InlinedVariable IV, const DILocalVariable *&Cleansed) { - // More then one inlined variable corresponds to one abstract variable. - Cleansed = IV.first; - auto &AbstractVariables = getAbstractVariables(); - auto I = AbstractVariables.find(Cleansed); - if (I != AbstractVariables.end()) +DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) { + auto &AbstractEntities = getAbstractEntities(); + auto I = AbstractEntities.find(Node); + if (I != AbstractEntities.end()) return I->second.get(); return nullptr; } -void DwarfCompileUnit::createAbstractVariable(const DILocalVariable *Var, - LexicalScope *Scope) { +void DwarfCompileUnit::createAbstractEntity(const DINode *Node, + LexicalScope *Scope) { assert(Scope && Scope->isAbstractScope()); - auto AbsDbgVariable = llvm::make_unique<DbgVariable>(Var, /* IA */ nullptr); - DU->addScopeVariable(Scope, AbsDbgVariable.get()); - getAbstractVariables()[Var] = std::move(AbsDbgVariable); + auto &Entity = getAbstractEntities()[Node]; + if (isa<const DILocalVariable>(Node)) { + Entity = llvm::make_unique<DbgVariable>( + cast<const DILocalVariable>(Node), nullptr /* IA */);; + DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get())); + } else if (isa<const DILabel>(Node)) { + Entity = llvm::make_unique<DbgLabel>( + cast<const DILabel>(Node), nullptr /* IA */); + DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get())); + } } void DwarfCompileUnit::emitHeader(bool UseOffsets) { @@ -1005,6 +1032,15 @@ void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var, addFlag(VariableDie, dwarf::DW_AT_artificial); } +void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label, + DIE &LabelDie) { + StringRef Name = Label.getName(); + if (!Name.empty()) + addString(LabelDie, dwarf::DW_AT_name, Name); + const auto *DILabel = Label.getLabel(); + addSourceLine(LabelDie, DILabel); +} + /// Add a Dwarf expression attribute data and value. void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr) { |