@@ -97,25 +97,20 @@ namespace {
97
97
static int64_t unrotateSign (uint64_t U) { return U & 1 ? ~(U >> 1 ) : U >> 1 ; }
98
98
99
99
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
-
113
100
// / Array of metadata references.
114
101
// /
115
102
// / Don't use std::vector here. Some versions of libc++ copy (instead of
116
103
// / move) on resize, and TrackingMDRef is very expensive to copy.
117
104
SmallVector<TrackingMDRef, 1 > MetadataPtrs;
118
105
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
+
119
114
// / Structures for resolving old type refs.
120
115
struct {
121
116
SmallDenseMap<MDString *, TempMDTuple, 1 > Unknown;
@@ -151,7 +146,8 @@ class BitcodeReaderMetadataList {
151
146
152
147
void shrinkTo (unsigned N) {
153
148
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" );
155
151
MetadataPtrs.resize (N);
156
152
}
157
153
@@ -168,7 +164,7 @@ class BitcodeReaderMetadataList {
168
164
MDNode *getMDNodeFwdRefOrNull (unsigned Idx);
169
165
void assignValue (Metadata *MD, unsigned Idx);
170
166
void tryToResolveCycles ();
171
- bool hasFwdRefs () const { return AnyFwdRefs ; }
167
+ bool hasFwdRefs () const { return !ForwardReference. empty () ; }
172
168
173
169
// / Upgrade a type that had an MDString reference.
174
170
void addTypeRef (MDString &UUID, DICompositeType &CT);
@@ -184,6 +180,10 @@ class BitcodeReaderMetadataList {
184
180
};
185
181
186
182
void BitcodeReaderMetadataList::assignValue (Metadata *MD, unsigned Idx) {
183
+ if (auto *MDN = dyn_cast<MDNode>(MD))
184
+ if (!MDN->isResolved ())
185
+ UnresolvedNodes.insert (Idx);
186
+
187
187
if (Idx == size ()) {
188
188
push_back (MD);
189
189
return ;
@@ -201,7 +201,7 @@ void BitcodeReaderMetadataList::assignValue(Metadata *MD, unsigned Idx) {
201
201
// If there was a forward reference to this value, replace it.
202
202
TempMDTuple PrevMD (cast<MDTuple>(OldMD.get ()));
203
203
PrevMD->replaceAllUsesWith (MD);
204
- --NumFwdRefs ;
204
+ ForwardReference. erase (Idx) ;
205
205
}
206
206
207
207
Metadata *BitcodeReaderMetadataList::getMetadataFwdRef (unsigned Idx) {
@@ -212,14 +212,7 @@ Metadata *BitcodeReaderMetadataList::getMetadataFwdRef(unsigned Idx) {
212
212
return MD;
213
213
214
214
// 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);
223
216
224
217
// Create and return a placeholder, which will later be RAUW'd.
225
218
Metadata *MD = MDNode::getTemporary (Context, None).release ();
@@ -240,50 +233,38 @@ MDNode *BitcodeReaderMetadataList::getMDNodeFwdRefOrNull(unsigned Idx) {
240
233
}
241
234
242
235
void BitcodeReaderMetadataList::tryToResolveCycles () {
243
- if (NumFwdRefs )
236
+ if (!ForwardReference. empty () )
244
237
// Still forward references... can't resolve cycles.
245
238
return ;
246
239
247
- bool DidReplaceTypeRefs = false ;
248
-
249
240
// Give up on finding a full definition for any forward decls that remain.
250
241
for (const auto &Ref : OldTypeRefs.FwdDecls )
251
242
OldTypeRefs.Final .insert (Ref);
252
243
OldTypeRefs.FwdDecls .clear ();
253
244
254
245
// Upgrade from old type ref arrays. In strange cases, this could add to
255
246
// OldTypeRefs.Unknown.
256
- for (const auto &Array : OldTypeRefs.Arrays ) {
257
- DidReplaceTypeRefs = true ;
247
+ for (const auto &Array : OldTypeRefs.Arrays )
258
248
Array.second ->replaceAllUsesWith (resolveTypeRefArray (Array.first .get ()));
259
- }
260
249
OldTypeRefs.Arrays .clear ();
261
250
262
251
// Replace old string-based type refs with the resolved node, if possible.
263
252
// If we haven't seen the node, leave it to the verifier to complain about
264
253
// the invalid string reference.
265
254
for (const auto &Ref : OldTypeRefs.Unknown ) {
266
- DidReplaceTypeRefs = true ;
267
255
if (DICompositeType *CT = OldTypeRefs.Final .lookup (Ref.first ))
268
256
Ref.second ->replaceAllUsesWith (CT);
269
257
else
270
258
Ref.second ->replaceAllUsesWith (Ref.first );
271
259
}
272
260
OldTypeRefs.Unknown .clear ();
273
261
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 ())
282
263
// Nothing to do.
283
264
return ;
284
265
285
266
// Resolve any cycles.
286
- for (unsigned I = MinFwdRef, E = MaxFwdRef + 1 ; I != E; ++I ) {
267
+ for (unsigned I : UnresolvedNodes ) {
287
268
auto &MD = MetadataPtrs[I];
288
269
auto *N = dyn_cast_or_null<MDNode>(MD);
289
270
if (!N)
@@ -293,10 +274,8 @@ void BitcodeReaderMetadataList::tryToResolveCycles() {
293
274
N->resolveCycles ();
294
275
}
295
276
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 ();
300
279
}
301
280
302
281
void BitcodeReaderMetadataList::addTypeRef (MDString &UUID,
0 commit comments