summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2015-11-05 22:03:56 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2015-11-05 22:03:56 +0000
commitd4bff30370db9f2cb13838897012768739cf1ee0 (patch)
treef6c80f666794291c78575617d326207f57939b61 /llvm/lib/Bitcode/Reader/BitcodeReader.cpp
parent18da38edb315fe9e063348c4d785b26111b6d7ec (diff)
downloadbcm5719-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.cpp49
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();
OpenPOWER on IntegriCloud