@@ -108,6 +108,7 @@ class BlockPartitionState {
108108
109109class TrackableValue ;
110110class TrackableValueState ;
111+ struct TrackableValueLookupResult ;
111112
112113enum class TrackableValueFlag {
113114 // / Base value that says a value is uniquely represented and is
@@ -272,6 +273,25 @@ class regionanalysisimpl::TrackableValue {
272273 }
273274};
274275
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+
275295class RegionAnalysis ;
276296
277297class RegionAnalysisValueMap {
@@ -282,6 +302,8 @@ class RegionAnalysisValueMap {
282302 using Region = PartitionPrimitives::Region;
283303 using TrackableValue = regionanalysisimpl::TrackableValue;
284304 using TrackableValueState = regionanalysisimpl::TrackableValueState;
305+ using TrackableValueLookupResult =
306+ regionanalysisimpl::TrackableValueLookupResult;
285307
286308private:
287309 // / A map from the representative of an equivalence class of values to their
@@ -301,30 +323,57 @@ class RegionAnalysisValueMap {
301323
302324 // / State that the value -> representative computation yields to us.
303325 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.
304330 SILValue value;
305331
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;
308336
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+ }
310342
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() {}
312359
313360 UnderlyingTrackedValueInfo (const UnderlyingTrackedValueInfo &newVal)
314- : value(newVal.value), actorIsolation (newVal.actorIsolation ) {}
361+ : value(newVal.value), base (newVal.base ) {}
315362
316363 UnderlyingTrackedValueInfo &
317364 operator =(const UnderlyingTrackedValueInfo &newVal) {
318365 value = newVal.value ;
319- actorIsolation = newVal.actorIsolation ;
366+ base = newVal.base ;
320367 return *this ;
321368 }
322369
323- UnderlyingTrackedValueInfo (SILValue value,
324- std::optional<ActorIsolation> actorIsolation)
325- : value(value), actorIsolation(actorIsolation) {}
326-
327370 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+ }
328377 };
329378
330379 // / A map from a SILValue to its equivalence class representative.
@@ -363,10 +412,16 @@ class RegionAnalysisValueMap {
363412 void print (llvm::raw_ostream &os) const ;
364413 SWIFT_DEBUG_DUMP { print (llvm::dbgs ()); }
365414
366- TrackableValue
415+ TrackableValueLookupResult
367416 getTrackableValue (SILValue value,
368417 bool isAddressCapturedByPartialApply = false ) const ;
369418
419+ private:
420+ TrackableValue
421+ getTrackableValueHelper (SILValue value,
422+ bool isAddressCapturedByPartialApply = false ) const ;
423+
424+ public:
370425 // / An actor introducing inst is an instruction that doesn't have any
371426 // / non-Sendable parameters and produces a new value that has to be actor
372427 // / isolated.
@@ -378,7 +433,8 @@ class RegionAnalysisValueMap {
378433
379434private:
380435 std::optional<TrackableValue> getValueForId (Element id) const ;
381- std::optional<TrackableValue> tryToTrackValue (SILValue value) const ;
436+ std::optional<TrackableValueLookupResult>
437+ tryToTrackValue (SILValue value) const ;
382438 TrackableValue
383439 getActorIntroducingRepresentative (SILInstruction *introducingInst,
384440 SILIsolationInfo isolation) const ;
@@ -400,6 +456,15 @@ class RegionAnalysisValueMap {
400456 UnderlyingTrackedValueInfo
401457 getUnderlyingTrackedValueHelper (SILValue value) const ;
402458
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+
403468 UnderlyingTrackedValueInfo getUnderlyingTrackedValue (SILValue value) const {
404469 // Use try_emplace so we only construct underlying tracked value info on
405470 // success and only lookup once in the hash table.
0 commit comments