From d4bff30370db9f2cb13838897012768739cf1ee0 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 5 Nov 2015 22:03:56 +0000 Subject: DI: Reverse direction of subprogram -> function edge. Previously, subprograms contained a metadata reference to the function they described. Because most clients need to get or set a subprogram for a given function rather than the other way around, this created unneeded inefficiency. For example, many passes needed to call the function llvm::makeSubprogramMap() to build a mapping from functions to subprograms, and the IR linker needed to fix up function references in a way that caused quadratic complexity in the IR linking phase of LTO. This change reverses the direction of the edge by storing the subprogram as function-level metadata and removing DISubprogram's function field. Since this is an IR change, a bitcode upgrade has been provided. Fixes PR23367. An upgrade script for textual IR for out-of-tree clients is attached to the PR. Differential Revision: http://reviews.llvm.org/D14265 llvm-svn: 252219 --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 49 ++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 14 deletions(-) (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp') diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 522f2aa..7c1b208 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 FunctionsWithSPs; + std::vector 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(getMDOrNull(Record[15]))) + if (auto *F = dyn_cast(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(); -- cgit v1.1