summaryrefslogtreecommitdiff
path: root/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-02-19 20:55:17 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-02-19 20:55:17 +0000
commit8af9f2019d565de6161a3ce884a16942fe2dde29 (patch)
tree16dc2c22ced0ee00053811c657e52dead9db406d /lib/Bitcode/Reader/BitcodeReader.cpp
parent608e665946afc2b89050fcf0b99070db2c006bee (diff)
Notes
Diffstat (limited to 'lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 409adafc78631..3d9546fc2b79d 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -538,9 +538,17 @@ Metadata *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) {
if (Metadata *MD = MDValuePtrs[Idx])
return MD;
- // Create and return a placeholder, which will later be RAUW'd.
- AnyFwdRefs = true;
+ // Track forward refs to be resolved later.
+ if (AnyFwdRefs) {
+ MinFwdRef = std::min(MinFwdRef, Idx);
+ MaxFwdRef = std::max(MaxFwdRef, Idx);
+ } else {
+ AnyFwdRefs = true;
+ MinFwdRef = MaxFwdRef = Idx;
+ }
++NumFwdRefs;
+
+ // Create and return a placeholder, which will later be RAUW'd.
Metadata *MD = MDNode::getTemporary(Context, None);
MDValuePtrs[Idx].reset(MD);
return MD;
@@ -556,11 +564,15 @@ void BitcodeReaderMDValueList::tryToResolveCycles() {
return;
// Resolve any cycles.
- for (auto &MD : MDValuePtrs) {
+ for (unsigned I = MinFwdRef, E = MaxFwdRef + 1; I != E; ++I) {
+ auto &MD = MDValuePtrs[I];
assert(!(MD && isa<MDNodeFwdDecl>(MD)) && "Unexpected forward reference");
if (auto *N = dyn_cast_or_null<UniquableMDNode>(MD))
N->resolveCycles();
}
+
+ // Make sure we return early again until there's another forward ref.
+ AnyFwdRefs = false;
}
Type *BitcodeReader::getTypeByID(unsigned ID) {