Skip to content

Commit 690952d

Browse files
committedDec 25, 2016
MetadataLoader: replace the tracking of ForwardReferences and UnresolvedNodes with a set-based solution (NFC)
This makes it explicit what is the exact list to handle, and it looks much more easy to manipulate and understand that the previous custom tracking of min/max to express the range where to look for. Differential Revision: https://reviews.llvm.org/D28089 llvm-svn: 290507
1 parent 4f90ee0 commit 690952d

File tree

1 file changed

+23
-44
lines changed

1 file changed

+23
-44
lines changed
 

‎llvm/lib/Bitcode/Reader/MetadataLoader.cpp

+23-44
Original file line numberDiff line numberDiff line change
@@ -97,25 +97,20 @@ namespace {
9797
static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; }
9898

9999
class BitcodeReaderMetadataList {
100-
/// Keep track of the current number of ForwardReference in the list.
101-
unsigned NumFwdRefs = 0;
102-
/// Maintain the range [min-max] that needs to be inspected to resolve cycles.
103-
/// This is the range of Metadata that have involved forward reference during
104-
/// loading and that needs to be inspected to resolve cycles. It is purely an
105-
/// optimization to avoid spending time resolving cycles outside of this
106-
/// range, i.e. where there hasn't been any forward reference.
107-
unsigned MinFwdRef = 0;
108-
unsigned MaxFwdRef = 0;
109-
/// Set to true if there was any FwdRef encountered. This is used to track if
110-
/// we need to resolve cycles after loading metadatas.
111-
bool AnyFwdRefs = false;
112-
113100
/// Array of metadata references.
114101
///
115102
/// Don't use std::vector here. Some versions of libc++ copy (instead of
116103
/// move) on resize, and TrackingMDRef is very expensive to copy.
117104
SmallVector<TrackingMDRef, 1> MetadataPtrs;
118105

106+
/// The set of indices in MetadataPtrs above of forward references that were
107+
/// generated.
108+
SmallDenseSet<unsigned, 1> ForwardReference;
109+
110+
/// The set of indices in MetadataPtrs above of Metadata that need to be
111+
/// resolved.
112+
SmallDenseSet<unsigned, 1> UnresolvedNodes;
113+
119114
/// Structures for resolving old type refs.
120115
struct {
121116
SmallDenseMap<MDString *, TempMDTuple, 1> Unknown;
@@ -151,7 +146,8 @@ class BitcodeReaderMetadataList {
151146

152147
void shrinkTo(unsigned N) {
153148
assert(N <= size() && "Invalid shrinkTo request!");
154-
assert(!AnyFwdRefs && "Unexpected forward refs");
149+
assert(ForwardReference.empty() && "Unexpected forward refs");
150+
assert(UnresolvedNodes.empty() && "Unexpected unresolved node");
155151
MetadataPtrs.resize(N);
156152
}
157153

@@ -168,7 +164,7 @@ class BitcodeReaderMetadataList {
168164
MDNode *getMDNodeFwdRefOrNull(unsigned Idx);
169165
void assignValue(Metadata *MD, unsigned Idx);
170166
void tryToResolveCycles();
171-
bool hasFwdRefs() const { return AnyFwdRefs; }
167+
bool hasFwdRefs() const { return !ForwardReference.empty(); }
172168

173169
/// Upgrade a type that had an MDString reference.
174170
void addTypeRef(MDString &UUID, DICompositeType &CT);
@@ -184,6 +180,10 @@ class BitcodeReaderMetadataList {
184180
};
185181

186182
void BitcodeReaderMetadataList::assignValue(Metadata *MD, unsigned Idx) {
183+
if (auto *MDN = dyn_cast<MDNode>(MD))
184+
if (!MDN->isResolved())
185+
UnresolvedNodes.insert(Idx);
186+
187187
if (Idx == size()) {
188188
push_back(MD);
189189
return;
@@ -201,7 +201,7 @@ void BitcodeReaderMetadataList::assignValue(Metadata *MD, unsigned Idx) {
201201
// If there was a forward reference to this value, replace it.
202202
TempMDTuple PrevMD(cast<MDTuple>(OldMD.get()));
203203
PrevMD->replaceAllUsesWith(MD);
204-
--NumFwdRefs;
204+
ForwardReference.erase(Idx);
205205
}
206206

207207
Metadata *BitcodeReaderMetadataList::getMetadataFwdRef(unsigned Idx) {
@@ -212,14 +212,7 @@ Metadata *BitcodeReaderMetadataList::getMetadataFwdRef(unsigned Idx) {
212212
return MD;
213213

214214
// Track forward refs to be resolved later.
215-
if (AnyFwdRefs) {
216-
MinFwdRef = std::min(MinFwdRef, Idx);
217-
MaxFwdRef = std::max(MaxFwdRef, Idx);
218-
} else {
219-
AnyFwdRefs = true;
220-
MinFwdRef = MaxFwdRef = Idx;
221-
}
222-
++NumFwdRefs;
215+
ForwardReference.insert(Idx);
223216

224217
// Create and return a placeholder, which will later be RAUW'd.
225218
Metadata *MD = MDNode::getTemporary(Context, None).release();
@@ -240,50 +233,38 @@ MDNode *BitcodeReaderMetadataList::getMDNodeFwdRefOrNull(unsigned Idx) {
240233
}
241234

242235
void BitcodeReaderMetadataList::tryToResolveCycles() {
243-
if (NumFwdRefs)
236+
if (!ForwardReference.empty())
244237
// Still forward references... can't resolve cycles.
245238
return;
246239

247-
bool DidReplaceTypeRefs = false;
248-
249240
// Give up on finding a full definition for any forward decls that remain.
250241
for (const auto &Ref : OldTypeRefs.FwdDecls)
251242
OldTypeRefs.Final.insert(Ref);
252243
OldTypeRefs.FwdDecls.clear();
253244

254245
// Upgrade from old type ref arrays. In strange cases, this could add to
255246
// OldTypeRefs.Unknown.
256-
for (const auto &Array : OldTypeRefs.Arrays) {
257-
DidReplaceTypeRefs = true;
247+
for (const auto &Array : OldTypeRefs.Arrays)
258248
Array.second->replaceAllUsesWith(resolveTypeRefArray(Array.first.get()));
259-
}
260249
OldTypeRefs.Arrays.clear();
261250

262251
// Replace old string-based type refs with the resolved node, if possible.
263252
// If we haven't seen the node, leave it to the verifier to complain about
264253
// the invalid string reference.
265254
for (const auto &Ref : OldTypeRefs.Unknown) {
266-
DidReplaceTypeRefs = true;
267255
if (DICompositeType *CT = OldTypeRefs.Final.lookup(Ref.first))
268256
Ref.second->replaceAllUsesWith(CT);
269257
else
270258
Ref.second->replaceAllUsesWith(Ref.first);
271259
}
272260
OldTypeRefs.Unknown.clear();
273261

274-
// Make sure all the upgraded types are resolved.
275-
if (DidReplaceTypeRefs) {
276-
AnyFwdRefs = true;
277-
MinFwdRef = 0;
278-
MaxFwdRef = MetadataPtrs.size() - 1;
279-
}
280-
281-
if (!AnyFwdRefs)
262+
if (UnresolvedNodes.empty())
282263
// Nothing to do.
283264
return;
284265

285266
// Resolve any cycles.
286-
for (unsigned I = MinFwdRef, E = MaxFwdRef + 1; I != E; ++I) {
267+
for (unsigned I : UnresolvedNodes) {
287268
auto &MD = MetadataPtrs[I];
288269
auto *N = dyn_cast_or_null<MDNode>(MD);
289270
if (!N)
@@ -293,10 +274,8 @@ void BitcodeReaderMetadataList::tryToResolveCycles() {
293274
N->resolveCycles();
294275
}
295276

296-
// Make sure we return early again until there's another forward ref.
297-
AnyFwdRefs = false;
298-
MinFwdRef = 0;
299-
MaxFwdRef = 0;
277+
// Make sure we return early again until there's another unresolved ref.
278+
UnresolvedNodes.clear();
300279
}
301280

302281
void BitcodeReaderMetadataList::addTypeRef(MDString &UUID,

0 commit comments

Comments
 (0)
Please sign in to comment.