diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2015-11-05 22:03:56 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2015-11-05 22:03:56 +0000 |
commit | d4bff30370db9f2cb13838897012768739cf1ee0 (patch) | |
tree | f6c80f666794291c78575617d326207f57939b61 /llvm/lib/Bitcode/Reader/BitcodeReader.cpp | |
parent | 18da38edb315fe9e063348c4d785b26111b6d7ec (diff) | |
download | bcm5719-llvm-d4bff30370db9f2cb13838897012768739cf1ee0.tar.gz bcm5719-llvm-d4bff30370db9f2cb13838897012768739cf1ee0.zip |
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
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 49 |
1 files changed, 35 insertions, 14 deletions
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(); |