@@ -108,6 +108,7 @@ class BlockPartitionState {
108
108
109
109
class TrackableValue ;
110
110
class TrackableValueState ;
111
+ struct TrackableValueLookupResult ;
111
112
112
113
enum class TrackableValueFlag {
113
114
// / Base value that says a value is uniquely represented and is
@@ -272,6 +273,25 @@ class regionanalysisimpl::TrackableValue {
272
273
}
273
274
};
274
275
276
+ // / A class that contains both a lookup value as well as extra metadata about
277
+ // / properties of the original value that we looked up up from that we
278
+ // / discovered as we searched for the lookup value.
279
+ struct regionanalysisimpl ::TrackableValueLookupResult {
280
+ // / The actual value that we are tracking.
281
+ // /
282
+ // / If we are tracking a Sendable address that has a non-Sendable base, this
283
+ // / will be an empty TrackableValue.
284
+ TrackableValue value;
285
+
286
+ // / If we are tracking an address, this is the base trackable value that is
287
+ // / being tracked. If the base is a Sendable value, then this will be an empty
288
+ // / TrackableValue.
289
+ std::optional<TrackableValue> base;
290
+
291
+ void print (llvm::raw_ostream &os) const ;
292
+ SWIFT_DEBUG_DUMP { print (llvm::dbgs ()); }
293
+ };
294
+
275
295
class RegionAnalysis ;
276
296
277
297
class RegionAnalysisValueMap {
@@ -282,6 +302,8 @@ class RegionAnalysisValueMap {
282
302
using Region = PartitionPrimitives::Region;
283
303
using TrackableValue = regionanalysisimpl::TrackableValue;
284
304
using TrackableValueState = regionanalysisimpl::TrackableValueState;
305
+ using TrackableValueLookupResult =
306
+ regionanalysisimpl::TrackableValueLookupResult;
285
307
286
308
private:
287
309
// / A map from the representative of an equivalence class of values to their
@@ -301,30 +323,57 @@ class RegionAnalysisValueMap {
301
323
302
324
// / State that the value -> representative computation yields to us.
303
325
struct UnderlyingTrackedValueInfo {
326
+ // / The equivalence class value that we found that should be merged into
327
+ // / regions.
328
+ // /
329
+ // / Always set to a real value.
304
330
SILValue value;
305
331
306
- // / Only used for addresses.
307
- std::optional<ActorIsolation> actorIsolation;
332
+ // / The actual base value that we found if we were looking for an address
333
+ // / equivilance class and had a non-Sendable base. If we have an object or
334
+ // / we do not have a separate base, this is SILValue().
335
+ SILValue base;
308
336
309
- explicit UnderlyingTrackedValueInfo (SILValue value) : value(value) {}
337
+ // / Constructor for use if we only have either an object or an address
338
+ // / equivalence class that involves a complete non-Sendable path.
339
+ explicit UnderlyingTrackedValueInfo (SILValue value) : value(value), base() {
340
+ assert (value);
341
+ }
310
342
311
- UnderlyingTrackedValueInfo () : value(), actorIsolation() {}
343
+ // / Constructor for use with addresses only where we have either:
344
+ // /
345
+ // / 1. A sendable address that is used but that has a non-Sendable base that
346
+ // / we have to insert requires for.
347
+ // /
348
+ // / 2. A non-Sendable address that is used but that has a separate
349
+ // / non-Sendable base due to an access path chain that has a split in
350
+ // / between the two due to the non-Sendable address being projected out of
351
+ // / an intervening sendable struct. The struct can be Sendable due to things
352
+ // / like being global actor isolated or by being marked @unchecked Sendable.
353
+ explicit UnderlyingTrackedValueInfo (SILValue value, SILValue base)
354
+ : value(value), base(base) {
355
+ assert (value);
356
+ assert (base);
357
+ }
358
+ UnderlyingTrackedValueInfo () : value(), base() {}
312
359
313
360
UnderlyingTrackedValueInfo (const UnderlyingTrackedValueInfo &newVal)
314
- : value(newVal.value), actorIsolation (newVal.actorIsolation ) {}
361
+ : value(newVal.value), base (newVal.base ) {}
315
362
316
363
UnderlyingTrackedValueInfo &
317
364
operator =(const UnderlyingTrackedValueInfo &newVal) {
318
365
value = newVal.value ;
319
- actorIsolation = newVal.actorIsolation ;
366
+ base = newVal.base ;
320
367
return *this ;
321
368
}
322
369
323
- UnderlyingTrackedValueInfo (SILValue value,
324
- std::optional<ActorIsolation> actorIsolation)
325
- : value(value), actorIsolation(actorIsolation) {}
326
-
327
370
operator bool () const { return value; }
371
+
372
+ void print (llvm::raw_ostream &os) const ;
373
+ SWIFT_DEBUG_DUMP {
374
+ print (llvm::dbgs ());
375
+ llvm::dbgs () << ' \n ' ;
376
+ }
328
377
};
329
378
330
379
// / A map from a SILValue to its equivalence class representative.
@@ -363,10 +412,16 @@ class RegionAnalysisValueMap {
363
412
void print (llvm::raw_ostream &os) const ;
364
413
SWIFT_DEBUG_DUMP { print (llvm::dbgs ()); }
365
414
366
- TrackableValue
415
+ TrackableValueLookupResult
367
416
getTrackableValue (SILValue value,
368
417
bool isAddressCapturedByPartialApply = false ) const ;
369
418
419
+ private:
420
+ TrackableValue
421
+ getTrackableValueHelper (SILValue value,
422
+ bool isAddressCapturedByPartialApply = false ) const ;
423
+
424
+ public:
370
425
// / An actor introducing inst is an instruction that doesn't have any
371
426
// / non-Sendable parameters and produces a new value that has to be actor
372
427
// / isolated.
@@ -378,7 +433,8 @@ class RegionAnalysisValueMap {
378
433
379
434
private:
380
435
std::optional<TrackableValue> getValueForId (Element id) const ;
381
- std::optional<TrackableValue> tryToTrackValue (SILValue value) const ;
436
+ std::optional<TrackableValueLookupResult>
437
+ tryToTrackValue (SILValue value) const ;
382
438
TrackableValue
383
439
getActorIntroducingRepresentative (SILInstruction *introducingInst,
384
440
SILIsolationInfo isolation) const ;
@@ -400,6 +456,15 @@ class RegionAnalysisValueMap {
400
456
UnderlyingTrackedValueInfo
401
457
getUnderlyingTrackedValueHelper (SILValue value) const ;
402
458
459
+ // / A helper function that performs the actual getUnderlyingTrackedValue
460
+ // / computation that is cached in getUnderlyingTrackedValue(). Please never
461
+ // / call this directly! Only call it from getUnderlyingTrackedValue.
462
+ UnderlyingTrackedValueInfo
463
+ getUnderlyingTrackedValueHelperObject (SILValue value) const ;
464
+
465
+ UnderlyingTrackedValueInfo
466
+ getUnderlyingTrackedValueHelperAddress (SILValue value) const ;
467
+
403
468
UnderlyingTrackedValueInfo getUnderlyingTrackedValue (SILValue value) const {
404
469
// Use try_emplace so we only construct underlying tracked value info on
405
470
// success and only lookup once in the hash table.
0 commit comments