@@ -93,21 +93,23 @@ regionanalysisimpl::getApplyIsolationCrossing(SILInstruction *inst) {
93
93
94
94
namespace {
95
95
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 ;
103
104
104
105
SILValue visitAll (SILValue sourceAddr) {
105
106
SILValue result = visit (sourceAddr);
106
107
if (!result)
107
108
return sourceAddr;
108
109
109
- while (SILValue nextAddr = visit (result))
110
+ while (SILValue nextAddr = visit (result)) {
110
111
result = nextAddr;
112
+ }
111
113
112
114
return result;
113
115
}
@@ -154,7 +156,7 @@ struct UseDefChainVisitor
154
156
}
155
157
156
158
// If we do not have an identity cast, mark this as a merge.
157
- isMerge |= castType != AccessStorageCast::Identity;
159
+ isProjectedFromAggregate |= castType != AccessStorageCast::Identity;
158
160
159
161
return sourceAddr->get ();
160
162
}
@@ -179,7 +181,7 @@ struct UseDefChainVisitor
179
181
llvm_unreachable (" Shouldn't see this here" );
180
182
case ProjectionKind::Index:
181
183
// Index is always a merge.
182
- isMerge = true ;
184
+ isProjectedFromAggregate = true ;
183
185
break ;
184
186
case ProjectionKind::Enum: {
185
187
auto op = cast<UncheckedTakeEnumDataAddrInst>(inst)->getOperand ();
@@ -200,7 +202,7 @@ struct UseDefChainVisitor
200
202
op->getFunction ()))
201
203
return SILValue ();
202
204
203
- isMerge |= op->getType ().getNumTupleElements () > 1 ;
205
+ isProjectedFromAggregate |= op->getType ().getNumTupleElements () > 1 ;
204
206
break ;
205
207
}
206
208
case ProjectionKind::Struct:
@@ -216,7 +218,7 @@ struct UseDefChainVisitor
216
218
return SILValue ();
217
219
218
220
// These are merges if we have multiple fields.
219
- isMerge |= op->getType ().getNumNominalFields () > 1 ;
221
+ isProjectedFromAggregate |= op->getType ().getNumNominalFields () > 1 ;
220
222
break ;
221
223
}
222
224
}
@@ -395,9 +397,9 @@ struct TermArgSources {
395
397
396
398
static bool isProjectedFromAggregate (SILValue value) {
397
399
assert (value->getType ().isAddress ());
398
- UseDefChainVisitor visitor;
400
+ AddressBaseComputingVisitor visitor;
399
401
visitor.visitAll (value);
400
- return visitor.isMerge ;
402
+ return visitor.isProjectedFromAggregate ;
401
403
}
402
404
403
405
namespace {
@@ -667,23 +669,6 @@ TrackableValue RegionAnalysisValueMap::getTrackableValue(
667
669
668
670
// Ok, at this point we have a non-Sendable value. First process addresses.
669
671
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
-
687
672
auto storage = AccessStorageWithBase::compute (value);
688
673
if (storage.storage ) {
689
674
// Check if we have a uniquely identified address that was not captured
@@ -705,19 +690,6 @@ TrackableValue RegionAnalysisValueMap::getTrackableValue(
705
690
if (isa<LoadInst, LoadBorrowInst>(iter.first ->first .getValue ())) {
706
691
auto *svi = cast<SingleValueInstruction>(iter.first ->first .getValue ());
707
692
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
-
721
693
auto storage = AccessStorageWithBase::compute (svi->getOperand (0 ));
722
694
if (storage.storage ) {
723
695
if (auto isolation = SILIsolationInfo::get (storage.base )) {
@@ -886,24 +858,31 @@ RegionAnalysisValueMap::getUnderlyingTrackedValueHelper(SILValue value) const {
886
858
return UnderlyingTrackedValueInfo (underlyingValue);
887
859
}
888
860
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.
891
863
value = cast<SingleValueInstruction>(underlyingValue)->getOperand (0 );
892
864
}
893
865
assert (value->getType ().isAddress ());
894
866
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;
896
872
SILValue base = visitor.visitAll (value);
897
873
assert (base);
874
+
875
+ // If we have an object base...
898
876
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
900
878
// rather than recurse into getUnderlyingTrackedObjectValueHelper. This is
901
879
// safe since we know that value was previously an address so if our base is
902
880
// an object, it cannot be the same object.
903
- return { getUnderlyingTrackedValue (base).value , visitor. actorIsolation } ;
881
+ return UnderlyingTrackedValueInfo ( getUnderlyingTrackedValue (base).value ) ;
904
882
}
905
883
906
- return {base, visitor.actorIsolation };
884
+ // Otherwise, we return the actorIsolation that our visitor found.
885
+ return UnderlyingTrackedValueInfo (base);
907
886
}
908
887
909
888
// ===----------------------------------------------------------------------===//
@@ -2599,9 +2578,9 @@ class PartitionOpTranslator {
2599
2578
2600
2579
// Then check if we are assigning into an aggregate projection. In such a
2601
2580
// 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.
2605
2584
if (isProjectedFromAggregate (destOperand->get ()))
2606
2585
return ;
2607
2586
0 commit comments