@@ -93,21 +93,23 @@ regionanalysisimpl::getApplyIsolationCrossing(SILInstruction *inst) {
9393
9494namespace {
9595
96- struct UseDefChainVisitor
97- : public AccessUseDefChainVisitor<UseDefChainVisitor, SILValue> {
98- bool isMerge = false ;
99-
100- // / The actor isolation that we found while walking from use->def. Always set
101- // / to the first one encountered.
102- std::optional<ActorIsolation> actorIsolation;
96+ // / A visitor that walks from uses -> def attempting to determine an object or
97+ // / address base for the passed in address.
98+ // /
99+ // / It also is used to determine if we are assigning into a part of an aggregate
100+ // / or are assigning over an entire value.
101+ struct AddressBaseComputingVisitor
102+ : public AccessUseDefChainVisitor<AddressBaseComputingVisitor, SILValue> {
103+ bool isProjectedFromAggregate = false ;
103104
104105 SILValue visitAll (SILValue sourceAddr) {
105106 SILValue result = visit (sourceAddr);
106107 if (!result)
107108 return sourceAddr;
108109
109- while (SILValue nextAddr = visit (result))
110+ while (SILValue nextAddr = visit (result)) {
110111 result = nextAddr;
112+ }
111113
112114 return result;
113115 }
@@ -154,7 +156,7 @@ struct UseDefChainVisitor
154156 }
155157
156158 // If we do not have an identity cast, mark this as a merge.
157- isMerge |= castType != AccessStorageCast::Identity;
159+ isProjectedFromAggregate |= castType != AccessStorageCast::Identity;
158160
159161 return sourceAddr->get ();
160162 }
@@ -179,7 +181,7 @@ struct UseDefChainVisitor
179181 llvm_unreachable (" Shouldn't see this here" );
180182 case ProjectionKind::Index:
181183 // Index is always a merge.
182- isMerge = true ;
184+ isProjectedFromAggregate = true ;
183185 break ;
184186 case ProjectionKind::Enum: {
185187 auto op = cast<UncheckedTakeEnumDataAddrInst>(inst)->getOperand ();
@@ -200,7 +202,7 @@ struct UseDefChainVisitor
200202 op->getFunction ()))
201203 return SILValue ();
202204
203- isMerge |= op->getType ().getNumTupleElements () > 1 ;
205+ isProjectedFromAggregate |= op->getType ().getNumTupleElements () > 1 ;
204206 break ;
205207 }
206208 case ProjectionKind::Struct:
@@ -216,7 +218,7 @@ struct UseDefChainVisitor
216218 return SILValue ();
217219
218220 // These are merges if we have multiple fields.
219- isMerge |= op->getType ().getNumNominalFields () > 1 ;
221+ isProjectedFromAggregate |= op->getType ().getNumNominalFields () > 1 ;
220222 break ;
221223 }
222224 }
@@ -395,9 +397,9 @@ struct TermArgSources {
395397
396398static bool isProjectedFromAggregate (SILValue value) {
397399 assert (value->getType ().isAddress ());
398- UseDefChainVisitor visitor;
400+ AddressBaseComputingVisitor visitor;
399401 visitor.visitAll (value);
400- return visitor.isMerge ;
402+ return visitor.isProjectedFromAggregate ;
401403}
402404
403405namespace {
@@ -667,23 +669,6 @@ TrackableValue RegionAnalysisValueMap::getTrackableValue(
667669
668670 // Ok, at this point we have a non-Sendable value. First process addresses.
669671 if (value->getType ().isAddress ()) {
670- // If we were able to find this was actor isolated from finding our
671- // underlying object, use that. It is never wrong.
672- if (info.actorIsolation ) {
673- SILIsolationInfo isolation;
674- if (info.value ->getType ().isAnyActor ()) {
675- isolation = SILIsolationInfo::getActorInstanceIsolated (
676- value, info.value , info.actorIsolation ->getActor ());
677- } else if (info.actorIsolation ->isGlobalActor ()) {
678- isolation = SILIsolationInfo::getGlobalActorIsolated (
679- value, info.actorIsolation ->getGlobalActor ());
680- }
681-
682- if (isolation) {
683- iter.first ->getSecond ().setIsolationRegionInfo (isolation);
684- }
685- }
686-
687672 auto storage = AccessStorageWithBase::compute (value);
688673 if (storage.storage ) {
689674 // Check if we have a uniquely identified address that was not captured
@@ -705,19 +690,6 @@ TrackableValue RegionAnalysisValueMap::getTrackableValue(
705690 if (isa<LoadInst, LoadBorrowInst>(iter.first ->first .getValue ())) {
706691 auto *svi = cast<SingleValueInstruction>(iter.first ->first .getValue ());
707692
708- // See if we can use get underlying tracked value to find if it is actor
709- // isolated.
710- //
711- // TODO: Instead of using AccessStorageBase, just use our own visitor
712- // everywhere. Just haven't done it due to possible perturbations.
713- auto parentAddrInfo = getUnderlyingTrackedValue (svi);
714- if (parentAddrInfo.actorIsolation ) {
715- iter.first ->getSecond ().setIsolationRegionInfo (
716- SILIsolationInfo::getActorInstanceIsolated (
717- svi, parentAddrInfo.value ,
718- parentAddrInfo.actorIsolation ->getActor ()));
719- }
720-
721693 auto storage = AccessStorageWithBase::compute (svi->getOperand (0 ));
722694 if (storage.storage ) {
723695 if (auto isolation = SILIsolationInfo::get (storage.base )) {
@@ -886,24 +858,31 @@ RegionAnalysisValueMap::getUnderlyingTrackedValueHelper(SILValue value) const {
886858 return UnderlyingTrackedValueInfo (underlyingValue);
887859 }
888860
889- // If we got an address , lets see if we can do even better by looking at the
890- // address.
861+ // If we have a load or a load_borrow , lets see if we can do even better by
862+ // looking at the address.
891863 value = cast<SingleValueInstruction>(underlyingValue)->getOperand (0 );
892864 }
893865 assert (value->getType ().isAddress ());
894866
895- UseDefChainVisitor visitor;
867+ // At this point, we either have a value that we loaded from a
868+ // load/load_borrow or just an address. We need to attempt to find either an
869+ // object base for that address or an underlying actorIsolation for an address
870+ // base.
871+ AddressBaseComputingVisitor visitor;
896872 SILValue base = visitor.visitAll (value);
897873 assert (base);
874+
875+ // If we have an object base...
898876 if (base->getType ().isObject ()) {
899- // NOTE: We purposely recurse into the cached version of our computation
877+ // ... we purposely recurse into the cached version of our computation
900878 // rather than recurse into getUnderlyingTrackedObjectValueHelper. This is
901879 // safe since we know that value was previously an address so if our base is
902880 // an object, it cannot be the same object.
903- return { getUnderlyingTrackedValue (base).value , visitor. actorIsolation } ;
881+ return UnderlyingTrackedValueInfo ( getUnderlyingTrackedValue (base).value ) ;
904882 }
905883
906- return {base, visitor.actorIsolation };
884+ // Otherwise, we return the actorIsolation that our visitor found.
885+ return UnderlyingTrackedValueInfo (base);
907886}
908887
909888// ===----------------------------------------------------------------------===//
@@ -2599,9 +2578,9 @@ class PartitionOpTranslator {
25992578
26002579 // Then check if we are assigning into an aggregate projection. In such a
26012580 // case, we want to ensure that we keep tracking the elements already in the
2602- // region of sending. This is more conservative than we need to be
2603- // (since we could forget anything reachable from the aggregate
2604- // field)... but being more conservative is ok.
2581+ // region as sending. This is more conservative than we need to be (since we
2582+ // could forget anything reachable from the aggregate field)... but being
2583+ // more conservative is ok.
26052584 if (isProjectedFromAggregate (destOperand->get ()))
26062585 return ;
26072586
0 commit comments