|
@@ -188,12 +188,12 @@ bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,
|
|
|
}
|
|
|
|
|
|
bool DbgVariable::isBlockByrefVariable() const {
|
|
|
- assert(Var && "Invalid complex DbgVariable!");
|
|
|
- return Var->getType().resolve()->isBlockByrefStruct();
|
|
|
+ assert(getVariable() && "Invalid complex DbgVariable!");
|
|
|
+ return getVariable()->getType().resolve()->isBlockByrefStruct();
|
|
|
}
|
|
|
|
|
|
const DIType *DbgVariable::getType() const {
|
|
|
- DIType *Ty = Var->getType().resolve();
|
|
|
+ DIType *Ty = getVariable()->getType().resolve();
|
|
|
// FIXME: isBlockByrefVariable should be reformulated in terms of complex
|
|
|
// addresses instead.
|
|
|
if (Ty->isBlockByrefStruct()) {
|
|
@@ -258,8 +258,8 @@ ArrayRef<DbgVariable::FrameIndexExpr> DbgVariable::getFrameIndexExprs() const {
|
|
|
void DbgVariable::addMMIEntry(const DbgVariable &V) {
|
|
|
assert(DebugLocListIndex == ~0U && !MInsn && "not an MMI entry");
|
|
|
assert(V.DebugLocListIndex == ~0U && !V.MInsn && "not an MMI entry");
|
|
|
- assert(V.Var == Var && "conflicting variable");
|
|
|
- assert(V.IA == IA && "conflicting inlined-at location");
|
|
|
+ assert(V.getVariable() == getVariable() && "conflicting variable");
|
|
|
+ assert(V.getInlinedAt() == getInlinedAt() && "conflicting inlined-at location");
|
|
|
|
|
|
assert(!FrameIndexExprs.empty() && "Expected an MMI entry");
|
|
|
assert(!V.FrameIndexExprs.empty() && "Expected an MMI entry");
|
|
@@ -726,16 +726,16 @@ void DwarfDebug::beginModule() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void DwarfDebug::finishVariableDefinitions() {
|
|
|
- for (const auto &Var : ConcreteVariables) {
|
|
|
- DIE *VariableDie = Var->getDIE();
|
|
|
- assert(VariableDie);
|
|
|
+void DwarfDebug::finishEntityDefinitions() {
|
|
|
+ for (const auto &Entity : ConcreteEntities) {
|
|
|
+ DIE *Die = Entity->getDIE();
|
|
|
+ assert(Die);
|
|
|
// FIXME: Consider the time-space tradeoff of just storing the unit pointer
|
|
|
- // in the ConcreteVariables list, rather than looking it up again here.
|
|
|
+ // in the ConcreteEntities list, rather than looking it up again here.
|
|
|
// DIE::getUnit isn't simple - it walks parent pointers, etc.
|
|
|
- DwarfCompileUnit *Unit = CUDieMap.lookup(VariableDie->getUnitDie());
|
|
|
+ DwarfCompileUnit *Unit = CUDieMap.lookup(Die->getUnitDie());
|
|
|
assert(Unit);
|
|
|
- Unit->finishVariableDefinition(*Var);
|
|
|
+ Unit->finishEntityDefinition(Entity.get());
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -753,7 +753,7 @@ void DwarfDebug::finalizeModuleInfo() {
|
|
|
|
|
|
finishSubprogramDefinitions();
|
|
|
|
|
|
- finishVariableDefinitions();
|
|
|
+ finishEntityDefinitions();
|
|
|
|
|
|
// 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
|
|
@@ -914,25 +914,24 @@ void DwarfDebug::endModule() {
|
|
|
// FIXME: AbstractVariables.clear();
|
|
|
}
|
|
|
|
|
|
-void DwarfDebug::ensureAbstractVariableIsCreated(DwarfCompileUnit &CU, InlinedVariable IV,
|
|
|
- const MDNode *ScopeNode) {
|
|
|
- const DILocalVariable *Cleansed = nullptr;
|
|
|
- if (CU.getExistingAbstractVariable(IV, Cleansed))
|
|
|
+void DwarfDebug::ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
|
|
|
+ const DINode *Node,
|
|
|
+ const MDNode *ScopeNode) {
|
|
|
+ if (CU.getExistingAbstractEntity(Node))
|
|
|
return;
|
|
|
|
|
|
- CU.createAbstractVariable(Cleansed, LScopes.getOrCreateAbstractScope(
|
|
|
+ CU.createAbstractEntity(Node, LScopes.getOrCreateAbstractScope(
|
|
|
cast<DILocalScope>(ScopeNode)));
|
|
|
}
|
|
|
|
|
|
-void DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(DwarfCompileUnit &CU,
|
|
|
- InlinedVariable IV, const MDNode *ScopeNode) {
|
|
|
- const DILocalVariable *Cleansed = nullptr;
|
|
|
- if (CU.getExistingAbstractVariable(IV, Cleansed))
|
|
|
+void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
|
|
|
+ const DINode *Node, const MDNode *ScopeNode) {
|
|
|
+ if (CU.getExistingAbstractEntity(Node))
|
|
|
return;
|
|
|
|
|
|
if (LexicalScope *Scope =
|
|
|
LScopes.findAbstractScope(cast_or_null<DILocalScope>(ScopeNode)))
|
|
|
- CU.createAbstractVariable(Cleansed, Scope);
|
|
|
+ CU.createAbstractEntity(Node, Scope);
|
|
|
}
|
|
|
|
|
|
// Collect variable information from side table maintained by MF.
|
|
@@ -953,14 +952,14 @@ void DwarfDebug::collectVariableInfoFromMFTable(
|
|
|
if (!Scope)
|
|
|
continue;
|
|
|
|
|
|
- ensureAbstractVariableIsCreatedIfScoped(TheCU, Var, Scope->getScopeNode());
|
|
|
+ ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode());
|
|
|
auto RegVar = llvm::make_unique<DbgVariable>(Var.first, Var.second);
|
|
|
RegVar->initializeMMI(VI.Expr, VI.Slot);
|
|
|
if (DbgVariable *DbgVar = MFVars.lookup(Var))
|
|
|
DbgVar->addMMIEntry(*RegVar);
|
|
|
else if (InfoHolder.addScopeVariable(Scope, RegVar.get())) {
|
|
|
MFVars.insert({Var, RegVar.get()});
|
|
|
- ConcreteVariables.push_back(std::move(RegVar));
|
|
|
+ ConcreteEntities.push_back(std::move(RegVar));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -1125,14 +1124,26 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-DbgVariable *DwarfDebug::createConcreteVariable(DwarfCompileUnit &TheCU,
|
|
|
- LexicalScope &Scope,
|
|
|
- InlinedVariable IV) {
|
|
|
- ensureAbstractVariableIsCreatedIfScoped(TheCU, IV, Scope.getScopeNode());
|
|
|
- ConcreteVariables.push_back(
|
|
|
- llvm::make_unique<DbgVariable>(IV.first, IV.second));
|
|
|
- InfoHolder.addScopeVariable(&Scope, ConcreteVariables.back().get());
|
|
|
- return ConcreteVariables.back().get();
|
|
|
+DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU,
|
|
|
+ LexicalScope &Scope,
|
|
|
+ const DINode *Node,
|
|
|
+ const DILocation *Location,
|
|
|
+ const MCSymbol *Sym) {
|
|
|
+ ensureAbstractEntityIsCreatedIfScoped(TheCU, Node, Scope.getScopeNode());
|
|
|
+ if (isa<const DILocalVariable>(Node)) {
|
|
|
+ ConcreteEntities.push_back(
|
|
|
+ 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
|
|
@@ -1194,9 +1205,9 @@ static bool validThroughout(LexicalScopes &LScopes,
|
|
|
}
|
|
|
|
|
|
// Find variables for each lexical scope.
|
|
|
-void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU,
|
|
|
- const DISubprogram *SP,
|
|
|
- DenseSet<InlinedVariable> &Processed) {
|
|
|
+void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
|
|
|
+ const DISubprogram *SP,
|
|
|
+ DenseSet<InlinedVariable> &Processed) {
|
|
|
// Grab the variable info that was squirreled away in the MMI side-table.
|
|
|
collectVariableInfoFromMFTable(TheCU, Processed);
|
|
|
|
|
@@ -1220,7 +1231,8 @@ void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU,
|
|
|
continue;
|
|
|
|
|
|
Processed.insert(IV);
|
|
|
- DbgVariable *RegVar = createConcreteVariable(TheCU, *Scope, IV);
|
|
|
+ DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
|
|
|
+ *Scope, IV.first, IV.second));
|
|
|
|
|
|
const MachineInstr *MInsn = Ranges.front().first;
|
|
|
assert(MInsn->isDebugValue() && "History must begin with debug value");
|
|
@@ -1253,13 +1265,44 @@ void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU,
|
|
|
Entry.finalize(*Asm, List, BT);
|
|
|
}
|
|
|
|
|
|
- // Collect info for variables that were optimized out.
|
|
|
+ // For each InlinedLabel collected from DBG_LABEL instructions, convert to
|
|
|
+ // 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()) {
|
|
|
+ LexicalScope *Scope = nullptr;
|
|
|
if (auto *DV = dyn_cast<DILocalVariable>(DN)) {
|
|
|
- if (Processed.insert(InlinedVariable(DV, nullptr)).second)
|
|
|
- if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope()))
|
|
|
- createConcreteVariable(TheCU, *Scope, InlinedVariable(DV, nullptr));
|
|
|
+ if (!Processed.insert(InlinedVariable(DV, nullptr)).second)
|
|
|
+ continue;
|
|
|
+ Scope = LScopes.findLexicalScope(DV->getScope());
|
|
|
+ } else if (auto *DL = dyn_cast<DILabel>(DN)) {
|
|
|
+ Scope = LScopes.findLexicalScope(DL->getScope());
|
|
|
}
|
|
|
+
|
|
|
+ if (Scope)
|
|
|
+ createConcreteEntity(TheCU, *Scope, DN, nullptr);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1417,7 +1460,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
|
|
|
DwarfCompileUnit &TheCU = *CUMap.lookup(SP->getUnit());
|
|
|
|
|
|
DenseSet<InlinedVariable> ProcessedVars;
|
|
|
- collectVariableInfo(TheCU, SP, ProcessedVars);
|
|
|
+ collectEntityInfo(TheCU, SP, ProcessedVars);
|
|
|
|
|
|
// Add the range of this function to the list of ranges for the CU.
|
|
|
TheCU.addRange(RangeSpan(Asm->getFunctionBegin(), Asm->getFunctionEnd()));
|
|
@@ -1445,10 +1488,11 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
|
|
|
// Collect info for variables that were optimized out.
|
|
|
if (!ProcessedVars.insert(InlinedVariable(DV, nullptr)).second)
|
|
|
continue;
|
|
|
- ensureAbstractVariableIsCreated(TheCU, InlinedVariable(DV, nullptr),
|
|
|
- DV->getScope());
|
|
|
+ ensureAbstractEntityIsCreated(TheCU, DV, DV->getScope());
|
|
|
assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes
|
|
|
- && "ensureAbstractVariableIsCreated inserted abstract scopes");
|
|
|
+ && "ensureAbstractEntityIsCreated inserted abstract scopes");
|
|
|
+ } else if (auto *DL = dyn_cast<DILabel>(DN)) {
|
|
|
+ ensureAbstractEntityIsCreated(TheCU, DL, DL->getScope());
|
|
|
}
|
|
|
}
|
|
|
constructAbstractSubprogramScopeDIE(TheCU, AScope);
|
|
@@ -1466,6 +1510,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
|
|
|
// DbgVariables except those that are also in AbstractVariables (since they
|
|
|
// can be used cross-function)
|
|
|
InfoHolder.getScopeVariables().clear();
|
|
|
+ InfoHolder.getScopeLabels().clear();
|
|
|
PrevLabel = nullptr;
|
|
|
CurFn = nullptr;
|
|
|
}
|