@@ -308,7 +308,6 @@ static bool isStaticallyLookThroughInst(SILInstruction *inst) {
308
308
case SILInstructionKind::StrongCopyUnmanagedValueInst:
309
309
case SILInstructionKind::RefToUnmanagedInst:
310
310
case SILInstructionKind::UnmanagedToRefInst:
311
- case SILInstructionKind::InitExistentialValueInst:
312
311
case SILInstructionKind::UncheckedEnumDataInst:
313
312
case SILInstructionKind::StructElementAddrInst:
314
313
case SILInstructionKind::TupleElementAddrInst:
@@ -319,9 +318,17 @@ static bool isStaticallyLookThroughInst(SILInstruction *inst) {
319
318
case SILInstructionKind::BeginBorrowInst:
320
319
// Look through if it isn't from a var decl.
321
320
return !cast<BeginBorrowInst>(inst)->isFromVarDecl ();
321
+ case SILInstructionKind::InitExistentialValueInst:
322
+ return !SILIsolationInfo::getConformanceIsolation (inst);
322
323
case SILInstructionKind::UnconditionalCheckedCastInst: {
323
324
auto cast = SILDynamicCastInst::getAs (inst);
324
325
assert (cast);
326
+
327
+ // If this cast introduces isolation due to conformances, we cannot look
328
+ // through it to the source.
329
+ if (SILIsolationInfo::getConformanceIsolation (inst))
330
+ return false ;
331
+
325
332
if (cast.isRCIdentityPreserving ())
326
333
return true ;
327
334
return false ;
@@ -2822,13 +2829,19 @@ class PartitionOpTranslator {
2822
2829
2823
2830
template <typename Collection>
2824
2831
void translateSILMerge (SILValue dest, Collection srcCollection,
2825
- bool requireOperands = true ) {
2826
- auto destResult = tryToTrackValue (dest);
2832
+ bool requireOperands,
2833
+ SILIsolationInfo resultIsolationInfoOverride = {}) {
2834
+ auto destResult = tryToTrackValue (dest);
2827
2835
if (!destResult)
2828
2836
return ;
2829
2837
2830
2838
if (requireOperands) {
2831
2839
builder.addRequire (*destResult);
2840
+
2841
+ if (resultIsolationInfoOverride && !srcCollection.empty ()) {
2842
+ using std::begin;
2843
+ builder.addActorIntroducingInst (dest, *begin (srcCollection), resultIsolationInfoOverride);
2844
+ }
2832
2845
}
2833
2846
2834
2847
for (Operand *op : srcCollection) {
@@ -2847,17 +2860,29 @@ class PartitionOpTranslator {
2847
2860
2848
2861
template <>
2849
2862
void translateSILMerge<Operand *>(SILValue dest, Operand *src,
2850
- bool requireOperands) {
2863
+ bool requireOperands,
2864
+ SILIsolationInfo resultIsolationInfoOverride) {
2851
2865
return translateSILMerge (dest, TinyPtrVector<Operand *>(src),
2852
- requireOperands);
2866
+ requireOperands, resultIsolationInfoOverride );
2853
2867
}
2854
2868
2855
2869
void translateSILMerge (MutableArrayRef<Operand> array,
2856
- bool requireOperands = true ) {
2870
+ bool requireOperands,
2871
+ SILIsolationInfo resultIsolationInfoOverride = {}) {
2857
2872
if (array.size () < 2 )
2858
2873
return ;
2859
2874
2860
- auto destResult = tryToTrackValue (array.front ().get ());
2875
+ std::optional<TrackableValueLookupResult> destResult;
2876
+ if (resultIsolationInfoOverride) {
2877
+ if (auto nonSendableValue = initializeTrackedValue (
2878
+ array.front ().get (), resultIsolationInfoOverride)) {
2879
+ destResult = TrackableValueLookupResult{
2880
+ nonSendableValue->first , std::nullopt};
2881
+ }
2882
+ } else {
2883
+ destResult = tryToTrackValue (array.front ().get ());
2884
+ }
2885
+
2861
2886
if (!destResult)
2862
2887
return ;
2863
2888
@@ -2882,7 +2907,8 @@ class PartitionOpTranslator {
2882
2907
// / captures by applications), then these can be treated as assignments of \p
2883
2908
// / dest to src. If the \p dest could be aliased, then we must instead treat
2884
2909
// / them as merges, to ensure any aliases of \p dest are also updated.
2885
- void translateSILStore (Operand *dest, Operand *src) {
2910
+ void translateSILStore (Operand *dest, Operand *src,
2911
+ SILIsolationInfo resultIsolationInfoOverride = {}) {
2886
2912
SILValue destValue = dest->get ();
2887
2913
2888
2914
if (auto destResult = tryToTrackValue (destValue)) {
@@ -2901,11 +2927,13 @@ class PartitionOpTranslator {
2901
2927
// TODO: Should this change if we have a Sendable address with a
2902
2928
// non-Sendable base.
2903
2929
if (destResult.value ().value .isNoAlias () &&
2930
+ !resultIsolationInfoOverride &&
2904
2931
!isProjectedFromAggregate (destValue))
2905
2932
return translateSILAssign (destValue, src);
2906
2933
2907
2934
// Stores to possibly aliased storage must be treated as merges.
2908
- return translateSILMerge (destValue, src);
2935
+ return translateSILMerge (destValue, src, /* requireOperand*/ true ,
2936
+ resultIsolationInfoOverride);
2909
2937
}
2910
2938
2911
2939
// Stores to storage of non-Sendable type can be ignored.
@@ -2935,7 +2963,8 @@ class PartitionOpTranslator {
2935
2963
2936
2964
// Stores to possibly aliased storage must be treated as merges.
2937
2965
return translateSILMerge (dest,
2938
- makeOperandRefRange (inst->getElementOperands ()));
2966
+ makeOperandRefRange (inst->getElementOperands ()),
2967
+ /* requireOperands=*/ true );
2939
2968
}
2940
2969
2941
2970
// Stores to storage of non-Sendable type can be ignored.
@@ -2980,10 +3009,12 @@ class PartitionOpTranslator {
2980
3009
// and a pointer to the bb being branches to itself.
2981
3010
// this is handled as assigning to each possible arg being branched to the
2982
3011
// merge of all values that could be passed to it from this basic block.
2983
- void translateSILPhi (TermArgSources &argSources) {
3012
+ void translateSILPhi (TermArgSources &argSources,
3013
+ SILIsolationInfo resultIsolationInfoOverride = {}) {
2984
3014
argSources.argSources .setFrozen ();
2985
3015
for (auto pair : argSources.argSources .getRange ()) {
2986
- translateSILMultiAssign (TinyPtrVector<SILValue>(pair.first ), pair.second );
3016
+ translateSILMultiAssign (TinyPtrVector<SILValue>(pair.first ), pair.second ,
3017
+ resultIsolationInfoOverride);
2987
3018
}
2988
3019
}
2989
3020
@@ -3068,7 +3099,8 @@ class PartitionOpTranslator {
3068
3099
3069
3100
case TranslationSemantics::Assign:
3070
3101
return translateSILMultiAssign (
3071
- inst->getResults (), makeOperandRefRange (inst->getAllOperands ()));
3102
+ inst->getResults (), makeOperandRefRange (inst->getAllOperands ()),
3103
+ SILIsolationInfo::getConformanceIsolation (inst));
3072
3104
3073
3105
case TranslationSemantics::Require:
3074
3106
for (auto op : inst->getOperandValues ())
@@ -3085,7 +3117,8 @@ class PartitionOpTranslator {
3085
3117
case TranslationSemantics::Store:
3086
3118
return translateSILStore (
3087
3119
&inst->getAllOperands ()[CopyLikeInstruction::Dest],
3088
- &inst->getAllOperands ()[CopyLikeInstruction::Src]);
3120
+ &inst->getAllOperands ()[CopyLikeInstruction::Src],
3121
+ SILIsolationInfo::getConformanceIsolation (inst));
3089
3122
3090
3123
case TranslationSemantics::Special:
3091
3124
return ;
@@ -3096,7 +3129,8 @@ class PartitionOpTranslator {
3096
3129
case TranslationSemantics::TerminatorPhi: {
3097
3130
TermArgSources sources;
3098
3131
sources.init (inst);
3099
- return translateSILPhi (sources);
3132
+ return translateSILPhi (
3133
+ sources, SILIsolationInfo::getConformanceIsolation (inst));
3100
3134
}
3101
3135
3102
3136
case TranslationSemantics::Asserting:
@@ -3382,7 +3416,6 @@ CONSTANT_TRANSLATION(StrongCopyWeakValueInst, LookThrough)
3382
3416
CONSTANT_TRANSLATION(StrongCopyUnmanagedValueInst, LookThrough)
3383
3417
CONSTANT_TRANSLATION(RefToUnmanagedInst, LookThrough)
3384
3418
CONSTANT_TRANSLATION(UnmanagedToRefInst, LookThrough)
3385
- CONSTANT_TRANSLATION(InitExistentialValueInst, LookThrough)
3386
3419
CONSTANT_TRANSLATION(UncheckedEnumDataInst, LookThrough)
3387
3420
CONSTANT_TRANSLATION(TupleElementAddrInst, LookThrough)
3388
3421
CONSTANT_TRANSLATION(StructElementAddrInst, LookThrough)
@@ -3393,7 +3426,7 @@ CONSTANT_TRANSLATION(UncheckedTakeEnumDataAddrInst, LookThrough)
3393
3426
//
3394
3427
3395
3428
// These are treated as stores - meaning that they could write values into
3396
- // memory. The beahvior of this depends on whether the tgt addr is aliased,
3429
+ // memory. The behavior of this depends on whether the tgt addr is aliased,
3397
3430
// but conservative behavior is to treat these as merges of the regions of
3398
3431
// the src value and tgt addr
3399
3432
CONSTANT_TRANSLATION(CopyAddrInst, Store)
@@ -3879,7 +3912,10 @@ PartitionOpTranslator::visitPointerToAddressInst(PointerToAddressInst *ptai) {
3879
3912
3880
3913
TranslationSemantics PartitionOpTranslator::visitUnconditionalCheckedCastInst (
3881
3914
UnconditionalCheckedCastInst *ucci) {
3882
- if (SILDynamicCastInst (ucci).isRCIdentityPreserving ()) {
3915
+ auto isolation = SILIsolationInfo::getConformanceIsolation (ucci);
3916
+
3917
+ if (!isolation &&
3918
+ SILDynamicCastInst (ucci).isRCIdentityPreserving ()) {
3883
3919
assert (isStaticallyLookThroughInst (ucci) && " Out of sync" );
3884
3920
return TranslationSemantics::LookThrough;
3885
3921
}
@@ -3974,6 +4010,14 @@ PartitionOpTranslator::visitPartialApplyInst(PartialApplyInst *pai) {
3974
4010
return TranslationSemantics::Special;
3975
4011
}
3976
4012
4013
+ TranslationSemantics
4014
+ PartitionOpTranslator::visitInitExistentialValueInst (InitExistentialValueInst *ievi) {
4015
+ if (isStaticallyLookThroughInst (ievi))
4016
+ return TranslationSemantics::LookThrough;
4017
+
4018
+ return TranslationSemantics::Assign;
4019
+ }
4020
+
3977
4021
TranslationSemantics PartitionOpTranslator::visitCheckedCastAddrBranchInst (
3978
4022
CheckedCastAddrBranchInst *ccabi) {
3979
4023
assert (ccabi->getSuccessBB ()->getNumArguments () <= 1 );
@@ -3986,7 +4030,8 @@ TranslationSemantics PartitionOpTranslator::visitCheckedCastAddrBranchInst(
3986
4030
// is. For now just keep the current behavior. It is more conservative,
3987
4031
// but still correct.
3988
4032
translateSILMultiAssign (ArrayRef<SILValue>(),
3989
- makeOperandRefRange (ccabi->getAllOperands ()));
4033
+ makeOperandRefRange (ccabi->getAllOperands ()),
4034
+ SILIsolationInfo::getConformanceIsolation (ccabi));
3990
4035
return TranslationSemantics::Special;
3991
4036
}
3992
4037
0 commit comments