diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index f83a340219d..e6f5590164d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -464,6 +464,26 @@ void DwarfDebug::constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU, D->addChild(TheCU.constructImportedEntityDIE(N)); } +/// Sort and unique GVEs by comparing their fragment offset. +static SmallVectorImpl<DwarfCompileUnit::GlobalExpr> & +sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) { + std::sort(GVEs.begin(), GVEs.end(), + [](DwarfCompileUnit::GlobalExpr A, DwarfCompileUnit::GlobalExpr B) { + if (A.Expr != B.Expr && A.Expr && B.Expr && + A.Expr->isFragment() && B.Expr->isFragment()) + return A.Expr->getFragmentOffsetInBits() < + B.Expr->getFragmentOffsetInBits(); + return false; + }); + GVEs.erase(std::unique(GVEs.begin(), GVEs.end(), + [](DwarfCompileUnit::GlobalExpr A, + DwarfCompileUnit::GlobalExpr B) { + return A.Expr == B.Expr; + }), + GVEs.end()); + return GVEs; +} + // Emit all Dwarf sections that should come prior to the content. Create // global DIEs and emit initial debug info sections. This is invoked by // the target AsmPrinter. @@ -480,21 +500,30 @@ void DwarfDebug::beginModule() { // Tell MMI whether we have debug info. MMI->setDebugInfoAvailability(NumDebugCUs > 0); SingleCU = NumDebugCUs == 1; - - DenseMap<DIGlobalVariable *, const GlobalVariable *> GVMap; + DenseMap<DIGlobalVariable *, SmallVector<DwarfCompileUnit::GlobalExpr, 1>> + GVMap; for (const GlobalVariable &Global : M->globals()) { - SmallVector<DIGlobalVariable *, 1> GVs; + SmallVector<DIGlobalVariableExpression *, 1> GVs; Global.getDebugInfo(GVs); - for (auto &GV : GVs) - GVMap[GV] = &Global; + for (auto *GVE : GVs) + GVMap[GVE->getVariable()].push_back({&Global, GVE->getExpression()}); } for (DICompileUnit *CUNode : M->debug_compile_units()) { DwarfCompileUnit &CU = constructDwarfCompileUnit(CUNode); for (auto *IE : CUNode->getImportedEntities()) CU.addImportedEntity(IE); - for (auto *GV : CUNode->getGlobalVariables()) - CU.getOrCreateGlobalVariableDIE(GV, GVMap.lookup(GV)); + + // Global Variables. + for (auto *GVE : CUNode->getGlobalVariables()) + GVMap[GVE->getVariable()].push_back({nullptr, GVE->getExpression()}); + DenseSet<DIGlobalVariable *> Processed; + for (auto *GVE : CUNode->getGlobalVariables()) { + DIGlobalVariable *GV = GVE->getVariable(); + if (Processed.insert(GV).second) + CU.getOrCreateGlobalVariableDIE(GV, sortGlobalExprs(GVMap[GV])); + } + for (auto *Ty : CUNode->getEnumTypes()) { // The enum types array by design contains pointers to // MDNodes rather than DIRefs. Unique them here. |