mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 13:11:39 +01:00
[DebugInfo] Do not generate label debug info if it has been processed.
In DwarfDebug::collectEntityInfo(), if the label entity is processed in DbgLabels list, it means the label is not optimized out. There is no need to generate debug info for it with null position. llvm-svn: 341513
This commit is contained in:
parent
35d13c1feb
commit
c7272d28a4
@ -1048,7 +1048,7 @@ CodeViewDebug::createDefRangeGeneral(uint16_t CVRegister, bool InMemory,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CodeViewDebug::collectVariableInfoFromMFTable(
|
void CodeViewDebug::collectVariableInfoFromMFTable(
|
||||||
DenseSet<InlinedVariable> &Processed) {
|
DenseSet<InlinedEntity> &Processed) {
|
||||||
const MachineFunction &MF = *Asm->MF;
|
const MachineFunction &MF = *Asm->MF;
|
||||||
const TargetSubtargetInfo &TSI = MF.getSubtarget();
|
const TargetSubtargetInfo &TSI = MF.getSubtarget();
|
||||||
const TargetFrameLowering *TFI = TSI.getFrameLowering();
|
const TargetFrameLowering *TFI = TSI.getFrameLowering();
|
||||||
@ -1060,7 +1060,7 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
|
|||||||
assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&
|
assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&
|
||||||
"Expected inlined-at fields to agree");
|
"Expected inlined-at fields to agree");
|
||||||
|
|
||||||
Processed.insert(InlinedVariable(VI.Var, VI.Loc->getInlinedAt()));
|
Processed.insert(InlinedEntity(VI.Var, VI.Loc->getInlinedAt()));
|
||||||
LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
|
LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
|
||||||
|
|
||||||
// If variable scope is not found then skip this variable.
|
// If variable scope is not found then skip this variable.
|
||||||
@ -1196,15 +1196,15 @@ void CodeViewDebug::calculateRanges(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
|
void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
|
||||||
DenseSet<InlinedVariable> Processed;
|
DenseSet<InlinedEntity> 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(Processed);
|
collectVariableInfoFromMFTable(Processed);
|
||||||
|
|
||||||
for (const auto &I : DbgValues) {
|
for (const auto &I : DbgValues) {
|
||||||
InlinedVariable IV = I.first;
|
InlinedEntity IV = I.first;
|
||||||
if (Processed.count(IV))
|
if (Processed.count(IV))
|
||||||
continue;
|
continue;
|
||||||
const DILocalVariable *DIVar = IV.first;
|
const DILocalVariable *DIVar = cast<DILocalVariable>(IV.first);
|
||||||
const DILocation *InlinedAt = IV.second;
|
const DILocation *InlinedAt = IV.second;
|
||||||
|
|
||||||
// Instruction ranges, specifying where IV is accessible.
|
// Instruction ranges, specifying where IV is accessible.
|
||||||
|
@ -277,11 +277,11 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
|
|||||||
void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt,
|
void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt,
|
||||||
const InlineSite &Site);
|
const InlineSite &Site);
|
||||||
|
|
||||||
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
|
using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
|
||||||
|
|
||||||
void collectVariableInfo(const DISubprogram *SP);
|
void collectVariableInfo(const DISubprogram *SP);
|
||||||
|
|
||||||
void collectVariableInfoFromMFTable(DenseSet<InlinedVariable> &Processed);
|
void collectVariableInfoFromMFTable(DenseSet<InlinedEntity> &Processed);
|
||||||
|
|
||||||
// Construct the lexical block tree for a routine, pruning emptpy lexical
|
// Construct the lexical block tree for a routine, pruning emptpy lexical
|
||||||
// scopes, and populate it with local variables.
|
// scopes, and populate it with local variables.
|
||||||
|
@ -42,7 +42,7 @@ static unsigned isDescribedByReg(const MachineInstr &MI) {
|
|||||||
return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0;
|
return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DbgValueHistoryMap::startInstrRange(InlinedVariable Var,
|
void DbgValueHistoryMap::startInstrRange(InlinedEntity Var,
|
||||||
const MachineInstr &MI) {
|
const MachineInstr &MI) {
|
||||||
// Instruction range should start with a DBG_VALUE instruction for the
|
// Instruction range should start with a DBG_VALUE instruction for the
|
||||||
// variable.
|
// variable.
|
||||||
@ -57,7 +57,7 @@ void DbgValueHistoryMap::startInstrRange(InlinedVariable Var,
|
|||||||
Ranges.push_back(std::make_pair(&MI, nullptr));
|
Ranges.push_back(std::make_pair(&MI, nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DbgValueHistoryMap::endInstrRange(InlinedVariable Var,
|
void DbgValueHistoryMap::endInstrRange(InlinedEntity Var,
|
||||||
const MachineInstr &MI) {
|
const MachineInstr &MI) {
|
||||||
auto &Ranges = VarInstrRanges[Var];
|
auto &Ranges = VarInstrRanges[Var];
|
||||||
// Verify that the current instruction range is not yet closed.
|
// Verify that the current instruction range is not yet closed.
|
||||||
@ -68,7 +68,7 @@ void DbgValueHistoryMap::endInstrRange(InlinedVariable Var,
|
|||||||
Ranges.back().second = &MI;
|
Ranges.back().second = &MI;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned DbgValueHistoryMap::getRegisterForVar(InlinedVariable Var) const {
|
unsigned DbgValueHistoryMap::getRegisterForVar(InlinedEntity Var) const {
|
||||||
const auto &I = VarInstrRanges.find(Var);
|
const auto &I = VarInstrRanges.find(Var);
|
||||||
if (I == VarInstrRanges.end())
|
if (I == VarInstrRanges.end())
|
||||||
return 0;
|
return 0;
|
||||||
@ -78,7 +78,7 @@ unsigned DbgValueHistoryMap::getRegisterForVar(InlinedVariable Var) const {
|
|||||||
return isDescribedByReg(*Ranges.back().first);
|
return isDescribedByReg(*Ranges.back().first);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DbgLabelInstrMap::addInstr(InlinedLabel Label, const MachineInstr &MI) {
|
void DbgLabelInstrMap::addInstr(InlinedEntity Label, const MachineInstr &MI) {
|
||||||
assert(MI.isDebugLabel() && "not a DBG_LABEL");
|
assert(MI.isDebugLabel() && "not a DBG_LABEL");
|
||||||
LabelInstr[Label] = &MI;
|
LabelInstr[Label] = &MI;
|
||||||
}
|
}
|
||||||
@ -86,15 +86,14 @@ void DbgLabelInstrMap::addInstr(InlinedLabel Label, const MachineInstr &MI) {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Maps physreg numbers to the variables they describe.
|
// Maps physreg numbers to the variables they describe.
|
||||||
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
|
using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
|
||||||
using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedVariable, 1>>;
|
using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedEntity, 1>>;
|
||||||
using InlinedLabel = DbgLabelInstrMap::InlinedLabel;
|
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
// Claim that @Var is not described by @RegNo anymore.
|
// Claim that @Var is not described by @RegNo anymore.
|
||||||
static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
|
static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
|
||||||
InlinedVariable Var) {
|
InlinedEntity Var) {
|
||||||
const auto &I = RegVars.find(RegNo);
|
const auto &I = RegVars.find(RegNo);
|
||||||
assert(RegNo != 0U && I != RegVars.end());
|
assert(RegNo != 0U && I != RegVars.end());
|
||||||
auto &VarSet = I->second;
|
auto &VarSet = I->second;
|
||||||
@ -108,7 +107,7 @@ static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
|
|||||||
|
|
||||||
// Claim that @Var is now described by @RegNo.
|
// Claim that @Var is now described by @RegNo.
|
||||||
static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
|
static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
|
||||||
InlinedVariable Var) {
|
InlinedEntity Var) {
|
||||||
assert(RegNo != 0U);
|
assert(RegNo != 0U);
|
||||||
auto &VarSet = RegVars[RegNo];
|
auto &VarSet = RegVars[RegNo];
|
||||||
assert(!is_contained(VarSet, Var));
|
assert(!is_contained(VarSet, Var));
|
||||||
@ -249,7 +248,7 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
|
|||||||
const DILocalVariable *RawVar = MI.getDebugVariable();
|
const DILocalVariable *RawVar = MI.getDebugVariable();
|
||||||
assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
|
assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
|
||||||
"Expected inlined-at fields to agree");
|
"Expected inlined-at fields to agree");
|
||||||
InlinedVariable Var(RawVar, MI.getDebugLoc()->getInlinedAt());
|
InlinedEntity Var(RawVar, MI.getDebugLoc()->getInlinedAt());
|
||||||
|
|
||||||
if (unsigned PrevReg = DbgValues.getRegisterForVar(Var))
|
if (unsigned PrevReg = DbgValues.getRegisterForVar(Var))
|
||||||
dropRegDescribedVar(RegVars, PrevReg, Var);
|
dropRegDescribedVar(RegVars, PrevReg, Var);
|
||||||
@ -266,7 +265,7 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
|
|||||||
// When collecting debug information for labels, there is no MCSymbol
|
// When collecting debug information for labels, there is no MCSymbol
|
||||||
// generated for it. So, we keep MachineInstr in DbgLabels in order
|
// generated for it. So, we keep MachineInstr in DbgLabels in order
|
||||||
// to query MCSymbol afterward.
|
// to query MCSymbol afterward.
|
||||||
InlinedLabel L(RawLabel, MI.getDebugLoc()->getInlinedAt());
|
InlinedEntity L(RawLabel, MI.getDebugLoc()->getInlinedAt());
|
||||||
DbgLabels.addInstr(L, MI);
|
DbgLabels.addInstr(L, MI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,10 +288,10 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
|
|||||||
LLVM_DUMP_METHOD void DbgValueHistoryMap::dump() const {
|
LLVM_DUMP_METHOD void DbgValueHistoryMap::dump() const {
|
||||||
dbgs() << "DbgValueHistoryMap:\n";
|
dbgs() << "DbgValueHistoryMap:\n";
|
||||||
for (const auto &VarRangePair : *this) {
|
for (const auto &VarRangePair : *this) {
|
||||||
const InlinedVariable &Var = VarRangePair.first;
|
const InlinedEntity &Var = VarRangePair.first;
|
||||||
const InstrRanges &Ranges = VarRangePair.second;
|
const InstrRanges &Ranges = VarRangePair.second;
|
||||||
|
|
||||||
const DILocalVariable *LocalVar = Var.first;
|
const DILocalVariable *LocalVar = cast<DILocalVariable>(Var.first);
|
||||||
const DILocation *Location = Var.second;
|
const DILocation *Location = Var.second;
|
||||||
|
|
||||||
dbgs() << " - " << LocalVar->getName() << " at ";
|
dbgs() << " - " << LocalVar->getName() << " at ";
|
||||||
|
@ -33,20 +33,19 @@ class DbgValueHistoryMap {
|
|||||||
public:
|
public:
|
||||||
using InstrRange = std::pair<const MachineInstr *, const MachineInstr *>;
|
using InstrRange = std::pair<const MachineInstr *, const MachineInstr *>;
|
||||||
using InstrRanges = SmallVector<InstrRange, 4>;
|
using InstrRanges = SmallVector<InstrRange, 4>;
|
||||||
using InlinedVariable =
|
using InlinedEntity = std::pair<const DINode *, const DILocation *>;
|
||||||
std::pair<const DILocalVariable *, const DILocation *>;
|
using InstrRangesMap = MapVector<InlinedEntity, InstrRanges>;
|
||||||
using InstrRangesMap = MapVector<InlinedVariable, InstrRanges>;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InstrRangesMap VarInstrRanges;
|
InstrRangesMap VarInstrRanges;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void startInstrRange(InlinedVariable Var, const MachineInstr &MI);
|
void startInstrRange(InlinedEntity Var, const MachineInstr &MI);
|
||||||
void endInstrRange(InlinedVariable Var, const MachineInstr &MI);
|
void endInstrRange(InlinedEntity Var, const MachineInstr &MI);
|
||||||
|
|
||||||
// Returns register currently describing @Var. If @Var is currently
|
// Returns register currently describing @Var. If @Var is currently
|
||||||
// unaccessible or is not described by a register, returns 0.
|
// unaccessible or is not described by a register, returns 0.
|
||||||
unsigned getRegisterForVar(InlinedVariable Var) const;
|
unsigned getRegisterForVar(InlinedEntity Var) const;
|
||||||
|
|
||||||
bool empty() const { return VarInstrRanges.empty(); }
|
bool empty() const { return VarInstrRanges.empty(); }
|
||||||
void clear() { VarInstrRanges.clear(); }
|
void clear() { VarInstrRanges.clear(); }
|
||||||
@ -63,14 +62,14 @@ public:
|
|||||||
/// a temporary (assembler) label before it.
|
/// a temporary (assembler) label before it.
|
||||||
class DbgLabelInstrMap {
|
class DbgLabelInstrMap {
|
||||||
public:
|
public:
|
||||||
using InlinedLabel = std::pair<const DILabel *, const DILocation *>;
|
using InlinedEntity = std::pair<const DINode *, const DILocation *>;
|
||||||
using InstrMap = MapVector<InlinedLabel, const MachineInstr *>;
|
using InstrMap = MapVector<InlinedEntity, const MachineInstr *>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InstrMap LabelInstr;
|
InstrMap LabelInstr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void addInstr(InlinedLabel Label, const MachineInstr &MI);
|
void addInstr(InlinedEntity Label, const MachineInstr &MI);
|
||||||
|
|
||||||
bool empty() const { return LabelInstr.empty(); }
|
bool empty() const { return LabelInstr.empty(); }
|
||||||
void clear() { LabelInstr.clear(); }
|
void clear() { LabelInstr.clear(); }
|
||||||
|
@ -216,7 +216,7 @@ public:
|
|||||||
void finishEntityDefinition(const DbgEntity *Entity);
|
void finishEntityDefinition(const DbgEntity *Entity);
|
||||||
|
|
||||||
/// Find abstract variable associated with Var.
|
/// Find abstract variable associated with Var.
|
||||||
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
|
using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
|
||||||
DbgEntity *getExistingAbstractEntity(const DINode *Node);
|
DbgEntity *getExistingAbstractEntity(const DINode *Node);
|
||||||
void createAbstractEntity(const DINode *Node, LexicalScope *Scope);
|
void createAbstractEntity(const DINode *Node, LexicalScope *Scope);
|
||||||
|
|
||||||
|
@ -938,15 +938,15 @@ void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
|
|||||||
|
|
||||||
// Collect variable information from side table maintained by MF.
|
// Collect variable information from side table maintained by MF.
|
||||||
void DwarfDebug::collectVariableInfoFromMFTable(
|
void DwarfDebug::collectVariableInfoFromMFTable(
|
||||||
DwarfCompileUnit &TheCU, DenseSet<InlinedVariable> &Processed) {
|
DwarfCompileUnit &TheCU, DenseSet<InlinedEntity> &Processed) {
|
||||||
SmallDenseMap<InlinedVariable, DbgVariable *> MFVars;
|
SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
|
||||||
for (const auto &VI : Asm->MF->getVariableDbgInfo()) {
|
for (const auto &VI : Asm->MF->getVariableDbgInfo()) {
|
||||||
if (!VI.Var)
|
if (!VI.Var)
|
||||||
continue;
|
continue;
|
||||||
assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&
|
assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&
|
||||||
"Expected inlined-at fields to agree");
|
"Expected inlined-at fields to agree");
|
||||||
|
|
||||||
InlinedVariable Var(VI.Var, VI.Loc->getInlinedAt());
|
InlinedEntity Var(VI.Var, VI.Loc->getInlinedAt());
|
||||||
Processed.insert(Var);
|
Processed.insert(Var);
|
||||||
LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
|
LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
|
||||||
|
|
||||||
@ -955,7 +955,8 @@ void DwarfDebug::collectVariableInfoFromMFTable(
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode());
|
ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode());
|
||||||
auto RegVar = llvm::make_unique<DbgVariable>(Var.first, Var.second);
|
auto RegVar = llvm::make_unique<DbgVariable>(
|
||||||
|
cast<DILocalVariable>(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);
|
||||||
@ -1209,12 +1210,12 @@ static bool validThroughout(LexicalScopes &LScopes,
|
|||||||
// Find variables for each lexical scope.
|
// Find variables for each lexical scope.
|
||||||
void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
|
void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
|
||||||
const DISubprogram *SP,
|
const DISubprogram *SP,
|
||||||
DenseSet<InlinedVariable> &Processed) {
|
DenseSet<InlinedEntity> &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);
|
||||||
|
|
||||||
for (const auto &I : DbgValues) {
|
for (const auto &I : DbgValues) {
|
||||||
InlinedVariable IV = I.first;
|
InlinedEntity IV = I.first;
|
||||||
if (Processed.count(IV))
|
if (Processed.count(IV))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1224,17 +1225,18 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
LexicalScope *Scope = nullptr;
|
LexicalScope *Scope = nullptr;
|
||||||
|
const DILocalVariable *LocalVar = cast<DILocalVariable>(IV.first);
|
||||||
if (const DILocation *IA = IV.second)
|
if (const DILocation *IA = IV.second)
|
||||||
Scope = LScopes.findInlinedScope(IV.first->getScope(), IA);
|
Scope = LScopes.findInlinedScope(LocalVar->getScope(), IA);
|
||||||
else
|
else
|
||||||
Scope = LScopes.findLexicalScope(IV.first->getScope());
|
Scope = LScopes.findLexicalScope(LocalVar->getScope());
|
||||||
// If variable scope is not found then skip this variable.
|
// If variable scope is not found then skip this variable.
|
||||||
if (!Scope)
|
if (!Scope)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Processed.insert(IV);
|
Processed.insert(IV);
|
||||||
DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
|
DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
|
||||||
*Scope, IV.first, IV.second));
|
*Scope, LocalVar, 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");
|
||||||
@ -1260,44 +1262,46 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
|
|||||||
// unique identifiers, so don't bother resolving the type with the
|
// unique identifiers, so don't bother resolving the type with the
|
||||||
// identifier map.
|
// identifier map.
|
||||||
const DIBasicType *BT = dyn_cast<DIBasicType>(
|
const DIBasicType *BT = dyn_cast<DIBasicType>(
|
||||||
static_cast<const Metadata *>(IV.first->getType()));
|
static_cast<const Metadata *>(LocalVar->getType()));
|
||||||
|
|
||||||
// Finalize the entry by lowering it into a DWARF bytestream.
|
// Finalize the entry by lowering it into a DWARF bytestream.
|
||||||
for (auto &Entry : Entries)
|
for (auto &Entry : Entries)
|
||||||
Entry.finalize(*Asm, List, BT);
|
Entry.finalize(*Asm, List, BT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each InlinedLabel collected from DBG_LABEL instructions, convert to
|
// For each InlinedEntity collected from DBG_LABEL instructions, convert to
|
||||||
// DWARF-related DbgLabel.
|
// DWARF-related DbgLabel.
|
||||||
for (const auto &I : DbgLabels) {
|
for (const auto &I : DbgLabels) {
|
||||||
InlinedLabel IL = I.first;
|
InlinedEntity IL = I.first;
|
||||||
const MachineInstr *MI = I.second;
|
const MachineInstr *MI = I.second;
|
||||||
if (MI == nullptr)
|
if (MI == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
LexicalScope *Scope = nullptr;
|
LexicalScope *Scope = nullptr;
|
||||||
|
const DILabel *Label = cast<DILabel>(IL.first);
|
||||||
// Get inlined DILocation if it is inlined label.
|
// Get inlined DILocation if it is inlined label.
|
||||||
if (const DILocation *IA = IL.second)
|
if (const DILocation *IA = IL.second)
|
||||||
Scope = LScopes.findInlinedScope(IL.first->getScope(), IA);
|
Scope = LScopes.findInlinedScope(Label->getScope(), IA);
|
||||||
else
|
else
|
||||||
Scope = LScopes.findLexicalScope(IL.first->getScope());
|
Scope = LScopes.findLexicalScope(Label->getScope());
|
||||||
// If label scope is not found then skip this label.
|
// If label scope is not found then skip this label.
|
||||||
if (!Scope)
|
if (!Scope)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
Processed.insert(IL);
|
||||||
/// At this point, the temporary label is created.
|
/// At this point, the temporary label is created.
|
||||||
/// Save the temporary label to DbgLabel entity to get the
|
/// Save the temporary label to DbgLabel entity to get the
|
||||||
/// actually address when generating Dwarf DIE.
|
/// actually address when generating Dwarf DIE.
|
||||||
MCSymbol *Sym = getLabelBeforeInsn(MI);
|
MCSymbol *Sym = getLabelBeforeInsn(MI);
|
||||||
createConcreteEntity(TheCU, *Scope, IL.first, IL.second, Sym);
|
createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect info for variables/labels that were optimized out.
|
// Collect info for variables/labels that were optimized out.
|
||||||
for (const DINode *DN : SP->getRetainedNodes()) {
|
for (const DINode *DN : SP->getRetainedNodes()) {
|
||||||
|
if (!Processed.insert(InlinedEntity(DN, nullptr)).second)
|
||||||
|
continue;
|
||||||
LexicalScope *Scope = nullptr;
|
LexicalScope *Scope = nullptr;
|
||||||
if (auto *DV = dyn_cast<DILocalVariable>(DN)) {
|
if (auto *DV = dyn_cast<DILocalVariable>(DN)) {
|
||||||
if (!Processed.insert(InlinedVariable(DV, nullptr)).second)
|
|
||||||
continue;
|
|
||||||
Scope = LScopes.findLexicalScope(DV->getScope());
|
Scope = LScopes.findLexicalScope(DV->getScope());
|
||||||
} else if (auto *DL = dyn_cast<DILabel>(DN)) {
|
} else if (auto *DL = dyn_cast<DILabel>(DN)) {
|
||||||
Scope = LScopes.findLexicalScope(DL->getScope());
|
Scope = LScopes.findLexicalScope(DL->getScope());
|
||||||
@ -1466,8 +1470,8 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DenseSet<InlinedVariable> ProcessedVars;
|
DenseSet<InlinedEntity> Processed;
|
||||||
collectEntityInfo(TheCU, SP, ProcessedVars);
|
collectEntityInfo(TheCU, SP, Processed);
|
||||||
|
|
||||||
// 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()));
|
||||||
@ -1491,16 +1495,21 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
|
|||||||
for (LexicalScope *AScope : LScopes.getAbstractScopesList()) {
|
for (LexicalScope *AScope : LScopes.getAbstractScopesList()) {
|
||||||
auto *SP = cast<DISubprogram>(AScope->getScopeNode());
|
auto *SP = cast<DISubprogram>(AScope->getScopeNode());
|
||||||
for (const DINode *DN : SP->getRetainedNodes()) {
|
for (const DINode *DN : SP->getRetainedNodes()) {
|
||||||
if (auto *DV = dyn_cast<DILocalVariable>(DN)) {
|
if (!Processed.insert(InlinedEntity(DN, nullptr)).second)
|
||||||
// Collect info for variables that were optimized out.
|
|
||||||
if (!ProcessedVars.insert(InlinedVariable(DV, nullptr)).second)
|
|
||||||
continue;
|
continue;
|
||||||
ensureAbstractEntityIsCreated(TheCU, DV, DV->getScope());
|
|
||||||
|
const MDNode *Scope = nullptr;
|
||||||
|
if (auto *DV = dyn_cast<DILocalVariable>(DN))
|
||||||
|
Scope = DV->getScope();
|
||||||
|
else if (auto *DL = dyn_cast<DILabel>(DN))
|
||||||
|
Scope = DL->getScope();
|
||||||
|
else
|
||||||
|
llvm_unreachable("Unexpected DI type!");
|
||||||
|
|
||||||
|
// Collect info for variables/labels that were optimized out.
|
||||||
|
ensureAbstractEntityIsCreated(TheCU, DN, Scope);
|
||||||
assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes
|
assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes
|
||||||
&& "ensureAbstractEntityIsCreated inserted abstract scopes");
|
&& "ensureAbstractEntityIsCreated inserted abstract scopes");
|
||||||
} else if (auto *DL = dyn_cast<DILabel>(DN)) {
|
|
||||||
ensureAbstractEntityIsCreated(TheCU, DL, DL->getScope());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
constructAbstractSubprogramScopeDIE(TheCU, AScope);
|
constructAbstractSubprogramScopeDIE(TheCU, AScope);
|
||||||
}
|
}
|
||||||
|
@ -406,8 +406,7 @@ class DwarfDebug : public DebugHandlerBase {
|
|||||||
return InfoHolder.getUnits();
|
return InfoHolder.getUnits();
|
||||||
}
|
}
|
||||||
|
|
||||||
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
|
using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
|
||||||
using InlinedLabel = DbgLabelInstrMap::InlinedLabel;
|
|
||||||
|
|
||||||
void ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
|
void ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
|
||||||
const DINode *Node,
|
const DINode *Node,
|
||||||
@ -550,7 +549,7 @@ class DwarfDebug : public DebugHandlerBase {
|
|||||||
|
|
||||||
/// Populate LexicalScope entries with variables' info.
|
/// Populate LexicalScope entries with variables' info.
|
||||||
void collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP,
|
void collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP,
|
||||||
DenseSet<InlinedVariable> &ProcessedVars);
|
DenseSet<InlinedEntity> &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.
|
||||||
@ -559,7 +558,7 @@ class DwarfDebug : public DebugHandlerBase {
|
|||||||
|
|
||||||
/// Collect variable information from the side table maintained by MF.
|
/// Collect variable information from the side table maintained by MF.
|
||||||
void collectVariableInfoFromMFTable(DwarfCompileUnit &TheCU,
|
void collectVariableInfoFromMFTable(DwarfCompileUnit &TheCU,
|
||||||
DenseSet<InlinedVariable> &P);
|
DenseSet<InlinedEntity> &P);
|
||||||
|
|
||||||
/// Emit the reference to the section.
|
/// Emit the reference to the section.
|
||||||
void emitSectionReference(const DwarfCompileUnit &CU);
|
void emitSectionReference(const DwarfCompileUnit &CU);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
; CHECK-NEXT: DW_AT_decl_file [DW_FORM_data1] {{.*}}debug-label.c
|
; 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_decl_line [DW_FORM_data1] {{.*}}7
|
||||||
; CHECK-NEXT: DW_AT_low_pc [DW_FORM_addr] {{.*}}{{0x[0-9a-f]+}}
|
; CHECK-NEXT: DW_AT_low_pc [DW_FORM_addr] {{.*}}{{0x[0-9a-f]+}}
|
||||||
|
; CHECK-NOT: DW_AT_name [DW_FORM_strp] {{.*}}"top"
|
||||||
;
|
;
|
||||||
; RUN: llc -O0 -o - %s | FileCheck %s -check-prefix=ASM
|
; RUN: llc -O0 -o - %s | FileCheck %s -check-prefix=ASM
|
||||||
;
|
;
|
||||||
@ -61,8 +62,9 @@ declare void @llvm.dbg.label(metadata)
|
|||||||
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: false, emissionKind: FullDebug, enums: !2)
|
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: false, emissionKind: FullDebug, enums: !2)
|
||||||
!1 = !DIFile(filename: "debug-label.c", directory: "./")
|
!1 = !DIFile(filename: "debug-label.c", directory: "./")
|
||||||
!2 = !{}
|
!2 = !{}
|
||||||
|
!3 = !{!10}
|
||||||
!4 = !{i32 2, !"Debug Info Version", i32 3}
|
!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)
|
!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !0, retainedNodes: !3)
|
||||||
!7 = !DISubroutineType(types: !8)
|
!7 = !DISubroutineType(types: !8)
|
||||||
!8 = !{!9, !9, !9}
|
!8 = !{!9, !9, !9}
|
||||||
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user