Skip to content

Commit 1d86ed5

Browse files
committed
[Region analysis] Simplify logic for dynamic casts by making them less special
Extend and use SILIsolationInfo::getConformanceIsolation() for the dynamic cast instructions.
1 parent 066fa0b commit 1d86ed5

File tree

3 files changed

+43
-55
lines changed

3 files changed

+43
-55
lines changed

include/swift/SILOptimizer/Utils/SILIsolationInfo.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@ class SILIsolationInfo {
253253
static SILIsolationInfo getFromConformances(
254254
SILValue value, ArrayRef<ProtocolConformanceRef> conformances);
255255

256+
/// Determine the isolation of conformances that could be introduced by a
257+
/// cast from sourceType to destType.
258+
static SILIsolationInfo getForCastConformances(
259+
SILValue value, CanType sourceType, CanType destType);
260+
256261
public:
257262
SILIsolationInfo() : actorIsolation(), kind(Kind::Unknown), options(0) {}
258263

@@ -507,11 +512,6 @@ class SILIsolationInfo {
507512
return {};
508513
}
509514

510-
/// Determine the isolation of conformances that could be introduced by a
511-
/// cast from sourceType to destType.
512-
static SILIsolationInfo getForCastConformances(
513-
SILValue value, CanType sourceType, CanType destType);
514-
515515
/// Infer isolation of conformances for the given instruction.
516516
static SILIsolationInfo getConformanceIsolation(SILInstruction *inst);
517517

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 11 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,7 @@ static bool isStaticallyLookThroughInst(SILInstruction *inst) {
326326

327327
// If this cast introduces isolation due to conformances, we cannot look
328328
// through it to the source.
329-
if (!SILIsolationInfo::getForCastConformances(
330-
llvm::cast<UnconditionalCheckedCastInst>(inst),
331-
cast.getSourceFormalType(), cast.getTargetFormalType())
332-
.isDisconnected())
329+
if (SILIsolationInfo::getConformanceIsolation(inst))
333330
return false;
334331

335332
if (cast.isRCIdentityPreserving())
@@ -3120,7 +3117,8 @@ class PartitionOpTranslator {
31203117
case TranslationSemantics::Store:
31213118
return translateSILStore(
31223119
&inst->getAllOperands()[CopyLikeInstruction::Dest],
3123-
&inst->getAllOperands()[CopyLikeInstruction::Src]);
3120+
&inst->getAllOperands()[CopyLikeInstruction::Src],
3121+
SILIsolationInfo::getConformanceIsolation(inst));
31243122

31253123
case TranslationSemantics::Special:
31263124
return;
@@ -3131,7 +3129,8 @@ class PartitionOpTranslator {
31313129
case TranslationSemantics::TerminatorPhi: {
31323130
TermArgSources sources;
31333131
sources.init(inst);
3134-
return translateSILPhi(sources);
3132+
return translateSILPhi(
3133+
sources, SILIsolationInfo::getConformanceIsolation(inst));
31353134
}
31363135

31373136
case TranslationSemantics::Asserting:
@@ -3436,6 +3435,7 @@ CONSTANT_TRANSLATION(StoreInst, Store)
34363435
CONSTANT_TRANSLATION(StoreWeakInst, Store)
34373436
CONSTANT_TRANSLATION(MarkUnresolvedMoveAddrInst, Store)
34383437
CONSTANT_TRANSLATION(UncheckedRefCastAddrInst, Store)
3438+
CONSTANT_TRANSLATION(UnconditionalCheckedCastAddrInst, Store)
34393439
CONSTANT_TRANSLATION(StoreUnownedInst, Store)
34403440

34413441
//===---
@@ -3510,6 +3510,7 @@ CONSTANT_TRANSLATION(YieldInst, Require)
35103510
// Terminators that act as phis.
35113511
CONSTANT_TRANSLATION(BranchInst, TerminatorPhi)
35123512
CONSTANT_TRANSLATION(CondBranchInst, TerminatorPhi)
3513+
CONSTANT_TRANSLATION(CheckedCastBranchInst, TerminatorPhi)
35133514
CONSTANT_TRANSLATION(DynamicMethodBranchInst, TerminatorPhi)
35143515

35153516
// Function exiting terminators.
@@ -3911,34 +3912,16 @@ PartitionOpTranslator::visitPointerToAddressInst(PointerToAddressInst *ptai) {
39113912

39123913
TranslationSemantics PartitionOpTranslator::visitUnconditionalCheckedCastInst(
39133914
UnconditionalCheckedCastInst *ucci) {
3914-
auto isolation = SILIsolationInfo::getForCastConformances(
3915-
ucci, ucci->getSourceFormalType(), ucci->getTargetFormalType());
3915+
auto isolation = SILIsolationInfo::getConformanceIsolation(ucci);
39163916

3917-
if (isolation.isDisconnected() &&
3917+
if (!isolation &&
39183918
SILDynamicCastInst(ucci).isRCIdentityPreserving()) {
39193919
assert(isStaticallyLookThroughInst(ucci) && "Out of sync");
39203920
return TranslationSemantics::LookThrough;
39213921
}
39223922

39233923
assert(!isStaticallyLookThroughInst(ucci) && "Out of sync");
3924-
translateSILMultiAssign(
3925-
ucci->getResults(), makeOperandRefRange(ucci->getAllOperands()),
3926-
isolation);
3927-
return TranslationSemantics::Special;
3928-
}
3929-
3930-
TranslationSemantics PartitionOpTranslator::visitUnconditionalCheckedCastAddrInst(
3931-
UnconditionalCheckedCastAddrInst *uccai) {
3932-
auto isolation = SILIsolationInfo::getForCastConformances(
3933-
uccai->getAllOperands()[CopyLikeInstruction::Dest].get(),
3934-
uccai->getSourceFormalType(), uccai->getTargetFormalType());
3935-
3936-
translateSILStore(
3937-
&uccai->getAllOperands()[CopyLikeInstruction::Dest],
3938-
&uccai->getAllOperands()[CopyLikeInstruction::Src],
3939-
isolation);
3940-
3941-
return TranslationSemantics::Special;
3924+
return TranslationSemantics::Assign;
39423925
}
39433926

39443927
// RefElementAddrInst is not considered to be a lookThrough since we want to
@@ -4035,32 +4018,10 @@ PartitionOpTranslator::visitInitExistentialValueInst(InitExistentialValueInst *i
40354018
return TranslationSemantics::Assign;
40364019
}
40374020

4038-
TranslationSemantics
4039-
PartitionOpTranslator::visitCheckedCastBranchInst(CheckedCastBranchInst *ccbi) {
4040-
// Consider whether the value produced by the cast might be task-isolated.
4041-
auto resultValue = ccbi->getSuccessBB()->getArgument(0);
4042-
auto conformanceIsolation = SILIsolationInfo::getForCastConformances(
4043-
resultValue,
4044-
ccbi->getSourceFormalType(),
4045-
ccbi->getTargetFormalType());
4046-
TermArgSources sources;
4047-
sources.init(static_cast<SILInstruction *>(ccbi));
4048-
translateSILPhi(sources, conformanceIsolation);
4049-
4050-
return TranslationSemantics::Special;
4051-
}
4052-
40534021
TranslationSemantics PartitionOpTranslator::visitCheckedCastAddrBranchInst(
40544022
CheckedCastAddrBranchInst *ccabi) {
40554023
assert(ccabi->getSuccessBB()->getNumArguments() <= 1);
40564024

4057-
// Consider whether the value written into by the cast might be task-isolated.
4058-
auto resultValue = ccabi->getAllOperands().back().get();
4059-
auto conformanceIsolation = SILIsolationInfo::getForCastConformances(
4060-
resultValue,
4061-
ccabi->getSourceFormalType(),
4062-
ccabi->getTargetFormalType());
4063-
40644025
// checked_cast_addr_br does not have any arguments in its resulting
40654026
// block. We should just use a multi-assign on its operands.
40664027
//
@@ -4070,7 +4031,7 @@ TranslationSemantics PartitionOpTranslator::visitCheckedCastAddrBranchInst(
40704031
// but still correct.
40714032
translateSILMultiAssign(ArrayRef<SILValue>(),
40724033
makeOperandRefRange(ccabi->getAllOperands()),
4073-
conformanceIsolation);
4034+
SILIsolationInfo::getConformanceIsolation(ccabi));
40744035
return TranslationSemantics::Special;
40754036
}
40764037

lib/SILOptimizer/Utils/SILIsolationInfo.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/AST/ProtocolConformance.h"
2222
#include "swift/SIL/AddressWalker.h"
2323
#include "swift/SIL/ApplySite.h"
24+
#include "swift/SIL/DynamicCasts.h"
2425
#include "swift/SIL/InstructionUtils.h"
2526
#include "swift/SIL/PatternMatch.h"
2627
#include "swift/SIL/SILGlobalVariable.h"
@@ -1062,6 +1063,24 @@ SILIsolationInfo SILIsolationInfo::getForCastConformances(
10621063
return {};
10631064
}
10641065

1066+
/// Retrieve a suitable destination value for the cast instruction.
1067+
///
1068+
/// TODO: This should probably be SILDynamicCastInst::getDest(), but that has
1069+
/// unimplemented TODOs.
1070+
static SILValue destValueForDynamicCast(SILDynamicCastInst dynCast) {
1071+
auto inst = dynCast.getInstruction();
1072+
switch (dynCast.getKind()) {
1073+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
1074+
return cast<CheckedCastAddrBranchInst>(inst)->getDest();
1075+
case SILDynamicCastKind::CheckedCastBranchInst:
1076+
return cast<CheckedCastBranchInst>(inst)->getSuccessBB()->getArgument(0);
1077+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
1078+
return cast<UnconditionalCheckedCastAddrInst>(inst)->getDest();
1079+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
1080+
return cast<UnconditionalCheckedCastInst>(inst);
1081+
}
1082+
}
1083+
10651084
SILIsolationInfo SILIsolationInfo::getConformanceIsolation(SILInstruction *inst) {
10661085
// Existential initialization.
10671086
if (auto ieai = dyn_cast<InitExistentialAddrInst>(inst)) {
@@ -1074,6 +1093,14 @@ SILIsolationInfo SILIsolationInfo::getConformanceIsolation(SILInstruction *inst)
10741093
return getFromConformances(ievi, ievi->getConformances());
10751094
}
10761095

1096+
// Dynamic casts.
1097+
if (auto dynCast = SILDynamicCastInst::getAs(inst)) {
1098+
return getForCastConformances(
1099+
destValueForDynamicCast(dynCast),
1100+
dynCast.getSourceFormalType(),
1101+
dynCast.getTargetFormalType());
1102+
}
1103+
10771104
return {};
10781105
}
10791106

0 commit comments

Comments
 (0)