Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions llvm/include/llvm/CodeGen/LexicalScopes.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,18 @@ class LexicalScopes {
return I != LexicalScopeMap.end() ? &I->second : nullptr;
}

bool currentFunctionHasInlinedScopes() {
return !InlinedLexicalScopeMap.empty();
}

/// Find or create an abstract lexical scope.
LLVM_ABI LexicalScope *getOrCreateAbstractScope(const DILocalScope *Scope);

/// Get function to which the given subprogram is attached, if exists.
const Function *getFunction(const DISubprogram *SP) const {
return FunctionMap.lookup(SP);
/// Get functions to which the given subprogram is attached.
const SmallPtrSet<const Function *, 1> *
getFunctions(const DISubprogram *SP) const {
auto I = FunctionMap.find(SP);
return I == FunctionMap.end() ? nullptr : &I->second;
}

private:
Expand All @@ -218,6 +224,15 @@ class LexicalScopes {
: nullptr;
}

/// Create abstract lexical scope for local scopes used by multiple
/// functions, if needed.
void ensureAbstractLexicalScopeIsCreated(const DILocalScope *Scope) {
const DISubprogram *SP = Scope->getSubprogram();
const auto *Fns = getFunctions(SP);
if (!Fns || Fns->size() != 1)
getOrCreateAbstractScope(Scope);
}

/// Find or create a regular lexical scope.
LexicalScope *getOrCreateRegularScope(const DILocalScope *Scope);

Expand All @@ -237,7 +252,7 @@ class LexicalScopes {
const MachineFunction *MF = nullptr;

/// Mapping between DISubprograms and IR functions.
DenseMap<const DISubprogram *, const Function *> FunctionMap;
DenseMap<const DISubprogram *, SmallPtrSet<const Function *, 1>> FunctionMap;

/// Tracks the scopes in the current function.
// Use an unordered_map to ensure value pointer validity over insertion.
Expand Down
23 changes: 16 additions & 7 deletions llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1658,9 +1658,9 @@ void CodeViewDebug::addToUDTs(const DIType *Ty) {
formatNestedName(ParentScopeNames, getPrettyScopeName(Ty));

if (ClosestSubprogram == nullptr) {
GlobalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);
GlobalUDTs[Ty] = std::move(FullyQualifiedName);
} else if (ClosestSubprogram == CurrentSubprogram) {
LocalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);
LocalUDTs[Ty] = std::move(FullyQualifiedName);
}

// TODO: What if the ClosestSubprogram is neither null or the current
Expand Down Expand Up @@ -2698,6 +2698,12 @@ TypeIndex CodeViewDebug::getTypeIndex(const DIType *Ty, const DIType *ClassTy) {
if (!Ty)
return TypeIndex::Void();

if (Ty->getTag() == dwarf::DW_TAG_typedef) {
// Ensure that UDT is added even if the (local) type has been translated
// during processing of the previous function.
addToUDTs(Ty);
}

// Check if we've already translated this type. Don't try to do a
// get-or-create style insertion that caches the hash lookup across the
// lowerType call. It will update the TypeIndices map.
Expand Down Expand Up @@ -2787,6 +2793,10 @@ TypeIndex CodeViewDebug::getCompleteTypeIndex(const DIType *Ty) {
return FwdDeclTI;
}

// Ensure that UDT is added even if the (local) type has been translated
// during processing of the previous function.
addToUDTs(CTy);

// Check if we've already translated the complete record type.
// Insert the type with a null TypeIndex to signify that the type is currently
// being lowered.
Expand Down Expand Up @@ -3217,20 +3227,19 @@ void CodeViewDebug::emitEndSymbolRecord(SymbolKind EndKind) {
OS.emitInt16(uint16_t(EndKind)); // Record Kind
}

void CodeViewDebug::emitDebugInfoForUDTs(
const std::vector<std::pair<std::string, const DIType *>> &UDTs) {
template <typename Range>
void CodeViewDebug::emitDebugInfoForUDTs(Range &&UDTs) {
#ifndef NDEBUG
size_t OriginalSize = UDTs.size();
#endif
for (const auto &UDT : UDTs) {
const DIType *T = UDT.second;
for (const auto &[T, Name] : UDTs) {
assert(shouldEmitUdt(T));
MCSymbol *UDTRecordEnd = beginSymbolRecord(SymbolKind::S_UDT);
OS.AddComment("Type");
OS.emitInt32(getCompleteTypeIndex(T).getIndex());
assert(OriginalSize == UDTs.size() &&
"getCompleteTypeIndex found new UDTs!");
emitNullTerminatedSymbolName(OS, UDT.first);
emitNullTerminatedSymbolName(OS, Name);
endSymbolRecord(UDTRecordEnd);
}
}
Expand Down
7 changes: 3 additions & 4 deletions llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {

// The UDTs we have seen while processing types; each entry is a pair of type
// index and type name.
std::vector<std::pair<std::string, const DIType *>> LocalUDTs;
std::vector<std::pair<std::string, const DIType *>> GlobalUDTs;
MapVector<const DIType *, std::string> LocalUDTs;
MapVector<const DIType *, std::string> GlobalUDTs;

using FileToFilepathMapTy = std::map<const DIFile *, std::string>;
FileToFilepathMapTy FileToFilepathMap;
Expand Down Expand Up @@ -352,8 +352,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {

void emitDebugInfoForRetainedTypes();

void emitDebugInfoForUDTs(
const std::vector<std::pair<std::string, const DIType *>> &UDTs);
template <typename Range> void emitDebugInfoForUDTs(Range &&UDTs);

void collectDebugInfoForGlobals();
void emitDebugInfoForGlobals();
Expand Down
21 changes: 14 additions & 7 deletions llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {
DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
// Check for pre-existence.
if (DIE *Die = getDIE(GV))
if (DIE *Die = getDIEs(GV).getVariableDIE(GV))
return Die;

assert(GV);
Expand Down Expand Up @@ -795,7 +795,9 @@ DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {

DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {
auto *VariableDie = DIE::get(DIEValueAllocator, DV.getTag());
insertDIE(DV.getVariable(), VariableDie);
getDIEs(DV.getVariable())
.getLVs()
.insertDIE(DV.getVariable(), &DV, VariableDie, Abstract);
DV.setDIE(*VariableDie);
// Abstract variables don't get common attributes later, so apply them now.
if (Abstract) {
Expand Down Expand Up @@ -1010,7 +1012,9 @@ DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL,
const LexicalScope &Scope) {
auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag());
insertDIE(DL.getLabel(), LabelDie);
getDIEs(DL.getLabel())
.getLabels()
.insertDIE(DL.getLabel(), &DL, LabelDie, Scope.isAbstractScope());
DL.setDIE(*LabelDie);

if (Scope.isAbstractScope())
Expand Down Expand Up @@ -1472,8 +1476,9 @@ DIE *DwarfCompileUnit::getOrCreateImportedEntityDIE(
return IMDie;
}

void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
DIE *D = getDIE(SP);
void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP,
const Function *F) {
DIE *D = getDIEs(SP).getLocalScopes().getConcreteDIE(SP, F);
if (DIE *AbsSPDIE = getAbstractScopeDIEs().lookup(SP)) {
if (D)
// If this subprogram has an abstract definition, reference that
Expand Down Expand Up @@ -1834,14 +1839,16 @@ DIE *DwarfCompileUnit::getOrCreateSubprogramDIE(const DISubprogram *SP,
const Function *F,
bool Minimal) {
if (!F && SP->isDefinition()) {
F = DD->getLexicalScopes().getFunction(SP);
const auto *Fs = DD->getLexicalScopes().getFunctions(SP);

if (!F) {
if (!Fs || Fs->size() != 1) {
// SP may belong to another CU. Determine the CU similarly
// to DwarfDebug::constructAbstractSubprogramScopeDIE.
return &DD->getOrCreateAbstractSubprogramCU(SP, *this)
.getOrCreateAbstractSubprogramDIE(SP);
}

F = *Fs->begin();
}

return DwarfUnit::getOrCreateSubprogramDIE(SP, F, Minimal);
Expand Down
26 changes: 9 additions & 17 deletions llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,10 @@ class DwarfCompileUnit final : public DwarfUnit {
// List of concrete lexical block scopes belong to subprograms within this CU.
DenseMap<const DILocalScope *, DIE *> LexicalBlockDIEs;

// List of abstract local scopes (either DISubprogram or DILexicalBlock).
DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
SmallPtrSet<const DISubprogram *, 8> FinalizedAbstractSubprograms;

// List of inlined lexical block scopes that belong to subprograms within this
// CU.
DenseMap<const DILocalScope *, SmallVector<DIE *, 2>> InlinedLocalScopeDIEs;

DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;

/// DWO ID for correlating skeleton and split units.
uint64_t DWOId = 0;

Expand Down Expand Up @@ -126,22 +120,20 @@ class DwarfCompileUnit final : public DwarfUnit {

bool isDwoUnit() const override;

DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() {
if (isDwoUnit() && !DD->shareAcrossDWOCUs())
return AbstractLocalScopeDIEs;
return DU->getAbstractScopeDIEs();
DwarfInfoHolder &getDIEs(const DINode *N) { return DwarfUnit::getDIEs(N); }

DwarfInfoHolder &getDIEs() { return getDIEs(nullptr); }

DwarfInfoHolder::AbstractScopeMapT &getAbstractScopeDIEs() {
return getDIEs().getLocalScopes().getAbstractDIEs();
}

DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {
if (isDwoUnit() && !DD->shareAcrossDWOCUs())
return AbstractEntities;
return DU->getAbstractEntities();
return getDIEs().getAbstractEntities();
}

auto &getFinalizedAbstractSubprograms() {
if (isDwoUnit() && !DD->shareAcrossDWOCUs())
return FinalizedAbstractSubprograms;
return DU->getFinalizedAbstractSubprograms();
return getDIEs().getFinalizedAbstractSubprograms();
}

void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) override;
Expand Down Expand Up @@ -327,7 +319,7 @@ class DwarfCompileUnit final : public DwarfUnit {
DIE *getOrCreateImportedEntityDIE(const DIImportedEntity *IE);
DIE *constructImportedEntityDIE(const DIImportedEntity *IE);

void finishSubprogramDefinition(const DISubprogram *SP);
void finishSubprogramDefinition(const DISubprogram *SP, const Function *F);
void finishEntityDefinition(const DbgEntity *Entity);
void attachLexicalScopesAbstractOrigins();

Expand Down
19 changes: 11 additions & 8 deletions llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,8 @@ void DwarfDebug::addSubprogramNames(
// well into the name table. Only do that if we are going to actually emit
// that name.
if (LinkageName != "" && SP->getName() != LinkageName &&
(useAllLinkageNames() || InfoHolder.getAbstractScopeDIEs().lookup(SP)))
(useAllLinkageNames() ||
InfoHolder.getDIEs().getLocalScopes().getAbstractDIEs().lookup(SP)))
addAccelName(Unit, NameTableKind, LinkageName, Die);

// If this is an Objective-C selector name add it to the ObjC accelerator
Expand Down Expand Up @@ -1263,11 +1264,13 @@ void DwarfDebug::finishEntityDefinitions() {
}

void DwarfDebug::finishSubprogramDefinitions() {
for (const DISubprogram *SP : ProcessedSPNodes) {
for (auto SPF : ProcessedSPNodes) {
const DISubprogram *SP = SPF.first;
assert(SP->getUnit()->getEmissionKind() != DICompileUnit::NoDebug);
forBothCUs(
getOrCreateDwarfCompileUnit(SP->getUnit()),
[&](DwarfCompileUnit &CU) { CU.finishSubprogramDefinition(SP); });
forBothCUs(getOrCreateDwarfCompileUnit(SP->getUnit()),
[&](DwarfCompileUnit &CU) {
CU.finishSubprogramDefinition(SP, SPF.second);
});
}
}

Expand Down Expand Up @@ -2747,7 +2750,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
// is still needed as we need its source location.
if (!TheCU.getCUNode()->getDebugInfoForProfiling() &&
TheCU.getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly &&
LScopes.getAbstractScopesList().empty() && !IsDarwin) {
!LScopes.currentFunctionHasInlinedScopes() && !IsDarwin) {
for (const auto &R : Asm->MBBSectionRanges)
addArangeLabel(SymbolCU(&TheCU, R.second.BeginLabel));

Expand Down Expand Up @@ -2784,11 +2787,11 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
constructAbstractSubprogramScopeDIE(TheCU, AScope);
}

ProcessedSPNodes.insert(SP);
ProcessedSPNodes.insert(std::make_pair(SP, &F));
DIE &ScopeDIE =
TheCU.constructSubprogramScopeDIE(SP, F, FnScope, FunctionLineTableLabel);
if (auto *SkelCU = TheCU.getSkeleton())
if (!LScopes.getAbstractScopesList().empty() &&
if (LScopes.currentFunctionHasInlinedScopes() &&
TheCU.getCUNode()->getSplitDebugInlining())
SkelCU->constructSubprogramScopeDIE(SP, F, FnScope,
FunctionLineTableLabel);
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,8 @@ class DwarfDebug : public DebugHandlerBase {

/// This is a collection of subprogram MDNodes that are processed to
/// create DIEs.
SmallSetVector<const DISubprogram *, 16> ProcessedSPNodes;
SmallSetVector<std::pair<const DISubprogram *, const Function *>, 16>
ProcessedSPNodes;

/// Map function-local imported entities to their parent local scope
/// (either DILexicalBlock or DISubprogram) for a processed function
Expand Down
Loading