1515#include " swift/SILOptimizer/Analysis/RegionAnalysis.h"
1616
1717#include " swift/AST/ASTWalker.h"
18- #include " swift/AST/ConformanceLookup.h"
1918#include " swift/AST/DiagnosticsSIL.h"
2019#include " swift/AST/Expr.h"
21- #include " swift/AST/ExistentialLayout.h"
22- #include " swift/AST/PackConformance.h"
23- #include " swift/AST/ProtocolConformance.h"
2420#include " swift/AST/Type.h"
2521#include " swift/Basic/Assertions.h"
2622#include " swift/Basic/FrozenMultiMap.h"
@@ -274,59 +270,6 @@ struct AddressBaseComputingVisitor
274270
275271} // namespace
276272
277- // / Determine the isolation of conformances that could be introduced by a cast from sourceType to
278- // / destType.
279- // /
280- // /
281- static SILIsolationInfo getIsolationForCastConformances (
282- SILValue value, CanType sourceType, CanType destType) {
283- // If the enclosing function is @concurrent, then a cast cannot pick up
284- // any isolated conformances because it's not on any actor.
285- auto function = value->getFunction ();
286- auto functionIsolation = function->getActorIsolation ();
287- if (functionIsolation && functionIsolation->isNonisolated ())
288- return {};
289-
290- auto sendableMetatype =
291- sourceType->getASTContext ().getProtocol (KnownProtocolKind::SendableMetatype);
292- if (!sendableMetatype)
293- return {};
294-
295- if (!destType.isAnyExistentialType ())
296- return {};
297-
298- const auto &destLayout = destType.getExistentialLayout ();
299- for (auto proto : destLayout.getProtocols ()) {
300- if (proto->isMarkerProtocol ())
301- continue ;
302-
303- // If the source type already conforms to the protocol, we won't be looking
304- // it up dynamically.
305- if (!lookupConformance (sourceType, proto, /* allowMissing=*/ false ).isInvalid ())
306- continue ;
307-
308- // If the protocol inherits SendableMetatype, it can't have isolated
309- // conformances.
310- if (proto->inheritsFrom (sendableMetatype))
311- continue ;
312-
313- // The cast can produce a conformance with the same isolation as this
314- // function is dynamically executing. If that's known (i.e., because we're
315- // on a global actor), the value is isolated to that global actor.
316- // Otherwise, it's task-isolated.
317- if (functionIsolation && functionIsolation->isGlobalActor ()) {
318- return SILIsolationInfo::getGlobalActorIsolated (
319- value, functionIsolation->getGlobalActor (), proto);
320- }
321-
322- // Consider the cast to be task-isolated, because the runtime could find
323- // a conformance that is isolated to the current context.
324- return SILIsolationInfo::getTaskIsolated (value, proto);
325- }
326-
327- return {};
328- }
329-
330273// / Classify an instructions as look through when we are looking through
331274// / values. We assert that all instructions that are CONSTANT_TRANSLATION
332275// / LookThrough to make sure they stay in sync.
@@ -385,16 +328,15 @@ static bool isStaticallyLookThroughInst(SILInstruction *inst) {
385328 case SILInstructionKind::BeginBorrowInst:
386329 // Look through if it isn't from a var decl.
387330 return !cast<BeginBorrowInst>(inst)->isFromVarDecl ();
331+ case SILInstructionKind::InitExistentialValueInst:
332+ return !SILIsolationInfo::getConformanceIsolation (inst);
388333 case SILInstructionKind::UnconditionalCheckedCastInst: {
389334 auto cast = SILDynamicCastInst::getAs (inst);
390335 assert (cast);
391336
392337 // If this cast introduces isolation due to conformances, we cannot look
393338 // through it to the source.
394- if (!getIsolationForCastConformances (
395- llvm::cast<UnconditionalCheckedCastInst>(inst),
396- cast.getSourceFormalType (), cast.getTargetFormalType ())
397- .isDisconnected ())
339+ if (SILIsolationInfo::getConformanceIsolation (inst))
398340 return false ;
399341
400342 if (cast.isRCIdentityPreserving ())
@@ -2231,13 +2173,6 @@ class PartitionOpTranslator {
22312173 return valueMap.lookupValueID (value);
22322174 }
22332175
2234- // / Determine the isolation of a set of conformances.
2235- // /
2236- // / This function identifies potentially-isolated conformances that might affect the isolation of the given
2237- // / value.
2238- SILIsolationInfo getIsolationFromConformances (
2239- SILValue value, ArrayRef<ProtocolConformanceRef> conformances);
2240-
22412176public:
22422177 // / Return the partition consisting of all function arguments.
22432178 // /
@@ -3210,7 +3145,8 @@ class PartitionOpTranslator {
32103145
32113146 case TranslationSemantics::Assign:
32123147 return translateSILMultiAssign (
3213- inst->getResults (), makeOperandRefRange (inst->getAllOperands ()));
3148+ inst->getResults (), makeOperandRefRange (inst->getAllOperands ()),
3149+ SILIsolationInfo::getConformanceIsolation (inst));
32143150
32153151 case TranslationSemantics::Require:
32163152 for (auto op : inst->getOperandValues ())
@@ -3227,7 +3163,8 @@ class PartitionOpTranslator {
32273163 case TranslationSemantics::Store:
32283164 return translateSILStore (
32293165 &inst->getAllOperands ()[CopyLikeInstruction::Dest],
3230- &inst->getAllOperands ()[CopyLikeInstruction::Src]);
3166+ &inst->getAllOperands ()[CopyLikeInstruction::Src],
3167+ SILIsolationInfo::getConformanceIsolation (inst));
32313168
32323169 case TranslationSemantics::Special:
32333170 return ;
@@ -3238,7 +3175,8 @@ class PartitionOpTranslator {
32383175 case TranslationSemantics::TerminatorPhi: {
32393176 TermArgSources sources;
32403177 sources.init (inst);
3241- return translateSILPhi (sources);
3178+ return translateSILPhi (
3179+ sources, SILIsolationInfo::getConformanceIsolation (inst));
32423180 }
32433181
32443182 case TranslationSemantics::Asserting:
@@ -3451,6 +3389,8 @@ CONSTANT_TRANSLATION(CopyBlockInst, Assign)
34513389CONSTANT_TRANSLATION(CopyBlockWithoutEscapingInst, Assign)
34523390CONSTANT_TRANSLATION(IndexAddrInst, Assign)
34533391CONSTANT_TRANSLATION(InitBlockStorageHeaderInst, Assign)
3392+ CONSTANT_TRANSLATION(InitExistentialAddrInst, Assign)
3393+ CONSTANT_TRANSLATION(InitExistentialRefInst, Assign)
34543394CONSTANT_TRANSLATION(OpenExistentialBoxInst, Assign)
34553395CONSTANT_TRANSLATION(OpenExistentialRefInst, Assign)
34563396CONSTANT_TRANSLATION(TailAddrInst, Assign)
@@ -3539,6 +3479,7 @@ CONSTANT_TRANSLATION(StoreInst, Store)
35393479CONSTANT_TRANSLATION(StoreWeakInst, Store)
35403480CONSTANT_TRANSLATION(MarkUnresolvedMoveAddrInst, Store)
35413481CONSTANT_TRANSLATION(UncheckedRefCastAddrInst, Store)
3482+ CONSTANT_TRANSLATION(UnconditionalCheckedCastAddrInst, Store)
35423483CONSTANT_TRANSLATION(StoreUnownedInst, Store)
35433484
35443485// ===---
@@ -3613,6 +3554,7 @@ CONSTANT_TRANSLATION(YieldInst, Require)
36133554// Terminators that act as phis.
36143555CONSTANT_TRANSLATION(BranchInst, TerminatorPhi)
36153556CONSTANT_TRANSLATION(CondBranchInst, TerminatorPhi)
3557+ CONSTANT_TRANSLATION(CheckedCastBranchInst, TerminatorPhi)
36163558CONSTANT_TRANSLATION(DynamicMethodBranchInst, TerminatorPhi)
36173559
36183560// Function exiting terminators.
@@ -4014,34 +3956,16 @@ PartitionOpTranslator::visitPointerToAddressInst(PointerToAddressInst *ptai) {
40143956
40153957TranslationSemantics PartitionOpTranslator::visitUnconditionalCheckedCastInst (
40163958 UnconditionalCheckedCastInst *ucci) {
4017- auto isolation = getIsolationForCastConformances (
4018- ucci, ucci->getSourceFormalType (), ucci->getTargetFormalType ());
3959+ auto isolation = SILIsolationInfo::getConformanceIsolation (ucci);
40193960
4020- if (isolation. isDisconnected () &&
3961+ if (! isolation &&
40213962 SILDynamicCastInst (ucci).isRCIdentityPreserving ()) {
40223963 assert (isStaticallyLookThroughInst (ucci) && " Out of sync" );
40233964 return TranslationSemantics::LookThrough;
40243965 }
40253966
40263967 assert (!isStaticallyLookThroughInst (ucci) && " Out of sync" );
4027- translateSILMultiAssign (
4028- ucci->getResults (), makeOperandRefRange (ucci->getAllOperands ()),
4029- isolation);
4030- return TranslationSemantics::Special;
4031- }
4032-
4033- TranslationSemantics PartitionOpTranslator::visitUnconditionalCheckedCastAddrInst (
4034- UnconditionalCheckedCastAddrInst *uccai) {
4035- auto isolation = getIsolationForCastConformances (
4036- uccai->getAllOperands ()[CopyLikeInstruction::Dest].get (),
4037- uccai->getSourceFormalType (), uccai->getTargetFormalType ());
4038-
4039- translateSILStore (
4040- &uccai->getAllOperands ()[CopyLikeInstruction::Dest],
4041- &uccai->getAllOperands ()[CopyLikeInstruction::Src],
4042- isolation);
4043-
4044- return TranslationSemantics::Special;
3968+ return TranslationSemantics::Assign;
40453969}
40463970
40473971// RefElementAddrInst is not considered to be a lookThrough since we want to
@@ -4130,117 +4054,18 @@ PartitionOpTranslator::visitPartialApplyInst(PartialApplyInst *pai) {
41304054 return TranslationSemantics::Special;
41314055}
41324056
4133- SILIsolationInfo
4134- PartitionOpTranslator::getIsolationFromConformances (
4135- SILValue value, ArrayRef<ProtocolConformanceRef> conformances) {
4136- for (auto conformance: conformances) {
4137- if (conformance.getProtocol ()->isMarkerProtocol ())
4138- continue ;
4139-
4140- // If the conformance is a pack, recurse.
4141- if (conformance.isPack ()) {
4142- auto pack = conformance.getPack ();
4143- for (auto innerConformance : pack->getPatternConformances ()) {
4144- auto isolation = getIsolationFromConformances (value, innerConformance);
4145- if (isolation)
4146- return isolation;
4147- }
4148-
4149- continue ;
4150- }
4151-
4152- // If a concrete conformance is global-actor-isolated, then the resulting
4153- // value must be.
4154- if (conformance.isConcrete ()) {
4155- auto isolation = conformance.getConcrete ()->getIsolation ();
4156- if (isolation.isGlobalActor ()) {
4157- return SILIsolationInfo::getGlobalActorIsolated (
4158- value, isolation.getGlobalActor (), conformance.getProtocol ());
4159- }
4160-
4161- continue ;
4162- }
4163-
4164- // If an abstract conformance is for a non-SendableMetatype-conforming
4165- // type, the resulting value is task-isolated.
4166- if (conformance.isAbstract ()) {
4167- auto sendableMetatype =
4168- conformance.getType ()->getASTContext ()
4169- .getProtocol (KnownProtocolKind::SendableMetatype);
4170- if (sendableMetatype &&
4171- lookupConformance (conformance.getType (), sendableMetatype,
4172- /* allowMissing=*/ false ).isInvalid ()) {
4173- return SILIsolationInfo::getTaskIsolated (value,
4174- conformance.getProtocol ());
4175- }
4176- }
4177- }
4178-
4179- return {};
4180- }
4181-
4182- TranslationSemantics
4183- PartitionOpTranslator::visitInitExistentialAddrInst (InitExistentialAddrInst *ieai) {
4184- auto conformanceIsolationInfo = getIsolationFromConformances (
4185- ieai, ieai->getConformances ());
4186-
4187- translateSILMultiAssign (ieai->getResults (),
4188- makeOperandRefRange (ieai->getAllOperands ()),
4189- conformanceIsolationInfo);
4190-
4191- return TranslationSemantics::Special;
4192- }
4193-
4194- TranslationSemantics
4195- PartitionOpTranslator::visitInitExistentialRefInst (InitExistentialRefInst *ieri) {
4196- auto conformanceIsolationInfo = getIsolationFromConformances (
4197- ieri, ieri->getConformances ());
4198-
4199- translateSILMultiAssign (ieri->getResults (),
4200- makeOperandRefRange (ieri->getAllOperands ()),
4201- conformanceIsolationInfo);
4202-
4203- return TranslationSemantics::Special;
4204- }
4205-
42064057TranslationSemantics
42074058PartitionOpTranslator::visitInitExistentialValueInst (InitExistentialValueInst *ievi) {
4208- auto conformanceIsolationInfo = getIsolationFromConformances (
4209- ievi, ievi->getConformances ());
4210-
4211- translateSILMultiAssign (ievi->getResults (),
4212- makeOperandRefRange (ievi->getAllOperands ()),
4213- conformanceIsolationInfo);
4214-
4215- return TranslationSemantics::Special;
4216- }
4217-
4218- TranslationSemantics
4219- PartitionOpTranslator::visitCheckedCastBranchInst (CheckedCastBranchInst *ccbi) {
4220- // Consider whether the value produced by the cast might be task-isolated.
4221- auto resultValue = ccbi->getSuccessBB ()->getArgument (0 );
4222- auto conformanceIsolation = getIsolationForCastConformances (
4223- resultValue,
4224- ccbi->getSourceFormalType (),
4225- ccbi->getTargetFormalType ());
4226- TermArgSources sources;
4227- sources.init (static_cast <SILInstruction *>(ccbi));
4228- translateSILPhi (sources, conformanceIsolation);
4059+ if (isStaticallyLookThroughInst (ievi))
4060+ return TranslationSemantics::LookThrough;
42294061
4230- return TranslationSemantics::Special ;
4062+ return TranslationSemantics::Assign ;
42314063}
42324064
42334065TranslationSemantics PartitionOpTranslator::visitCheckedCastAddrBranchInst (
42344066 CheckedCastAddrBranchInst *ccabi) {
42354067 assert (ccabi->getSuccessBB ()->getNumArguments () <= 1 );
42364068
4237- // Consider whether the value written into by the cast might be task-isolated.
4238- auto resultValue = ccabi->getAllOperands ().back ().get ();
4239- auto conformanceIsolation = getIsolationForCastConformances (
4240- resultValue,
4241- ccabi->getSourceFormalType (),
4242- ccabi->getTargetFormalType ());
4243-
42444069 // checked_cast_addr_br does not have any arguments in its resulting
42454070 // block. We should just use a multi-assign on its operands.
42464071 //
@@ -4250,7 +4075,7 @@ TranslationSemantics PartitionOpTranslator::visitCheckedCastAddrBranchInst(
42504075 // but still correct.
42514076 translateSILMultiAssign (ArrayRef<SILValue>(),
42524077 makeOperandRefRange (ccabi->getAllOperands ()),
4253- conformanceIsolation );
4078+ SILIsolationInfo::getConformanceIsolation (ccabi) );
42544079 return TranslationSemantics::Special;
42554080}
42564081
0 commit comments