diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 37 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h | 3 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 79 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 3 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalMerge.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/DIBuilder.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfoMetadata.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 12 | ||||
-rw-r--r-- | llvm/lib/IR/Metadata.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Linker/IRMover.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/StripSymbols.cpp | 17 |
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(); } |