@@ -1571,6 +1571,40 @@ optimizeBridgedObjCToSwiftCast(SILInstruction *Inst,
1571
1571
return (NewI) ? NewI : AI;
1572
1572
}
1573
1573
1574
+ static bool canOptimizeCast (const swift::Type &BridgedTargetTy,
1575
+ swift::SILModule &M,
1576
+ swift::SILFunctionConventions &substConv) {
1577
+ // DestTy is the type which we want to convert to
1578
+ SILType DestTy =
1579
+ SILType::getPrimitiveObjectType (BridgedTargetTy->getCanonicalType ());
1580
+ // ConvTy is the return type of the _bridgeToObjectiveCImpl()
1581
+ auto ConvTy = substConv.getSILResultType ().getObjectType ();
1582
+ if (ConvTy == DestTy) {
1583
+ // Destination is the same type
1584
+ return true ;
1585
+ }
1586
+ // Check if a superclass/subclass of the source operand
1587
+ if (DestTy.isExactSuperclassOf (ConvTy)) {
1588
+ return true ;
1589
+ }
1590
+ if (ConvTy.isExactSuperclassOf (DestTy)) {
1591
+ return true ;
1592
+ }
1593
+ // check if it is a bridgeable CF type
1594
+ if (ConvTy.getSwiftRValueType () ==
1595
+ getNSBridgedClassOfCFClass (M.getSwiftModule (),
1596
+ DestTy.getSwiftRValueType ())) {
1597
+ return true ;
1598
+ }
1599
+ if (DestTy.getSwiftRValueType () ==
1600
+ getNSBridgedClassOfCFClass (M.getSwiftModule (),
1601
+ ConvTy.getSwiftRValueType ())) {
1602
+ return true ;
1603
+ }
1604
+ // All else failed - can't optimize this case
1605
+ return false ;
1606
+ }
1607
+
1574
1608
// / Create a call of _bridgeToObjectiveC which converts an _ObjectiveCBridgeable
1575
1609
// / instance into a bridged ObjC type.
1576
1610
SILInstruction *
@@ -1646,7 +1680,8 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
1646
1680
if (ResultsRef.size () != 1 )
1647
1681
return nullptr ;
1648
1682
1649
- auto MemberDeclRef = SILDeclRef (Results.front ());
1683
+ auto *resultDecl = Results.front ();
1684
+ auto MemberDeclRef = SILDeclRef (resultDecl);
1650
1685
auto *BridgedFunc = M.getOrCreateFunction (Loc, MemberDeclRef,
1651
1686
ForDefinition_t::NotForDefinition);
1652
1687
@@ -1677,6 +1712,11 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
1677
1712
SILType SubstFnTy = SILFnTy.substGenericArgs (M, SubMap);
1678
1713
SILFunctionConventions substConv (SubstFnTy.castTo <SILFunctionType>(), M);
1679
1714
1715
+ // check that we can go through with the optimization
1716
+ if (!canOptimizeCast (BridgedTargetTy, M, substConv)) {
1717
+ return nullptr ;
1718
+ }
1719
+
1680
1720
auto FnRef = Builder.createFunctionRef (Loc, BridgedFunc);
1681
1721
if (Src->getType ().isAddress () && !substConv.isSILIndirect (ParamTypes[0 ])) {
1682
1722
// Create load
@@ -1811,6 +1851,9 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
1811
1851
// If it is addr cast then store the result.
1812
1852
auto ConvTy = NewAI->getType ();
1813
1853
auto DestTy = Dest->getType ().getObjectType ();
1854
+ assert (DestTy == SILType::getPrimitiveObjectType (
1855
+ BridgedTargetTy->getCanonicalType ()) &&
1856
+ " Expected Dest Type to be the same as BridgedTargetTy" );
1814
1857
SILValue CastedValue;
1815
1858
if (ConvTy == DestTy) {
1816
1859
CastedValue = NewAI;
@@ -1842,9 +1885,11 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
1842
1885
CastedValue =
1843
1886
SILValue (Builder.createUncheckedRefCast (Loc, NewAI, DestTy));
1844
1887
} else {
1845
- llvm_unreachable (
1846
- " Destination should have the same type, be bridgeable CF "
1847
- " type or be a superclass/subclass of the source operand" );
1888
+ llvm_unreachable (" optimizeBridgedSwiftToObjCCast: should never reach "
1889
+ " this condition: if the Destination does not have the "
1890
+ " same type, is not a bridgeable CF type and isn't a "
1891
+ " superclass/subclass of the source operand we should "
1892
+ " have bailed earlier" );
1848
1893
}
1849
1894
NewI = Builder.createStore (Loc, CastedValue, Dest,
1850
1895
StoreOwnershipQualifier::Unqualified);
0 commit comments