summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
diff options
context:
space:
mode:
authorHsiangkai Wang <hsiangkai@gmail.com>2018-08-14 13:50:59 +0000
committerHsiangkai Wang <hsiangkai@gmail.com>2018-08-14 13:50:59 +0000
commitccae278938ac2925aea9892d43ee83415c44598f (patch)
treef2e1ca91500f85e7035579ca0a973d42a27a1337 /llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
parent5bd88cf7ddc3342c1a17578aa550e21383b4d079 (diff)
downloadbcm5719-llvm-ccae278938ac2925aea9892d43ee83415c44598f.tar.gz
bcm5719-llvm-ccae278938ac2925aea9892d43ee83415c44598f.zip
[DebugInfo] Generate DWARF debug information for labels. (Fix leak problems)
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. It also generates label debug information under global isel. Differential Revision: https://reviews.llvm.org/D45556 llvm-svn: 339676
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h137
1 files changed, 110 insertions, 27 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index abf2e43b131..e314f8e17d6 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -15,7 +15,7 @@
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H
#include "AddressPool.h"
-#include "DbgValueHistoryCalculator.h"
+#include "DbgEntityHistoryCalculator.h"
#include "DebugHandlerBase.h"
#include "DebugLocStream.h"
#include "DwarfFile.h"
@@ -62,6 +62,47 @@ class MDNode;
class Module;
//===----------------------------------------------------------------------===//
+/// This class is defined as the common parent of DbgVariable and DbgLabel
+/// such that it could levarage polymorphism to extract common code for
+/// DbgVariable and DbgLabel.
+class DbgEntity {
+ const DINode *Entity;
+ const DILocation *InlinedAt;
+ DIE *TheDIE = nullptr;
+ unsigned SubclassID;
+
+public:
+ enum DbgEntityKind {
+ DbgVariableKind,
+ DbgLabelKind
+ };
+
+ DbgEntity(const DINode *N, const DILocation *IA, unsigned ID)
+ : Entity(N), InlinedAt(IA), SubclassID(ID) {}
+ virtual ~DbgEntity() {}
+
+ /// Accessors.
+ /// @{
+ const DINode *getEntity() const { return Entity; }
+ const DILocation *getInlinedAt() const { return InlinedAt; }
+ DIE *getDIE() const { return TheDIE; }
+ unsigned getDbgEntityID() const { return SubclassID; }
+ /// @}
+
+ void setDIE(DIE &D) { TheDIE = &D; }
+
+ static bool classof(const DbgEntity *N) {
+ switch (N->getDbgEntityID()) {
+ default:
+ return false;
+ case DbgVariableKind:
+ case DbgLabelKind:
+ return true;
+ }
+ }
+};
+
+//===----------------------------------------------------------------------===//
/// This class is used to track local variable information.
///
/// Variables can be created from allocas, in which case they're generated from
@@ -73,10 +114,7 @@ class Module;
/// single instruction use \a MInsn and (optionally) a single entry of \a Expr.
///
/// Variables that have been optimized out use none of these fields.
-class DbgVariable {
- const DILocalVariable *Var; /// Variable Descriptor.
- const DILocation *IA; /// Inlined at location.
- DIE *TheDIE = nullptr; /// Variable DIE.
+class DbgVariable : public DbgEntity {
unsigned DebugLocListIndex = ~0u; /// Offset in DebugLocs.
const MachineInstr *MInsn = nullptr; /// DBG_VALUE instruction.
@@ -93,7 +131,7 @@ public:
/// Creates a variable without any DW_AT_location. Call \a initializeMMI()
/// for MMI entries, or \a initializeDbgValue() for DBG_VALUE instructions.
DbgVariable(const DILocalVariable *V, const DILocation *IA)
- : Var(V), IA(IA) {}
+ : DbgEntity(V, IA, DbgVariableKind) {}
/// Initialize from the MMI table.
void initializeMMI(const DIExpression *E, int FI) {
@@ -111,8 +149,9 @@ public:
assert(FrameIndexExprs.empty() && "Already initialized?");
assert(!MInsn && "Already initialized?");
- assert(Var == DbgValue->getDebugVariable() && "Wrong variable");
- assert(IA == DbgValue->getDebugLoc()->getInlinedAt() && "Wrong inlined-at");
+ assert(getVariable() == DbgValue->getDebugVariable() && "Wrong variable");
+ assert(getInlinedAt() == DbgValue->getDebugLoc()->getInlinedAt() &&
+ "Wrong inlined-at");
MInsn = DbgValue;
if (auto *E = DbgValue->getDebugExpression())
@@ -121,19 +160,18 @@ public:
}
// Accessors.
- const DILocalVariable *getVariable() const { return Var; }
- const DILocation *getInlinedAt() const { return IA; }
+ const DILocalVariable *getVariable() const {
+ return cast<DILocalVariable>(getEntity());
+ }
const DIExpression *getSingleExpression() const {
assert(MInsn && FrameIndexExprs.size() <= 1);
return FrameIndexExprs.size() ? FrameIndexExprs[0].Expr : nullptr;
}
- void setDIE(DIE &D) { TheDIE = &D; }
- DIE *getDIE() const { return TheDIE; }
void setDebugLocListIndex(unsigned O) { DebugLocListIndex = O; }
unsigned getDebugLocListIndex() const { return DebugLocListIndex; }
- StringRef getName() const { return Var->getName(); }
+ StringRef getName() const { return getVariable()->getName(); }
const MachineInstr *getMInsn() const { return MInsn; }
/// Get the FI entries, sorted by fragment offset.
ArrayRef<FrameIndexExpr> getFrameIndexExprs() const;
@@ -143,7 +181,7 @@ public:
// Translate tag to proper Dwarf tag.
dwarf::Tag getTag() const {
// FIXME: Why don't we just infer this tag and store it all along?
- if (Var->isParameter())
+ if (getVariable()->isParameter())
return dwarf::DW_TAG_formal_parameter;
return dwarf::DW_TAG_variable;
@@ -151,7 +189,7 @@ public:
/// Return true if DbgVariable is artificial.
bool isArtificial() const {
- if (Var->isArtificial())
+ if (getVariable()->isArtificial())
return true;
if (getType()->isArtificial())
return true;
@@ -159,7 +197,7 @@ public:
}
bool isObjectPointer() const {
- if (Var->isObjectPointer())
+ if (getVariable()->isObjectPointer())
return true;
if (getType()->isObjectPointer())
return true;
@@ -178,6 +216,45 @@ public:
bool isBlockByrefVariable() const;
const DIType *getType() const;
+ static bool classof(const DbgEntity *N) {
+ return N->getDbgEntityID() == DbgVariableKind;
+ }
+
+private:
+ template <typename T> T *resolve(TypedDINodeRef<T> Ref) const {
+ return Ref.resolve();
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// This class is used to track label information.
+///
+/// Labels are collected from \c DBG_LABEL instructions.
+class DbgLabel : public DbgEntity {
+ const MCSymbol *Sym; /// Symbol before DBG_LABEL instruction.
+
+public:
+ /// We need MCSymbol information to generate DW_AT_low_pc.
+ DbgLabel(const DILabel *L, const DILocation *IA, const MCSymbol *Sym = nullptr)
+ : DbgEntity(L, IA, DbgLabelKind), Sym(Sym) {}
+
+ /// Accessors.
+ /// @{
+ const DILabel *getLabel() const { return cast<DILabel>(getEntity()); }
+ const MCSymbol *getSymbol() const { return Sym; }
+
+ StringRef getName() const { return getLabel()->getName(); }
+ /// @}
+
+ /// Translate tag to proper Dwarf tag.
+ dwarf::Tag getTag() const {
+ return dwarf::DW_TAG_label;
+ }
+
+ static bool classof(const DbgEntity *N) {
+ return N->getDbgEntityID() == DbgLabelKind;
+ }
+
private:
template <typename T> T *resolve(TypedDINodeRef<T> Ref) const {
return Ref.resolve();
@@ -217,8 +294,8 @@ class DwarfDebug : public DebugHandlerBase {
/// Size of each symbol emitted (for those symbols that have a specific size).
DenseMap<const MCSymbol *, uint64_t> SymSize;
- /// Collection of abstract variables.
- SmallVector<std::unique_ptr<DbgVariable>, 64> ConcreteVariables;
+ /// Collection of abstract variables/labels.
+ SmallVector<std::unique_ptr<DbgEntity>, 64> ConcreteEntities;
/// Collection of DebugLocEntry. Stored in a linked list so that DIELocLists
/// can refer to them in spite of insertions into this list.
@@ -333,14 +410,20 @@ class DwarfDebug : public DebugHandlerBase {
}
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
+ using InlinedLabel = DbgLabelInstrMap::InlinedLabel;
- void ensureAbstractVariableIsCreated(DwarfCompileUnit &CU, InlinedVariable IV,
- const MDNode *Scope);
- void ensureAbstractVariableIsCreatedIfScoped(DwarfCompileUnit &CU, InlinedVariable IV,
- const MDNode *Scope);
+ void ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
+ const DINode *Node,
+ const MDNode *Scope);
+ void ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
+ const DINode *Node,
+ const MDNode *Scope);
- DbgVariable *createConcreteVariable(DwarfCompileUnit &TheCU,
- LexicalScope &Scope, InlinedVariable IV);
+ DbgEntity *createConcreteEntity(DwarfCompileUnit &TheCU,
+ LexicalScope &Scope,
+ const DINode *Node,
+ const DILocation *Location,
+ const MCSymbol *Sym = nullptr);
/// Construct a DIE for this abstract scope.
void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, LexicalScope *Scope);
@@ -349,7 +432,7 @@ class DwarfDebug : public DebugHandlerBase {
void addAccelNameImpl(AccelTable<DataT> &AppleAccel, StringRef Name,
const DIE &Die);
- void finishVariableDefinitions();
+ void finishEntityDefinitions();
void finishSubprogramDefinitions();
@@ -469,8 +552,8 @@ class DwarfDebug : public DebugHandlerBase {
unsigned Flags);
/// Populate LexicalScope entries with variables' info.
- void collectVariableInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP,
- DenseSet<InlinedVariable> &ProcessedVars);
+ void collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP,
+ DenseSet<InlinedVariable> &ProcessedVars);
/// Build the location list for all DBG_VALUEs in the
/// function that describe the same variable.
OpenPOWER on IntegriCloud