mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
Revert "[DebugInfo] Generate DWARF debug information for labels."
This reverts commits r338390 and r338398, they were causing LSan failures on the ASan bot. llvm-svn: 338408
This commit is contained in:
parent
dc24ddad39
commit
59d98289d5
@ -208,10 +208,6 @@ public:
|
|||||||
const MDNode *Variable,
|
const MDNode *Variable,
|
||||||
const MDNode *Expr);
|
const MDNode *Expr);
|
||||||
|
|
||||||
/// Build and insert a DBG_LABEL instructions specifying that \p Label is
|
|
||||||
/// given. Convert "llvm.dbg.label Label" to "DBG_LABEL Label".
|
|
||||||
MachineInstrBuilder buildDbgLabel(const MDNode *Label);
|
|
||||||
|
|
||||||
/// Build and insert \p Res = G_FRAME_INDEX \p Idx
|
/// Build and insert \p Res = G_FRAME_INDEX \p Idx
|
||||||
///
|
///
|
||||||
/// G_FRAME_INDEX materializes the address of an alloca value or other
|
/// G_FRAME_INDEX materializes the address of an alloca value or other
|
||||||
|
@ -5,7 +5,7 @@ add_llvm_library(LLVMAsmPrinter
|
|||||||
AsmPrinter.cpp
|
AsmPrinter.cpp
|
||||||
AsmPrinterDwarf.cpp
|
AsmPrinterDwarf.cpp
|
||||||
AsmPrinterInlineAsm.cpp
|
AsmPrinterInlineAsm.cpp
|
||||||
DbgEntityHistoryCalculator.cpp
|
DbgValueHistoryCalculator.cpp
|
||||||
DebugHandlerBase.cpp
|
DebugHandlerBase.cpp
|
||||||
DebugLocStream.cpp
|
DebugLocStream.cpp
|
||||||
DIE.cpp
|
DIE.cpp
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
|
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
|
||||||
#define LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
|
#define LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
|
||||||
|
|
||||||
#include "DbgEntityHistoryCalculator.h"
|
#include "DbgValueHistoryCalculator.h"
|
||||||
#include "DebugHandlerBase.h"
|
#include "DebugHandlerBase.h"
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//===- llvm/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp -------------===//
|
//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp --------------===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "DbgEntityHistoryCalculator.h"
|
#include "DbgValueHistoryCalculator.h"
|
||||||
#include "llvm/ADT/BitVector.h"
|
#include "llvm/ADT/BitVector.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
@ -78,17 +78,11 @@ unsigned DbgValueHistoryMap::getRegisterForVar(InlinedVariable Var) const {
|
|||||||
return isDescribedByReg(*Ranges.back().first);
|
return isDescribedByReg(*Ranges.back().first);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DbgLabelInstrMap::addInstr(InlinedLabel Label, const MachineInstr &MI) {
|
|
||||||
assert(MI.isDebugLabel() && "not a DBG_LABEL");
|
|
||||||
LabelInstr[Label] = &MI;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Maps physreg numbers to the variables they describe.
|
// Maps physreg numbers to the variables they describe.
|
||||||
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
|
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
|
||||||
using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedVariable, 1>>;
|
using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedVariable, 1>>;
|
||||||
using InlinedLabel = DbgLabelInstrMap::InlinedLabel;
|
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
@ -193,10 +187,9 @@ static void collectChangingRegs(const MachineFunction *MF,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
|
void llvm::calculateDbgValueHistory(const MachineFunction *MF,
|
||||||
const TargetRegisterInfo *TRI,
|
const TargetRegisterInfo *TRI,
|
||||||
DbgValueHistoryMap &DbgValues,
|
DbgValueHistoryMap &Result) {
|
||||||
DbgLabelInstrMap &DbgLabels) {
|
|
||||||
BitVector ChangingRegs(TRI->getNumRegs());
|
BitVector ChangingRegs(TRI->getNumRegs());
|
||||||
collectChangingRegs(MF, TRI, ChangingRegs);
|
collectChangingRegs(MF, TRI, ChangingRegs);
|
||||||
|
|
||||||
@ -217,14 +210,14 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
|
|||||||
// If this is a virtual register, only clobber it since it doesn't
|
// If this is a virtual register, only clobber it since it doesn't
|
||||||
// have aliases.
|
// have aliases.
|
||||||
if (TRI->isVirtualRegister(MO.getReg()))
|
if (TRI->isVirtualRegister(MO.getReg()))
|
||||||
clobberRegisterUses(RegVars, MO.getReg(), DbgValues, MI);
|
clobberRegisterUses(RegVars, MO.getReg(), Result, MI);
|
||||||
// If this is a register def operand, it may end a debug value
|
// If this is a register def operand, it may end a debug value
|
||||||
// range.
|
// range.
|
||||||
else {
|
else {
|
||||||
for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
|
for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
|
||||||
++AI)
|
++AI)
|
||||||
if (ChangingRegs.test(*AI))
|
if (ChangingRegs.test(*AI))
|
||||||
clobberRegisterUses(RegVars, *AI, DbgValues, MI);
|
clobberRegisterUses(RegVars, *AI, Result, MI);
|
||||||
}
|
}
|
||||||
} else if (MO.isRegMask()) {
|
} else if (MO.isRegMask()) {
|
||||||
// If this is a register mask operand, clobber all debug values in
|
// If this is a register mask operand, clobber all debug values in
|
||||||
@ -233,7 +226,7 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
|
|||||||
// Don't consider SP to be clobbered by register masks.
|
// Don't consider SP to be clobbered by register masks.
|
||||||
if (unsigned(I) != SP && TRI->isPhysicalRegister(I) &&
|
if (unsigned(I) != SP && TRI->isPhysicalRegister(I) &&
|
||||||
MO.clobbersPhysReg(I)) {
|
MO.clobbersPhysReg(I)) {
|
||||||
clobberRegisterUses(RegVars, I, DbgValues, MI);
|
clobberRegisterUses(RegVars, I, Result, MI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -241,34 +234,26 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MI.isDebugValue()) {
|
// Skip DBG_LABEL instructions.
|
||||||
assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!");
|
if (MI.isDebugLabel())
|
||||||
// Use the base variable (without any DW_OP_piece expressions)
|
continue;
|
||||||
// as index into History. The full variables including the
|
|
||||||
// piece expressions are attached to the MI.
|
|
||||||
const DILocalVariable *RawVar = MI.getDebugVariable();
|
|
||||||
assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
|
|
||||||
"Expected inlined-at fields to agree");
|
|
||||||
InlinedVariable Var(RawVar, MI.getDebugLoc()->getInlinedAt());
|
|
||||||
|
|
||||||
if (unsigned PrevReg = DbgValues.getRegisterForVar(Var))
|
assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!");
|
||||||
dropRegDescribedVar(RegVars, PrevReg, Var);
|
// Use the base variable (without any DW_OP_piece expressions)
|
||||||
|
// as index into History. The full variables including the
|
||||||
|
// piece expressions are attached to the MI.
|
||||||
|
const DILocalVariable *RawVar = MI.getDebugVariable();
|
||||||
|
assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
|
||||||
|
"Expected inlined-at fields to agree");
|
||||||
|
InlinedVariable Var(RawVar, MI.getDebugLoc()->getInlinedAt());
|
||||||
|
|
||||||
DbgValues.startInstrRange(Var, MI);
|
if (unsigned PrevReg = Result.getRegisterForVar(Var))
|
||||||
|
dropRegDescribedVar(RegVars, PrevReg, Var);
|
||||||
|
|
||||||
if (unsigned NewReg = isDescribedByReg(MI))
|
Result.startInstrRange(Var, MI);
|
||||||
addRegDescribedVar(RegVars, NewReg, Var);
|
|
||||||
} else if (MI.isDebugLabel()) {
|
if (unsigned NewReg = isDescribedByReg(MI))
|
||||||
assert(MI.getNumOperands() == 1 && "Invalid DBG_LABEL instruction!");
|
addRegDescribedVar(RegVars, NewReg, Var);
|
||||||
const DILabel *RawLabel = MI.getDebugLabel();
|
|
||||||
assert(RawLabel->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
|
|
||||||
"Expected inlined-at fields to agree");
|
|
||||||
// When collecting debug information for labels, there is no MCSymbol
|
|
||||||
// generated for it. So, we keep MachineInstr in DbgLabels in order
|
|
||||||
// to query MCSymbol afterward.
|
|
||||||
InlinedLabel L(RawLabel, MI.getDebugLoc()->getInlinedAt());
|
|
||||||
DbgLabels.addInstr(L, MI);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure locations for register-described variables are valid only
|
// Make sure locations for register-described variables are valid only
|
||||||
@ -279,7 +264,7 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
|
|||||||
auto CurElem = I++; // CurElem can be erased below.
|
auto CurElem = I++; // CurElem can be erased below.
|
||||||
if (TRI->isVirtualRegister(CurElem->first) ||
|
if (TRI->isVirtualRegister(CurElem->first) ||
|
||||||
ChangingRegs.test(CurElem->first))
|
ChangingRegs.test(CurElem->first))
|
||||||
clobberRegisterUses(RegVars, CurElem, DbgValues, MBB.back());
|
clobberRegisterUses(RegVars, CurElem, Result, MBB.back());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
//===- llvm/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.h -----*- C++ -*-===//
|
//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h ------*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
@ -58,30 +58,9 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/// For each inlined instance of a source-level label, keep the corresponding
|
void calculateDbgValueHistory(const MachineFunction *MF,
|
||||||
/// DBG_LABEL instruction. The DBG_LABEL instruction could be used to generate
|
const TargetRegisterInfo *TRI,
|
||||||
/// a temporary (assembler) label before it.
|
DbgValueHistoryMap &Result);
|
||||||
class DbgLabelInstrMap {
|
|
||||||
public:
|
|
||||||
using InlinedLabel = std::pair<const DILabel *, const DILocation *>;
|
|
||||||
using InstrMap = MapVector<InlinedLabel, const MachineInstr *>;
|
|
||||||
|
|
||||||
private:
|
|
||||||
InstrMap LabelInstr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void addInstr(InlinedLabel Label, const MachineInstr &MI);
|
|
||||||
|
|
||||||
bool empty() const { return LabelInstr.empty(); }
|
|
||||||
void clear() { LabelInstr.clear(); }
|
|
||||||
InstrMap::const_iterator begin() const { return LabelInstr.begin(); }
|
|
||||||
InstrMap::const_iterator end() const { return LabelInstr.end(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
void calculateDbgEntityHistory(const MachineFunction *MF,
|
|
||||||
const TargetRegisterInfo *TRI,
|
|
||||||
DbgValueHistoryMap &DbgValues,
|
|
||||||
DbgLabelInstrMap &DbgLabels);
|
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
@ -190,9 +190,8 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
|
|||||||
|
|
||||||
// Calculate history for local variables.
|
// Calculate history for local variables.
|
||||||
assert(DbgValues.empty() && "DbgValues map wasn't cleaned!");
|
assert(DbgValues.empty() && "DbgValues map wasn't cleaned!");
|
||||||
assert(DbgLabels.empty() && "DbgLabels map wasn't cleaned!");
|
calculateDbgValueHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
|
||||||
calculateDbgEntityHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
|
DbgValues);
|
||||||
DbgValues, DbgLabels);
|
|
||||||
LLVM_DEBUG(DbgValues.dump());
|
LLVM_DEBUG(DbgValues.dump());
|
||||||
|
|
||||||
// Request labels for the full history.
|
// Request labels for the full history.
|
||||||
@ -230,12 +229,6 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure there is a symbol before DBG_LABEL.
|
|
||||||
for (const auto &I : DbgLabels) {
|
|
||||||
const MachineInstr *MI = I.second;
|
|
||||||
requestLabelBeforeInsn(MI);
|
|
||||||
}
|
|
||||||
|
|
||||||
PrevInstLoc = DebugLoc();
|
PrevInstLoc = DebugLoc();
|
||||||
PrevLabel = Asm->getFunctionBegin();
|
PrevLabel = Asm->getFunctionBegin();
|
||||||
beginFunctionImpl(MF);
|
beginFunctionImpl(MF);
|
||||||
@ -303,7 +296,6 @@ void DebugHandlerBase::endFunction(const MachineFunction *MF) {
|
|||||||
if (hasDebugInfo(MMI, MF))
|
if (hasDebugInfo(MMI, MF))
|
||||||
endFunctionImpl(MF);
|
endFunctionImpl(MF);
|
||||||
DbgValues.clear();
|
DbgValues.clear();
|
||||||
DbgLabels.clear();
|
|
||||||
LabelsBeforeInsn.clear();
|
LabelsBeforeInsn.clear();
|
||||||
LabelsAfterInsn.clear();
|
LabelsAfterInsn.clear();
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGHANDLERBASE_H
|
#define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGHANDLERBASE_H
|
||||||
|
|
||||||
#include "AsmPrinterHandler.h"
|
#include "AsmPrinterHandler.h"
|
||||||
#include "DbgEntityHistoryCalculator.h"
|
#include "DbgValueHistoryCalculator.h"
|
||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/CodeGen/LexicalScopes.h"
|
#include "llvm/CodeGen/LexicalScopes.h"
|
||||||
#include "llvm/CodeGen/MachineInstr.h"
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
@ -82,9 +82,6 @@ protected:
|
|||||||
/// variable. Variables are listed in order of appearance.
|
/// variable. Variables are listed in order of appearance.
|
||||||
DbgValueHistoryMap DbgValues;
|
DbgValueHistoryMap DbgValues;
|
||||||
|
|
||||||
/// Mapping of inlined labels and DBG_LABEL machine instruction.
|
|
||||||
DbgLabelInstrMap DbgLabels;
|
|
||||||
|
|
||||||
/// Maps instruction with label emitted before instruction.
|
/// Maps instruction with label emitted before instruction.
|
||||||
/// FIXME: Make this private from DwarfDebug, we have the necessary accessors
|
/// FIXME: Make this private from DwarfDebug, we have the necessary accessors
|
||||||
/// for it.
|
/// for it.
|
||||||
|
@ -506,18 +506,6 @@ DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {
|
|||||||
return D;
|
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,
|
DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
|
||||||
bool Abstract) {
|
bool Abstract) {
|
||||||
// Define variable debug information entry.
|
// Define variable debug information entry.
|
||||||
@ -711,9 +699,6 @@ DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope,
|
|||||||
if (HasNonScopeChildren)
|
if (HasNonScopeChildren)
|
||||||
*HasNonScopeChildren = !Children.empty();
|
*HasNonScopeChildren = !Children.empty();
|
||||||
|
|
||||||
for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))
|
|
||||||
Children.push_back(constructLabelDIE(*DL, *Scope));
|
|
||||||
|
|
||||||
for (LexicalScope *LS : Scope->getChildren())
|
for (LexicalScope *LS : Scope->getChildren())
|
||||||
constructScopeDIE(LS, Children);
|
constructScopeDIE(LS, Children);
|
||||||
|
|
||||||
@ -839,52 +824,40 @@ void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
|
void DwarfCompileUnit::finishVariableDefinition(const DbgVariable &Var) {
|
||||||
DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity());
|
DbgVariable *AbsVar = getExistingAbstractVariable(
|
||||||
|
InlinedVariable(Var.getVariable(), Var.getInlinedAt()));
|
||||||
auto *Die = Entity->getDIE();
|
auto *VariableDie = Var.getDIE();
|
||||||
/// Label may be used to generate DW_AT_low_pc, so put it outside
|
if (AbsVar && AbsVar->getDIE()) {
|
||||||
/// if/else block.
|
addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin,
|
||||||
const DbgLabel *Label = nullptr;
|
*AbsVar->getDIE());
|
||||||
if (AbsEntity && AbsEntity->getDIE()) {
|
} else
|
||||||
addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());
|
applyVariableAttributes(Var, *VariableDie);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {
|
DbgVariable *DwarfCompileUnit::getExistingAbstractVariable(InlinedVariable IV) {
|
||||||
auto &AbstractEntities = getAbstractEntities();
|
const DILocalVariable *Cleansed;
|
||||||
auto I = AbstractEntities.find(Node);
|
return getExistingAbstractVariable(IV, Cleansed);
|
||||||
if (I != AbstractEntities.end())
|
}
|
||||||
|
|
||||||
|
// 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())
|
||||||
return I->second.get();
|
return I->second.get();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfCompileUnit::createAbstractEntity(const DINode *Node,
|
void DwarfCompileUnit::createAbstractVariable(const DILocalVariable *Var,
|
||||||
LexicalScope *Scope) {
|
LexicalScope *Scope) {
|
||||||
assert(Scope && Scope->isAbstractScope());
|
assert(Scope && Scope->isAbstractScope());
|
||||||
auto &Entity = getAbstractEntities()[Node];
|
auto AbsDbgVariable = llvm::make_unique<DbgVariable>(Var, /* IA */ nullptr);
|
||||||
if (isa<const DILocalVariable>(Node)) {
|
DU->addScopeVariable(Scope, AbsDbgVariable.get());
|
||||||
Entity = llvm::make_unique<DbgVariable>(
|
getAbstractVariables()[Var] = std::move(AbsDbgVariable);
|
||||||
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) {
|
void DwarfCompileUnit::emitHeader(bool UseOffsets) {
|
||||||
@ -1039,15 +1012,6 @@ void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var,
|
|||||||
addFlag(VariableDie, dwarf::DW_AT_artificial);
|
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.
|
/// Add a Dwarf expression attribute data and value.
|
||||||
void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
|
void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
|
||||||
const MCExpr *Expr) {
|
const MCExpr *Expr) {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
|
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
|
||||||
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
|
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
|
||||||
|
|
||||||
#include "DbgEntityHistoryCalculator.h"
|
#include "DbgValueHistoryCalculator.h"
|
||||||
#include "DwarfDebug.h"
|
#include "DwarfDebug.h"
|
||||||
#include "DwarfUnit.h"
|
#include "DwarfUnit.h"
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
@ -81,7 +81,7 @@ class DwarfCompileUnit final : public DwarfUnit {
|
|||||||
const MCSymbol *BaseAddress = nullptr;
|
const MCSymbol *BaseAddress = nullptr;
|
||||||
|
|
||||||
DenseMap<const MDNode *, DIE *> AbstractSPDies;
|
DenseMap<const MDNode *, DIE *> AbstractSPDies;
|
||||||
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
|
DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> AbstractVariables;
|
||||||
|
|
||||||
/// DWO ID for correlating skeleton and split units.
|
/// DWO ID for correlating skeleton and split units.
|
||||||
uint64_t DWOId = 0;
|
uint64_t DWOId = 0;
|
||||||
@ -98,10 +98,10 @@ class DwarfCompileUnit final : public DwarfUnit {
|
|||||||
return DU->getAbstractSPDies();
|
return DU->getAbstractSPDies();
|
||||||
}
|
}
|
||||||
|
|
||||||
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {
|
DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> &getAbstractVariables() {
|
||||||
if (isDwoUnit() && !DD->shareAcrossDWOCUs())
|
if (isDwoUnit() && !DD->shareAcrossDWOCUs())
|
||||||
return AbstractEntities;
|
return AbstractVariables;
|
||||||
return DU->getAbstractEntities();
|
return DU->getAbstractVariables();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -194,9 +194,6 @@ public:
|
|||||||
DIE *constructVariableDIE(DbgVariable &DV, const LexicalScope &Scope,
|
DIE *constructVariableDIE(DbgVariable &DV, const LexicalScope &Scope,
|
||||||
DIE *&ObjectPointer);
|
DIE *&ObjectPointer);
|
||||||
|
|
||||||
/// Construct a DIE for the given DbgLabel.
|
|
||||||
DIE *constructLabelDIE(DbgLabel &DL, const LexicalScope &Scope);
|
|
||||||
|
|
||||||
/// A helper function to create children of a Scope DIE.
|
/// A helper function to create children of a Scope DIE.
|
||||||
DIE *createScopeChildrenDIE(LexicalScope *Scope,
|
DIE *createScopeChildrenDIE(LexicalScope *Scope,
|
||||||
SmallVectorImpl<DIE *> &Children,
|
SmallVectorImpl<DIE *> &Children,
|
||||||
@ -213,12 +210,14 @@ public:
|
|||||||
DIE *constructImportedEntityDIE(const DIImportedEntity *Module);
|
DIE *constructImportedEntityDIE(const DIImportedEntity *Module);
|
||||||
|
|
||||||
void finishSubprogramDefinition(const DISubprogram *SP);
|
void finishSubprogramDefinition(const DISubprogram *SP);
|
||||||
void finishEntityDefinition(const DbgEntity *Entity);
|
void finishVariableDefinition(const DbgVariable &Var);
|
||||||
|
|
||||||
/// Find abstract variable associated with Var.
|
/// Find abstract variable associated with Var.
|
||||||
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
|
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
|
||||||
DbgEntity *getExistingAbstractEntity(const DINode *Node);
|
DbgVariable *getExistingAbstractVariable(InlinedVariable IV,
|
||||||
void createAbstractEntity(const DINode *Node, LexicalScope *Scope);
|
const DILocalVariable *&Cleansed);
|
||||||
|
DbgVariable *getExistingAbstractVariable(InlinedVariable IV);
|
||||||
|
void createAbstractVariable(const DILocalVariable *Var, LexicalScope *Scope);
|
||||||
|
|
||||||
/// Set the skeleton unit associated with this unit.
|
/// Set the skeleton unit associated with this unit.
|
||||||
void setSkeleton(DwarfCompileUnit &Skel) { Skeleton = &Skel; }
|
void setSkeleton(DwarfCompileUnit &Skel) { Skeleton = &Skel; }
|
||||||
@ -289,8 +288,6 @@ public:
|
|||||||
void applySubprogramAttributesToDefinition(const DISubprogram *SP,
|
void applySubprogramAttributesToDefinition(const DISubprogram *SP,
|
||||||
DIE &SPDie);
|
DIE &SPDie);
|
||||||
|
|
||||||
void applyLabelAttributes(const DbgLabel &Label, DIE &LabelDie);
|
|
||||||
|
|
||||||
/// getRangeLists - Get the vector of range lists.
|
/// getRangeLists - Get the vector of range lists.
|
||||||
const SmallVectorImpl<RangeSpanList> &getRangeLists() const {
|
const SmallVectorImpl<RangeSpanList> &getRangeLists() const {
|
||||||
return (Skeleton ? Skeleton : this)->CURangeLists;
|
return (Skeleton ? Skeleton : this)->CURangeLists;
|
||||||
|
@ -188,12 +188,12 @@ bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool DbgVariable::isBlockByrefVariable() const {
|
bool DbgVariable::isBlockByrefVariable() const {
|
||||||
assert(getVariable() && "Invalid complex DbgVariable!");
|
assert(Var && "Invalid complex DbgVariable!");
|
||||||
return getVariable()->getType().resolve()->isBlockByrefStruct();
|
return Var->getType().resolve()->isBlockByrefStruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
const DIType *DbgVariable::getType() const {
|
const DIType *DbgVariable::getType() const {
|
||||||
DIType *Ty = getVariable()->getType().resolve();
|
DIType *Ty = Var->getType().resolve();
|
||||||
// FIXME: isBlockByrefVariable should be reformulated in terms of complex
|
// FIXME: isBlockByrefVariable should be reformulated in terms of complex
|
||||||
// addresses instead.
|
// addresses instead.
|
||||||
if (Ty->isBlockByrefStruct()) {
|
if (Ty->isBlockByrefStruct()) {
|
||||||
@ -258,8 +258,8 @@ ArrayRef<DbgVariable::FrameIndexExpr> DbgVariable::getFrameIndexExprs() const {
|
|||||||
void DbgVariable::addMMIEntry(const DbgVariable &V) {
|
void DbgVariable::addMMIEntry(const DbgVariable &V) {
|
||||||
assert(DebugLocListIndex == ~0U && !MInsn && "not an MMI entry");
|
assert(DebugLocListIndex == ~0U && !MInsn && "not an MMI entry");
|
||||||
assert(V.DebugLocListIndex == ~0U && !V.MInsn && "not an MMI entry");
|
assert(V.DebugLocListIndex == ~0U && !V.MInsn && "not an MMI entry");
|
||||||
assert(V.getVariable() == getVariable() && "conflicting variable");
|
assert(V.Var == Var && "conflicting variable");
|
||||||
assert(V.getInlinedAt() == getInlinedAt() && "conflicting inlined-at location");
|
assert(V.IA == IA && "conflicting inlined-at location");
|
||||||
|
|
||||||
assert(!FrameIndexExprs.empty() && "Expected an MMI entry");
|
assert(!FrameIndexExprs.empty() && "Expected an MMI entry");
|
||||||
assert(!V.FrameIndexExprs.empty() && "Expected an MMI entry");
|
assert(!V.FrameIndexExprs.empty() && "Expected an MMI entry");
|
||||||
@ -726,16 +726,16 @@ void DwarfDebug::beginModule() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfDebug::finishEntityDefinitions() {
|
void DwarfDebug::finishVariableDefinitions() {
|
||||||
for (const auto &Entity : ConcreteEntities) {
|
for (const auto &Var : ConcreteVariables) {
|
||||||
DIE *Die = Entity->getDIE();
|
DIE *VariableDie = Var->getDIE();
|
||||||
assert(Die);
|
assert(VariableDie);
|
||||||
// FIXME: Consider the time-space tradeoff of just storing the unit pointer
|
// FIXME: Consider the time-space tradeoff of just storing the unit pointer
|
||||||
// in the ConcreteEntities list, rather than looking it up again here.
|
// in the ConcreteVariables list, rather than looking it up again here.
|
||||||
// DIE::getUnit isn't simple - it walks parent pointers, etc.
|
// DIE::getUnit isn't simple - it walks parent pointers, etc.
|
||||||
DwarfCompileUnit *Unit = CUDieMap.lookup(Die->getUnitDie());
|
DwarfCompileUnit *Unit = CUDieMap.lookup(VariableDie->getUnitDie());
|
||||||
assert(Unit);
|
assert(Unit);
|
||||||
Unit->finishEntityDefinition(Entity.get());
|
Unit->finishVariableDefinition(*Var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -753,7 +753,7 @@ void DwarfDebug::finalizeModuleInfo() {
|
|||||||
|
|
||||||
finishSubprogramDefinitions();
|
finishSubprogramDefinitions();
|
||||||
|
|
||||||
finishEntityDefinitions();
|
finishVariableDefinitions();
|
||||||
|
|
||||||
// Include the DWO file name in the hash if there's more than one CU.
|
// Include the DWO file name in the hash if there's more than one CU.
|
||||||
// This handles ThinLTO's situation where imported CUs may very easily be
|
// This handles ThinLTO's situation where imported CUs may very easily be
|
||||||
@ -914,24 +914,25 @@ void DwarfDebug::endModule() {
|
|||||||
// FIXME: AbstractVariables.clear();
|
// FIXME: AbstractVariables.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfDebug::ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
|
void DwarfDebug::ensureAbstractVariableIsCreated(DwarfCompileUnit &CU, InlinedVariable IV,
|
||||||
const DINode *Node,
|
const MDNode *ScopeNode) {
|
||||||
const MDNode *ScopeNode) {
|
const DILocalVariable *Cleansed = nullptr;
|
||||||
if (CU.getExistingAbstractEntity(Node))
|
if (CU.getExistingAbstractVariable(IV, Cleansed))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CU.createAbstractEntity(Node, LScopes.getOrCreateAbstractScope(
|
CU.createAbstractVariable(Cleansed, LScopes.getOrCreateAbstractScope(
|
||||||
cast<DILocalScope>(ScopeNode)));
|
cast<DILocalScope>(ScopeNode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
|
void DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(DwarfCompileUnit &CU,
|
||||||
const DINode *Node, const MDNode *ScopeNode) {
|
InlinedVariable IV, const MDNode *ScopeNode) {
|
||||||
if (CU.getExistingAbstractEntity(Node))
|
const DILocalVariable *Cleansed = nullptr;
|
||||||
|
if (CU.getExistingAbstractVariable(IV, Cleansed))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (LexicalScope *Scope =
|
if (LexicalScope *Scope =
|
||||||
LScopes.findAbstractScope(cast_or_null<DILocalScope>(ScopeNode)))
|
LScopes.findAbstractScope(cast_or_null<DILocalScope>(ScopeNode)))
|
||||||
CU.createAbstractEntity(Node, Scope);
|
CU.createAbstractVariable(Cleansed, Scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect variable information from side table maintained by MF.
|
// Collect variable information from side table maintained by MF.
|
||||||
@ -952,14 +953,14 @@ void DwarfDebug::collectVariableInfoFromMFTable(
|
|||||||
if (!Scope)
|
if (!Scope)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode());
|
ensureAbstractVariableIsCreatedIfScoped(TheCU, Var, Scope->getScopeNode());
|
||||||
auto RegVar = llvm::make_unique<DbgVariable>(Var.first, Var.second);
|
auto RegVar = llvm::make_unique<DbgVariable>(Var.first, Var.second);
|
||||||
RegVar->initializeMMI(VI.Expr, VI.Slot);
|
RegVar->initializeMMI(VI.Expr, VI.Slot);
|
||||||
if (DbgVariable *DbgVar = MFVars.lookup(Var))
|
if (DbgVariable *DbgVar = MFVars.lookup(Var))
|
||||||
DbgVar->addMMIEntry(*RegVar);
|
DbgVar->addMMIEntry(*RegVar);
|
||||||
else if (InfoHolder.addScopeVariable(Scope, RegVar.get())) {
|
else if (InfoHolder.addScopeVariable(Scope, RegVar.get())) {
|
||||||
MFVars.insert({Var, RegVar.get()});
|
MFVars.insert({Var, RegVar.get()});
|
||||||
ConcreteEntities.push_back(std::move(RegVar));
|
ConcreteVariables.push_back(std::move(RegVar));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1124,26 +1125,14 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU,
|
DbgVariable *DwarfDebug::createConcreteVariable(DwarfCompileUnit &TheCU,
|
||||||
LexicalScope &Scope,
|
LexicalScope &Scope,
|
||||||
const DINode *Node,
|
InlinedVariable IV) {
|
||||||
const DILocation *Location,
|
ensureAbstractVariableIsCreatedIfScoped(TheCU, IV, Scope.getScopeNode());
|
||||||
const MCSymbol *Sym) {
|
ConcreteVariables.push_back(
|
||||||
ensureAbstractEntityIsCreatedIfScoped(TheCU, Node, Scope.getScopeNode());
|
llvm::make_unique<DbgVariable>(IV.first, IV.second));
|
||||||
if (isa<const DILocalVariable>(Node)) {
|
InfoHolder.addScopeVariable(&Scope, ConcreteVariables.back().get());
|
||||||
ConcreteEntities.push_back(
|
return ConcreteVariables.back().get();
|
||||||
llvm::make_unique<DbgVariable>(cast<const DILocalVariable>(Node),
|
|
||||||
Location));
|
|
||||||
InfoHolder.addScopeVariable(&Scope,
|
|
||||||
cast<DbgVariable>(ConcreteEntities.back().get()));
|
|
||||||
} else if (isa<const DILabel>(Node)) {
|
|
||||||
ConcreteEntities.push_back(
|
|
||||||
llvm::make_unique<DbgLabel>(cast<const DILabel>(Node),
|
|
||||||
Location, Sym));
|
|
||||||
InfoHolder.addScopeLabel(&Scope,
|
|
||||||
cast<DbgLabel>(ConcreteEntities.back().get()));
|
|
||||||
}
|
|
||||||
return ConcreteEntities.back().get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine whether a *singular* DBG_VALUE is valid for the entirety of its
|
/// Determine whether a *singular* DBG_VALUE is valid for the entirety of its
|
||||||
@ -1205,9 +1194,9 @@ static bool validThroughout(LexicalScopes &LScopes,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find variables for each lexical scope.
|
// Find variables for each lexical scope.
|
||||||
void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
|
void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU,
|
||||||
const DISubprogram *SP,
|
const DISubprogram *SP,
|
||||||
DenseSet<InlinedVariable> &Processed) {
|
DenseSet<InlinedVariable> &Processed) {
|
||||||
// Grab the variable info that was squirreled away in the MMI side-table.
|
// Grab the variable info that was squirreled away in the MMI side-table.
|
||||||
collectVariableInfoFromMFTable(TheCU, Processed);
|
collectVariableInfoFromMFTable(TheCU, Processed);
|
||||||
|
|
||||||
@ -1231,8 +1220,7 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
Processed.insert(IV);
|
Processed.insert(IV);
|
||||||
DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
|
DbgVariable *RegVar = createConcreteVariable(TheCU, *Scope, IV);
|
||||||
*Scope, IV.first, IV.second));
|
|
||||||
|
|
||||||
const MachineInstr *MInsn = Ranges.front().first;
|
const MachineInstr *MInsn = Ranges.front().first;
|
||||||
assert(MInsn->isDebugValue() && "History must begin with debug value");
|
assert(MInsn->isDebugValue() && "History must begin with debug value");
|
||||||
@ -1265,44 +1253,13 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
|
|||||||
Entry.finalize(*Asm, List, BT);
|
Entry.finalize(*Asm, List, BT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each InlinedLabel collected from DBG_LABEL instructions, convert to
|
// Collect info for variables that were optimized out.
|
||||||
// DWARF-related DbgLabel.
|
|
||||||
for (const auto &I : DbgLabels) {
|
|
||||||
InlinedLabel IL = I.first;
|
|
||||||
const MachineInstr *MI = I.second;
|
|
||||||
if (MI == nullptr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
LexicalScope *Scope = nullptr;
|
|
||||||
// Get inlined DILocation if it is inlined label.
|
|
||||||
if (const DILocation *IA = IL.second)
|
|
||||||
Scope = LScopes.findInlinedScope(IL.first->getScope(), IA);
|
|
||||||
else
|
|
||||||
Scope = LScopes.findLexicalScope(IL.first->getScope());
|
|
||||||
// If label scope is not found then skip this label.
|
|
||||||
if (!Scope)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/// At this point, the temporary label is created.
|
|
||||||
/// Save the temporary label to DbgLabel entity to get the
|
|
||||||
/// actually address when generating Dwarf DIE.
|
|
||||||
MCSymbol *Sym = getLabelBeforeInsn(MI);
|
|
||||||
createConcreteEntity(TheCU, *Scope, IL.first, IL.second, Sym);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect info for variables/labels that were optimized out.
|
|
||||||
for (const DINode *DN : SP->getRetainedNodes()) {
|
for (const DINode *DN : SP->getRetainedNodes()) {
|
||||||
LexicalScope *Scope = nullptr;
|
|
||||||
if (auto *DV = dyn_cast<DILocalVariable>(DN)) {
|
if (auto *DV = dyn_cast<DILocalVariable>(DN)) {
|
||||||
if (!Processed.insert(InlinedVariable(DV, nullptr)).second)
|
if (Processed.insert(InlinedVariable(DV, nullptr)).second)
|
||||||
continue;
|
if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope()))
|
||||||
Scope = LScopes.findLexicalScope(DV->getScope());
|
createConcreteVariable(TheCU, *Scope, InlinedVariable(DV, nullptr));
|
||||||
} else if (auto *DL = dyn_cast<DILabel>(DN)) {
|
|
||||||
Scope = LScopes.findLexicalScope(DL->getScope());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Scope)
|
|
||||||
createConcreteEntity(TheCU, *Scope, DN, nullptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1460,7 +1417,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
|
|||||||
DwarfCompileUnit &TheCU = *CUMap.lookup(SP->getUnit());
|
DwarfCompileUnit &TheCU = *CUMap.lookup(SP->getUnit());
|
||||||
|
|
||||||
DenseSet<InlinedVariable> ProcessedVars;
|
DenseSet<InlinedVariable> ProcessedVars;
|
||||||
collectEntityInfo(TheCU, SP, ProcessedVars);
|
collectVariableInfo(TheCU, SP, ProcessedVars);
|
||||||
|
|
||||||
// Add the range of this function to the list of ranges for the CU.
|
// Add the range of this function to the list of ranges for the CU.
|
||||||
TheCU.addRange(RangeSpan(Asm->getFunctionBegin(), Asm->getFunctionEnd()));
|
TheCU.addRange(RangeSpan(Asm->getFunctionBegin(), Asm->getFunctionEnd()));
|
||||||
@ -1488,11 +1445,10 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
|
|||||||
// Collect info for variables that were optimized out.
|
// Collect info for variables that were optimized out.
|
||||||
if (!ProcessedVars.insert(InlinedVariable(DV, nullptr)).second)
|
if (!ProcessedVars.insert(InlinedVariable(DV, nullptr)).second)
|
||||||
continue;
|
continue;
|
||||||
ensureAbstractEntityIsCreated(TheCU, DV, DV->getScope());
|
ensureAbstractVariableIsCreated(TheCU, InlinedVariable(DV, nullptr),
|
||||||
|
DV->getScope());
|
||||||
assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes
|
assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes
|
||||||
&& "ensureAbstractEntityIsCreated inserted abstract scopes");
|
&& "ensureAbstractVariableIsCreated inserted abstract scopes");
|
||||||
} else if (auto *DL = dyn_cast<DILabel>(DN)) {
|
|
||||||
ensureAbstractEntityIsCreated(TheCU, DL, DL->getScope());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
constructAbstractSubprogramScopeDIE(TheCU, AScope);
|
constructAbstractSubprogramScopeDIE(TheCU, AScope);
|
||||||
@ -1510,7 +1466,6 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
|
|||||||
// DbgVariables except those that are also in AbstractVariables (since they
|
// DbgVariables except those that are also in AbstractVariables (since they
|
||||||
// can be used cross-function)
|
// can be used cross-function)
|
||||||
InfoHolder.getScopeVariables().clear();
|
InfoHolder.getScopeVariables().clear();
|
||||||
InfoHolder.getScopeLabels().clear();
|
|
||||||
PrevLabel = nullptr;
|
PrevLabel = nullptr;
|
||||||
CurFn = nullptr;
|
CurFn = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H
|
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H
|
||||||
|
|
||||||
#include "AddressPool.h"
|
#include "AddressPool.h"
|
||||||
#include "DbgEntityHistoryCalculator.h"
|
#include "DbgValueHistoryCalculator.h"
|
||||||
#include "DebugHandlerBase.h"
|
#include "DebugHandlerBase.h"
|
||||||
#include "DebugLocStream.h"
|
#include "DebugLocStream.h"
|
||||||
#include "DwarfFile.h"
|
#include "DwarfFile.h"
|
||||||
@ -61,46 +61,6 @@ class MCSymbol;
|
|||||||
class MDNode;
|
class MDNode;
|
||||||
class Module;
|
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) {}
|
|
||||||
|
|
||||||
/// 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.
|
/// This class is used to track local variable information.
|
||||||
///
|
///
|
||||||
@ -113,7 +73,10 @@ public:
|
|||||||
/// single instruction use \a MInsn and (optionally) a single entry of \a Expr.
|
/// single instruction use \a MInsn and (optionally) a single entry of \a Expr.
|
||||||
///
|
///
|
||||||
/// Variables that have been optimized out use none of these fields.
|
/// Variables that have been optimized out use none of these fields.
|
||||||
class DbgVariable : public DbgEntity {
|
class DbgVariable {
|
||||||
|
const DILocalVariable *Var; /// Variable Descriptor.
|
||||||
|
const DILocation *IA; /// Inlined at location.
|
||||||
|
DIE *TheDIE = nullptr; /// Variable DIE.
|
||||||
unsigned DebugLocListIndex = ~0u; /// Offset in DebugLocs.
|
unsigned DebugLocListIndex = ~0u; /// Offset in DebugLocs.
|
||||||
const MachineInstr *MInsn = nullptr; /// DBG_VALUE instruction.
|
const MachineInstr *MInsn = nullptr; /// DBG_VALUE instruction.
|
||||||
|
|
||||||
@ -130,7 +93,7 @@ public:
|
|||||||
/// Creates a variable without any DW_AT_location. Call \a initializeMMI()
|
/// Creates a variable without any DW_AT_location. Call \a initializeMMI()
|
||||||
/// for MMI entries, or \a initializeDbgValue() for DBG_VALUE instructions.
|
/// for MMI entries, or \a initializeDbgValue() for DBG_VALUE instructions.
|
||||||
DbgVariable(const DILocalVariable *V, const DILocation *IA)
|
DbgVariable(const DILocalVariable *V, const DILocation *IA)
|
||||||
: DbgEntity(V, IA, DbgVariableKind) {}
|
: Var(V), IA(IA) {}
|
||||||
|
|
||||||
/// Initialize from the MMI table.
|
/// Initialize from the MMI table.
|
||||||
void initializeMMI(const DIExpression *E, int FI) {
|
void initializeMMI(const DIExpression *E, int FI) {
|
||||||
@ -148,9 +111,8 @@ public:
|
|||||||
assert(FrameIndexExprs.empty() && "Already initialized?");
|
assert(FrameIndexExprs.empty() && "Already initialized?");
|
||||||
assert(!MInsn && "Already initialized?");
|
assert(!MInsn && "Already initialized?");
|
||||||
|
|
||||||
assert(getVariable() == DbgValue->getDebugVariable() && "Wrong variable");
|
assert(Var == DbgValue->getDebugVariable() && "Wrong variable");
|
||||||
assert(getInlinedAt() == DbgValue->getDebugLoc()->getInlinedAt() &&
|
assert(IA == DbgValue->getDebugLoc()->getInlinedAt() && "Wrong inlined-at");
|
||||||
"Wrong inlined-at");
|
|
||||||
|
|
||||||
MInsn = DbgValue;
|
MInsn = DbgValue;
|
||||||
if (auto *E = DbgValue->getDebugExpression())
|
if (auto *E = DbgValue->getDebugExpression())
|
||||||
@ -159,18 +121,19 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Accessors.
|
// Accessors.
|
||||||
const DILocalVariable *getVariable() const {
|
const DILocalVariable *getVariable() const { return Var; }
|
||||||
return cast<DILocalVariable>(getEntity());
|
const DILocation *getInlinedAt() const { return IA; }
|
||||||
}
|
|
||||||
|
|
||||||
const DIExpression *getSingleExpression() const {
|
const DIExpression *getSingleExpression() const {
|
||||||
assert(MInsn && FrameIndexExprs.size() <= 1);
|
assert(MInsn && FrameIndexExprs.size() <= 1);
|
||||||
return FrameIndexExprs.size() ? FrameIndexExprs[0].Expr : nullptr;
|
return FrameIndexExprs.size() ? FrameIndexExprs[0].Expr : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDIE(DIE &D) { TheDIE = &D; }
|
||||||
|
DIE *getDIE() const { return TheDIE; }
|
||||||
void setDebugLocListIndex(unsigned O) { DebugLocListIndex = O; }
|
void setDebugLocListIndex(unsigned O) { DebugLocListIndex = O; }
|
||||||
unsigned getDebugLocListIndex() const { return DebugLocListIndex; }
|
unsigned getDebugLocListIndex() const { return DebugLocListIndex; }
|
||||||
StringRef getName() const { return getVariable()->getName(); }
|
StringRef getName() const { return Var->getName(); }
|
||||||
const MachineInstr *getMInsn() const { return MInsn; }
|
const MachineInstr *getMInsn() const { return MInsn; }
|
||||||
/// Get the FI entries, sorted by fragment offset.
|
/// Get the FI entries, sorted by fragment offset.
|
||||||
ArrayRef<FrameIndexExpr> getFrameIndexExprs() const;
|
ArrayRef<FrameIndexExpr> getFrameIndexExprs() const;
|
||||||
@ -180,7 +143,7 @@ public:
|
|||||||
// Translate tag to proper Dwarf tag.
|
// Translate tag to proper Dwarf tag.
|
||||||
dwarf::Tag getTag() const {
|
dwarf::Tag getTag() const {
|
||||||
// FIXME: Why don't we just infer this tag and store it all along?
|
// FIXME: Why don't we just infer this tag and store it all along?
|
||||||
if (getVariable()->isParameter())
|
if (Var->isParameter())
|
||||||
return dwarf::DW_TAG_formal_parameter;
|
return dwarf::DW_TAG_formal_parameter;
|
||||||
|
|
||||||
return dwarf::DW_TAG_variable;
|
return dwarf::DW_TAG_variable;
|
||||||
@ -188,7 +151,7 @@ public:
|
|||||||
|
|
||||||
/// Return true if DbgVariable is artificial.
|
/// Return true if DbgVariable is artificial.
|
||||||
bool isArtificial() const {
|
bool isArtificial() const {
|
||||||
if (getVariable()->isArtificial())
|
if (Var->isArtificial())
|
||||||
return true;
|
return true;
|
||||||
if (getType()->isArtificial())
|
if (getType()->isArtificial())
|
||||||
return true;
|
return true;
|
||||||
@ -196,7 +159,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isObjectPointer() const {
|
bool isObjectPointer() const {
|
||||||
if (getVariable()->isObjectPointer())
|
if (Var->isObjectPointer())
|
||||||
return true;
|
return true;
|
||||||
if (getType()->isObjectPointer())
|
if (getType()->isObjectPointer())
|
||||||
return true;
|
return true;
|
||||||
@ -215,45 +178,6 @@ public:
|
|||||||
bool isBlockByrefVariable() const;
|
bool isBlockByrefVariable() const;
|
||||||
const DIType *getType() 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:
|
private:
|
||||||
template <typename T> T *resolve(TypedDINodeRef<T> Ref) const {
|
template <typename T> T *resolve(TypedDINodeRef<T> Ref) const {
|
||||||
return Ref.resolve();
|
return Ref.resolve();
|
||||||
@ -293,8 +217,8 @@ class DwarfDebug : public DebugHandlerBase {
|
|||||||
/// Size of each symbol emitted (for those symbols that have a specific size).
|
/// Size of each symbol emitted (for those symbols that have a specific size).
|
||||||
DenseMap<const MCSymbol *, uint64_t> SymSize;
|
DenseMap<const MCSymbol *, uint64_t> SymSize;
|
||||||
|
|
||||||
/// Collection of abstract variables/labels.
|
/// Collection of abstract variables.
|
||||||
SmallVector<std::unique_ptr<DbgEntity>, 64> ConcreteEntities;
|
SmallVector<std::unique_ptr<DbgVariable>, 64> ConcreteVariables;
|
||||||
|
|
||||||
/// Collection of DebugLocEntry. Stored in a linked list so that DIELocLists
|
/// Collection of DebugLocEntry. Stored in a linked list so that DIELocLists
|
||||||
/// can refer to them in spite of insertions into this list.
|
/// can refer to them in spite of insertions into this list.
|
||||||
@ -409,20 +333,14 @@ class DwarfDebug : public DebugHandlerBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
|
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
|
||||||
using InlinedLabel = DbgLabelInstrMap::InlinedLabel;
|
|
||||||
|
|
||||||
void ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
|
void ensureAbstractVariableIsCreated(DwarfCompileUnit &CU, InlinedVariable IV,
|
||||||
const DINode *Node,
|
const MDNode *Scope);
|
||||||
const MDNode *Scope);
|
void ensureAbstractVariableIsCreatedIfScoped(DwarfCompileUnit &CU, InlinedVariable IV,
|
||||||
void ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
|
const MDNode *Scope);
|
||||||
const DINode *Node,
|
|
||||||
const MDNode *Scope);
|
|
||||||
|
|
||||||
DbgEntity *createConcreteEntity(DwarfCompileUnit &TheCU,
|
DbgVariable *createConcreteVariable(DwarfCompileUnit &TheCU,
|
||||||
LexicalScope &Scope,
|
LexicalScope &Scope, InlinedVariable IV);
|
||||||
const DINode *Node,
|
|
||||||
const DILocation *Location,
|
|
||||||
const MCSymbol *Sym = nullptr);
|
|
||||||
|
|
||||||
/// Construct a DIE for this abstract scope.
|
/// Construct a DIE for this abstract scope.
|
||||||
void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, LexicalScope *Scope);
|
void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, LexicalScope *Scope);
|
||||||
@ -431,7 +349,7 @@ class DwarfDebug : public DebugHandlerBase {
|
|||||||
void addAccelNameImpl(AccelTable<DataT> &AppleAccel, StringRef Name,
|
void addAccelNameImpl(AccelTable<DataT> &AppleAccel, StringRef Name,
|
||||||
const DIE &Die);
|
const DIE &Die);
|
||||||
|
|
||||||
void finishEntityDefinitions();
|
void finishVariableDefinitions();
|
||||||
|
|
||||||
void finishSubprogramDefinitions();
|
void finishSubprogramDefinitions();
|
||||||
|
|
||||||
@ -548,8 +466,8 @@ class DwarfDebug : public DebugHandlerBase {
|
|||||||
unsigned Flags);
|
unsigned Flags);
|
||||||
|
|
||||||
/// Populate LexicalScope entries with variables' info.
|
/// Populate LexicalScope entries with variables' info.
|
||||||
void collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP,
|
void collectVariableInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP,
|
||||||
DenseSet<InlinedVariable> &ProcessedVars);
|
DenseSet<InlinedVariable> &ProcessedVars);
|
||||||
|
|
||||||
/// Build the location list for all DBG_VALUEs in the
|
/// Build the location list for all DBG_VALUEs in the
|
||||||
/// function that describe the same variable.
|
/// function that describe the same variable.
|
||||||
|
@ -98,8 +98,3 @@ bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfFile::addScopeLabel(LexicalScope *LS, DbgLabel *Label) {
|
|
||||||
SmallVectorImpl<DbgLabel *> &Labels = ScopeLabels[LS];
|
|
||||||
Labels.push_back(Label);
|
|
||||||
}
|
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class AsmPrinter;
|
class AsmPrinter;
|
||||||
class DbgEntity;
|
|
||||||
class DbgVariable;
|
class DbgVariable;
|
||||||
class DbgLabel;
|
|
||||||
class DwarfCompileUnit;
|
class DwarfCompileUnit;
|
||||||
class DwarfUnit;
|
class DwarfUnit;
|
||||||
class LexicalScope;
|
class LexicalScope;
|
||||||
@ -64,13 +62,9 @@ class DwarfFile {
|
|||||||
/// Collection of DbgVariables of each lexical scope.
|
/// Collection of DbgVariables of each lexical scope.
|
||||||
DenseMap<LexicalScope *, ScopeVars> ScopeVariables;
|
DenseMap<LexicalScope *, ScopeVars> ScopeVariables;
|
||||||
|
|
||||||
/// Collection of DbgLabels of each lexical scope.
|
|
||||||
using LabelList = SmallVector<DbgLabel *, 4>;
|
|
||||||
DenseMap<LexicalScope *, LabelList> ScopeLabels;
|
|
||||||
|
|
||||||
// Collection of abstract subprogram DIEs.
|
// Collection of abstract subprogram DIEs.
|
||||||
DenseMap<const MDNode *, DIE *> AbstractSPDies;
|
DenseMap<const MDNode *, DIE *> AbstractSPDies;
|
||||||
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
|
DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> AbstractVariables;
|
||||||
|
|
||||||
/// Maps MDNodes for type system with the corresponding DIEs. These DIEs can
|
/// Maps MDNodes for type system with the corresponding DIEs. These DIEs can
|
||||||
/// be shared across CUs, that is why we keep the map here instead
|
/// be shared across CUs, that is why we keep the map here instead
|
||||||
@ -128,22 +122,16 @@ public:
|
|||||||
/// \returns false if the variable was merged with a previous one.
|
/// \returns false if the variable was merged with a previous one.
|
||||||
bool addScopeVariable(LexicalScope *LS, DbgVariable *Var);
|
bool addScopeVariable(LexicalScope *LS, DbgVariable *Var);
|
||||||
|
|
||||||
void addScopeLabel(LexicalScope *LS, DbgLabel *Label);
|
|
||||||
|
|
||||||
DenseMap<LexicalScope *, ScopeVars> &getScopeVariables() {
|
DenseMap<LexicalScope *, ScopeVars> &getScopeVariables() {
|
||||||
return ScopeVariables;
|
return ScopeVariables;
|
||||||
}
|
}
|
||||||
|
|
||||||
DenseMap<LexicalScope *, LabelList> &getScopeLabels() {
|
|
||||||
return ScopeLabels;
|
|
||||||
}
|
|
||||||
|
|
||||||
DenseMap<const MDNode *, DIE *> &getAbstractSPDies() {
|
DenseMap<const MDNode *, DIE *> &getAbstractSPDies() {
|
||||||
return AbstractSPDies;
|
return AbstractSPDies;
|
||||||
}
|
}
|
||||||
|
|
||||||
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {
|
DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> &getAbstractVariables() {
|
||||||
return AbstractEntities;
|
return AbstractVariables;
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertDIE(const MDNode *TypeMD, DIE *Die) {
|
void insertDIE(const MDNode *TypeMD, DIE *Die) {
|
||||||
|
@ -401,12 +401,6 @@ void DwarfUnit::addSourceLine(DIE &Die, const DISubprogram *SP) {
|
|||||||
addSourceLine(Die, SP->getLine(), SP->getFile());
|
addSourceLine(Die, SP->getLine(), SP->getFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfUnit::addSourceLine(DIE &Die, const DILabel *L) {
|
|
||||||
assert(L);
|
|
||||||
|
|
||||||
addSourceLine(Die, L->getLine(), L->getFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
void DwarfUnit::addSourceLine(DIE &Die, const DIType *Ty) {
|
void DwarfUnit::addSourceLine(DIE &Die, const DIType *Ty) {
|
||||||
assert(Ty);
|
assert(Ty);
|
||||||
|
|
||||||
|
@ -213,7 +213,6 @@ public:
|
|||||||
void addSourceLine(DIE &Die, const DILocalVariable *V);
|
void addSourceLine(DIE &Die, const DILocalVariable *V);
|
||||||
void addSourceLine(DIE &Die, const DIGlobalVariable *G);
|
void addSourceLine(DIE &Die, const DIGlobalVariable *G);
|
||||||
void addSourceLine(DIE &Die, const DISubprogram *SP);
|
void addSourceLine(DIE &Die, const DISubprogram *SP);
|
||||||
void addSourceLine(DIE &Die, const DILabel *L);
|
|
||||||
void addSourceLine(DIE &Die, const DIType *Ty);
|
void addSourceLine(DIE &Die, const DIType *Ty);
|
||||||
void addSourceLine(DIE &Die, const DIObjCProperty *Ty);
|
void addSourceLine(DIE &Die, const DIObjCProperty *Ty);
|
||||||
|
|
||||||
|
@ -766,17 +766,6 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
|
|||||||
DI.getVariable(), DI.getExpression());
|
DI.getVariable(), DI.getExpression());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case Intrinsic::dbg_label: {
|
|
||||||
const DbgLabelInst &DI = cast<DbgLabelInst>(CI);
|
|
||||||
assert(DI.getLabel() && "Missing label");
|
|
||||||
|
|
||||||
assert(DI.getLabel()->isValidLocationForIntrinsic(
|
|
||||||
MIRBuilder.getDebugLoc()) &&
|
|
||||||
"Expected inlined-at fields to agree");
|
|
||||||
|
|
||||||
MIRBuilder.buildDbgLabel(DI.getLabel());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case Intrinsic::vaend:
|
case Intrinsic::vaend:
|
||||||
// No target I know of cares about va_end. Certainly no in-tree target
|
// No target I know of cares about va_end. Certainly no in-tree target
|
||||||
// does. Simplest intrinsic ever!
|
// does. Simplest intrinsic ever!
|
||||||
|
@ -149,15 +149,6 @@ MachineInstrBuilder MachineIRBuilderBase::buildConstDbgValue(
|
|||||||
return MIB.addImm(0).addMetadata(Variable).addMetadata(Expr);
|
return MIB.addImm(0).addMetadata(Variable).addMetadata(Expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineInstrBuilder MachineIRBuilderBase::buildDbgLabel(const MDNode *Label) {
|
|
||||||
assert(isa<DILabel>(Label) && "not a label");
|
|
||||||
assert(cast<DILabel>(Label)->isValidLocationForIntrinsic(State.DL) &&
|
|
||||||
"Expected inlined-at fields to agree");
|
|
||||||
auto MIB = buildInstr(TargetOpcode::DBG_LABEL);
|
|
||||||
|
|
||||||
return MIB.addMetadata(Label);
|
|
||||||
}
|
|
||||||
|
|
||||||
MachineInstrBuilder MachineIRBuilderBase::buildFrameIndex(unsigned Res,
|
MachineInstrBuilder MachineIRBuilderBase::buildFrameIndex(unsigned Res,
|
||||||
int Idx) {
|
int Idx) {
|
||||||
assert(getMRI()->getType(Res).isPointer() && "invalid operand type");
|
assert(getMRI()->getType(Res).isPointer() && "invalid operand type");
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
; RUN: llc -O2 -filetype=obj -o - %s | llvm-dwarfdump -v - | FileCheck %s
|
|
||||||
;
|
|
||||||
; CHECK: .debug_info contents:
|
|
||||||
; CHECK: [[LABEL_ORIGIN:0x[0-9a-zA-Z]+]]:{{ *}}DW_TAG_label
|
|
||||||
; CHECK-NEXT: DW_AT_name [DW_FORM_strp] {{.*}}"top"
|
|
||||||
; CHECK-NEXT: DW_AT_decl_file [DW_FORM_data1] {{.*}}debug-label-inline.c
|
|
||||||
; CHECK-NEXT: DW_AT_decl_line [DW_FORM_data1] {{.*}}8
|
|
||||||
; CHECK: DW_TAG_label
|
|
||||||
; CHECK-NEXT: DW_AT_abstract_origin [DW_FORM_ref4] {{.*}}{[[LABEL_ORIGIN]]} "top"
|
|
||||||
; CHECK-NEXT: DW_AT_low_pc [DW_FORM_addr] {{.*}}{{0x[0-9a-f]+}}
|
|
||||||
|
|
||||||
source_filename = "debug-label-inline.c"
|
|
||||||
|
|
||||||
@ga = external local_unnamed_addr global i32, align 4
|
|
||||||
@gb = external local_unnamed_addr global i32, align 4
|
|
||||||
|
|
||||||
define i32 @f2() local_unnamed_addr #0 !dbg !4 {
|
|
||||||
entry:
|
|
||||||
%0 = load i32, i32* @ga, align 4, !dbg !1
|
|
||||||
%1 = load i32, i32* @gb, align 4, !dbg !1
|
|
||||||
call void @llvm.dbg.label(metadata !15), !dbg !17
|
|
||||||
%add.i = add nsw i32 %1, %0, !dbg !18
|
|
||||||
ret i32 %add.i, !dbg !1
|
|
||||||
}
|
|
||||||
|
|
||||||
declare void @llvm.dbg.label(metadata)
|
|
||||||
declare void @llvm.dbg.value(metadata, metadata, metadata)
|
|
||||||
|
|
||||||
attributes #0 = { nounwind readonly }
|
|
||||||
|
|
||||||
!llvm.dbg.cu = !{!0}
|
|
||||||
!llvm.module.flags = !{!3}
|
|
||||||
|
|
||||||
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !6, isOptimized: true, emissionKind: FullDebug, enums: !2)
|
|
||||||
!1 = !DILocation(line: 18, scope: !4)
|
|
||||||
!2 = !{}
|
|
||||||
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
|
||||||
!4 = distinct !DISubprogram(name: "f2", scope: !6, file: !6, line: 15, type: !7, isLocal: false, isDefinition: true, scopeLine: 15, isOptimized: true, unit: !0, retainedNodes: !2)
|
|
||||||
!6 = !DIFile(filename: "debug-label-inline.c", directory: "./")
|
|
||||||
!7 = !DISubroutineType(types: !8)
|
|
||||||
!8 = !{!10}
|
|
||||||
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
||||||
!11 = distinct !DISubprogram(name: "f1", scope: !6, file: !6, line: 5, type: !12, isLocal: false, isDefinition: true, scopeLine: 5, isOptimized: true, unit: !0, retainedNodes: !14)
|
|
||||||
!12 = !DISubroutineType(types: !13)
|
|
||||||
!13 = !{!10, !10, !10}
|
|
||||||
!14 = !{!15}
|
|
||||||
!15 = !DILabel(scope: !11, name: "top", file: !6, line: 8)
|
|
||||||
!16 = distinct !DILocation(line: 18, scope: !4)
|
|
||||||
!17 = !DILocation(line: 8, scope: !11, inlinedAt: !16)
|
|
||||||
!18 = !DILocation(line: 9, scope: !11, inlinedAt: !16)
|
|
@ -1,84 +0,0 @@
|
|||||||
; RUN: llc -fast-isel=false -O0 -filetype=obj -o - %s | llvm-dwarfdump -v - | FileCheck %s
|
|
||||||
;
|
|
||||||
; CHECK: .debug_info contents:
|
|
||||||
; CHECK: DW_TAG_label
|
|
||||||
; CHECK-NEXT: DW_AT_name [DW_FORM_strp] {{.*}}"top"
|
|
||||||
; CHECK-NEXT: DW_AT_decl_file [DW_FORM_data1] {{.*}}debug-label.c
|
|
||||||
; CHECK-NEXT: DW_AT_decl_line [DW_FORM_data1] {{.*}}4
|
|
||||||
; CHECK-NEXT: DW_AT_low_pc [DW_FORM_addr] {{.*}}{{0x[0-9a-f]+}}
|
|
||||||
; CHECK: DW_TAG_label
|
|
||||||
; CHECK-NEXT: DW_AT_name [DW_FORM_strp] {{.*}}"done"
|
|
||||||
; CHECK-NEXT: DW_AT_decl_file [DW_FORM_data1] {{.*}}debug-label.c
|
|
||||||
; CHECK-NEXT: DW_AT_decl_line [DW_FORM_data1] {{.*}}7
|
|
||||||
; CHECK-NEXT: DW_AT_low_pc [DW_FORM_addr] {{.*}}{{0x[0-9a-f]+}}
|
|
||||||
;
|
|
||||||
; RUN: llc -fast-isel=false -O0 -o - %s | FileCheck %s -check-prefix=ASM
|
|
||||||
;
|
|
||||||
; ASM: [[TOP_LOW_PC:[.0-9a-zA-Z]+]]:{{[[:space:]].*}}DEBUG_LABEL: foo:top
|
|
||||||
; ASM: [[DONE_LOW_PC:[.0-9a-zA-Z]+]]:{{[[:space:]].*}}DEBUG_LABEL: foo:done
|
|
||||||
; ASM-LABEL: .debug_str
|
|
||||||
; ASM: [[TOP_LABEL:[.0-9a-zA-Z]+]]:{{[[:space:]].*}}"top"
|
|
||||||
; ASM: [[DONE_LABEL:[.0-9a-zA-Z]+]]:{{[[:space:]].*}}"done"
|
|
||||||
; ASM-LABEL: .debug_info
|
|
||||||
; ASM: DW_TAG_label
|
|
||||||
; ASM-NEXT: [[TOP_LABEL]]
|
|
||||||
; ASM-SAME: DW_AT_name
|
|
||||||
; ASM-NEXT: 1
|
|
||||||
; ASM-SAME: DW_AT_decl_file
|
|
||||||
; ASM-NEXT: 4
|
|
||||||
; ASM-SAME: DW_AT_decl_line
|
|
||||||
; ASM-NEXT: [[TOP_LOW_PC]]
|
|
||||||
; ASM-SAME: DW_AT_low_pc
|
|
||||||
; ASM: DW_TAG_label
|
|
||||||
; ASM-NEXT: [[DONE_LABEL]]
|
|
||||||
; ASM-SAME: DW_AT_name
|
|
||||||
; ASM-NEXT: 1
|
|
||||||
; ASM-SAME: DW_AT_decl_file
|
|
||||||
; ASM-NEXT: 7
|
|
||||||
; ASM-SAME: DW_AT_decl_line
|
|
||||||
; ASM-NEXT: [[DONE_LOW_PC]]
|
|
||||||
; ASM-SAME: DW_AT_low_pc
|
|
||||||
|
|
||||||
source_filename = "debug-label.c"
|
|
||||||
|
|
||||||
define dso_local i32 @foo(i32 %a, i32 %b) !dbg !6 {
|
|
||||||
entry:
|
|
||||||
%a.addr = alloca i32, align 4
|
|
||||||
%b.addr = alloca i32, align 4
|
|
||||||
%sum = alloca i32, align 4
|
|
||||||
store i32 %a, i32* %a.addr, align 4
|
|
||||||
store i32 %b, i32* %b.addr, align 4
|
|
||||||
br label %top
|
|
||||||
|
|
||||||
top:
|
|
||||||
call void @llvm.dbg.label(metadata !10), !dbg !11
|
|
||||||
%0 = load i32, i32* %a.addr, align 4
|
|
||||||
%1 = load i32, i32* %b.addr, align 4
|
|
||||||
%add = add nsw i32 %0, %1
|
|
||||||
store i32 %add, i32* %sum, align 4
|
|
||||||
br label %done
|
|
||||||
|
|
||||||
done:
|
|
||||||
call void @llvm.dbg.label(metadata !12), !dbg !13
|
|
||||||
%2 = load i32, i32* %sum, align 4
|
|
||||||
ret i32 %2, !dbg !14
|
|
||||||
}
|
|
||||||
|
|
||||||
declare void @llvm.dbg.label(metadata)
|
|
||||||
|
|
||||||
!llvm.dbg.cu = !{!0}
|
|
||||||
!llvm.module.flags = !{!4}
|
|
||||||
|
|
||||||
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: false, emissionKind: FullDebug, enums: !2)
|
|
||||||
!1 = !DIFile(filename: "debug-label.c", directory: "./")
|
|
||||||
!2 = !{}
|
|
||||||
!4 = !{i32 2, !"Debug Info Version", i32 3}
|
|
||||||
!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !0, retainedNodes: !2)
|
|
||||||
!7 = !DISubroutineType(types: !8)
|
|
||||||
!8 = !{!9, !9, !9}
|
|
||||||
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
||||||
!10 = !DILabel(scope: !6, name: "top", file: !1, line: 4)
|
|
||||||
!11 = !DILocation(line: 4, column: 1, scope: !6)
|
|
||||||
!12 = !DILabel(scope: !6, name: "done", file: !1, line: 7)
|
|
||||||
!13 = !DILocation(line: 7, column: 1, scope: !6)
|
|
||||||
!14 = !DILocation(line: 8, column: 3, scope: !6)
|
|
Loading…
Reference in New Issue
Block a user