summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp19
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h3
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp79
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h3
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp10
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp7
-rw-r--r--llvm/lib/CodeGen/GlobalMerge.cpp6
7 files changed, 63 insertions, 64 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 017fc208870..91a480ec043 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -2001,6 +2001,14 @@ void CodeViewDebug::emitDebugInfoForUDTs(
}
void CodeViewDebug::emitDebugInfoForGlobals() {
+ DenseMap<const DIGlobalVariable *, const GlobalVariable *> GlobalMap;
+ for (const GlobalVariable &GV : MMI->getModule()->globals()) {
+ 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");
for (const MDNode *Node : CUs->operands()) {
const auto *CU = cast<DICompileUnit>(Node);
@@ -2011,15 +2019,14 @@ void CodeViewDebug::emitDebugInfoForGlobals() {
switchToDebugSectionForSymbol(nullptr);
MCSymbol *EndLabel = nullptr;
for (const DIGlobalVariable *G : CU->getGlobalVariables()) {
- if (const auto *GV = dyn_cast_or_null<GlobalVariable>(G->getVariable())) {
+ if (const auto *GV = GlobalMap.lookup(G))
if (!GV->hasComdat() && !GV->isDeclarationForLinker()) {
if (!EndLabel) {
OS.AddComment("Symbol subsection for globals");
EndLabel = beginCVSubsection(ModuleSubstreamKind::Symbols);
}
- emitDebugInfoForGlobal(G, Asm->getSymbol(GV));
+ emitDebugInfoForGlobal(G, GV, Asm->getSymbol(GV));
}
- }
}
if (EndLabel)
endCVSubsection(EndLabel);
@@ -2027,14 +2034,14 @@ 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 DIGlobalVariable *G : CU->getGlobalVariables()) {
- if (const auto *GV = dyn_cast_or_null<GlobalVariable>(G->getVariable())) {
+ 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);
- emitDebugInfoForGlobal(G, GVSym);
+ emitDebugInfoForGlobal(G, GV, GVSym);
endCVSubsection(EndLabel);
}
}
@@ -2055,6 +2062,7 @@ void CodeViewDebug::emitDebugInfoForRetainedTypes() {
}
void CodeViewDebug::emitDebugInfoForGlobal(const DIGlobalVariable *DIGV,
+ const GlobalVariable *GV,
MCSymbol *GVSym) {
// DataSym record, see SymbolRecord.h for more info.
// FIXME: Thread local data, etc
@@ -2063,7 +2071,6 @@ void CodeViewDebug::emitDebugInfoForGlobal(const DIGlobalVariable *DIGV,
OS.AddComment("Record length");
OS.emitAbsoluteSymbolDiff(DataEnd, DataBegin, 2);
OS.EmitLabel(DataBegin);
- const auto *GV = cast<GlobalVariable>(DIGV->getVariable());
if (DIGV->isLocalToUnit()) {
if (GV->isThreadLocal()) {
OS.AddComment("Record kind: S_LTHREAD32");
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index 729012bbd0f..0149af5e84f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -202,7 +202,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
void emitDebugInfoForUDTs(
ArrayRef<std::pair<std::string, codeview::TypeIndex>> UDTs);
- void emitDebugInfoForGlobal(const DIGlobalVariable *DIGV, MCSymbol *GVSym);
+ void emitDebugInfoForGlobal(const DIGlobalVariable *DIGV,
+ const GlobalVariable *GV, MCSymbol *GVSym);
/// Opens a subsection of the given kind in a .debug$S codeview section.
/// Returns an end label for use with endCVSubsection when the subsection is
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 7822814c7a0..f9030d118e5 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -73,36 +73,9 @@ unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName,
Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID());
}
-// Return const expression if value is a GEP to access merged global
-// constant. e.g.
-// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0)
-static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
- const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V);
- if (!CE || CE->getNumOperands() != 3 ||
- CE->getOpcode() != Instruction::GetElementPtr)
- return nullptr;
-
- // First operand points to a global struct.
- Value *Ptr = CE->getOperand(0);
- GlobalValue *GV = dyn_cast<GlobalValue>(Ptr);
- if (!GV || !isa<StructType>(GV->getValueType()))
- return nullptr;
-
- // Second operand is zero.
- const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1));
- if (!CI || !CI->isZero())
- return nullptr;
-
- // Third operand is offset.
- if (!isa<ConstantInt>(CE->getOperand(2)))
- return nullptr;
-
- return CE;
-}
-
/// getOrCreateGlobalVariableDIE - get or create global variable DIE.
DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
- const DIGlobalVariable *GV) {
+ const DIGlobalVariable *GV, const GlobalVariable *Global) {
// Check for pre-existence.
if (DIE *Die = getDIE(GV))
return Die;
@@ -147,12 +120,22 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
// Add location.
bool addToAccelTable = false;
- if (auto *Global = dyn_cast_or_null<GlobalVariable>(GV->getVariable())) {
+
+ 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.
- if (!Global->hasDLLImportStorageClass()) {
+ } else if (!Global || !Global->hasDLLImportStorageClass()) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ if (Global) {
addToAccelTable = true;
- DIELoc *Loc = new (DIEValueAllocator) DIELoc;
const MCSymbol *Sym = Asm->getSymbol(Global);
if (Global->isThreadLocal()) {
if (Asm->TM.Options.EmulatedTLS) {
@@ -187,30 +170,16 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
addOpAddress(*Loc, Sym);
}
- addBlock(*VariableDIE, dwarf::DW_AT_location, Loc);
- if (DD->useAllLinkageNames())
- addLinkageName(*VariableDIE, GV->getLinkageName());
- }
- } else if (const ConstantInt *CI =
- dyn_cast_or_null<ConstantInt>(GV->getVariable())) {
- addConstantValue(*VariableDIE, CI, GTy);
- } else if (const ConstantExpr *CE = getMergedGlobalExpr(GV->getVariable())) {
- auto *Ptr = cast<GlobalValue>(CE->getOperand(0));
- if (!Ptr->hasDLLImportStorageClass()) {
- addToAccelTable = true;
- // GV is a merged global.
- DIELoc *Loc = new (DIEValueAllocator) DIELoc;
- MCSymbol *Sym = Asm->getSymbol(Ptr);
- DD->addArangeLabel(SymbolCU(this, Sym));
- addOpAddress(*Loc, Sym);
- addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
- SmallVector<Value *, 3> Idx(CE->op_begin() + 1, CE->op_end());
- addUInt(*Loc, dwarf::DW_FORM_udata,
- Asm->getDataLayout().getIndexedOffsetInType(Ptr->getValueType(),
- Idx));
- addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
- addBlock(*VariableDIE, dwarf::DW_AT_location, Loc);
+ if (Expr) {
+ DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
+ DwarfExpr.AddExpression(Expr->expr_op_begin(), Expr->expr_op_end());
+ }
}
+
+ addBlock(*VariableDIE, dwarf::DW_AT_location, Loc);
+
+ if (DD->useAllLinkageNames())
+ addLinkageName(*VariableDIE, GV->getLinkageName());
}
if (addToAccelTable) {
@@ -674,7 +643,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);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 90f74a3686e..766da4a3f7b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -97,7 +97,8 @@ public:
void applyStmtList(DIE &D);
/// getOrCreateGlobalVariableDIE - get or create global variable DIE.
- DIE *getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV);
+ 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 307782245a6..d9c7c2bea9e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -477,12 +477,20 @@ void DwarfDebug::beginModule() {
MMI->setDebugInfoAvailability(NumDebugCUs > 0);
SingleCU = NumDebugCUs == 1;
+ DenseMap<DIGlobalVariable *, const GlobalVariable *> GVMap;
+ for (const GlobalVariable &Global : M->globals()) {
+ SmallVector<DIGlobalVariable *, 1> GVs;
+ Global.getDebugInfo(GVs);
+ 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);
for (auto *GV : CUNode->getGlobalVariables())
- CU.getOrCreateGlobalVariableDIE(GV);
+ 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.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index 7dbc6cb3995..d3e63e3b34f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -278,6 +278,13 @@ void DwarfExpression::AddExpression(DIExpression::expr_op_iterator I,
case dwarf::DW_OP_deref:
EmitOp(dwarf::DW_OP_deref);
break;
+ case dwarf::DW_OP_constu:
+ EmitOp(dwarf::DW_OP_constu);
+ EmitUnsigned(I->getArg(0));
+ break;
+ case dwarf::DW_OP_stack_value:
+ AddStackValue();
+ break;
default:
llvm_unreachable("unhandled opcode found in expression");
}
diff --git a/llvm/lib/CodeGen/GlobalMerge.cpp b/llvm/lib/CodeGen/GlobalMerge.cpp
index 8c760b724d1..de39e96a52d 100644
--- a/llvm/lib/CodeGen/GlobalMerge.cpp
+++ b/llvm/lib/CodeGen/GlobalMerge.cpp
@@ -451,10 +451,16 @@ bool GlobalMerge::doMerge(const SmallVectorImpl<GlobalVariable *> &Globals,
M, MergedTy, isConst, GlobalValue::PrivateLinkage, MergedInit,
"_MergedGlobals", nullptr, GlobalVariable::NotThreadLocal, AddrSpace);
+ const StructLayout *MergedLayout = DL.getStructLayout(MergedTy);
+
for (ssize_t k = i, idx = 0; k != j; k = GlobalSet.find_next(k), ++idx) {
GlobalValue::LinkageTypes Linkage = Globals[k]->getLinkage();
std::string Name = Globals[k]->getName();
+ // Copy metadata while adjusting any debug info metadata by the original
+ // global's offset within the merged global.
+ MergedGV->copyMetadata(Globals[k], MergedLayout->getElementOffset(idx));
+
Constant *Idx[2] = {
ConstantInt::get(Int32Ty, 0),
ConstantInt::get(Int32Ty, idx),
OpenPOWER on IntegriCloud