Skip to content

Commit 066fa0b

Browse files
committed
[Region isolation] Re-simplify handling of init_existential* instructions
Centralize the logic for figuring out the conformances for the various init_existential* instructions in a SILIsolationInfo static method, and always go through that when handling "assign" semantics. This way, we can use CONSTANT_TRANSLATION again for these instructions, or a simpler decision process between Assign and LookThrough. The actually undoes a small change made earlier when we stopped looking through `init_existential_value` instructions. Now we do when there are no isolated conformances.
1 parent 22ca6b9 commit 066fa0b

File tree

4 files changed

+33
-38
lines changed

4 files changed

+33
-38
lines changed

include/swift/SILOptimizer/Utils/SILIsolationInfo.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ class SILIsolationInfo {
249249
SILIsolationInfo(Kind kind, Options options = Options())
250250
: actorIsolation(), kind(kind), options(options.toRaw()) {}
251251

252+
/// Infer isolation region from the set of protocol conformances.
253+
static SILIsolationInfo getFromConformances(
254+
SILValue value, ArrayRef<ProtocolConformanceRef> conformances);
255+
252256
public:
253257
SILIsolationInfo() : actorIsolation(), kind(Kind::Unknown), options(0) {}
254258

@@ -503,15 +507,14 @@ class SILIsolationInfo {
503507
return {};
504508
}
505509

506-
/// Infer isolation region from the set of protocol conformances.
507-
static SILIsolationInfo getFromConformances(
508-
SILValue value, ArrayRef<ProtocolConformanceRef> conformances);
509-
510510
/// Determine the isolation of conformances that could be introduced by a
511511
/// cast from sourceType to destType.
512512
static SILIsolationInfo getForCastConformances(
513513
SILValue value, CanType sourceType, CanType destType);
514514

515+
/// Infer isolation of conformances for the given instruction.
516+
static SILIsolationInfo getConformanceIsolation(SILInstruction *inst);
517+
515518
/// A helper that is used to ensure that we treat certain builtin values as
516519
/// non-Sendable that the AST level otherwise thinks are non-Sendable.
517520
///

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ static bool isStaticallyLookThroughInst(SILInstruction *inst) {
318318
case SILInstructionKind::BeginBorrowInst:
319319
// Look through if it isn't from a var decl.
320320
return !cast<BeginBorrowInst>(inst)->isFromVarDecl();
321+
case SILInstructionKind::InitExistentialValueInst:
322+
return !SILIsolationInfo::getConformanceIsolation(inst);
321323
case SILInstructionKind::UnconditionalCheckedCastInst: {
322324
auto cast = SILDynamicCastInst::getAs(inst);
323325
assert(cast);
@@ -3100,7 +3102,8 @@ class PartitionOpTranslator {
31003102

31013103
case TranslationSemantics::Assign:
31023104
return translateSILMultiAssign(
3103-
inst->getResults(), makeOperandRefRange(inst->getAllOperands()));
3105+
inst->getResults(), makeOperandRefRange(inst->getAllOperands()),
3106+
SILIsolationInfo::getConformanceIsolation(inst));
31043107

31053108
case TranslationSemantics::Require:
31063109
for (auto op : inst->getOperandValues())
@@ -3344,6 +3347,8 @@ CONSTANT_TRANSLATION(CopyBlockInst, Assign)
33443347
CONSTANT_TRANSLATION(CopyBlockWithoutEscapingInst, Assign)
33453348
CONSTANT_TRANSLATION(IndexAddrInst, Assign)
33463349
CONSTANT_TRANSLATION(InitBlockStorageHeaderInst, Assign)
3350+
CONSTANT_TRANSLATION(InitExistentialAddrInst, Assign)
3351+
CONSTANT_TRANSLATION(InitExistentialRefInst, Assign)
33473352
CONSTANT_TRANSLATION(OpenExistentialBoxInst, Assign)
33483353
CONSTANT_TRANSLATION(OpenExistentialRefInst, Assign)
33493354
CONSTANT_TRANSLATION(TailAddrInst, Assign)
@@ -4022,40 +4027,12 @@ PartitionOpTranslator::visitPartialApplyInst(PartialApplyInst *pai) {
40224027
return TranslationSemantics::Special;
40234028
}
40244029

4025-
TranslationSemantics
4026-
PartitionOpTranslator::visitInitExistentialAddrInst(InitExistentialAddrInst *ieai) {
4027-
auto conformanceIsolationInfo = SILIsolationInfo::getFromConformances(
4028-
ieai, ieai->getConformances());
4029-
4030-
translateSILMultiAssign(ieai->getResults(),
4031-
makeOperandRefRange(ieai->getAllOperands()),
4032-
conformanceIsolationInfo);
4033-
4034-
return TranslationSemantics::Special;
4035-
}
4036-
4037-
TranslationSemantics
4038-
PartitionOpTranslator::visitInitExistentialRefInst(InitExistentialRefInst *ieri) {
4039-
auto conformanceIsolationInfo = SILIsolationInfo::getFromConformances(
4040-
ieri, ieri->getConformances());
4041-
4042-
translateSILMultiAssign(ieri->getResults(),
4043-
makeOperandRefRange(ieri->getAllOperands()),
4044-
conformanceIsolationInfo);
4045-
4046-
return TranslationSemantics::Special;
4047-
}
4048-
40494030
TranslationSemantics
40504031
PartitionOpTranslator::visitInitExistentialValueInst(InitExistentialValueInst *ievi) {
4051-
auto conformanceIsolationInfo = SILIsolationInfo::getFromConformances(
4052-
ievi, ievi->getConformances());
4053-
4054-
translateSILMultiAssign(ievi->getResults(),
4055-
makeOperandRefRange(ievi->getAllOperands()),
4056-
conformanceIsolationInfo);
4032+
if (isStaticallyLookThroughInst(ievi))
4033+
return TranslationSemantics::LookThrough;
40574034

4058-
return TranslationSemantics::Special;
4035+
return TranslationSemantics::Assign;
40594036
}
40604037

40614038
TranslationSemantics

lib/SILOptimizer/Utils/SILIsolationInfo.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,21 @@ SILIsolationInfo SILIsolationInfo::getForCastConformances(
10621062
return {};
10631063
}
10641064

1065+
SILIsolationInfo SILIsolationInfo::getConformanceIsolation(SILInstruction *inst) {
1066+
// Existential initialization.
1067+
if (auto ieai = dyn_cast<InitExistentialAddrInst>(inst)) {
1068+
return getFromConformances(ieai, ieai->getConformances());
1069+
}
1070+
if (auto ieri = dyn_cast<InitExistentialRefInst>(inst)) {
1071+
return getFromConformances(ieri, ieri->getConformances());
1072+
}
1073+
if (auto ievi = dyn_cast<InitExistentialValueInst>(inst)) {
1074+
return getFromConformances(ievi, ievi->getConformances());
1075+
}
1076+
1077+
return {};
1078+
}
1079+
10651080
void SILIsolationInfo::printOptions(llvm::raw_ostream &os) const {
10661081
if (isolatedConformance) {
10671082
os << "isolated-conformance-to(" << isolatedConformance->getName() << ")";

test/Concurrency/transfernonsendable_instruction_matching_opaquevalues.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,9 @@ bb0:
192192
// expected-warning @-1 {{}}
193193
// expected-note @-2 {{}}
194194

195-
%i = init_existential_value %1 : $NonSendableKlass, $NonSendableKlass, $P // expected-note {{access can happen concurrently}}
195+
%i = init_existential_value %1 : $NonSendableKlass, $NonSendableKlass, $P
196196
%f2 = function_ref @useP : $@convention(thin) (@in_guaranteed P) -> ()
197-
apply %f2(%i) : $@convention(thin) (@in_guaranteed P) -> ()
197+
apply %f2(%i) : $@convention(thin) (@in_guaranteed P) -> () // expected-note {{access can happen concurrently}}
198198
destroy_value %i : $P
199199

200200
%9999 = tuple ()

0 commit comments

Comments
 (0)