summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2016-09-13 01:12:59 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2016-09-13 01:12:59 +0000
commitd4135bbc30de3d3dbd44d64d718fb2169f41bae0 (patch)
tree0b96e34c50822aed89a2272d9e9f3688bc3a0e46 /llvm/lib
parentefc066758309683482edd289d82ec7670d38931f (diff)
downloadbcm5719-llvm-d4135bbc30de3d3dbd44d64d718fb2169f41bae0.tar.gz
bcm5719-llvm-d4135bbc30de3d3dbd44d64d718fb2169f41bae0.zip
DebugInfo: New metadata representation for global variables.
This patch reverses the edge from DIGlobalVariable to GlobalVariable. This will allow us to more easily preserve debug info metadata when manipulating global variables. Fixes PR30362. A program for upgrading test cases is attached to that bug. Differential Revision: http://reviews.llvm.org/D20147 llvm-svn: 281284
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp4
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp37
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp2
-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
-rw-r--r--llvm/lib/IR/AsmWriter.cpp2
-rw-r--r--llvm/lib/IR/DIBuilder.cpp8
-rw-r--r--llvm/lib/IR/DebugInfoMetadata.cpp6
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h12
-rw-r--r--llvm/lib/IR/Metadata.cpp27
-rw-r--r--llvm/lib/IR/Verifier.cpp8
-rw-r--r--llvm/lib/Linker/IRMover.cpp8
-rw-r--r--llvm/lib/Transforms/IPO/StripSymbols.cpp17
18 files changed, 153 insertions, 105 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 5120b949e84..15327a1d065 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -4201,7 +4201,7 @@ bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
OPTIONAL(type, MDField, ); \
OPTIONAL(isLocal, MDBoolField, ); \
OPTIONAL(isDefinition, MDBoolField, (true)); \
- OPTIONAL(variable, MDConstant, ); \
+ OPTIONAL(expr, MDField, ); \
OPTIONAL(declaration, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
@@ -4209,7 +4209,7 @@ bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
Result = GET_OR_DISTINCT(DIGlobalVariable,
(Context, scope.Val, name.Val, linkageName.Val,
file.Val, line.Val, type.Val, isLocal.Val,
- isDefinition.Val, variable.Val, declaration.Val));
+ isDefinition.Val, expr.Val, declaration.Val));
return false;
}
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index db82766aa6c..2504ce78cc6 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2679,14 +2679,35 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
return error("Invalid record");
IsDistinct = Record[0];
- MetadataList.assignValue(
- GET_OR_DISTINCT(DIGlobalVariable,
- (Context, getMDOrNull(Record[1]),
- getMDString(Record[2]), getMDString(Record[3]),
- getMDOrNull(Record[4]), Record[5],
- getDITypeRefOrNull(Record[6]), Record[7], Record[8],
- getMDOrNull(Record[9]), getMDOrNull(Record[10]))),
- NextMetadataNo++);
+
+ // Upgrade old metadata, which stored a global variable reference or a
+ // ConstantInt here.
+ Metadata *Expr = getMDOrNull(Record[9]);
+ GlobalVariable *Attach = nullptr;
+ if (auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(Expr)) {
+ if (auto *GV = dyn_cast<GlobalVariable>(CMD->getValue())) {
+ Attach = GV;
+ Expr = nullptr;
+ } else if (auto *CI = dyn_cast<ConstantInt>(CMD->getValue())) {
+ Expr = DIExpression::get(Context,
+ {dwarf::DW_OP_constu, CI->getZExtValue(),
+ dwarf::DW_OP_stack_value});
+ } else {
+ Expr = nullptr;
+ }
+ }
+
+ DIGlobalVariable *DGV = GET_OR_DISTINCT(
+ DIGlobalVariable,
+ (Context, getMDOrNull(Record[1]), getMDString(Record[2]),
+ getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
+ getDITypeRefOrNull(Record[6]), Record[7], Record[8], Expr,
+ getMDOrNull(Record[10])));
+ MetadataList.assignValue(DGV, NextMetadataNo++);
+
+ if (Attach)
+ Attach->addDebugInfo(DGV);
+
break;
}
case bitc::METADATA_LOCAL_VAR: {
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 391adeb47f0..da6a8910318 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1710,7 +1710,7 @@ void ModuleBitcodeWriter::writeDIGlobalVariable(
Record.push_back(VE.getMetadataOrNullID(N->getType()));
Record.push_back(N->isLocalToUnit());
Record.push_back(N->isDefinition());
- Record.push_back(VE.getMetadataOrNullID(N->getRawVariable()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawExpr()));
Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration()));
Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR, Record, Abbrev);
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),
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index bcb5f198853..0734a3772e3 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1816,7 +1816,7 @@ static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N,
Printer.printMetadata("type", N->getRawType());
Printer.printBool("isLocal", N->isLocalToUnit());
Printer.printBool("isDefinition", N->isDefinition());
- Printer.printMetadata("variable", N->getRawVariable());
+ Printer.printMetadata("expr", N->getExpr());
Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration());
Out << ")";
}
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index 21cedeee78d..1adf9288e25 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -535,13 +535,13 @@ static void checkGlobalVariableScope(DIScope *Context) {
DIGlobalVariable *DIBuilder::createGlobalVariable(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
- unsigned LineNumber, DIType *Ty, bool isLocalToUnit, Constant *Val,
+ unsigned LineNumber, DIType *Ty, bool isLocalToUnit, DIExpression *Expr,
MDNode *Decl) {
checkGlobalVariableScope(Context);
auto *N = DIGlobalVariable::getDistinct(
VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
- LineNumber, Ty, isLocalToUnit, true, Val,
+ LineNumber, Ty, isLocalToUnit, true, Expr,
cast_or_null<DIDerivedType>(Decl));
AllGVs.push_back(N);
return N;
@@ -549,13 +549,13 @@ DIGlobalVariable *DIBuilder::createGlobalVariable(
DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
- unsigned LineNumber, DIType *Ty, bool isLocalToUnit, Constant *Val,
+ unsigned LineNumber, DIType *Ty, bool isLocalToUnit, DIExpression *Expr,
MDNode *Decl) {
checkGlobalVariableScope(Context);
return DIGlobalVariable::getTemporary(
VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
- LineNumber, Ty, isLocalToUnit, false, Val,
+ LineNumber, Ty, isLocalToUnit, false, Expr,
cast_or_null<DIDerivedType>(Decl))
.release();
}
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 208fa9bf9df..74f8ce84db0 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -551,6 +551,7 @@ unsigned DIExpression::ExprOperand::getSize() const {
switch (getOp()) {
case dwarf::DW_OP_bit_piece:
return 3;
+ case dwarf::DW_OP_constu:
case dwarf::DW_OP_plus:
case dwarf::DW_OP_minus:
return 2;
@@ -570,8 +571,11 @@ bool DIExpression::isValid() const {
default:
return false;
case dwarf::DW_OP_bit_piece:
- // Piece expressions must be at the end.
+ case dwarf::DW_OP_stack_value:
+ // We only support bit piece and stack value expressions which appear at
+ // the end.
return I->get() + I->getSize() == E->get();
+ case dwarf::DW_OP_constu:
case dwarf::DW_OP_plus:
case dwarf::DW_OP_minus:
case dwarf::DW_OP_deref:
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 1d0b1b1524a..40935d9331e 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -758,23 +758,23 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> {
Metadata *Type;
bool IsLocalToUnit;
bool IsDefinition;
- Metadata *Variable;
+ Metadata *Expr;
Metadata *StaticDataMemberDeclaration;
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
Metadata *File, unsigned Line, Metadata *Type,
- bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
+ bool IsLocalToUnit, bool IsDefinition, Metadata *Expr,
Metadata *StaticDataMemberDeclaration)
: Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
- IsDefinition(IsDefinition), Variable(Variable),
+ IsDefinition(IsDefinition), Expr(Expr),
StaticDataMemberDeclaration(StaticDataMemberDeclaration) {}
MDNodeKeyImpl(const DIGlobalVariable *N)
: Scope(N->getRawScope()), Name(N->getRawName()),
LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
Line(N->getLine()), Type(N->getRawType()),
IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
- Variable(N->getRawVariable()),
+ Expr(N->getRawExpr()),
StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()) {}
bool isKeyOf(const DIGlobalVariable *RHS) const {
@@ -783,13 +783,13 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> {
File == RHS->getRawFile() && Line == RHS->getLine() &&
Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
IsDefinition == RHS->isDefinition() &&
- Variable == RHS->getRawVariable() &&
+ Expr == RHS->getRawExpr() &&
StaticDataMemberDeclaration ==
RHS->getRawStaticDataMemberDeclaration();
}
unsigned getHashValue() const {
return hash_combine(Scope, Name, LinkageName, File, Line, Type,
- IsLocalToUnit, IsDefinition, Variable,
+ IsLocalToUnit, IsDefinition, Expr,
StaticDataMemberDeclaration);
}
};
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index ad95bff9e83..223326b715f 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -1424,6 +1424,21 @@ void GlobalObject::copyMetadata(const GlobalObject *Other, unsigned Offset) {
*MDNode::get(getContext(), {NewOffsetMD, TypeId}));
continue;
}
+ // If an offset adjustment was specified we need to modify the DIExpression
+ // to prepend the adjustment:
+ // !DIExpression(DW_OP_plus, Offset, [original expr])
+ if (Offset != 0 && MD.first == LLVMContext::MD_dbg) {
+ DIGlobalVariable *GV = cast<DIGlobalVariable>(MD.second);
+ DIExpression *E = GV->getExpr();
+ ArrayRef<uint64_t> OrigElements;
+ if (E)
+ OrigElements = E->getElements();
+ std::vector<uint64_t> Elements(OrigElements.size() + 2);
+ Elements[0] = dwarf::DW_OP_plus;
+ Elements[1] = Offset;
+ std::copy(OrigElements.begin(), OrigElements.end(), Elements.begin() + 2);
+ GV->replaceExpr(DIExpression::get(getContext(), Elements));
+ }
addMetadata(MD.first, *MD.second);
}
}
@@ -1444,3 +1459,15 @@ void Function::setSubprogram(DISubprogram *SP) {
DISubprogram *Function::getSubprogram() const {
return cast_or_null<DISubprogram>(getMetadata(LLVMContext::MD_dbg));
}
+
+void GlobalVariable::addDebugInfo(DIGlobalVariable *GV) {
+ addMetadata(LLVMContext::MD_dbg, *GV);
+}
+
+void GlobalVariable::getDebugInfo(
+ SmallVectorImpl<DIGlobalVariable *> &GVs) const {
+ SmallVector<MDNode *, 1> MDs;
+ getMetadata(LLVMContext::MD_dbg, MDs);
+ for (MDNode *MD : MDs)
+ GVs.push_back(cast<DIGlobalVariable>(MD));
+}
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index ba7db85094e..32ead4f54ad 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1112,12 +1112,8 @@ void Verifier::visitDIGlobalVariable(const DIGlobalVariable &N) {
AssertDI(N.getTag() == dwarf::DW_TAG_variable, "invalid tag", &N);
AssertDI(!N.getName().empty(), "missing global variable name", &N);
- if (auto *V = N.getRawVariable()) {
- AssertDI(isa<ConstantAsMetadata>(V) &&
- !isa<Function>(cast<ConstantAsMetadata>(V)->getValue()),
- "invalid global variable ref", &N, V);
- visitConstantExprsRecursively(cast<ConstantAsMetadata>(V)->getValue());
- }
+ if (auto *V = N.getRawExpr())
+ AssertDI(isa<DIExpression>(V), "invalid expression location", &N, V);
if (auto *Member = N.getRawStaticDataMemberDeclaration()) {
AssertDI(isa<DIDerivedType>(Member),
"invalid static data member declaration", &N, Member);
diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp
index c02abd7e3ac..5a00aae7e8a 100644
--- a/llvm/lib/Linker/IRMover.cpp
+++ b/llvm/lib/Linker/IRMover.cpp
@@ -465,7 +465,7 @@ class IRLinker {
Error linkModuleFlagsMetadata();
- void linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src);
+ void linkGlobalVariable(GlobalVariable &Dst, GlobalVariable &Src);
Error linkFunctionBody(Function &Dst, Function &Src);
void linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src);
Error linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src);
@@ -942,7 +942,9 @@ Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV,
/// Update the initializers in the Dest module now that all globals that may be
/// referenced are in Dest.
-void IRLinker::linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src) {
+void IRLinker::linkGlobalVariable(GlobalVariable &Dst, GlobalVariable &Src) {
+ Dst.copyMetadata(&Src, 0);
+
// Figure out what the initializer looks like in the dest module.
Mapper.scheduleMapGlobalInitializer(Dst, *Src.getInitializer());
}
@@ -985,7 +987,7 @@ Error IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
if (auto *F = dyn_cast<Function>(&Src))
return linkFunctionBody(cast<Function>(Dst), *F);
if (auto *GVar = dyn_cast<GlobalVariable>(&Src)) {
- linkGlobalInit(cast<GlobalVariable>(Dst), *GVar);
+ linkGlobalVariable(cast<GlobalVariable>(Dst), *GVar);
return Error::success();
}
linkAliasBody(cast<GlobalAlias>(Dst), cast<GlobalAlias>(Src));
diff --git a/llvm/lib/Transforms/IPO/StripSymbols.cpp b/llvm/lib/Transforms/IPO/StripSymbols.cpp
index fd250366cef..51c2103e0e5 100644
--- a/llvm/lib/Transforms/IPO/StripSymbols.cpp
+++ b/llvm/lib/Transforms/IPO/StripSymbols.cpp
@@ -312,13 +312,14 @@ bool StripDeadDebugInfo::runOnModule(Module &M) {
// replace the current list of potentially dead global variables/functions
// with the live list.
SmallVector<Metadata *, 64> LiveGlobalVariables;
- SmallVector<Metadata *, 64> LiveSubprograms;
DenseSet<const MDNode *> VisitedSet;
- std::set<DISubprogram *> LiveSPs;
- for (Function &F : M) {
- if (DISubprogram *SP = F.getSubprogram())
- LiveSPs.insert(SP);
+ std::set<DIGlobalVariable *> LiveGVs;
+ for (GlobalVariable &GV : M.globals()) {
+ SmallVector<DIGlobalVariable *, 1> DIs;
+ GV.getDebugInfo(DIs);
+ for (DIGlobalVariable *DI : DIs)
+ LiveGVs.insert(DI);
}
for (DICompileUnit *DIC : F.compile_units()) {
@@ -329,9 +330,8 @@ bool StripDeadDebugInfo::runOnModule(Module &M) {
if (!VisitedSet.insert(DIG).second)
continue;
- // If the global variable referenced by DIG is not null, the global
- // variable is live.
- if (DIG->getVariable())
+ // If a global variable references DIG, the global variable is live.
+ if (LiveGVs.count(DIG))
LiveGlobalVariables.push_back(DIG);
else
GlobalVariableChange = true;
@@ -345,7 +345,6 @@ bool StripDeadDebugInfo::runOnModule(Module &M) {
}
// Reset lists for the next iteration.
- LiveSubprograms.clear();
LiveGlobalVariables.clear();
}
OpenPOWER on IntegriCloud