summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp18
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.h2
2 files changed, 17 insertions, 3 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 4fe054de370..ca4d66a540b 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -555,9 +555,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).release();
MDValuePtrs[Idx].reset(MD);
return MD;
@@ -573,7 +581,8 @@ 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];
auto *N = dyn_cast_or_null<MDNode>(MD);
if (!N)
continue;
@@ -581,6 +590,9 @@ void BitcodeReaderMDValueList::tryToResolveCycles() {
assert(!N->isTemporary() && "Unexpected forward reference");
N->resolveCycles();
}
+
+ // Make sure we return early again until there's another forward ref.
+ AnyFwdRefs = false;
}
Type *BitcodeReader::getTypeByID(unsigned ID) {
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.h b/llvm/lib/Bitcode/Reader/BitcodeReader.h
index 7f7eb70bce9..5090be48450 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.h
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.h
@@ -99,6 +99,8 @@ public:
class BitcodeReaderMDValueList {
unsigned NumFwdRefs;
bool AnyFwdRefs;
+ unsigned MinFwdRef;
+ unsigned MaxFwdRef;
std::vector<TrackingMDRef> MDValuePtrs;
LLVMContext &Context;
OpenPOWER on IntegriCloud