diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ModuleDebugInfoPrinter.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 23 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 130 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 13 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 43 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h | 4 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/IR/DIBuilder.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfo.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfoMetadata.cpp | 45 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 26 | ||||
-rw-r--r-- | llvm/lib/IR/Metadata.cpp | 21 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 26 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/StripSymbols.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 2 |
18 files changed, 151 insertions, 313 deletions
diff --git a/llvm/lib/Analysis/ModuleDebugInfoPrinter.cpp b/llvm/lib/Analysis/ModuleDebugInfoPrinter.cpp index f675830aa67..5b254c8cf11 100644 --- a/llvm/lib/Analysis/ModuleDebugInfoPrinter.cpp +++ b/llvm/lib/Analysis/ModuleDebugInfoPrinter.cpp @@ -91,8 +91,7 @@ void ModuleDebugInfoPrinter::print(raw_ostream &O, const Module *M) const { O << '\n'; } - for (auto GVU : Finder.global_variables()) { - const auto *GV = GVU->getVariable(); + for (const DIGlobalVariable *GV : Finder.global_variables()) { O << "Global variable: " << GV->getName(); printFile(O, GV->getFilename(), GV->getDirectory(), GV->getLine()); if (!GV->getLinkageName().empty()) diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 712a2c6762d..d4de28e2c1f 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4197,7 +4197,8 @@ bool LLParser::ParseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) { /// ParseDIGlobalVariable: /// ::= !DIGlobalVariable(scope: !0, name: "foo", linkageName: "foo", /// file: !1, line: 7, type: !2, isLocal: false, -/// isDefinition: true, declaration: !3, align: 8) +/// isDefinition: true, variable: i32* @foo, +/// declaration: !3, align: 8) bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(name, MDStringField, (/* AllowEmpty */ false)); \ @@ -4208,6 +4209,7 @@ bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { OPTIONAL(type, MDField, ); \ OPTIONAL(isLocal, MDBoolField, ); \ OPTIONAL(isDefinition, MDBoolField, (true)); \ + OPTIONAL(expr, MDField, ); \ OPTIONAL(declaration, MDField, ); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); PARSE_MD_FIELDS(); @@ -4216,7 +4218,8 @@ 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, declaration.Val, align.Val)); + isDefinition.Val, expr.Val, declaration.Val, + align.Val)); return false; } @@ -4284,21 +4287,6 @@ bool LLParser::ParseDIExpression(MDNode *&Result, bool IsDistinct) { return false; } -/// ParseDIGlobalVariableExpression: -/// ::= !DIGlobalVariableExpression(var: !0, expr: !1) -bool LLParser::ParseDIGlobalVariableExpression(MDNode *&Result, - bool IsDistinct) { -#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ - REQUIRED(var, MDField, ); \ - OPTIONAL(expr, MDField, ); - PARSE_MD_FIELDS(); -#undef VISIT_MD_FIELDS - - Result = - GET_OR_DISTINCT(DIGlobalVariableExpression, (Context, var.Val, expr.Val)); - return false; -} - /// ParseDIObjCProperty: /// ::= !DIObjCProperty(name: "foo", file: !1, line: 7, setter: "setFoo", /// getter: "getFoo", attributes: 7, type: !2) diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 96601100e34..1e28411d01e 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -982,16 +982,12 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) { DIGlobalVariable, (Context, getMDOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], - getDITypeRefOrNull(Record[6]), Record[7], Record[8], + getDITypeRefOrNull(Record[6]), Record[7], Record[8], Expr, getMDOrNull(Record[10]), AlignInBits)); + MetadataList.assignValue(DGV, NextMetadataNo++); - if (Expr || Attach) { - auto *DGVE = DIGlobalVariableExpression::getDistinct(Context, DGV, Expr); - MetadataList.assignValue(DGVE, NextMetadataNo++); - if (Attach) - Attach->addDebugInfo(DGVE); - } else - MetadataList.assignValue(DGV, NextMetadataNo++); + if (Attach) + Attach->addDebugInfo(DGV); break; } @@ -1041,17 +1037,6 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) { NextMetadataNo++); break; } - case bitc::METADATA_GLOBAL_VAR_EXPR: { - if (Record.size() != 3) - return error("Invalid record"); - - IsDistinct = Record[0]; - MetadataList.assignValue(GET_OR_DISTINCT(DIGlobalVariableExpression, - (Context, getMDOrNull(Record[1]), - getMDOrNull(Record[2]))), - NextMetadataNo++); - break; - } case bitc::METADATA_OBJC_PROPERTY: { if (Record.size() != 8) return error("Invalid record"); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 2905a98f619..cff2fd0c99c 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -210,9 +210,6 @@ private: SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); void writeDIExpression(const DIExpression *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); - void writeDIGlobalVariableExpression(const DIGlobalVariableExpression *N, - SmallVectorImpl<uint64_t> &Record, - unsigned Abbrev); void writeDIObjCProperty(const DIObjCProperty *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); void writeDIImportedEntity(const DIImportedEntity *N, @@ -1686,7 +1683,7 @@ void ModuleBitcodeWriter::writeDIGlobalVariable( Record.push_back(VE.getMetadataOrNullID(N->getType())); Record.push_back(N->isLocalToUnit()); Record.push_back(N->isDefinition()); - Record.push_back(/* expr */ 0); + Record.push_back(VE.getMetadataOrNullID(N->getRawExpr())); Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration())); Record.push_back(N->getAlignInBits()); @@ -1738,17 +1735,6 @@ void ModuleBitcodeWriter::writeDIExpression(const DIExpression *N, Record.clear(); } -void ModuleBitcodeWriter::writeDIGlobalVariableExpression( - const DIGlobalVariableExpression *N, SmallVectorImpl<uint64_t> &Record, - unsigned Abbrev) { - Record.push_back(N->isDistinct()); - Record.push_back(VE.getMetadataOrNullID(N->getVariable())); - Record.push_back(VE.getMetadataOrNullID(N->getExpression())); - - Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR_EXPR, Record, Abbrev); - Record.clear(); -} - void ModuleBitcodeWriter::writeDIObjCProperty(const DIObjCProperty *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { 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; - } }; } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 5c104f6ce0c..d58618f99ff 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1827,6 +1827,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("expr", N->getExpr()); Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration()); Printer.printInt("align", N->getAlignInBits()); Out << ")"; @@ -1869,18 +1870,6 @@ static void writeDIExpression(raw_ostream &Out, const DIExpression *N, Out << ")"; } -static void writeDIGlobalVariableExpression(raw_ostream &Out, - const DIGlobalVariableExpression *N, - TypePrinting *TypePrinter, - SlotTracker *Machine, - const Module *Context) { - Out << "!DIGlobalVariableExpression("; - MDFieldPrinter Printer(Out, TypePrinter, Machine, Context); - Printer.printMetadata("var", N->getVariable()); - Printer.printMetadata("expr", N->getExpression()); - Out << ")"; -} - static void writeDIObjCProperty(raw_ostream &Out, const DIObjCProperty *N, TypePrinting *TypePrinter, SlotTracker *Machine, const Module *Context) { diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index d009322a572..dfca6895590 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -532,30 +532,29 @@ static void checkGlobalVariableScope(DIScope *Context) { #endif } -DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression( +DIGlobalVariable *DIBuilder::createGlobalVariable( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, - unsigned LineNumber, DIType *Ty, bool isLocalToUnit, DIExpression *Expr, - MDNode *Decl, uint32_t AlignInBits) { + unsigned LineNumber, DIType *Ty, bool isLocalToUnit, + DIExpression *Expr, MDNode *Decl, uint32_t AlignInBits) { checkGlobalVariableScope(Context); - auto *GV = DIGlobalVariable::getDistinct( + auto *N = DIGlobalVariable::getDistinct( VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F, - LineNumber, Ty, isLocalToUnit, true, cast_or_null<DIDerivedType>(Decl), - AlignInBits); - auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr); + LineNumber, Ty, isLocalToUnit, true, Expr, + cast_or_null<DIDerivedType>(Decl), AlignInBits); AllGVs.push_back(N); return N; } DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, - unsigned LineNumber, DIType *Ty, bool isLocalToUnit, MDNode *Decl, - uint32_t AlignInBits) { + unsigned LineNumber, DIType *Ty, bool isLocalToUnit, + DIExpression *Expr, MDNode *Decl, uint32_t AlignInBits) { checkGlobalVariableScope(Context); return DIGlobalVariable::getTemporary( VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F, - LineNumber, Ty, isLocalToUnit, false, + LineNumber, Ty, isLocalToUnit, false, Expr, cast_or_null<DIDerivedType>(Decl), AlignInBits) .release(); } diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 6b9bc689a44..7f91b49d828 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -53,12 +53,11 @@ void DebugInfoFinder::reset() { void DebugInfoFinder::processModule(const Module &M) { for (auto *CU : M.debug_compile_units()) { addCompileUnit(CU); - for (auto DIG : CU->getGlobalVariables()) { - if (!addGlobalVariable(DIG)) - continue; - auto *GV = DIG->getVariable(); - processScope(GV->getScope()); - processType(GV->getType().resolve()); + for (auto *DIG : CU->getGlobalVariables()) { + if (addGlobalVariable(DIG)) { + processScope(DIG->getScope()); + processType(DIG->getType().resolve()); + } } for (auto *ET : CU->getEnumTypes()) processType(ET); @@ -207,7 +206,10 @@ bool DebugInfoFinder::addCompileUnit(DICompileUnit *CU) { return true; } -bool DebugInfoFinder::addGlobalVariable(DIGlobalVariableExpression *DIG) { +bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable *DIG) { + if (!DIG) + return false; + if (!NodesSeen.insert(DIG).second) return false; diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 75c397e1345..fe61c279778 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -514,17 +514,18 @@ DIGlobalVariable * DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, + Metadata *Variable, Metadata *StaticDataMemberDeclaration, - uint32_t AlignInBits, StorageType Storage, - bool ShouldCreate) { + uint32_t AlignInBits, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); assert(isCanonical(LinkageName) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, (Scope, Name, LinkageName, File, Line, Type, - IsLocalToUnit, IsDefinition, + IsLocalToUnit, IsDefinition, Variable, StaticDataMemberDeclaration, AlignInBits)); - Metadata *Ops[] = { - Scope, Name, File, Type, Name, LinkageName, StaticDataMemberDeclaration}; + Metadata *Ops[] = {Scope, Name, File, Type, + Name, LinkageName, Variable, StaticDataMemberDeclaration}; DEFINE_GETIMPL_STORE(DIGlobalVariable, (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops); @@ -580,17 +581,10 @@ bool DIExpression::isValid() const { default: return false; case dwarf::DW_OP_LLVM_fragment: - // A fragment operator must appear at the end. + case dwarf::DW_OP_stack_value: + // We only support fragment and stack value expressions which appear at + // the end. return I->get() + I->getSize() == E->get(); - case dwarf::DW_OP_stack_value: { - // Must be the last one or followed by a DW_OP_LLVM_fragment. - if (I->get() + I->getSize() == E->get()) - break; - auto J = I; - if ((++J)->getOp() != dwarf::DW_OP_LLVM_fragment) - return false; - break; - } case dwarf::DW_OP_constu: case dwarf::DW_OP_plus: case dwarf::DW_OP_minus: @@ -619,27 +613,6 @@ uint64_t DIExpression::getFragmentSizeInBits() const { return getElement(getNumElements() - 1); } -bool DIExpression::isConstant() const { - // Recognize DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment Len Ofs)?. - if (getNumElements() != 3 && getNumElements() != 6) - return false; - if (getElement(0) != dwarf::DW_OP_constu || - getElement(2) != dwarf::DW_OP_stack_value) - return false; - if (getNumElements() == 6 && getElement(3) != dwarf::DW_OP_LLVM_fragment) - return false; - return true; -} - -DIGlobalVariableExpression * -DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable, - Metadata *Expression, StorageType Storage, - bool ShouldCreate) { - DEFINE_GETIMPL_LOOKUP(DIGlobalVariableExpression, (Variable, Expression)); - Metadata *Ops[] = {Variable, Expression}; - DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGlobalVariableExpression, Ops); -} - DIObjCProperty *DIObjCProperty::getImpl( LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line, MDString *GetterName, MDString *SetterName, unsigned Attributes, diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 55443c598f9..f1cc12a2902 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -763,16 +763,18 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> { Metadata *Type; bool IsLocalToUnit; bool IsDefinition; + Metadata *Expr; Metadata *StaticDataMemberDeclaration; uint32_t AlignInBits; MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, - Metadata *StaticDataMemberDeclaration, uint32_t AlignInBits) + Metadata *Expr, Metadata *StaticDataMemberDeclaration, + uint32_t AlignInBits) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit), - IsDefinition(IsDefinition), + IsDefinition(IsDefinition), Expr(Expr), StaticDataMemberDeclaration(StaticDataMemberDeclaration), AlignInBits(AlignInBits) {} MDNodeKeyImpl(const DIGlobalVariable *N) @@ -780,6 +782,7 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> { LinkageName(N->getRawLinkageName()), File(N->getRawFile()), Line(N->getLine()), Type(N->getRawType()), IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), + Expr(N->getRawExpr()), StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()), AlignInBits(N->getAlignInBits()) {} @@ -789,6 +792,7 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> { File == RHS->getRawFile() && Line == RHS->getLine() && Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() && IsDefinition == RHS->isDefinition() && + Expr == RHS->getRawExpr() && StaticDataMemberDeclaration == RHS->getRawStaticDataMemberDeclaration() && AlignInBits == RHS->getAlignInBits(); @@ -802,7 +806,7 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> { // generated IR is random for each run and test fails with Align included. // TODO: make hashing work fine with such situations return hash_combine(Scope, Name, LinkageName, File, Line, Type, - IsLocalToUnit, IsDefinition, /* AlignInBits, */ + IsLocalToUnit, IsDefinition, /* AlignInBits, */ Expr, StaticDataMemberDeclaration); } }; @@ -859,22 +863,6 @@ template <> struct MDNodeKeyImpl<DIExpression> { } }; -template <> struct MDNodeKeyImpl<DIGlobalVariableExpression> { - Metadata *Variable; - Metadata *Expression; - - MDNodeKeyImpl(Metadata *Variable, Metadata *Expression) - : Variable(Variable), Expression(Expression) {} - MDNodeKeyImpl(const DIGlobalVariableExpression *N) - : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {} - - bool isKeyOf(const DIGlobalVariableExpression *RHS) const { - return Variable == RHS->getRawVariable() && - Expression == RHS->getRawExpression(); - } - unsigned getHashValue() const { return hash_combine(Variable, Expression); } -}; - template <> struct MDNodeKeyImpl<DIObjCProperty> { MDString *Name; Metadata *File; diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index 1d193045923..adc91573a7f 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -1419,15 +1419,9 @@ void GlobalObject::copyMetadata(const GlobalObject *Other, unsigned Offset) { // If an offset adjustment was specified we need to modify the DIExpression // to prepend the adjustment: // !DIExpression(DW_OP_plus, Offset, [original expr]) - auto *Attachment = MD.second; if (Offset != 0 && MD.first == LLVMContext::MD_dbg) { - DIGlobalVariable *GV = dyn_cast<DIGlobalVariable>(Attachment); - DIExpression *E = nullptr; - if (!GV) { - auto *GVE = cast<DIGlobalVariableExpression>(Attachment); - GV = GVE->getVariable(); - E = GVE->getExpression(); - } + DIGlobalVariable *GV = cast<DIGlobalVariable>(MD.second); + DIExpression *E = GV->getExpr(); ArrayRef<uint64_t> OrigElements; if (E) OrigElements = E->getElements(); @@ -1435,10 +1429,9 @@ void GlobalObject::copyMetadata(const GlobalObject *Other, unsigned Offset) { Elements[0] = dwarf::DW_OP_plus; Elements[1] = Offset; std::copy(OrigElements.begin(), OrigElements.end(), Elements.begin() + 2); - E = DIExpression::get(getContext(), Elements); - Attachment = DIGlobalVariableExpression::get(getContext(), GV, E); + GV->replaceExpr(DIExpression::get(getContext(), Elements)); } - addMetadata(MD.first, *Attachment); + addMetadata(MD.first, *MD.second); } } @@ -1459,14 +1452,14 @@ DISubprogram *Function::getSubprogram() const { return cast_or_null<DISubprogram>(getMetadata(LLVMContext::MD_dbg)); } -void GlobalVariable::addDebugInfo(DIGlobalVariableExpression *GV) { +void GlobalVariable::addDebugInfo(DIGlobalVariable *GV) { addMetadata(LLVMContext::MD_dbg, *GV); } void GlobalVariable::getDebugInfo( - SmallVectorImpl<DIGlobalVariableExpression *> &GVs) const { + SmallVectorImpl<DIGlobalVariable *> &GVs) const { SmallVector<MDNode *, 1> MDs; getMetadata(LLVMContext::MD_dbg, MDs); for (MDNode *MD : MDs) - GVs.push_back(cast<DIGlobalVariableExpression>(MD)); + GVs.push_back(cast<DIGlobalVariable>(MD)); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 2b9dfcea2fb..b0ba1c7a592 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -580,6 +580,7 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { "Global variable initializer type does not match global " "variable type!", &GV); + // If the global has common linkage, it must have a zero initializer and // cannot be constant. if (GV.hasCommonLinkage()) { @@ -645,16 +646,6 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { GV.hasAvailableExternallyLinkage(), "Global is marked as dllimport, but not external", &GV); - // Visit any debug info attachments. - SmallVector<MDNode *, 1> MDs; - GV.getMetadata(LLVMContext::MD_dbg, MDs); - for (auto *MD : MDs) { - if (auto *GVE = dyn_cast<DIGlobalVariableExpression>(MD)) - visitDIGlobalVariableExpression(*GVE); - else - AssertDI(false, "!dbg attachment of global variable must be a DIGlobalVariableExpression"); - } - if (!GV.hasInitializer()) { visitGlobalValue(GV); return; @@ -997,8 +988,8 @@ void Verifier::visitDICompileUnit(const DICompileUnit &N) { if (auto *Array = N.getRawGlobalVariables()) { AssertDI(isa<MDTuple>(Array), "invalid global variable list", &N, Array); for (Metadata *Op : N.getGlobalVariables()->operands()) { - AssertDI(Op && (isa<DIGlobalVariableExpression>(Op)), - "invalid global variable ref", &N, Op); + AssertDI(Op && isa<DIGlobalVariable>(Op), "invalid global variable ref", + &N, Op); } } if (auto *Array = N.getRawImportedEntities()) { @@ -1141,6 +1132,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.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); @@ -1160,15 +1153,6 @@ void Verifier::visitDIExpression(const DIExpression &N) { AssertDI(N.isValid(), "invalid expression", &N); } -void Verifier::visitDIGlobalVariableExpression( - const DIGlobalVariableExpression &GVE) { - AssertDI(GVE.getVariable(), "missing variable"); - if (auto *Var = GVE.getVariable()) - visitDIGlobalVariable(*Var); - if (auto *Expr = GVE.getExpression()) - visitDIExpression(*Expr); -} - void Verifier::visitDIObjCProperty(const DIObjCProperty &N) { AssertDI(N.getTag() == dwarf::DW_TAG_APPLE_property, "invalid tag", &N); if (auto *T = N.getRawType()) diff --git a/llvm/lib/Transforms/IPO/StripSymbols.cpp b/llvm/lib/Transforms/IPO/StripSymbols.cpp index 8f6f161428e..5cb8ff56584 100644 --- a/llvm/lib/Transforms/IPO/StripSymbols.cpp +++ b/llvm/lib/Transforms/IPO/StripSymbols.cpp @@ -313,23 +313,20 @@ bool StripDeadDebugInfo::runOnModule(Module &M) { // replace the current list of potentially dead global variables/functions // with the live list. SmallVector<Metadata *, 64> LiveGlobalVariables; - DenseSet<DIGlobalVariableExpression *> VisitedSet; + DenseSet<const MDNode *> VisitedSet; - std::set<DIGlobalVariableExpression *> LiveGVs; + std::set<DIGlobalVariable *> LiveGVs; for (GlobalVariable &GV : M.globals()) { - SmallVector<DIGlobalVariableExpression *, 1> GVEs; - GV.getDebugInfo(GVEs); - for (auto *GVE : GVEs) - LiveGVs.insert(GVE); + SmallVector<DIGlobalVariable *, 1> DIs; + GV.getDebugInfo(DIs); + for (DIGlobalVariable *DI : DIs) + LiveGVs.insert(DI); } for (DICompileUnit *DIC : F.compile_units()) { // Create our live global variable list. bool GlobalVariableChange = false; - for (auto *DIG : DIC->getGlobalVariables()) { - if (DIG->getExpression() && DIG->getExpression()->isConstant()) - LiveGVs.insert(DIG); - + for (DIGlobalVariable *DIG : DIC->getGlobalVariables()) { // Make sure we only visit each global variable only once. if (!VisitedSet.insert(DIG).second) continue; diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 6a7cb0e45c6..acc13aaeaf4 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1655,7 +1655,7 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) { // Transfer the debug info. The payload starts at offset zero so we can // copy the debug info over as is. - SmallVector<DIGlobalVariableExpression *, 1> GVs; + SmallVector<DIGlobalVariable *, 1> GVs; G->getDebugInfo(GVs); for (auto *GV : GVs) NewGlobal->addDebugInfo(GV); |