Skip to content

Commit 1e87656

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 0aa54a6 commit 1e87656

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
@@ -257,6 +257,11 @@ class SILIsolationInfo {
257257
static SILIsolationInfo getFromConformances(
258258
SILValue value, ArrayRef<ProtocolConformanceRef> conformances);
259259

260+
/// Determine the isolation of conformances that could be introduced by a
261+
/// cast from sourceType to destType.
262+
static SILIsolationInfo getForCastConformances(
263+
SILValue value, CanType sourceType, CanType destType);
264+
260265
public:
261266
SILIsolationInfo() : actorIsolation(), kind(Kind::Unknown), options(0) {}
262267

@@ -538,11 +543,6 @@ class SILIsolationInfo {
538543
return {};
539544
}
540545

541-
/// Determine the isolation of conformances that could be introduced by a
542-
/// cast from sourceType to destType.
543-
static SILIsolationInfo getForCastConformances(
544-
SILValue value, CanType sourceType, CanType destType);
545-
546546
/// Infer isolation of conformances for the given instruction.
547547
static SILIsolationInfo getConformanceIsolation(SILInstruction *inst);
548548

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

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

337337
// If this cast introduces isolation due to conformances, we cannot look
338338
// through it to the source.
339-
if (!SILIsolationInfo::getForCastConformances(
340-
llvm::cast<UnconditionalCheckedCastInst>(inst),
341-
cast.getSourceFormalType(), cast.getTargetFormalType())
342-
.isDisconnected())
339+
if (SILIsolationInfo::getConformanceIsolation(inst))
343340
return false;
344341

345342
if (cast.isRCIdentityPreserving())
@@ -3166,7 +3163,8 @@ class PartitionOpTranslator {
31663163
case TranslationSemantics::Store:
31673164
return translateSILStore(
31683165
&inst->getAllOperands()[CopyLikeInstruction::Dest],
3169-
&inst->getAllOperands()[CopyLikeInstruction::Src]);
3166+
&inst->getAllOperands()[CopyLikeInstruction::Src],
3167+
SILIsolationInfo::getConformanceIsolation(inst));
31703168

31713169
case TranslationSemantics::Special:
31723170
return;
@@ -3177,7 +3175,8 @@ class PartitionOpTranslator {
31773175
case TranslationSemantics::TerminatorPhi: {
31783176
TermArgSources sources;
31793177
sources.init(inst);
3180-
return translateSILPhi(sources);
3178+
return translateSILPhi(
3179+
sources, SILIsolationInfo::getConformanceIsolation(inst));
31813180
}
31823181

31833182
case TranslationSemantics::Asserting:
@@ -3480,6 +3479,7 @@ CONSTANT_TRANSLATION(StoreInst, Store)
34803479
CONSTANT_TRANSLATION(StoreWeakInst, Store)
34813480
CONSTANT_TRANSLATION(MarkUnresolvedMoveAddrInst, Store)
34823481
CONSTANT_TRANSLATION(UncheckedRefCastAddrInst, Store)
3482+
CONSTANT_TRANSLATION(UnconditionalCheckedCastAddrInst, Store)
34833483
CONSTANT_TRANSLATION(StoreUnownedInst, Store)
34843484

34853485
//===---
@@ -3554,6 +3554,7 @@ CONSTANT_TRANSLATION(YieldInst, Require)
35543554
// Terminators that act as phis.
35553555
CONSTANT_TRANSLATION(BranchInst, TerminatorPhi)
35563556
CONSTANT_TRANSLATION(CondBranchInst, TerminatorPhi)
3557+
CONSTANT_TRANSLATION(CheckedCastBranchInst, TerminatorPhi)
35573558
CONSTANT_TRANSLATION(DynamicMethodBranchInst, TerminatorPhi)
35583559

35593560
// Function exiting terminators.
@@ -3955,34 +3956,16 @@ PartitionOpTranslator::visitPointerToAddressInst(PointerToAddressInst *ptai) {
39553956

39563957
TranslationSemantics PartitionOpTranslator::visitUnconditionalCheckedCastInst(
39573958
UnconditionalCheckedCastInst *ucci) {
3958-
auto isolation = SILIsolationInfo::getForCastConformances(
3959-
ucci, ucci->getSourceFormalType(), ucci->getTargetFormalType());
3959+
auto isolation = SILIsolationInfo::getConformanceIsolation(ucci);
39603960

3961-
if (isolation.isDisconnected() &&
3961+
if (!isolation &&
39623962
SILDynamicCastInst(ucci).isRCIdentityPreserving()) {
39633963
assert(isStaticallyLookThroughInst(ucci) && "Out of sync");
39643964
return TranslationSemantics::LookThrough;
39653965
}
39663966

39673967
assert(!isStaticallyLookThroughInst(ucci) && "Out of sync");
3968-
translateSILMultiAssign(
3969-
ucci->getResults(), makeOperandRefRange(ucci->getAllOperands()),
3970-
isolation);
3971-
return TranslationSemantics::Special;
3972-
}
3973-
3974-
TranslationSemantics PartitionOpTranslator::visitUnconditionalCheckedCastAddrInst(
3975-
UnconditionalCheckedCastAddrInst *uccai) {
3976-
auto isolation = SILIsolationInfo::getForCastConformances(
3977-
uccai->getAllOperands()[CopyLikeInstruction::Dest].get(),
3978-
uccai->getSourceFormalType(), uccai->getTargetFormalType());
3979-
3980-
translateSILStore(
3981-
&uccai->getAllOperands()[CopyLikeInstruction::Dest],
3982-
&uccai->getAllOperands()[CopyLikeInstruction::Src],
3983-
isolation);
3984-
3985-
return TranslationSemantics::Special;
3968+
return TranslationSemantics::Assign;
39863969
}
39873970

39883971
// RefElementAddrInst is not considered to be a lookThrough since we want to
@@ -4079,32 +4062,10 @@ PartitionOpTranslator::visitInitExistentialValueInst(InitExistentialValueInst *i
40794062
return TranslationSemantics::Assign;
40804063
}
40814064

4082-
TranslationSemantics
4083-
PartitionOpTranslator::visitCheckedCastBranchInst(CheckedCastBranchInst *ccbi) {
4084-
// Consider whether the value produced by the cast might be task-isolated.
4085-
auto resultValue = ccbi->getSuccessBB()->getArgument(0);
4086-
auto conformanceIsolation = SILIsolationInfo::getForCastConformances(
4087-
resultValue,
4088-
ccbi->getSourceFormalType(),
4089-
ccbi->getTargetFormalType());
4090-
TermArgSources sources;
4091-
sources.init(static_cast<SILInstruction *>(ccbi));
4092-
translateSILPhi(sources, conformanceIsolation);
4093-
4094-
return TranslationSemantics::Special;
4095-
}
4096-
40974065
TranslationSemantics PartitionOpTranslator::visitCheckedCastAddrBranchInst(
40984066
CheckedCastAddrBranchInst *ccabi) {
40994067
assert(ccabi->getSuccessBB()->getNumArguments() <= 1);
41004068

4101-
// Consider whether the value written into by the cast might be task-isolated.
4102-
auto resultValue = ccabi->getAllOperands().back().get();
4103-
auto conformanceIsolation = SILIsolationInfo::getForCastConformances(
4104-
resultValue,
4105-
ccabi->getSourceFormalType(),
4106-
ccabi->getTargetFormalType());
4107-
41084069
// checked_cast_addr_br does not have any arguments in its resulting
41094070
// block. We should just use a multi-assign on its operands.
41104071
//
@@ -4114,7 +4075,7 @@ TranslationSemantics PartitionOpTranslator::visitCheckedCastAddrBranchInst(
41144075
// but still correct.
41154076
translateSILMultiAssign(ArrayRef<SILValue>(),
41164077
makeOperandRefRange(ccabi->getAllOperands()),
4117-
conformanceIsolation);
4078+
SILIsolationInfo::getConformanceIsolation(ccabi));
41184079
return TranslationSemantics::Special;
41194080
}
41204081

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"
@@ -1171,6 +1172,24 @@ SILIsolationInfo SILIsolationInfo::getForCastConformances(
11711172
return {};
11721173
}
11731174

1175+
/// Retrieve a suitable destination value for the cast instruction.
1176+
///
1177+
/// TODO: This should probably be SILDynamicCastInst::getDest(), but that has
1178+
/// unimplemented TODOs.
1179+
static SILValue destValueForDynamicCast(SILDynamicCastInst dynCast) {
1180+
auto inst = dynCast.getInstruction();
1181+
switch (dynCast.getKind()) {
1182+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
1183+
return cast<CheckedCastAddrBranchInst>(inst)->getDest();
1184+
case SILDynamicCastKind::CheckedCastBranchInst:
1185+
return cast<CheckedCastBranchInst>(inst)->getSuccessBB()->getArgument(0);
1186+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
1187+
return cast<UnconditionalCheckedCastAddrInst>(inst)->getDest();
1188+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
1189+
return cast<UnconditionalCheckedCastInst>(inst);
1190+
}
1191+
}
1192+
11741193
SILIsolationInfo SILIsolationInfo::getConformanceIsolation(SILInstruction *inst) {
11751194
// Existential initialization.
11761195
if (auto ieai = dyn_cast<InitExistentialAddrInst>(inst)) {
@@ -1183,6 +1202,14 @@ SILIsolationInfo SILIsolationInfo::getConformanceIsolation(SILInstruction *inst)
11831202
return getFromConformances(ievi, ievi->getConformances());
11841203
}
11851204

1205+
// Dynamic casts.
1206+
if (auto dynCast = SILDynamicCastInst::getAs(inst)) {
1207+
return getForCastConformances(
1208+
destValueForDynamicCast(dynCast),
1209+
dynCast.getSourceFormalType(),
1210+
dynCast.getTargetFormalType());
1211+
}
1212+
11861213
return {};
11871214
}
11881215

0 commit comments

Comments
 (0)