summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp25
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp130
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h13
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp43
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h4
5 files changed, 85 insertions, 130 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 3f5ef1a52ff..8e170323e5e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -2181,13 +2181,12 @@ void CodeViewDebug::emitDebugInfoForUDTs(
}
void CodeViewDebug::emitDebugInfoForGlobals() {
- DenseMap<const DIGlobalVariableExpression *, const GlobalVariable *>
- GlobalMap;
+ DenseMap<const DIGlobalVariable *, const GlobalVariable *> GlobalMap;
for (const GlobalVariable &GV : MMI->getModule()->globals()) {
- SmallVector<DIGlobalVariableExpression *, 1> GVEs;
- GV.getDebugInfo(GVEs);
- for (const auto *GVE : GVEs)
- GlobalMap[GVE] = &GV;
+ SmallVector<MDNode *, 1> MDs;
+ GV.getMetadata(LLVMContext::MD_dbg, MDs);
+ for (MDNode *MD : MDs)
+ GlobalMap[cast<DIGlobalVariable>(MD)] = &GV;
}
NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
@@ -2199,15 +2198,14 @@ void CodeViewDebug::emitDebugInfoForGlobals() {
// it if we have at least one global to emit.
switchToDebugSectionForSymbol(nullptr);
MCSymbol *EndLabel = nullptr;
- for (const auto *GVE : CU->getGlobalVariables()) {
- if (const auto *GV = GlobalMap.lookup(GVE))
+ for (const DIGlobalVariable *G : CU->getGlobalVariables()) {
+ if (const auto *GV = GlobalMap.lookup(G))
if (!GV->hasComdat() && !GV->isDeclarationForLinker()) {
if (!EndLabel) {
OS.AddComment("Symbol subsection for globals");
EndLabel = beginCVSubsection(ModuleSubstreamKind::Symbols);
}
- // FIXME: emitDebugInfoForGlobal() doesn't handle DIExpressions.
- emitDebugInfoForGlobal(GVE->getVariable(), GV, Asm->getSymbol(GV));
+ emitDebugInfoForGlobal(G, GV, Asm->getSymbol(GV));
}
}
if (EndLabel)
@@ -2215,16 +2213,15 @@ void CodeViewDebug::emitDebugInfoForGlobals() {
// Second, emit each global that is in a comdat into its own .debug$S
// section along with its own symbol substream.
- for (const auto *GVE : CU->getGlobalVariables()) {
- if (const auto *GV = GlobalMap.lookup(GVE)) {
+ for (const DIGlobalVariable *G : CU->getGlobalVariables()) {
+ if (const auto *GV = GlobalMap.lookup(G)) {
if (GV->hasComdat()) {
MCSymbol *GVSym = Asm->getSymbol(GV);
OS.AddComment("Symbol subsection for " +
Twine(GlobalValue::getRealLinkageName(GV->getName())));
switchToDebugSectionForSymbol(GVSym);
EndLabel = beginCVSubsection(ModuleSubstreamKind::Symbols);
- // FIXME: emitDebugInfoForGlobal() doesn't handle DIExpressions.
- emitDebugInfoForGlobal(GVE->getVariable(), GV, GVSym);
+ emitDebugInfoForGlobal(G, GV, GVSym);
endCVSubsection(EndLabel);
}
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 0db623bbc29..5f9506cd540 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -73,8 +73,9 @@ unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName,
Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID());
}
+/// getOrCreateGlobalVariableDIE - get or create global variable DIE.
DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
- const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
+ const DIGlobalVariable *GV, const GlobalVariable *Global) {
// Check for pre-existence.
if (DIE *Die = getDIE(GV))
return Die;
@@ -127,76 +128,69 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
// Add location.
bool addToAccelTable = false;
- DIELoc *Loc = nullptr;
- std::unique_ptr<DIEDwarfExpression> DwarfExpr;
- bool AllConstant = std::all_of(
- GlobalExprs.begin(), GlobalExprs.end(),
- [&](const GlobalExpr GE) {
- return GE.Expr && GE.Expr->isConstant();
- });
-
- for (const auto &GE : GlobalExprs) {
- const GlobalVariable *Global = GE.Var;
- const DIExpression *Expr = GE.Expr;
- // For compatibility with DWARF 3 and earlier,
- // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) becomes
- // DW_AT_const_value(X).
- if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {
- addConstantValue(*VariableDIE, /*Unsigned=*/true, Expr->getElement(1));
- // We cannot describe the location of dllimport'd variables: the
- // computation of their address requires loads from the IAT.
- } else if ((Global && !Global->hasDLLImportStorageClass()) || AllConstant) {
- if (!Loc) {
- Loc = new (DIEValueAllocator) DIELoc;
- DwarfExpr = llvm::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc);
- }
+
+ DIExpression *Expr = GV->getExpr();
+
+ // For compatibility with DWARF 3 and earlier,
+ // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) becomes
+ // DW_AT_const_value(X).
+ if (Expr && Expr->getNumElements() == 3 &&
+ Expr->getElement(0) == dwarf::DW_OP_constu &&
+ Expr->getElement(2) == dwarf::DW_OP_stack_value) {
+ addConstantValue(*VariableDIE, /*Unsigned=*/true, Expr->getElement(1));
+ // We cannot describe the location of dllimport'd variables: the computation
+ // of their address requires loads from the IAT.
+ } else if (!Global || !Global->hasDLLImportStorageClass()) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ if (Global) {
addToAccelTable = true;
- if (Global) {
- const MCSymbol *Sym = Asm->getSymbol(Global);
- if (Global->isThreadLocal()) {
- if (Asm->TM.Options.EmulatedTLS) {
- // TODO: add debug info for emulated thread local mode.
+ const MCSymbol *Sym = Asm->getSymbol(Global);
+ if (Global->isThreadLocal()) {
+ if (Asm->TM.Options.EmulatedTLS) {
+ // TODO: add debug info for emulated thread local mode.
+ } else {
+ // FIXME: Make this work with -gsplit-dwarf.
+ unsigned PointerSize = Asm->getDataLayout().getPointerSize();
+ assert((PointerSize == 4 || PointerSize == 8) &&
+ "Add support for other sizes if necessary");
+ // Based on GCC's support for TLS:
+ if (!DD->useSplitDwarf()) {
+ // 1) Start with a constNu of the appropriate pointer size
+ addUInt(*Loc, dwarf::DW_FORM_data1, PointerSize == 4
+ ? dwarf::DW_OP_const4u
+ : dwarf::DW_OP_const8u);
+ // 2) containing the (relocated) offset of the TLS variable
+ // within the module's TLS block.
+ addExpr(*Loc, dwarf::DW_FORM_udata,
+ Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
} else {
- // FIXME: Make this work with -gsplit-dwarf.
- unsigned PointerSize = Asm->getDataLayout().getPointerSize();
- assert((PointerSize == 4 || PointerSize == 8) &&
- "Add support for other sizes if necessary");
- // Based on GCC's support for TLS:
- if (!DD->useSplitDwarf()) {
- // 1) Start with a constNu of the appropriate pointer size
- addUInt(*Loc, dwarf::DW_FORM_data1,
- PointerSize == 4 ? dwarf::DW_OP_const4u
- : dwarf::DW_OP_const8u);
- // 2) containing the (relocated) offset of the TLS variable
- // within the module's TLS block.
- addExpr(*Loc, dwarf::DW_FORM_udata,
- Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
- } else {
- addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
- addUInt(*Loc, dwarf::DW_FORM_udata,
- DD->getAddressPool().getIndex(Sym, /* TLS */ true));
- }
- // 3) followed by an OP to make the debugger do a TLS lookup.
- addUInt(*Loc, dwarf::DW_FORM_data1,
- DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
- : dwarf::DW_OP_form_tls_address);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
+ addUInt(*Loc, dwarf::DW_FORM_udata,
+ DD->getAddressPool().getIndex(Sym, /* TLS */ true));
}
- } else {
- DD->addArangeLabel(SymbolCU(this, Sym));
- addOpAddress(*Loc, Sym);
+ // 3) followed by an OP to make the debugger do a TLS lookup.
+ addUInt(*Loc, dwarf::DW_FORM_data1,
+ DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
+ : dwarf::DW_OP_form_tls_address);
}
+ } else {
+ DD->addArangeLabel(SymbolCU(this, Sym));
+ addOpAddress(*Loc, Sym);
}
+
if (Expr) {
- DwarfExpr->addFragmentOffset(Expr);
- DwarfExpr->AddExpression(Expr);
+ DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
+ DwarfExpr.addFragmentOffset(Expr);
+ DwarfExpr.AddExpression(Expr);
+ DwarfExpr.finalize();
}
}
- }
- if (Loc)
- addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());
- if (DD->useAllLinkageNames())
- addLinkageName(*VariableDIE, GV->getLinkageName());
+ addBlock(*VariableDIE, dwarf::DW_AT_location, Loc);
+
+ if (DD->useAllLinkageNames())
+ addLinkageName(*VariableDIE, GV->getLinkageName());
+ }
if (addToAccelTable) {
DD->addAccelName(GV->getName(), *VariableDIE);
@@ -509,7 +503,8 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
DwarfExpr.addFragmentOffset(Expr);
DwarfExpr.AddUnsignedConstant(DVInsn->getOperand(0).getImm());
DwarfExpr.AddExpression(Expr);
- addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
+ DwarfExpr.finalize();
+ addBlock(*VariableDie, dwarf::DW_AT_location, Loc);
} else
addConstantValue(*VariableDie, DVInsn->getOperand(0), DV.getType());
} else if (DVInsn->getOperand(0).isFPImm())
@@ -539,7 +534,8 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
DwarfExpr.AddExpression(*Expr);
++Expr;
}
- addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
+ DwarfExpr.finalize();
+ addBlock(*VariableDie, dwarf::DW_AT_location, Loc);
return VariableDie;
}
@@ -658,7 +654,7 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE(
else if (auto *T = dyn_cast<DIType>(Entity))
EntityDie = getOrCreateTypeDIE(T);
else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))
- EntityDie = getOrCreateGlobalVariableDIE(GV, {});
+ EntityDie = getOrCreateGlobalVariableDIE(GV, nullptr);
else
EntityDie = getDIE(Entity);
assert(EntityDie);
@@ -744,8 +740,10 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
if (!validReg)
return;
+ Expr.finalize();
+
// Now attach the location information to the DIE.
- addBlock(Die, Attribute, Expr.finalize());
+ addBlock(Die, Attribute, Loc);
}
/// Start with the address based on the location provided, and generate the
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index a8025f1d152..da20bef5221 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -91,16 +91,9 @@ public:
/// Apply the DW_AT_stmt_list from this compile unit to the specified DIE.
void applyStmtList(DIE &D);
- /// A pair of GlobalVariable and DIExpression.
- struct GlobalExpr {
- const GlobalVariable *Var;
- const DIExpression *Expr;
- };
-
- /// Get or create global variable DIE.
- DIE *
- getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV,
- ArrayRef<GlobalExpr> GlobalExprs);
+ /// getOrCreateGlobalVariableDIE - get or create global variable DIE.
+ DIE *getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV,
+ const GlobalVariable *Global);
/// addLabelAddress - Add a dwarf label attribute data and value using
/// either DW_FORM_addr or DW_FORM_GNU_addr_index.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index e6f5590164d..f83a340219d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -464,26 +464,6 @@ 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.
@@ -500,30 +480,21 @@ void DwarfDebug::beginModule() {
// Tell MMI whether we have debug info.
MMI->setDebugInfoAvailability(NumDebugCUs > 0);
SingleCU = NumDebugCUs == 1;
- DenseMap<DIGlobalVariable *, SmallVector<DwarfCompileUnit::GlobalExpr, 1>>
- GVMap;
+
+ DenseMap<DIGlobalVariable *, const GlobalVariable *> GVMap;
for (const GlobalVariable &Global : M->globals()) {
- SmallVector<DIGlobalVariableExpression *, 1> GVs;
+ SmallVector<DIGlobalVariable *, 1> GVs;
Global.getDebugInfo(GVs);
- for (auto *GVE : GVs)
- GVMap[GVE->getVariable()].push_back({&Global, GVE->getExpression()});
+ for (auto &GV : GVs)
+ GVMap[GV] = &Global;
}
for (DICompileUnit *CUNode : M->debug_compile_units()) {
DwarfCompileUnit &CU = constructDwarfCompileUnit(CUNode);
for (auto *IE : CUNode->getImportedEntities())
CU.addImportedEntity(IE);
-
- // 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 *GV : CUNode->getGlobalVariables())
+ CU.getOrCreateGlobalVariableDIE(GV, GVMap.lookup(GV));
for (auto *Ty : CUNode->getEnumTypes()) {
// The enum types array by design contains pointers to
// MDNodes rather than DIRefs. Unique them here.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 96d9f09faf0..bebf3db42c6 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -215,10 +215,6 @@ public:
void EmitUnsigned(uint64_t Value) override;
bool isFrameRegister(const TargetRegisterInfo &TRI,
unsigned MachineReg) override;
- DIELoc *finalize() {
- DwarfExpression::finalize();
- return &DIE;
- }
};
}
OpenPOWER on IntegriCloud