15
15
#include " swift/SILOptimizer/Analysis/RegionAnalysis.h"
16
16
17
17
#include " swift/AST/ASTWalker.h"
18
- #include " swift/AST/ConformanceLookup.h"
19
18
#include " swift/AST/DiagnosticsSIL.h"
20
19
#include " swift/AST/Expr.h"
21
- #include " swift/AST/ExistentialLayout.h"
22
- #include " swift/AST/PackConformance.h"
23
- #include " swift/AST/ProtocolConformance.h"
24
20
#include " swift/AST/Type.h"
25
21
#include " swift/Basic/Assertions.h"
26
22
#include " swift/Basic/FrozenMultiMap.h"
@@ -274,59 +270,6 @@ struct AddressBaseComputingVisitor
274
270
275
271
} // namespace
276
272
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
-
330
273
// / Classify an instructions as look through when we are looking through
331
274
// / values. We assert that all instructions that are CONSTANT_TRANSLATION
332
275
// / LookThrough to make sure they stay in sync.
@@ -385,16 +328,15 @@ static bool isStaticallyLookThroughInst(SILInstruction *inst) {
385
328
case SILInstructionKind::BeginBorrowInst:
386
329
// Look through if it isn't from a var decl.
387
330
return !cast<BeginBorrowInst>(inst)->isFromVarDecl ();
331
+ case SILInstructionKind::InitExistentialValueInst:
332
+ return !SILIsolationInfo::getConformanceIsolation (inst);
388
333
case SILInstructionKind::UnconditionalCheckedCastInst: {
389
334
auto cast = SILDynamicCastInst::getAs (inst);
390
335
assert (cast);
391
336
392
337
// If this cast introduces isolation due to conformances, we cannot look
393
338
// 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))
398
340
return false ;
399
341
400
342
if (cast.isRCIdentityPreserving ())
@@ -2231,13 +2173,6 @@ class PartitionOpTranslator {
2231
2173
return valueMap.lookupValueID (value);
2232
2174
}
2233
2175
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
-
2241
2176
public:
2242
2177
// / Return the partition consisting of all function arguments.
2243
2178
// /
@@ -3210,7 +3145,8 @@ class PartitionOpTranslator {
3210
3145
3211
3146
case TranslationSemantics::Assign:
3212
3147
return translateSILMultiAssign (
3213
- inst->getResults (), makeOperandRefRange (inst->getAllOperands ()));
3148
+ inst->getResults (), makeOperandRefRange (inst->getAllOperands ()),
3149
+ SILIsolationInfo::getConformanceIsolation (inst));
3214
3150
3215
3151
case TranslationSemantics::Require:
3216
3152
for (auto op : inst->getOperandValues ())
@@ -3227,7 +3163,8 @@ class PartitionOpTranslator {
3227
3163
case TranslationSemantics::Store:
3228
3164
return translateSILStore (
3229
3165
&inst->getAllOperands ()[CopyLikeInstruction::Dest],
3230
- &inst->getAllOperands ()[CopyLikeInstruction::Src]);
3166
+ &inst->getAllOperands ()[CopyLikeInstruction::Src],
3167
+ SILIsolationInfo::getConformanceIsolation (inst));
3231
3168
3232
3169
case TranslationSemantics::Special:
3233
3170
return ;
@@ -3238,7 +3175,8 @@ class PartitionOpTranslator {
3238
3175
case TranslationSemantics::TerminatorPhi: {
3239
3176
TermArgSources sources;
3240
3177
sources.init (inst);
3241
- return translateSILPhi (sources);
3178
+ return translateSILPhi (
3179
+ sources, SILIsolationInfo::getConformanceIsolation (inst));
3242
3180
}
3243
3181
3244
3182
case TranslationSemantics::Asserting:
@@ -3451,6 +3389,8 @@ CONSTANT_TRANSLATION(CopyBlockInst, Assign)
3451
3389
CONSTANT_TRANSLATION(CopyBlockWithoutEscapingInst, Assign)
3452
3390
CONSTANT_TRANSLATION(IndexAddrInst, Assign)
3453
3391
CONSTANT_TRANSLATION(InitBlockStorageHeaderInst, Assign)
3392
+ CONSTANT_TRANSLATION(InitExistentialAddrInst, Assign)
3393
+ CONSTANT_TRANSLATION(InitExistentialRefInst, Assign)
3454
3394
CONSTANT_TRANSLATION(OpenExistentialBoxInst, Assign)
3455
3395
CONSTANT_TRANSLATION(OpenExistentialRefInst, Assign)
3456
3396
CONSTANT_TRANSLATION(TailAddrInst, Assign)
@@ -3539,6 +3479,7 @@ CONSTANT_TRANSLATION(StoreInst, Store)
3539
3479
CONSTANT_TRANSLATION(StoreWeakInst, Store)
3540
3480
CONSTANT_TRANSLATION(MarkUnresolvedMoveAddrInst, Store)
3541
3481
CONSTANT_TRANSLATION(UncheckedRefCastAddrInst, Store)
3482
+ CONSTANT_TRANSLATION(UnconditionalCheckedCastAddrInst, Store)
3542
3483
CONSTANT_TRANSLATION(StoreUnownedInst, Store)
3543
3484
3544
3485
// ===---
@@ -3613,6 +3554,7 @@ CONSTANT_TRANSLATION(YieldInst, Require)
3613
3554
// Terminators that act as phis.
3614
3555
CONSTANT_TRANSLATION(BranchInst, TerminatorPhi)
3615
3556
CONSTANT_TRANSLATION(CondBranchInst, TerminatorPhi)
3557
+ CONSTANT_TRANSLATION(CheckedCastBranchInst, TerminatorPhi)
3616
3558
CONSTANT_TRANSLATION(DynamicMethodBranchInst, TerminatorPhi)
3617
3559
3618
3560
// Function exiting terminators.
@@ -4014,34 +3956,16 @@ PartitionOpTranslator::visitPointerToAddressInst(PointerToAddressInst *ptai) {
4014
3956
4015
3957
TranslationSemantics PartitionOpTranslator::visitUnconditionalCheckedCastInst (
4016
3958
UnconditionalCheckedCastInst *ucci) {
4017
- auto isolation = getIsolationForCastConformances (
4018
- ucci, ucci->getSourceFormalType (), ucci->getTargetFormalType ());
3959
+ auto isolation = SILIsolationInfo::getConformanceIsolation (ucci);
4019
3960
4020
- if (isolation. isDisconnected () &&
3961
+ if (! isolation &&
4021
3962
SILDynamicCastInst (ucci).isRCIdentityPreserving ()) {
4022
3963
assert (isStaticallyLookThroughInst (ucci) && " Out of sync" );
4023
3964
return TranslationSemantics::LookThrough;
4024
3965
}
4025
3966
4026
3967
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;
4045
3969
}
4046
3970
4047
3971
// RefElementAddrInst is not considered to be a lookThrough since we want to
@@ -4130,117 +4054,18 @@ PartitionOpTranslator::visitPartialApplyInst(PartialApplyInst *pai) {
4130
4054
return TranslationSemantics::Special;
4131
4055
}
4132
4056
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
-
4206
4057
TranslationSemantics
4207
4058
PartitionOpTranslator::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;
4229
4061
4230
- return TranslationSemantics::Special ;
4062
+ return TranslationSemantics::Assign ;
4231
4063
}
4232
4064
4233
4065
TranslationSemantics PartitionOpTranslator::visitCheckedCastAddrBranchInst (
4234
4066
CheckedCastAddrBranchInst *ccabi) {
4235
4067
assert (ccabi->getSuccessBB ()->getNumArguments () <= 1 );
4236
4068
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
-
4244
4069
// checked_cast_addr_br does not have any arguments in its resulting
4245
4070
// block. We should just use a multi-assign on its operands.
4246
4071
//
@@ -4250,7 +4075,7 @@ TranslationSemantics PartitionOpTranslator::visitCheckedCastAddrBranchInst(
4250
4075
// but still correct.
4251
4076
translateSILMultiAssign (ArrayRef<SILValue>(),
4252
4077
makeOperandRefRange (ccabi->getAllOperands ()),
4253
- conformanceIsolation );
4078
+ SILIsolationInfo::getConformanceIsolation (ccabi) );
4254
4079
return TranslationSemantics::Special;
4255
4080
}
4256
4081
0 commit comments