Skip to content

Commit d0901de

Browse files
authored
Merge pull request #23068 from gottesmm/pr-2f8945ab6e6f259236689efe97127e060c1850f1
[cast-opt] Change optimize{Swift,ObjC}to{ObjC,Swift} to use SILDynami…
2 parents ea85726 + ee02174 commit d0901de

File tree

3 files changed

+78
-70
lines changed

3 files changed

+78
-70
lines changed

include/swift/SIL/DynamicCasts.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#ifndef SWIFT_SIL_DYNAMICCASTS_H
1919
#define SWIFT_SIL_DYNAMICCASTS_H
2020

21+
#include "swift/AST/Module.h"
2122
#include "swift/Basic/ProfileCounter.h"
2223
#include "swift/SIL/SILInstruction.h"
2324
#include "swift/SIL/SILModule.h"
@@ -420,10 +421,33 @@ struct SILDynamicCastInst {
420421
// Bridging casts cannot be further simplified.
421422
auto TargetIsBridgeable = getTargetType()->isBridgeableObjectType();
422423
auto SourceIsBridgeable = getSourceType()->isBridgeableObjectType();
423-
424424
return TargetIsBridgeable != SourceIsBridgeable;
425425
}
426426

427+
/// If getSourceType() is a Swift type that can bridge to an ObjC type, return
428+
/// the ObjC type it bridges to. If the source type is an objc type, an empty
429+
/// CanType() is returned.
430+
CanType getBridgedSourceType() const {
431+
SILModule &mod = getModule();
432+
Type t = mod.getASTContext().getBridgedToObjC(mod.getSwiftModule(),
433+
getSourceType());
434+
if (!t)
435+
return CanType();
436+
return t->getCanonicalType();
437+
}
438+
439+
/// If getTargetType() is a Swift type that can bridge to an ObjC type, return
440+
/// the ObjC type it bridges to. If the target type is an objc type, an empty
441+
/// CanType() is returned.
442+
CanType getBridgedTargetType() const {
443+
SILModule &mod = getModule();
444+
Type t = mod.getASTContext().getBridgedToObjC(mod.getSwiftModule(),
445+
getTargetType());
446+
if (!t)
447+
return CanType();
448+
return t->getCanonicalType();
449+
}
450+
427451
bool isConditional() const {
428452
switch (getKind()) {
429453
case SILDynamicCastKind::CheckedCastAddrBranchInst: {

include/swift/SILOptimizer/Utils/CastOptimizer.h

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -63,24 +63,6 @@ class CastOptimizer {
6363
/// that a cast will fail.
6464
std::function<void()> WillFailAction;
6565

66-
/// Optimize a cast from a bridged ObjC type into
67-
/// a corresponding Swift type implementing _ObjectiveCBridgeable.
68-
SILInstruction *optimizeBridgedObjCToSwiftCast(
69-
SILInstruction *Inst, bool isConditional, SILValue Src, SILValue Dest,
70-
CanType Source, CanType Target, Type BridgedSourceTy,
71-
Type BridgedTargetTy, SILBasicBlock *SuccessBB, SILBasicBlock *FailureBB);
72-
73-
/// Optimize a cast from a Swift type implementing _ObjectiveCBridgeable
74-
/// into a bridged ObjC type.
75-
SILInstruction *optimizeBridgedSwiftToObjCCast(
76-
SILInstruction *Inst, CastConsumptionKind ConsumptionKind,
77-
bool isConditional, SILValue Src, SILValue Dest, CanType Source,
78-
CanType Target, Type BridgedSourceTy, Type BridgedTargetTy,
79-
SILBasicBlock *SuccessBB, SILBasicBlock *FailureBB);
80-
81-
void deleteInstructionsAfterUnreachable(SILInstruction *UnreachableInst,
82-
SILInstruction *TrapInst);
83-
8466
public:
8567
CastOptimizer(SILOptFunctionBuilder &FunctionBuilder,
8668
SILBuilderContext *BuilderContext,
@@ -149,6 +131,19 @@ class CastOptimizer {
149131
/// May change the control flow.
150132
SILInstruction *optimizeBridgedCasts(SILDynamicCastInst cast);
151133

134+
/// Optimize a cast from a bridged ObjC type into
135+
/// a corresponding Swift type implementing _ObjectiveCBridgeable.
136+
SILInstruction *
137+
optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast);
138+
139+
/// Optimize a cast from a Swift type implementing _ObjectiveCBridgeable
140+
/// into a bridged ObjC type.
141+
SILInstruction *
142+
optimizeBridgedSwiftToObjCCast(SILDynamicCastInst dynamicCast);
143+
144+
void deleteInstructionsAfterUnreachable(SILInstruction *UnreachableInst,
145+
SILInstruction *TrapInst);
146+
152147
SILValue optimizeMetatypeConversion(ConversionInst *mci,
153148
MetatypeRepresentation representation);
154149
};

lib/SILOptimizer/Utils/CastOptimizer.cpp

Lines changed: 40 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,21 @@
4545

4646
using namespace swift;
4747

48-
/// If target is a Swift type bridging to an ObjC type,
49-
/// return the ObjC type it bridges to.
50-
/// If target is an ObjC type, return this type.
51-
static Type getCastFromObjC(SILModule &M, CanType source, CanType target) {
52-
return M.getASTContext().getBridgedToObjC(M.getSwiftModule(), target);
53-
}
54-
5548
/// Create a call of _forceBridgeFromObjectiveC_bridgeable or
5649
/// _conditionallyBridgeFromObjectiveC_bridgeable which converts an ObjC
5750
/// instance into a corresponding Swift type, conforming to
5851
/// _ObjectiveCBridgeable.
59-
SILInstruction *CastOptimizer::optimizeBridgedObjCToSwiftCast(
60-
SILInstruction *Inst, bool isConditional, SILValue Src, SILValue Dest,
61-
CanType Source, CanType Target, Type BridgedSourceTy, Type BridgedTargetTy,
62-
SILBasicBlock *SuccessBB, SILBasicBlock *FailureBB) {
52+
SILInstruction *
53+
CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) {
54+
55+
SILInstruction *Inst = dynamicCast.getInstruction();
56+
bool isConditional = dynamicCast.isConditional();
57+
SILValue Src = dynamicCast.getSource();
58+
SILValue Dest = dynamicCast.getDest();
59+
CanType Target = dynamicCast.getTargetType();
60+
CanType BridgedTargetTy = dynamicCast.getBridgedTargetType();
61+
SILBasicBlock *SuccessBB = dynamicCast.getSuccessBlock();
62+
SILBasicBlock *FailureBB = dynamicCast.getFailureBlock();
6363
auto *F = Inst->getFunction();
6464
auto &M = Inst->getModule();
6565
auto Loc = Inst->getLoc();
@@ -313,12 +313,17 @@ static bool canOptimizeCast(const swift::Type &BridgedTargetTy,
313313

314314
/// Create a call of _bridgeToObjectiveC which converts an _ObjectiveCBridgeable
315315
/// instance into a bridged ObjC type.
316-
SILInstruction *CastOptimizer::optimizeBridgedSwiftToObjCCast(
317-
SILInstruction *Inst, CastConsumptionKind ConsumptionKind,
318-
bool isConditional, SILValue Src, SILValue Dest, CanType Source,
319-
CanType Target, Type BridgedSourceTy, Type BridgedTargetTy,
320-
SILBasicBlock *SuccessBB, SILBasicBlock *FailureBB) {
321-
316+
SILInstruction *
317+
CastOptimizer::optimizeBridgedSwiftToObjCCast(SILDynamicCastInst dynamicCast) {
318+
SILInstruction *Inst = dynamicCast.getInstruction();
319+
CastConsumptionKind ConsumptionKind = dynamicCast.getBridgedConsumptionKind();
320+
bool isConditional = dynamicCast.isConditional();
321+
SILValue Src = dynamicCast.getSource();
322+
SILValue Dest = dynamicCast.getDest();
323+
CanType Source = dynamicCast.getSourceType();
324+
CanType BridgedTargetTy = dynamicCast.getBridgedTargetType();
325+
SILBasicBlock *SuccessBB = dynamicCast.getSuccessBlock();
326+
SILBasicBlock *FailureBB = dynamicCast.getFailureBlock();
322327
auto &M = Inst->getModule();
323328
auto Loc = Inst->getLoc();
324329

@@ -596,24 +601,17 @@ SILInstruction *CastOptimizer::optimizeBridgedSwiftToObjCCast(
596601
return NewI;
597602
}
598603

599-
/// Make use of the fact that some of these casts cannot fail. For example, if
600-
/// the ObjC type is exactly the expected _ObjectiveCType type, then it would
601-
/// always succeed for NSString, NSNumber, etc. Casts from NSArray,
602-
/// NSDictionary and NSSet may fail.
604+
/// Make use of the fact that some of these casts cannot fail. For
605+
/// example, if the ObjC type is exactly the expected _ObjectiveCType
606+
/// type, then it would always succeed for NSString, NSNumber, etc.
607+
/// Casts from NSArray, NSDictionary and NSSet may fail.
603608
///
604-
/// If ObjC class is not exactly _ObjectiveCType, then its conversion to a
605-
/// required _ObjectiveCType may fail.
609+
/// If ObjC class is not exactly _ObjectiveCType, then its conversion
610+
/// to a required _ObjectiveCType may fail.
606611
SILInstruction *
607612
CastOptimizer::optimizeBridgedCasts(SILDynamicCastInst dynamicCast) {
608-
SILInstruction *Inst = dynamicCast.getInstruction();
609-
CastConsumptionKind ConsumptionKind = dynamicCast.getBridgedConsumptionKind();
610-
bool isConditional = dynamicCast.isConditional();
611-
SILValue Src = dynamicCast.getSource();
612-
SILValue Dest = dynamicCast.getDest();
613613
CanType source = dynamicCast.getSourceType();
614614
CanType target = dynamicCast.getTargetType();
615-
SILBasicBlock *SuccessBB = dynamicCast.getSuccessBlock();
616-
SILBasicBlock *FailureBB = dynamicCast.getFailureBlock();
617615
auto &M = dynamicCast.getModule();
618616

619617
// To apply the bridged optimizations, we should ensure that types are not
@@ -631,17 +629,14 @@ CastOptimizer::optimizeBridgedCasts(SILDynamicCastInst dynamicCast) {
631629
if (source->hasArchetype() || target->hasArchetype())
632630
return nullptr;
633631

634-
auto BridgedTargetTy = getCastFromObjC(M, source, target);
635-
if (!BridgedTargetTy)
636-
return nullptr;
632+
CanType CanBridgedSourceTy = dynamicCast.getBridgedSourceType();
633+
CanType CanBridgedTargetTy = dynamicCast.getBridgedTargetType();
637634

638-
auto BridgedSourceTy = getCastFromObjC(M, target, source);
639-
if (!BridgedSourceTy)
635+
// If we were unable to bridge either of our source/target types, return
636+
// nullptr.
637+
if (!CanBridgedSourceTy || !CanBridgedTargetTy)
640638
return nullptr;
641639

642-
CanType CanBridgedTargetTy = BridgedTargetTy->getCanonicalType();
643-
CanType CanBridgedSourceTy = BridgedSourceTy->getCanonicalType();
644-
645640
if (CanBridgedSourceTy == source && CanBridgedTargetTy == target) {
646641
// Both source and target type are ObjC types.
647642
return nullptr;
@@ -660,19 +655,13 @@ CastOptimizer::optimizeBridgedCasts(SILDynamicCastInst dynamicCast) {
660655
return nullptr;
661656
}
662657

663-
if (CanBridgedSourceTy || CanBridgedTargetTy) {
664-
// Check what kind of conversion it is? ObjC->Swift or Swift-ObjC?
665-
if (CanBridgedTargetTy != target) {
666-
// This is an ObjC to Swift cast.
667-
return optimizeBridgedObjCToSwiftCast(
668-
Inst, isConditional, Src, Dest, source, target, BridgedSourceTy,
669-
BridgedTargetTy, SuccessBB, FailureBB);
670-
} else {
671-
// This is a Swift to ObjC cast
672-
return optimizeBridgedSwiftToObjCCast(
673-
Inst, ConsumptionKind, isConditional, Src, Dest, source, target,
674-
BridgedSourceTy, BridgedTargetTy, SuccessBB, FailureBB);
675-
}
658+
// Check what kind of conversion it is? ObjC->Swift or Swift-ObjC?
659+
if (CanBridgedTargetTy != target) {
660+
// This is an ObjC to Swift cast.
661+
return optimizeBridgedObjCToSwiftCast(dynamicCast);
662+
} else {
663+
// This is a Swift to ObjC cast
664+
return optimizeBridgedSwiftToObjCCast(dynamicCast);
676665
}
677666

678667
llvm_unreachable("Unknown kind of bridging");

0 commit comments

Comments
 (0)