diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 49 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/CodeGen/LiveDebugVariables.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/IR/DIBuilder.cpp | 57 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfo.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfoMetadata.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 13 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 77 | ||||
-rw-r--r-- | llvm/lib/Linker/LinkModules.cpp | 50 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/ArgumentPromotion.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/StripSymbols.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/CloneFunction.cpp | 4 |
18 files changed, 147 insertions, 252 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index d5e5848422b..1c219ad6cd8 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -3807,8 +3807,8 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { /// isDefinition: true, scopeLine: 8, containingType: !3, /// virtuality: DW_VIRTUALTIY_pure_virtual, /// virtualIndex: 10, flags: 11, -/// isOptimized: false, function: void ()* @_Z3foov, -/// templateParams: !4, declaration: !5, variables: !6) +/// isOptimized: false, templateParams: !4, declaration: !5, +/// variables: !6) bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) { auto Loc = Lex.getLoc(); #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ @@ -3826,7 +3826,6 @@ bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) { OPTIONAL(virtualIndex, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(isOptimized, MDBoolField, ); \ - OPTIONAL(function, MDConstant, ); \ OPTIONAL(templateParams, MDField, ); \ OPTIONAL(declaration, MDField, ); \ OPTIONAL(variables, MDField, ); @@ -3839,11 +3838,11 @@ bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) { "missing 'distinct', required for !DISubprogram when 'isDefinition'"); Result = GET_OR_DISTINCT( - DISubprogram, (Context, scope.Val, name.Val, linkageName.Val, file.Val, - line.Val, type.Val, isLocal.Val, isDefinition.Val, - scopeLine.Val, containingType.Val, virtuality.Val, - virtualIndex.Val, flags.Val, isOptimized.Val, function.Val, - templateParams.Val, declaration.Val, variables.Val)); + DISubprogram, + (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val, + type.Val, isLocal.Val, isDefinition.Val, scopeLine.Val, + containingType.Val, virtuality.Val, virtualIndex.Val, flags.Val, + isOptimized.Val, templateParams.Val, declaration.Val, variables.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 522f2aa4707..7c1b208c626 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -232,6 +232,10 @@ class BitcodeReader : public GVMaterializer { bool StripDebugInfo = false; + /// Functions that need to be matched with subprograms when upgrading old + /// metadata. + SmallDenseMap<Function *, DISubprogram *, 16> FunctionsWithSPs; + std::vector<std::string> BundleTags; public: @@ -2182,20 +2186,33 @@ std::error_code BitcodeReader::parseMetadata() { break; } case bitc::METADATA_SUBPROGRAM: { - if (Record.size() != 19) - return error("Invalid record"); - - MDValueList.assignValue( - GET_OR_DISTINCT( - DISubprogram, - Record[0] || Record[8], // All definitions should be distinct. - (Context, getMDOrNull(Record[1]), getMDString(Record[2]), - getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], - getMDOrNull(Record[6]), Record[7], Record[8], Record[9], - getMDOrNull(Record[10]), Record[11], Record[12], Record[13], - Record[14], getMDOrNull(Record[15]), getMDOrNull(Record[16]), - getMDOrNull(Record[17]), getMDOrNull(Record[18]))), - NextMDValueNo++); + if (Record.size() != 18 && Record.size() != 19) + return error("Invalid record"); + + bool HasFn = Record.size() == 19; + DISubprogram *SP = GET_OR_DISTINCT( + DISubprogram, + Record[0] || Record[8], // All definitions should be distinct. + (Context, getMDOrNull(Record[1]), getMDString(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], + getMDOrNull(Record[6]), Record[7], Record[8], Record[9], + getMDOrNull(Record[10]), Record[11], Record[12], Record[13], + Record[14], getMDOrNull(Record[15 + HasFn]), + getMDOrNull(Record[16 + HasFn]), getMDOrNull(Record[17 + HasFn]))); + MDValueList.assignValue(SP, NextMDValueNo++); + + // Upgrade sp->function mapping to function->sp mapping. + if (HasFn && Record[15]) { + if (auto *CMD = dyn_cast<ConstantAsMetadata>(getMDOrNull(Record[15]))) + if (auto *F = dyn_cast<Function>(CMD->getValue())) { + if (F->isMaterializable()) + // Defer until materialized; unmaterialized functions may not have + // metadata. + FunctionsWithSPs[F] = SP; + else if (!F->empty()) + F->setSubprogram(SP); + } + } break; } case bitc::METADATA_LEXICAL_BLOCK: { @@ -5139,6 +5156,10 @@ std::error_code BitcodeReader::materialize(GlobalValue *GV) { } } + // Finish fn->subprogram upgrade for materialized functions. + if (DISubprogram *SP = FunctionsWithSPs.lookup(F)) + F->setSubprogram(SP); + // Bring in any functions that this function forward-referenced via // blockaddresses. return materializeForwardReferencedFunctions(); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 755167a9636..c73b099e27f 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1024,7 +1024,6 @@ static void WriteDISubprogram(const DISubprogram *N, const ValueEnumerator &VE, Record.push_back(N->getVirtualIndex()); Record.push_back(N->getFlags()); Record.push_back(N->isOptimized()); - Record.push_back(VE.getMetadataOrNullID(N->getRawFunction())); Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get())); Record.push_back(VE.getMetadataOrNullID(N->getDeclaration())); Record.push_back(VE.getMetadataOrNullID(N->getVariables().get())); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index a9dca447980..477ebe1d638 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -476,8 +476,6 @@ void DwarfDebug::beginModule() { const Module *M = MMI->getModule(); - FunctionDIs = makeSubprogramMap(*M); - NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); if (!CU_Nodes) return; @@ -1113,8 +1111,8 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { if (!MMI->hasDebugInfo()) return; - auto DI = FunctionDIs.find(MF->getFunction()); - if (DI == FunctionDIs.end()) + auto DI = MF->getFunction()->getSubprogram(); + if (!DI) return; // Grab the lexical scopes for the function, if we don't have any of those @@ -1205,7 +1203,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { "endFunction should be called with the same function as beginFunction"); if (!MMI->hasDebugInfo() || LScopes.empty() || - !FunctionDIs.count(MF->getFunction())) { + !MF->getFunction()->getSubprogram()) { // If we don't have a lexical scope for this function then there will // be a hole in the range information. Keep note of this by setting the // previously used section to nullptr. diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp index 6559d8df1a2..654328714bc 100644 --- a/llvm/lib/CodeGen/LiveDebugVariables.cpp +++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp @@ -761,7 +761,7 @@ static void removeDebugValues(MachineFunction &mf) { bool LiveDebugVariables::runOnMachineFunction(MachineFunction &mf) { if (!EnableLDV) return false; - if (!FunctionDIs.count(mf.getFunction())) { + if (!mf.getFunction()->getSubprogram()) { removeDebugValues(mf); return false; } @@ -1045,7 +1045,6 @@ void LiveDebugVariables::emitDebugValues(VirtRegMap *VRM) { } bool LiveDebugVariables::doInitialization(Module &M) { - FunctionDIs = makeSubprogramMap(M); return Pass::doInitialization(M); } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 2b39f2273b3..db757508594 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1692,7 +1692,6 @@ static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N, Printer.printInt("virtualIndex", N->getVirtualIndex()); Printer.printDIFlags("flags", N->getFlags()); Printer.printBool("isOptimized", N->isOptimized()); - Printer.printMetadata("function", N->getRawFunction()); Printer.printMetadata("templateParams", N->getRawTemplateParams()); Printer.printMetadata("declaration", N->getRawDeclaration()); Printer.printMetadata("variables", N->getRawVariables()); diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index def72d6cf6e..7fc0652bf65 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -659,19 +659,17 @@ DIExpression *DIBuilder::createBitPieceExpression(unsigned OffsetInBytes, return DIExpression::get(VMContext, Addr); } -DISubprogram *DIBuilder::createFunction(DIScopeRef Context, StringRef Name, - StringRef LinkageName, DIFile *File, - unsigned LineNo, DISubroutineType *Ty, - bool isLocalToUnit, bool isDefinition, - unsigned ScopeLine, unsigned Flags, - bool isOptimized, Function *Fn, - MDNode *TParams, MDNode *Decl) { +DISubprogram *DIBuilder::createFunction( + DIScopeRef Context, StringRef Name, StringRef LinkageName, DIFile *File, + unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, + bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized, + DITemplateParameterArray TParams, DISubprogram *Decl) { // dragonegg does not generate identifier for types, so using an empty map // to resolve the context should be fine. DITypeIdentifierMap EmptyMap; return createFunction(Context.resolve(EmptyMap), Name, LinkageName, File, LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine, - Flags, isOptimized, Fn, TParams, Decl); + Flags, isOptimized, TParams, Decl); } template <class... Ts> @@ -681,20 +679,17 @@ static DISubprogram *getSubprogram(bool IsDistinct, Ts &&... Args) { return DISubprogram::get(std::forward<Ts>(Args)...); } -DISubprogram *DIBuilder::createFunction(DIScope *Context, StringRef Name, - StringRef LinkageName, DIFile *File, - unsigned LineNo, DISubroutineType *Ty, - bool isLocalToUnit, bool isDefinition, - unsigned ScopeLine, unsigned Flags, - bool isOptimized, Function *Fn, - MDNode *TParams, MDNode *Decl) { - auto *Node = getSubprogram(/* IsDistinct = */ isDefinition, VMContext, - DIScopeRef::get(getNonCompileUnitScope(Context)), - Name, LinkageName, File, LineNo, Ty, isLocalToUnit, - isDefinition, ScopeLine, nullptr, 0, 0, Flags, - isOptimized, Fn, cast_or_null<MDTuple>(TParams), - cast_or_null<DISubprogram>(Decl), - MDTuple::getTemporary(VMContext, None).release()); +DISubprogram *DIBuilder::createFunction( + DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, + unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, + bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized, + DITemplateParameterArray TParams, DISubprogram *Decl) { + auto *Node = + getSubprogram(/* IsDistinct = */ isDefinition, VMContext, + DIScopeRef::get(getNonCompileUnitScope(Context)), Name, + LinkageName, File, LineNo, Ty, isLocalToUnit, isDefinition, + ScopeLine, nullptr, 0, 0, Flags, isOptimized, TParams, Decl, + MDTuple::getTemporary(VMContext, None).release()); if (isDefinition) AllSubprograms.push_back(Node); @@ -706,12 +701,11 @@ DISubprogram *DIBuilder::createTempFunctionFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized, - Function *Fn, MDNode *TParams, MDNode *Decl) { + DITemplateParameterArray TParams, DISubprogram *Decl) { return DISubprogram::getTemporary( VMContext, DIScopeRef::get(getNonCompileUnitScope(Context)), Name, LinkageName, File, LineNo, Ty, isLocalToUnit, isDefinition, - ScopeLine, nullptr, 0, 0, Flags, isOptimized, Fn, - cast_or_null<MDTuple>(TParams), cast_or_null<DISubprogram>(Decl), + ScopeLine, nullptr, 0, 0, Flags, isOptimized, TParams, Decl, nullptr) .release(); } @@ -721,17 +715,16 @@ DIBuilder::createMethod(DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, bool isDefinition, unsigned VK, unsigned VIndex, DIType *VTableHolder, unsigned Flags, - bool isOptimized, Function *Fn, MDNode *TParam) { + bool isOptimized, DITemplateParameterArray TParams) { assert(getNonCompileUnitScope(Context) && "Methods should have both a Context and a context that isn't " "the compile unit."); // FIXME: Do we want to use different scope/lines? - auto *SP = getSubprogram(/* IsDistinct = */ isDefinition, VMContext, - DIScopeRef::get(cast<DIScope>(Context)), Name, - LinkageName, F, LineNo, Ty, isLocalToUnit, - isDefinition, LineNo, DITypeRef::get(VTableHolder), - VK, VIndex, Flags, isOptimized, Fn, - cast_or_null<MDTuple>(TParam), nullptr, nullptr); + auto *SP = getSubprogram( + /* IsDistinct = */ isDefinition, VMContext, + DIScopeRef::get(cast<DIScope>(Context)), Name, LinkageName, F, LineNo, Ty, + isLocalToUnit, isDefinition, LineNo, DITypeRef::get(VTableHolder), VK, + VIndex, Flags, isOptimized, TParams, nullptr, nullptr); if (isDefinition) AllSubprograms.push_back(SP); diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index b22ba53645d..a2443becdd0 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -300,6 +300,10 @@ bool DebugInfoFinder::addScope(DIScope *Scope) { bool llvm::stripDebugInfo(Function &F) { bool Changed = false; + if (F.getSubprogram()) { + Changed = true; + F.setSubprogram(nullptr); + } for (BasicBlock &BB : F) { for (Instruction &I : BB) { if (I.getDebugLoc()) { @@ -359,21 +363,3 @@ unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) { return Val->getZExtValue(); return 0; } - -DenseMap<const llvm::Function *, DISubprogram *> -llvm::makeSubprogramMap(const Module &M) { - DenseMap<const Function *, DISubprogram *> R; - - NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu"); - if (!CU_Nodes) - return R; - - for (MDNode *N : CU_Nodes->operands()) { - auto *CUNode = cast<DICompileUnit>(N); - for (auto *SP : CUNode->getSubprograms()) { - if (Function *F = SP->getFunction()) - R.insert(std::make_pair(F, SP)); - } - } - return R; -} diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 7ba51f66b79..cead10652e0 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -342,34 +342,28 @@ DISubprogram *DISubprogram::getImpl( MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, - unsigned Flags, bool IsOptimized, Metadata *Function, - Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables, - StorageType Storage, bool ShouldCreate) { + unsigned Flags, bool IsOptimized, Metadata *TemplateParams, + Metadata *Declaration, Metadata *Variables, StorageType Storage, + bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); assert(isCanonical(LinkageName) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DISubprogram, (Scope, getString(Name), getString(LinkageName), File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, - IsOptimized, Function, TemplateParams, Declaration, - Variables)); - Metadata *Ops[] = {File, Scope, Name, Name, - LinkageName, Type, ContainingType, Function, - TemplateParams, Declaration, Variables}; + IsOptimized, TemplateParams, Declaration, Variables)); + Metadata *Ops[] = {File, Scope, Name, Name, + LinkageName, Type, ContainingType, TemplateParams, + Declaration, Variables}; DEFINE_GETIMPL_STORE(DISubprogram, (Line, ScopeLine, Virtuality, VirtualIndex, Flags, IsLocalToUnit, IsDefinition, IsOptimized), Ops); } -Function *DISubprogram::getFunction() const { - // FIXME: Should this be looking through bitcasts? - return dyn_cast_or_null<Function>(getFunctionConstant()); -} - bool DISubprogram::describes(const Function *F) const { assert(F && "Invalid function"); - if (F == getFunction()) + if (F->getSubprogram() == this) return true; StringRef Name = getLinkageName(); if (Name.empty()) @@ -377,11 +371,6 @@ bool DISubprogram::describes(const Function *F) const { return F->getName() == Name; } -void DISubprogram::replaceFunction(Function *F) { - replaceFunction(F ? ConstantAsMetadata::get(F) - : static_cast<ConstantAsMetadata *>(nullptr)); -} - DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope, Metadata *File, unsigned Line, unsigned Column, StorageType Storage, diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 2df7d04708e..24f22b43fc0 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -473,7 +473,6 @@ template <> struct MDNodeKeyImpl<DISubprogram> { unsigned VirtualIndex; unsigned Flags; bool IsOptimized; - Metadata *Function; Metadata *TemplateParams; Metadata *Declaration; Metadata *Variables; @@ -483,15 +482,15 @@ template <> struct MDNodeKeyImpl<DISubprogram> { bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, unsigned Flags, bool IsOptimized, - Metadata *Function, Metadata *TemplateParams, - Metadata *Declaration, Metadata *Variables) + Metadata *TemplateParams, Metadata *Declaration, + Metadata *Variables) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), ScopeLine(ScopeLine), ContainingType(ContainingType), Virtuality(Virtuality), VirtualIndex(VirtualIndex), Flags(Flags), IsOptimized(IsOptimized), - Function(Function), TemplateParams(TemplateParams), - Declaration(Declaration), Variables(Variables) {} + TemplateParams(TemplateParams), Declaration(Declaration), + Variables(Variables) {} MDNodeKeyImpl(const DISubprogram *N) : Scope(N->getRawScope()), Name(N->getName()), LinkageName(N->getLinkageName()), File(N->getRawFile()), @@ -500,7 +499,6 @@ template <> struct MDNodeKeyImpl<DISubprogram> { ScopeLine(N->getScopeLine()), ContainingType(N->getRawContainingType()), Virtuality(N->getVirtuality()), VirtualIndex(N->getVirtualIndex()), Flags(N->getFlags()), IsOptimized(N->isOptimized()), - Function(N->getRawFunction()), TemplateParams(N->getRawTemplateParams()), Declaration(N->getRawDeclaration()), Variables(N->getRawVariables()) {} @@ -515,7 +513,6 @@ template <> struct MDNodeKeyImpl<DISubprogram> { Virtuality == RHS->getVirtuality() && VirtualIndex == RHS->getVirtualIndex() && Flags == RHS->getFlags() && IsOptimized == RHS->isOptimized() && - Function == RHS->getRawFunction() && TemplateParams == RHS->getRawTemplateParams() && Declaration == RHS->getRawDeclaration() && Variables == RHS->getRawVariables(); @@ -523,7 +520,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> { unsigned getHashValue() const { return hash_combine(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, Flags, IsOptimized, Function, + Virtuality, VirtualIndex, Flags, IsOptimized, TemplateParams, Declaration, Variables); } }; diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index f64d4e2fddc..813f9ca6744 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -937,13 +937,6 @@ void Verifier::visitDISubprogram(const DISubprogram &N) { Assert(isa<DISubroutineType>(T), "invalid subroutine type", &N, T); Assert(isTypeRef(N, N.getRawContainingType()), "invalid containing type", &N, N.getRawContainingType()); - if (auto *RawF = N.getRawFunction()) { - auto *FMD = dyn_cast<ConstantAsMetadata>(RawF); - auto *F = FMD ? FMD->getValue() : nullptr; - auto *FT = F ? dyn_cast<PointerType>(F->getType()) : nullptr; - Assert(F && FT && isa<FunctionType>(FT->getElementType()), - "invalid function", &N, F, FT); - } if (auto *Params = N.getRawTemplateParams()) visitTemplateParams(N, *Params); if (auto *S = N.getRawDeclaration()) { @@ -963,41 +956,6 @@ void Verifier::visitDISubprogram(const DISubprogram &N) { if (N.isDefinition()) Assert(N.isDistinct(), "subprogram definitions must be distinct", &N); - - auto *F = N.getFunction(); - if (!F) - return; - - // Check that all !dbg attachments lead to back to N (or, at least, another - // subprogram that describes the same function). - // - // FIXME: Check this incrementally while visiting !dbg attachments. - // FIXME: Only check when N is the canonical subprogram for F. - SmallPtrSet<const MDNode *, 32> Seen; - for (auto &BB : *F) - for (auto &I : BB) { - // Be careful about using DILocation here since we might be dealing with - // broken code (this is the Verifier after all). - DILocation *DL = - dyn_cast_or_null<DILocation>(I.getDebugLoc().getAsMDNode()); - if (!DL) - continue; - if (!Seen.insert(DL).second) - continue; - - DILocalScope *Scope = DL->getInlinedAtScope(); - if (Scope && !Seen.insert(Scope).second) - continue; - - DISubprogram *SP = Scope ? Scope->getSubprogram() : nullptr; - if (SP && !Seen.insert(SP).second) - continue; - - // FIXME: Once N is canonical, check "SP == &N". - Assert(SP->describes(F), - "!dbg attachment points at wrong subprogram for function", &N, F, - &I, DL, Scope, SP); - } } void Verifier::visitDILexicalBlockBase(const DILexicalBlockBase &N) { @@ -1812,6 +1770,41 @@ void Verifier::visitFunction(const Function &F) { (F.isDeclaration() && F.hasExternalLinkage()) || F.hasAvailableExternallyLinkage(), "Function is marked as dllimport, but not external.", &F); + + auto *N = F.getSubprogram(); + if (!N) + return; + + // Check that all !dbg attachments lead to back to N (or, at least, another + // subprogram that describes the same function). + // + // FIXME: Check this incrementally while visiting !dbg attachments. + // FIXME: Only check when N is the canonical subprogram for F. + SmallPtrSet<const MDNode *, 32> Seen; + for (auto &BB : F) + for (auto &I : BB) { + // Be careful about using DILocation here since we might be dealing with + // broken code (this is the Verifier after all). + DILocation *DL = + dyn_cast_or_null<DILocation>(I.getDebugLoc().getAsMDNode()); + if (!DL) + continue; + if (!Seen.insert(DL).second) + continue; + + DILocalScope *Scope = DL->getInlinedAtScope(); + if (Scope && !Seen.insert(Scope).second) + continue; + + DISubprogram *SP = Scope ? Scope->getSubprogram() : nullptr; + if (SP && !Seen.insert(SP).second) + continue; + + // FIXME: Once N is canonical, check "SP == &N". + Assert(SP->describes(&F), + "!dbg attachment points at wrong subprogram for function", N, &F, + &I, DL, Scope, SP); + } } // verifyBasicBlock - Verify that a basic block is well formed... diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp index a855ec06d17..4a12633c305 100644 --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -421,9 +421,6 @@ class ModuleLinker { // Vector of GlobalValues to lazily link in. std::vector<GlobalValue *> LazilyLinkGlobalValues; - /// Functions that have replaced other functions. - SmallPtrSet<const Function *, 16> OverridingFunctions; - DiagnosticHandlerFunction DiagnosticHandler; /// For symbol clashes, prefer those from Src. @@ -581,7 +578,6 @@ private: const GlobalValue *DGV = nullptr); void linkNamedMDNodes(); - void stripReplacedSubprograms(); }; } @@ -1416,10 +1412,6 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { } NewGV = copyGlobalValueProto(TypeMap, SGV, DGV); - - if (DGV && isa<Function>(DGV)) - if (auto *NewF = dyn_cast<Function>(NewGV)) - OverridingFunctions.insert(NewF); } NewGV->setUnnamedAddr(HasUnnamedAddr); @@ -1603,41 +1595,6 @@ void ModuleLinker::linkNamedMDNodes() { } } -/// Drop DISubprograms that have been superseded. -/// -/// FIXME: this creates an asymmetric result: we strip functions from losing -/// subprograms in DstM, but leave losing subprograms in SrcM. -/// TODO: Remove this logic once the backend can correctly determine canonical -/// subprograms. -void ModuleLinker::stripReplacedSubprograms() { - // Avoid quadratic runtime by returning early when there's nothing to do. - if (OverridingFunctions.empty()) - return; - - // Move the functions now, so the set gets cleared even on early returns. - auto Functions = std::move(OverridingFunctions); - OverridingFunctions.clear(); - - // Drop functions from subprograms if they've been overridden by the new - // compile unit. - NamedMDNode *CompileUnits = DstM->getNamedMetadata("llvm.dbg.cu"); - if (!CompileUnits) - return; - for (unsigned I = 0, E = CompileUnits->getNumOperands(); I != E; ++I) { - auto *CU = cast<DICompileUnit>(CompileUnits->getOperand(I)); - assert(CU && "Expected valid compile unit"); - - for (DISubprogram *SP : CU->getSubprograms()) { - if (!SP || !SP->getFunction() || !Functions.count(SP->getFunction())) - continue; - - // Prevent DebugInfoFinder from tagging this as the canonical subprogram, - // since the canonical one is in the incoming module. - SP->replaceFunction(nullptr); - } - } -} - /// Merge the linker flags in Src into the Dest module. bool ModuleLinker::linkModuleFlagsMetadata() { // If the source module has no module flags, we are done. @@ -1909,13 +1866,6 @@ bool ModuleLinker::run() { MapValue(GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer); } - // Strip replaced subprograms before mapping any metadata -- so that we're - // not changing metadata from the source module (note that - // linkGlobalValueBody() eventually calls RemapInstruction() and therefore - // MapMetadata()) -- but after linking global value protocols -- so that - // OverridingFunctions has been built. - stripReplacedSubprograms(); - // Link in the function bodies that are defined in the source module into // DstM. for (Function &SF : *SrcM) { diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp index bdd1b61f9b2..0e05129b526 100644 --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -95,7 +95,6 @@ namespace { bool doInitialization(CallGraph &CG) override; /// The maximum number of elements to expand, or 0 for unlimited. unsigned maxElements; - DenseMap<const Function *, DISubprogram *> FunctionDIs; }; } @@ -732,15 +731,8 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, NF->copyAttributesFrom(F); // Patch the pointer to LLVM function in debug info descriptor. - auto DI = FunctionDIs.find(F); - if (DI != FunctionDIs.end()) { - DISubprogram *SP = DI->second; - SP->replaceFunction(NF); - // Ensure the map is updated so it can be reused on subsequent argument - // promotions of the same function. - FunctionDIs.erase(DI); - FunctionDIs[NF] = SP; - } + NF->setSubprogram(F->getSubprogram()); + F->setSubprogram(nullptr); DEBUG(dbgs() << "ARG PROMOTION: Promoting to:" << *NF << "\n" << "From: " << *F); @@ -1023,6 +1015,5 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, } bool ArgPromotion::doInitialization(CallGraph &CG) { - FunctionDIs = makeSubprogramMap(CG.getModule()); return CallGraphSCCPass::doInitialization(CG); } diff --git a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp index c870b07f52e..e81c83e6b0c 100644 --- a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -122,14 +122,6 @@ namespace { typedef SmallVector<RetOrArg, 5> UseVector; - // Map each LLVM function to corresponding metadata with debug info. If - // the function is replaced with another one, we should patch the pointer - // to LLVM function in metadata. - // As the code generation for module is finished (and DIBuilder is - // finalized) we assume that subprogram descriptors won't be changed, and - // they are stored in map for short duration anyway. - DenseMap<const Function *, DISubprogram *> FunctionDIs; - protected: // DAH uses this to specify a different ID. explicit DAE(char &ID) : ModulePass(ID) {} @@ -309,15 +301,7 @@ bool DAE::DeleteDeadVarargs(Function &Fn) { } // Patch the pointer to LLVM function in debug info descriptor. - auto DI = FunctionDIs.find(&Fn); - if (DI != FunctionDIs.end()) { - DISubprogram *SP = DI->second; - SP->replaceFunction(NF); - // Ensure the map is updated so it can be reused on non-varargs argument - // eliminations of the same function. - FunctionDIs.erase(DI); - FunctionDIs[NF] = SP; - } + NF->setSubprogram(Fn.getSubprogram()); // Fix up any BlockAddresses that refer to the function. Fn.replaceAllUsesWith(ConstantExpr::getBitCast(NF, Fn.getType())); @@ -1097,9 +1081,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) { } // Patch the pointer to LLVM function in debug info descriptor. - auto DI = FunctionDIs.find(F); - if (DI != FunctionDIs.end()) - DI->second->replaceFunction(NF); + NF->setSubprogram(F->getSubprogram()); // Now that the old function is dead, delete it. F->eraseFromParent(); @@ -1110,9 +1092,6 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) { bool DAE::runOnModule(Module &M) { bool Changed = false; - // Collect debug info descriptors for functions. - FunctionDIs = makeSubprogramMap(M); - // First pass: Do a simple check to see if any functions can have their "..." // removed. We can do this if they never call va_start. This loop cannot be // fused with the next loop, because deleting a function invalidates diff --git a/llvm/lib/Transforms/IPO/StripSymbols.cpp b/llvm/lib/Transforms/IPO/StripSymbols.cpp index 15304cca002..46f352f7f9f 100644 --- a/llvm/lib/Transforms/IPO/StripSymbols.cpp +++ b/llvm/lib/Transforms/IPO/StripSymbols.cpp @@ -305,6 +305,12 @@ bool StripDeadDebugInfo::runOnModule(Module &M) { SmallVector<Metadata *, 64> LiveSubprograms; DenseSet<const MDNode *> VisitedSet; + std::set<DISubprogram *> LiveSPs; + for (Function &F : M) { + if (DISubprogram *SP = F.getSubprogram()) + LiveSPs.insert(SP); + } + for (DICompileUnit *DIC : F.compile_units()) { // Create our live subprogram list. bool SubprogramChange = false; @@ -314,7 +320,7 @@ bool StripDeadDebugInfo::runOnModule(Module &M) { continue; // If the function referenced by DISP is not null, the function is live. - if (DISP->getFunction()) + if (LiveSPs.count(DISP)) LiveSubprograms.push_back(DISP); else SubprogramChange = true; diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index 3b204b77f0e..21ef3207e89 100644 --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -258,7 +258,6 @@ class DataFlowSanitizer : public ModulePass { DFSanABIList ABIList; DenseMap<Value *, Function *> UnwrappedFnMap; AttributeSet ReadOnlyNoneAttrs; - DenseMap<const Function *, DISubprogram *> FunctionDIs; Value *getShadowAddress(Value *Addr, Instruction *Pos); bool isInstrumented(const Function *F); @@ -610,8 +609,6 @@ bool DataFlowSanitizer::runOnModule(Module &M) { if (ABIList.isIn(M, "skip")) return false; - FunctionDIs = makeSubprogramMap(M); - if (!GetArgTLSPtr) { Type *ArgTLSTy = ArrayType::get(ShadowTy, 64); ArgTLS = Mod->getOrInsertGlobal("__dfsan_arg_tls", ArgTLSTy); @@ -768,11 +765,6 @@ bool DataFlowSanitizer::runOnModule(Module &M) { ConstantExpr::getBitCast(NewF, PointerType::getUnqual(FT)); F.replaceAllUsesWith(WrappedFnCst); - // Patch the pointer to LLVM function in debug info descriptor. - auto DI = FunctionDIs.find(&F); - if (DI != FunctionDIs.end()) - DI->second->replaceFunction(&F); - UnwrappedFnMap[WrappedFnCst] = &F; *i = NewF; diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp index d2e707e1996..fa939aee252 100644 --- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -138,6 +138,7 @@ namespace { Module *M; LLVMContext *Ctx; SmallVector<std::unique_ptr<GCOVFunction>, 16> Funcs; + DenseMap<DISubprogram *, Function *> FnMap; }; } @@ -309,13 +310,12 @@ namespace { // object users can construct, the blocks and lines will be rooted here. class GCOVFunction : public GCOVRecord { public: - GCOVFunction(const DISubprogram *SP, raw_ostream *os, uint32_t Ident, - bool UseCfgChecksum, bool ExitBlockBeforeBody) + GCOVFunction(const DISubprogram *SP, Function *F, raw_ostream *os, + uint32_t Ident, bool UseCfgChecksum, bool ExitBlockBeforeBody) : SP(SP), Ident(Ident), UseCfgChecksum(UseCfgChecksum), CfgChecksum(0), ReturnBlock(1, os) { this->os = os; - Function *F = SP->getFunction(); DEBUG(dbgs() << "Function: " << getFunctionName(SP) << "\n"); uint32_t i = 0; @@ -450,6 +450,12 @@ bool GCOVProfiler::runOnModule(Module &M) { this->M = &M; Ctx = &M.getContext(); + FnMap.clear(); + for (Function &F : M) { + if (DISubprogram *SP = F.getSubprogram()) + FnMap[SP] = &F; + } + if (Options.EmitNotes) emitProfileNotes(); if (Options.EmitData) return emitProfileArcs(); return false; @@ -494,7 +500,7 @@ void GCOVProfiler::emitProfileNotes() { unsigned FunctionIdent = 0; for (auto *SP : CU->getSubprograms()) { - Function *F = SP->getFunction(); + Function *F = FnMap[SP]; if (!F) continue; if (!functionHasLines(F)) continue; @@ -506,7 +512,7 @@ void GCOVProfiler::emitProfileNotes() { ++It; EntryBlock.splitBasicBlock(It); - Funcs.push_back(make_unique<GCOVFunction>(SP, &out, FunctionIdent++, + Funcs.push_back(make_unique<GCOVFunction>(SP, F, &out, FunctionIdent++, Options.UseCfgChecksum, Options.ExitBlockBeforeBody)); GCOVFunction &Func = *Funcs.back(); @@ -573,7 +579,7 @@ bool GCOVProfiler::emitProfileArcs() { auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i)); SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP; for (auto *SP : CU->getSubprograms()) { - Function *F = SP->getFunction(); + Function *F = FnMap[SP]; if (!F) continue; if (!functionHasLines(F)) continue; if (!Result) Result = true; diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index 86f7068f975..bd6cd3a87b5 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -188,11 +188,9 @@ static void CloneDebugInfoMetadata(Function *NewFunc, const Function *OldFunc, const DISubprogram *OldSubprogramMDNode = FindSubprogram(OldFunc, Finder); if (!OldSubprogramMDNode) return; - // Ensure that OldFunc appears in the map. - // (if it's already there it must point to NewFunc anyway) - VMap[OldFunc] = NewFunc; auto *NewSubprogram = cast<DISubprogram>(MapMetadata(OldSubprogramMDNode, VMap)); + NewFunc->setSubprogram(NewSubprogram); for (auto *CU : Finder.compile_units()) { auto Subprograms = CU->getSubprograms(); |