@@ -109,6 +109,14 @@ using DependencySource = llvm::PointerIntPair<SourceFile *, 1, DependencyScope>;
109
109
110
110
struct DependencyRecorder ;
111
111
112
+ // / A \c DependencyCollector defines an abstract write-only buffer of
113
+ // / \c Reference objects. References are added to a collector during the write
114
+ // / phase of request evaluation (in \c writeDependencySink) with the various
115
+ // / \c add* functions below..
116
+ // /
117
+ // / A \c DependencyCollector cannot be created directly. You must invoke
118
+ // / \c DependencyRecorder::record, which will wire a dependency collector into
119
+ // / the provided continuation block.
112
120
struct DependencyCollector {
113
121
friend DependencyRecorder;
114
122
@@ -227,11 +235,15 @@ struct DependencyCollector {
227
235
void addDynamicLookupName (DeclBaseName name);
228
236
229
237
public:
238
+ // / Retrieves the dependency recorder that created this dependency collector.
230
239
const DependencyRecorder &getRecorder () const { return parent; }
240
+
241
+ // / Returns \c true if this collector has not accumulated
242
+ // / any \c Reference objects.
231
243
bool empty () const { return scratch.empty (); }
232
244
};
233
245
234
- // / A \c DependencyCollector is an aggregator of named references discovered in a
246
+ // / A \c DependencyRecorder is an aggregator of named references discovered in a
235
247
// / particular \c DependencyScope during the course of request evaluation.
236
248
struct DependencyRecorder {
237
249
friend DependencyCollector;
@@ -266,22 +278,62 @@ struct DependencyRecorder {
266
278
explicit DependencyRecorder (Mode mode) : mode{mode}, isRecording{false } {};
267
279
268
280
private:
281
+ // / Records the given \c Reference as a dependency of the current dependency
282
+ // / source.
283
+ // /
284
+ // / This is as opposed to merely collecting a \c Reference, which may just buffer
285
+ // / it for realization or replay later.
269
286
void realize (const DependencyCollector::Reference &ref);
270
287
271
288
public:
272
- void replay (const llvm::SetVector<swift::ActiveRequest> &stack,
273
- const swift::ActiveRequest &req);
289
+ // / Begins the recording of references by invoking the given continuation
290
+ // / with a fresh \c DependencyCollector object. This object should be used
291
+ // / to buffer dependency-relevant references to names looked up by a
292
+ // / given request.
293
+ // /
294
+ // / Recording only occurs for requests that are dependency sinks.
274
295
void record (const llvm::SetVector<swift::ActiveRequest> &stack,
275
296
llvm::function_ref<void (DependencyCollector &)> rec);
276
297
298
+ // / Replays the \c Reference objects collected by a given cached request and
299
+ // / its sub-requests into the current dependency scope.
300
+ // /
301
+ // / Dependency replay ensures that cached requests do not "hide" names from
302
+ // / the active dependency scope. This would otherwise occur frequently in
303
+ // / batch mode, where cached requests effectively block the re-evaluation of
304
+ // / a large quantity of computations that perform name lookups by design.
305
+ // /
306
+ // / Replay need only occur for requests that are (separately) cached.
307
+ void replay (const llvm::SetVector<swift::ActiveRequest> &stack,
308
+ const swift::ActiveRequest &req);
277
309
private:
310
+ // / Given the current stack of requests and a buffer of \c Reference objects
311
+ // / walk the active stack looking for the next-innermost cached request. If
312
+ // / found, insert the buffer of references into that request's known reference
313
+ // / set.
314
+ // /
315
+ // / This algorithm ensures that references propagate lazily up the request
316
+ // / graph from cached sub-requests to their cached parents. Once this process
317
+ // / completes, all cached requests in the request graph will see the
318
+ // / union of all references recorded while evaluating their sub-requests.
319
+ // /
320
+ // / This algorithm *must* be tail-called during
321
+ // / \c DependencyRecorder::record or \c DependencyRecorder::replay
322
+ // / or the corresponding set of references for the active dependency scope
323
+ // / will become incoherent.
278
324
void
279
325
unionNearestCachedRequest (ArrayRef<swift::ActiveRequest> stack,
280
326
const DependencyCollector::ReferenceSet &scratch);
281
327
282
328
public:
283
329
using ReferenceEnumerator =
284
330
llvm::function_ref<void (const DependencyCollector::Reference &)>;
331
+
332
+ // / Enumerates the set of references associated with a given source file,
333
+ // / passing them to the given enumeration callback.
334
+ // /
335
+ // / The order of enumeration is completely undefined. It is the responsibility
336
+ // / of callers to ensure they are order-invariant or are sorting the result.
285
337
void enumerateReferencesInFile (const SourceFile *SF,
286
338
ReferenceEnumerator f) const ;
287
339
0 commit comments