@@ -308,7 +308,6 @@ static bool isStaticallyLookThroughInst(SILInstruction *inst) {
308308 case SILInstructionKind::StrongCopyUnmanagedValueInst:
309309 case SILInstructionKind::RefToUnmanagedInst:
310310 case SILInstructionKind::UnmanagedToRefInst:
311- case SILInstructionKind::InitExistentialValueInst:
312311 case SILInstructionKind::UncheckedEnumDataInst:
313312 case SILInstructionKind::StructElementAddrInst:
314313 case SILInstructionKind::TupleElementAddrInst:
@@ -319,9 +318,17 @@ static bool isStaticallyLookThroughInst(SILInstruction *inst) {
319318 case SILInstructionKind::BeginBorrowInst:
320319 // Look through if it isn't from a var decl.
321320 return !cast<BeginBorrowInst>(inst)->isFromVarDecl ();
321+ case SILInstructionKind::InitExistentialValueInst:
322+ return !SILIsolationInfo::getConformanceIsolation (inst);
322323 case SILInstructionKind::UnconditionalCheckedCastInst: {
323324 auto cast = SILDynamicCastInst::getAs (inst);
324325 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+
325332 if (cast.isRCIdentityPreserving ())
326333 return true ;
327334 return false ;
@@ -2822,13 +2829,19 @@ class PartitionOpTranslator {
28222829
28232830 template <typename Collection>
28242831 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);
28272835 if (!destResult)
28282836 return ;
28292837
28302838 if (requireOperands) {
28312839 builder.addRequire (*destResult);
2840+
2841+ if (resultIsolationInfoOverride && !srcCollection.empty ()) {
2842+ using std::begin;
2843+ builder.addActorIntroducingInst (dest, *begin (srcCollection), resultIsolationInfoOverride);
2844+ }
28322845 }
28332846
28342847 for (Operand *op : srcCollection) {
@@ -2847,17 +2860,29 @@ class PartitionOpTranslator {
28472860
28482861 template <>
28492862 void translateSILMerge<Operand *>(SILValue dest, Operand *src,
2850- bool requireOperands) {
2863+ bool requireOperands,
2864+ SILIsolationInfo resultIsolationInfoOverride) {
28512865 return translateSILMerge (dest, TinyPtrVector<Operand *>(src),
2852- requireOperands);
2866+ requireOperands, resultIsolationInfoOverride );
28532867 }
28542868
28552869 void translateSILMerge (MutableArrayRef<Operand> array,
2856- bool requireOperands = true ) {
2870+ bool requireOperands,
2871+ SILIsolationInfo resultIsolationInfoOverride = {}) {
28572872 if (array.size () < 2 )
28582873 return ;
28592874
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+
28612886 if (!destResult)
28622887 return ;
28632888
@@ -2882,7 +2907,8 @@ class PartitionOpTranslator {
28822907 // / captures by applications), then these can be treated as assignments of \p
28832908 // / dest to src. If the \p dest could be aliased, then we must instead treat
28842909 // / 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 = {}) {
28862912 SILValue destValue = dest->get ();
28872913
28882914 if (auto destResult = tryToTrackValue (destValue)) {
@@ -2901,11 +2927,13 @@ class PartitionOpTranslator {
29012927 // TODO: Should this change if we have a Sendable address with a
29022928 // non-Sendable base.
29032929 if (destResult.value ().value .isNoAlias () &&
2930+ !resultIsolationInfoOverride &&
29042931 !isProjectedFromAggregate (destValue))
29052932 return translateSILAssign (destValue, src);
29062933
29072934 // Stores to possibly aliased storage must be treated as merges.
2908- return translateSILMerge (destValue, src);
2935+ return translateSILMerge (destValue, src, /* requireOperand*/ true ,
2936+ resultIsolationInfoOverride);
29092937 }
29102938
29112939 // Stores to storage of non-Sendable type can be ignored.
@@ -2935,7 +2963,8 @@ class PartitionOpTranslator {
29352963
29362964 // Stores to possibly aliased storage must be treated as merges.
29372965 return translateSILMerge (dest,
2938- makeOperandRefRange (inst->getElementOperands ()));
2966+ makeOperandRefRange (inst->getElementOperands ()),
2967+ /* requireOperands=*/ true );
29392968 }
29402969
29412970 // Stores to storage of non-Sendable type can be ignored.
@@ -2980,10 +3009,12 @@ class PartitionOpTranslator {
29803009 // and a pointer to the bb being branches to itself.
29813010 // this is handled as assigning to each possible arg being branched to the
29823011 // 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 = {}) {
29843014 argSources.argSources .setFrozen ();
29853015 for (auto pair : argSources.argSources .getRange ()) {
2986- translateSILMultiAssign (TinyPtrVector<SILValue>(pair.first ), pair.second );
3016+ translateSILMultiAssign (TinyPtrVector<SILValue>(pair.first ), pair.second ,
3017+ resultIsolationInfoOverride);
29873018 }
29883019 }
29893020
@@ -3068,7 +3099,8 @@ class PartitionOpTranslator {
30683099
30693100 case TranslationSemantics::Assign:
30703101 return translateSILMultiAssign (
3071- inst->getResults (), makeOperandRefRange (inst->getAllOperands ()));
3102+ inst->getResults (), makeOperandRefRange (inst->getAllOperands ()),
3103+ SILIsolationInfo::getConformanceIsolation (inst));
30723104
30733105 case TranslationSemantics::Require:
30743106 for (auto op : inst->getOperandValues ())
@@ -3085,7 +3117,8 @@ class PartitionOpTranslator {
30853117 case TranslationSemantics::Store:
30863118 return translateSILStore (
30873119 &inst->getAllOperands ()[CopyLikeInstruction::Dest],
3088- &inst->getAllOperands ()[CopyLikeInstruction::Src]);
3120+ &inst->getAllOperands ()[CopyLikeInstruction::Src],
3121+ SILIsolationInfo::getConformanceIsolation (inst));
30893122
30903123 case TranslationSemantics::Special:
30913124 return ;
@@ -3096,7 +3129,8 @@ class PartitionOpTranslator {
30963129 case TranslationSemantics::TerminatorPhi: {
30973130 TermArgSources sources;
30983131 sources.init (inst);
3099- return translateSILPhi (sources);
3132+ return translateSILPhi (
3133+ sources, SILIsolationInfo::getConformanceIsolation (inst));
31003134 }
31013135
31023136 case TranslationSemantics::Asserting:
@@ -3382,7 +3416,6 @@ CONSTANT_TRANSLATION(StrongCopyWeakValueInst, LookThrough)
33823416CONSTANT_TRANSLATION(StrongCopyUnmanagedValueInst, LookThrough)
33833417CONSTANT_TRANSLATION(RefToUnmanagedInst, LookThrough)
33843418CONSTANT_TRANSLATION(UnmanagedToRefInst, LookThrough)
3385- CONSTANT_TRANSLATION(InitExistentialValueInst, LookThrough)
33863419CONSTANT_TRANSLATION(UncheckedEnumDataInst, LookThrough)
33873420CONSTANT_TRANSLATION(TupleElementAddrInst, LookThrough)
33883421CONSTANT_TRANSLATION(StructElementAddrInst, LookThrough)
@@ -3393,7 +3426,7 @@ CONSTANT_TRANSLATION(UncheckedTakeEnumDataAddrInst, LookThrough)
33933426//
33943427
33953428// 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,
33973430// but conservative behavior is to treat these as merges of the regions of
33983431// the src value and tgt addr
33993432CONSTANT_TRANSLATION(CopyAddrInst, Store)
@@ -3879,7 +3912,10 @@ PartitionOpTranslator::visitPointerToAddressInst(PointerToAddressInst *ptai) {
38793912
38803913TranslationSemantics PartitionOpTranslator::visitUnconditionalCheckedCastInst (
38813914 UnconditionalCheckedCastInst *ucci) {
3882- if (SILDynamicCastInst (ucci).isRCIdentityPreserving ()) {
3915+ auto isolation = SILIsolationInfo::getConformanceIsolation (ucci);
3916+
3917+ if (!isolation &&
3918+ SILDynamicCastInst (ucci).isRCIdentityPreserving ()) {
38833919 assert (isStaticallyLookThroughInst (ucci) && " Out of sync" );
38843920 return TranslationSemantics::LookThrough;
38853921 }
@@ -3974,6 +4010,14 @@ PartitionOpTranslator::visitPartialApplyInst(PartialApplyInst *pai) {
39744010 return TranslationSemantics::Special;
39754011}
39764012
4013+ TranslationSemantics
4014+ PartitionOpTranslator::visitInitExistentialValueInst (InitExistentialValueInst *ievi) {
4015+ if (isStaticallyLookThroughInst (ievi))
4016+ return TranslationSemantics::LookThrough;
4017+
4018+ return TranslationSemantics::Assign;
4019+ }
4020+
39774021TranslationSemantics PartitionOpTranslator::visitCheckedCastAddrBranchInst (
39784022 CheckedCastAddrBranchInst *ccabi) {
39794023 assert (ccabi->getSuccessBB ()->getNumArguments () <= 1 );
@@ -3986,7 +4030,8 @@ TranslationSemantics PartitionOpTranslator::visitCheckedCastAddrBranchInst(
39864030 // is. For now just keep the current behavior. It is more conservative,
39874031 // but still correct.
39884032 translateSILMultiAssign (ArrayRef<SILValue>(),
3989- makeOperandRefRange (ccabi->getAllOperands ()));
4033+ makeOperandRefRange (ccabi->getAllOperands ()),
4034+ SILIsolationInfo::getConformanceIsolation (ccabi));
39904035 return TranslationSemantics::Special;
39914036}
39924037
0 commit comments