From 73aabff8a29a88ec7e9e14dfbf8625bf672923e9 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Tue, 9 Oct 2018 10:21:46 -0700 Subject: [PATCH 1/2] IRGen: lazily emit shared witness tables This avoids emitting synthesized witness tables if they are not needed. --- lib/IRGen/IRGenModule.cpp | 6 ++++++ test/IRGen/objc_ns_enum.swift | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index e674fefdeafbf..111814253152d 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -711,6 +711,12 @@ bool IRGenerator::canEmitWitnessTableLazily(SILWitnessTable *wt) { if (Opts.UseJIT) return false; + // Regardless of the access level, if the witness table is shared it means + // we can safely not emit it. Every other module which needs it will generate + // its own shared copy of it. + if (wt->getLinkage() == SILLinkage::Shared) + return true; + NominalTypeDecl *ConformingTy = wt->getConformance()->getType()->getNominalOrBoundGenericNominal(); diff --git a/test/IRGen/objc_ns_enum.swift b/test/IRGen/objc_ns_enum.swift index 9cd3f1f1e9f03..ec43fff50a173 100644 --- a/test/IRGen/objc_ns_enum.swift +++ b/test/IRGen/objc_ns_enum.swift @@ -12,7 +12,7 @@ import gizmo // CHECK: @"$sSo16NSRuncingOptionsVN" = linkonce_odr hidden constant // CHECK-SAME: @"$sBi{{[0-9]+}}_WV" // CHECK: @"$sSo16NSRuncingOptionsVSQSCMc" = linkonce_odr hidden constant %swift.protocol_conformance_descriptor { {{.*}}@"$sSo16NSRuncingOptionsVSQSCWa -// CHECK: @"$sSo28NeverActuallyMentionedByNameVSQSCWp" = linkonce_odr hidden constant +// CHECK-NOT: @"$sSo28NeverActuallyMentionedByNameVSQSCWp" = linkonce_odr hidden constant // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} i32 @main // CHECK: call swiftcc %swift.metadata_response @"$sSo16NSRuncingOptionsVMa"(i64 0) From 6e6aae8d61c3f56fd6bee0e3ae17980c072f437e Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Tue, 9 Oct 2018 10:27:02 -0700 Subject: [PATCH 2/2] Mark all _unconditionallyBridgeFromObjectiveC functions as @_effects(readonly) This enables removal of those bridging calls for dead parameters. Read-only lets the optimizer remove such a call if the result is not used. Note that "readonly" means: no observable write operations. It's okay to allocate and initialize new objects. rdar://problem/44944094 --- stdlib/public/SDK/Dispatch/Data.swift | 1 + .../SDK/Foundation/AffineTransform.swift | 1 + stdlib/public/SDK/Foundation/Calendar.swift | 1 + .../public/SDK/Foundation/CharacterSet.swift | 1 + stdlib/public/SDK/Foundation/Data.swift | 3 ++- stdlib/public/SDK/Foundation/Date.swift | 1 + .../public/SDK/Foundation/DateComponents.swift | 1 + .../public/SDK/Foundation/DateInterval.swift | 1 + stdlib/public/SDK/Foundation/Decimal.swift | 1 + stdlib/public/SDK/Foundation/Foundation.swift | 1 + stdlib/public/SDK/Foundation/IndexPath.swift | 1 + stdlib/public/SDK/Foundation/IndexSet.swift | 1 + stdlib/public/SDK/Foundation/Locale.swift | 1 + stdlib/public/SDK/Foundation/Measurement.swift | 1 + stdlib/public/SDK/Foundation/NSArray.swift | 1 + .../public/SDK/Foundation/NSDictionary.swift | 1 + stdlib/public/SDK/Foundation/NSError.swift | 1 + stdlib/public/SDK/Foundation/NSNumber.swift | 16 +++++++++++++++- stdlib/public/SDK/Foundation/NSSet.swift | 1 + .../public/SDK/Foundation/Notification.swift | 1 + .../SDK/Foundation/PersonNameComponents.swift | 1 + stdlib/public/SDK/Foundation/String.swift | 2 ++ stdlib/public/SDK/Foundation/TimeZone.swift | 1 + stdlib/public/SDK/Foundation/URL.swift | 1 + .../public/SDK/Foundation/URLComponents.swift | 2 ++ stdlib/public/SDK/Foundation/URLRequest.swift | 1 + stdlib/public/SDK/Foundation/UUID.swift | 1 + stdlib/public/SDK/Intents/INShortcut.swift | 1 + stdlib/public/core/BridgeObjectiveC.swift | 2 ++ stdlib/public/core/NewtypeWrapper.swift | 2 ++ stdlib/public/core/Optional.swift | 1 + test/SILOptimizer/dead_bridging_code.swift | 18 ++++++++++++++++++ 32 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 test/SILOptimizer/dead_bridging_code.swift diff --git a/stdlib/public/SDK/Dispatch/Data.swift b/stdlib/public/SDK/Dispatch/Data.swift index eabfe419b2f51..66cd487bf77c8 100644 --- a/stdlib/public/SDK/Dispatch/Data.swift +++ b/stdlib/public/SDK/Dispatch/Data.swift @@ -356,6 +356,7 @@ extension DispatchData { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: __DispatchData?) -> DispatchData { var result: DispatchData? _forceBridgeFromObjectiveC(source!, result: &result) diff --git a/stdlib/public/SDK/Foundation/AffineTransform.swift b/stdlib/public/SDK/Foundation/AffineTransform.swift index b94a601cdf1f1..80caad04f8aee 100644 --- a/stdlib/public/SDK/Foundation/AffineTransform.swift +++ b/stdlib/public/SDK/Foundation/AffineTransform.swift @@ -317,6 +317,7 @@ extension AffineTransform : _ObjectiveCBridgeable { return true // Can't fail } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ x: NSAffineTransform?) -> AffineTransform { guard let src = x else { return AffineTransform.identity } return AffineTransform(reference: src) diff --git a/stdlib/public/SDK/Foundation/Calendar.swift b/stdlib/public/SDK/Foundation/Calendar.swift index 803d824f257a4..4e870452d396a 100644 --- a/stdlib/public/SDK/Foundation/Calendar.swift +++ b/stdlib/public/SDK/Foundation/Calendar.swift @@ -1113,6 +1113,7 @@ extension Calendar : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSCalendar?) -> Calendar { var result: Calendar? _forceBridgeFromObjectiveC(source!, result: &result) diff --git a/stdlib/public/SDK/Foundation/CharacterSet.swift b/stdlib/public/SDK/Foundation/CharacterSet.swift index 2f9a4875042dc..3161d6a7b9bb4 100644 --- a/stdlib/public/SDK/Foundation/CharacterSet.swift +++ b/stdlib/public/SDK/Foundation/CharacterSet.swift @@ -782,6 +782,7 @@ extension CharacterSet : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSCharacterSet?) -> CharacterSet { guard let src = source else { return CharacterSet() } return CharacterSet(_bridged: src) diff --git a/stdlib/public/SDK/Foundation/Data.swift b/stdlib/public/SDK/Foundation/Data.swift index f1e332f94e7bd..57e14cb39fd68 100644 --- a/stdlib/public/SDK/Foundation/Data.swift +++ b/stdlib/public/SDK/Foundation/Data.swift @@ -1902,7 +1902,8 @@ extension Data : _ObjectiveCBridgeable { result = Data(referencing: input) return true } - + + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSData?) -> Data { guard let src = source else { return Data() } return Data(referencing: src) diff --git a/stdlib/public/SDK/Foundation/Date.swift b/stdlib/public/SDK/Foundation/Date.swift index 7231a6d541457..fcb455c39ca54 100644 --- a/stdlib/public/SDK/Foundation/Date.swift +++ b/stdlib/public/SDK/Foundation/Date.swift @@ -257,6 +257,7 @@ extension Date : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSDate?) -> Date { var result: Date? _forceBridgeFromObjectiveC(source!, result: &result) diff --git a/stdlib/public/SDK/Foundation/DateComponents.swift b/stdlib/public/SDK/Foundation/DateComponents.swift index 2507598a98151..f31e8400b46be 100644 --- a/stdlib/public/SDK/Foundation/DateComponents.swift +++ b/stdlib/public/SDK/Foundation/DateComponents.swift @@ -338,6 +338,7 @@ extension DateComponents : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSDateComponents?) -> DateComponents { guard let src = source else { return DateComponents() } return DateComponents(reference: src) diff --git a/stdlib/public/SDK/Foundation/DateInterval.swift b/stdlib/public/SDK/Foundation/DateInterval.swift index b9af8e5f13773..5c58a063e345d 100644 --- a/stdlib/public/SDK/Foundation/DateInterval.swift +++ b/stdlib/public/SDK/Foundation/DateInterval.swift @@ -216,6 +216,7 @@ extension DateInterval : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSDateInterval?) -> DateInterval { var result: DateInterval? _forceBridgeFromObjectiveC(source!, result: &result) diff --git a/stdlib/public/SDK/Foundation/Decimal.swift b/stdlib/public/SDK/Foundation/Decimal.swift index 1286a5d51d334..00d958ad046cd 100644 --- a/stdlib/public/SDK/Foundation/Decimal.swift +++ b/stdlib/public/SDK/Foundation/Decimal.swift @@ -487,6 +487,7 @@ extension Decimal : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSDecimalNumber?) -> Decimal { guard let src = source else { return Decimal(_exponent: 0, _length: 0, _isNegative: 0, _isCompact: 0, _reserved: 0, _mantissa: (0, 0, 0, 0, 0, 0, 0, 0)) } return src.decimalValue diff --git a/stdlib/public/SDK/Foundation/Foundation.swift b/stdlib/public/SDK/Foundation/Foundation.swift index 67605af981282..057faf2c39355 100644 --- a/stdlib/public/SDK/Foundation/Foundation.swift +++ b/stdlib/public/SDK/Foundation/Foundation.swift @@ -73,6 +73,7 @@ extension AnyHashable : _ObjectiveCBridgeable { return result != nil } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC( _ source: NSObject? ) -> AnyHashable { diff --git a/stdlib/public/SDK/Foundation/IndexPath.swift b/stdlib/public/SDK/Foundation/IndexPath.swift index 5f195d48e0c0e..8f7e4a2e1e524 100644 --- a/stdlib/public/SDK/Foundation/IndexPath.swift +++ b/stdlib/public/SDK/Foundation/IndexPath.swift @@ -780,6 +780,7 @@ extension IndexPath : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSIndexPath?) -> IndexPath { guard let src = source else { return IndexPath() } return IndexPath(nsIndexPath: src) diff --git a/stdlib/public/SDK/Foundation/IndexSet.swift b/stdlib/public/SDK/Foundation/IndexSet.swift index 28624a728601e..6f019a23e2bd2 100644 --- a/stdlib/public/SDK/Foundation/IndexSet.swift +++ b/stdlib/public/SDK/Foundation/IndexSet.swift @@ -775,6 +775,7 @@ extension IndexSet : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSIndexSet?) -> IndexSet { guard let src = source else { return IndexSet() } return IndexSet(reference: src) diff --git a/stdlib/public/SDK/Foundation/Locale.swift b/stdlib/public/SDK/Foundation/Locale.swift index 9711bb4427ee2..ae2ad027e3f1f 100644 --- a/stdlib/public/SDK/Foundation/Locale.swift +++ b/stdlib/public/SDK/Foundation/Locale.swift @@ -466,6 +466,7 @@ extension Locale : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSLocale?) -> Locale { var result: Locale? _forceBridgeFromObjectiveC(source!, result: &result) diff --git a/stdlib/public/SDK/Foundation/Measurement.swift b/stdlib/public/SDK/Foundation/Measurement.swift index 72513aa83990c..d2cb56eea240a 100644 --- a/stdlib/public/SDK/Foundation/Measurement.swift +++ b/stdlib/public/SDK/Foundation/Measurement.swift @@ -238,6 +238,7 @@ extension Measurement : MeasurementBridgeType { } } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSMeasurement?) -> Measurement { let u = source!.unit as! UnitType return Measurement(value: source!.doubleValue, unit: u) diff --git a/stdlib/public/SDK/Foundation/NSArray.swift b/stdlib/public/SDK/Foundation/NSArray.swift index 652e8a8617d79..cb13bff17e8ea 100644 --- a/stdlib/public/SDK/Foundation/NSArray.swift +++ b/stdlib/public/SDK/Foundation/NSArray.swift @@ -84,6 +84,7 @@ extension Array : _ObjectiveCBridgeable { return result != nil } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC( _ source: NSArray? ) -> Array { diff --git a/stdlib/public/SDK/Foundation/NSDictionary.swift b/stdlib/public/SDK/Foundation/NSDictionary.swift index 188da7446ba54..368ab3a97c2a0 100644 --- a/stdlib/public/SDK/Foundation/NSDictionary.swift +++ b/stdlib/public/SDK/Foundation/NSDictionary.swift @@ -125,6 +125,7 @@ extension Dictionary : _ObjectiveCBridgeable { return result != nil } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC( _ d: NSDictionary? ) -> Dictionary { diff --git a/stdlib/public/SDK/Foundation/NSError.swift b/stdlib/public/SDK/Foundation/NSError.swift index 96380595988be..29aa4a29e2e7a 100644 --- a/stdlib/public/SDK/Foundation/NSError.swift +++ b/stdlib/public/SDK/Foundation/NSError.swift @@ -547,6 +547,7 @@ extension _SwiftNewtypeWrapper where Self.RawValue == Error { } @inlinable // FIXME(sil-serialize-all) + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC( _ source: NSError? ) -> Self { diff --git a/stdlib/public/SDK/Foundation/NSNumber.swift b/stdlib/public/SDK/Foundation/NSNumber.swift index ed4a05f2e5843..5236064075d4d 100644 --- a/stdlib/public/SDK/Foundation/NSNumber.swift +++ b/stdlib/public/SDK/Foundation/NSNumber.swift @@ -46,6 +46,7 @@ extension Int8 : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int8 { var result: Int8? guard let src = source else { return Int8(0) } @@ -87,6 +88,7 @@ extension UInt8 : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt8 { var result: UInt8? guard let src = source else { return UInt8(0) } @@ -128,6 +130,7 @@ extension Int16 : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int16 { var result: Int16? guard let src = source else { return Int16(0) } @@ -169,6 +172,7 @@ extension UInt16 : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt16 { var result: UInt16? guard let src = source else { return UInt16(0) } @@ -210,6 +214,7 @@ extension Int32 : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int32 { var result: Int32? guard let src = source else { return Int32(0) } @@ -251,6 +256,7 @@ extension UInt32 : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt32 { var result: UInt32? guard let src = source else { return UInt32(0) } @@ -292,6 +298,7 @@ extension Int64 : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int64 { var result: Int64? guard let src = source else { return Int64(0) } @@ -332,7 +339,8 @@ extension UInt64 : _ObjectiveCBridgeable { result = value return true } - + + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt64 { var result: UInt64? guard let src = source else { return UInt64(0) } @@ -374,6 +382,7 @@ extension Int : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int { var result: Int? guard let src = source else { return Int(0) } @@ -415,6 +424,7 @@ extension UInt : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt { var result: UInt? guard let src = source else { return UInt(0) } @@ -467,6 +477,7 @@ extension Float : _ObjectiveCBridgeable { return result != nil } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Float { var result: Float? guard let src = source else { return Float(0) } @@ -521,6 +532,7 @@ extension Double : _ObjectiveCBridgeable { return result != nil } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Double { var result: Double? guard let src = source else { return Double(0) } @@ -572,6 +584,7 @@ extension Bool : _ObjectiveCBridgeable { return false } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Bool { var result: Bool? guard let src = source else { return false } @@ -614,6 +627,7 @@ extension CGFloat : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> CGFloat { var result: CGFloat? guard let src = source else { return CGFloat(0) } diff --git a/stdlib/public/SDK/Foundation/NSSet.swift b/stdlib/public/SDK/Foundation/NSSet.swift index 655f92772855b..fea8a1dd04820 100644 --- a/stdlib/public/SDK/Foundation/NSSet.swift +++ b/stdlib/public/SDK/Foundation/NSSet.swift @@ -111,6 +111,7 @@ extension Set : _ObjectiveCBridgeable { return result != nil } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ s: NSSet?) -> Set { // `nil` has historically been used as a stand-in for an empty // set; map it to an empty set. diff --git a/stdlib/public/SDK/Foundation/Notification.swift b/stdlib/public/SDK/Foundation/Notification.swift index 68d351f9e67e5..28331c040fab1 100644 --- a/stdlib/public/SDK/Foundation/Notification.swift +++ b/stdlib/public/SDK/Foundation/Notification.swift @@ -120,6 +120,7 @@ extension Notification : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNotification?) -> Notification { guard let src = source else { return Notification(name: Notification.Name("")) } return Notification(name: src.name, object: src.object, userInfo: src.userInfo) diff --git a/stdlib/public/SDK/Foundation/PersonNameComponents.swift b/stdlib/public/SDK/Foundation/PersonNameComponents.swift index 7b8901b2834a6..5c8ead8ca879c 100644 --- a/stdlib/public/SDK/Foundation/PersonNameComponents.swift +++ b/stdlib/public/SDK/Foundation/PersonNameComponents.swift @@ -129,6 +129,7 @@ extension PersonNameComponents : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSPersonNameComponents?) -> PersonNameComponents { var result: PersonNameComponents? _forceBridgeFromObjectiveC(source!, result: &result) diff --git a/stdlib/public/SDK/Foundation/String.swift b/stdlib/public/SDK/Foundation/String.swift index c460f71afba12..83e0c07df95c9 100644 --- a/stdlib/public/SDK/Foundation/String.swift +++ b/stdlib/public/SDK/Foundation/String.swift @@ -50,6 +50,7 @@ extension String : _ObjectiveCBridgeable { return result != nil } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC( _ source: NSString? ) -> String { @@ -82,6 +83,7 @@ extension Substring : _ObjectiveCBridgeable { return result != nil } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC( _ source: NSString? ) -> Substring { diff --git a/stdlib/public/SDK/Foundation/TimeZone.swift b/stdlib/public/SDK/Foundation/TimeZone.swift index a3c77e466e392..5facbe11db9e0 100644 --- a/stdlib/public/SDK/Foundation/TimeZone.swift +++ b/stdlib/public/SDK/Foundation/TimeZone.swift @@ -262,6 +262,7 @@ extension TimeZone : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSTimeZone?) -> TimeZone { var result: TimeZone? _forceBridgeFromObjectiveC(source!, result: &result) diff --git a/stdlib/public/SDK/Foundation/URL.swift b/stdlib/public/SDK/Foundation/URL.swift index e3311603ba301..fcd48bbcdcf1c 100644 --- a/stdlib/public/SDK/Foundation/URL.swift +++ b/stdlib/public/SDK/Foundation/URL.swift @@ -1205,6 +1205,7 @@ extension URL : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSURL?) -> URL { var result: URL? _forceBridgeFromObjectiveC(source!, result: &result) diff --git a/stdlib/public/SDK/Foundation/URLComponents.swift b/stdlib/public/SDK/Foundation/URLComponents.swift index ee5cbcf5be316..2d6eabf064326 100644 --- a/stdlib/public/SDK/Foundation/URLComponents.swift +++ b/stdlib/public/SDK/Foundation/URLComponents.swift @@ -372,6 +372,7 @@ extension URLComponents : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSURLComponents?) -> URLComponents { guard let src = source else { return URLComponents() } return URLComponents(reference: src) @@ -465,6 +466,7 @@ extension URLQueryItem : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSURLQueryItem?) -> URLQueryItem { var result: URLQueryItem? _forceBridgeFromObjectiveC(source!, result: &result) diff --git a/stdlib/public/SDK/Foundation/URLRequest.swift b/stdlib/public/SDK/Foundation/URLRequest.swift index f18aa5cc563db..b2695c7ad9cf5 100644 --- a/stdlib/public/SDK/Foundation/URLRequest.swift +++ b/stdlib/public/SDK/Foundation/URLRequest.swift @@ -286,6 +286,7 @@ extension URLRequest : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSURLRequest?) -> URLRequest { var result: URLRequest? _forceBridgeFromObjectiveC(source!, result: &result) diff --git a/stdlib/public/SDK/Foundation/UUID.swift b/stdlib/public/SDK/Foundation/UUID.swift index 2e64ea8801e6e..23c8507d1eab0 100644 --- a/stdlib/public/SDK/Foundation/UUID.swift +++ b/stdlib/public/SDK/Foundation/UUID.swift @@ -148,6 +148,7 @@ extension UUID : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: NSUUID?) -> UUID { var result: UUID? _forceBridgeFromObjectiveC(source!, result: &result) diff --git a/stdlib/public/SDK/Intents/INShortcut.swift b/stdlib/public/SDK/Intents/INShortcut.swift index 0d0945f5328c5..a68b9acf31cae 100644 --- a/stdlib/public/SDK/Intents/INShortcut.swift +++ b/stdlib/public/SDK/Intents/INShortcut.swift @@ -113,6 +113,7 @@ extension INShortcut : _ObjectiveCBridgeable { return true } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: INShortcutReference?) -> INShortcut { guard let src = source else { fatalError("Missing source") } return INShortcut(from: src) diff --git a/stdlib/public/core/BridgeObjectiveC.swift b/stdlib/public/core/BridgeObjectiveC.swift index 3e1579378e818..2aac8cf8d1254 100644 --- a/stdlib/public/core/BridgeObjectiveC.swift +++ b/stdlib/public/core/BridgeObjectiveC.swift @@ -78,6 +78,7 @@ public protocol _ObjectiveCBridgeable { /// implementation of `Swift.Array`'s conformance to /// `_ObjectiveCBridgeable` will produce an empty array rather than /// dynamically failing. + @_effects(readonly) static func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectiveCType?) -> Self } @@ -133,6 +134,7 @@ public struct _BridgeableMetatype: _ObjectiveCBridgeable { } @inlinable // FIXME(sil-serialize-all) + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: AnyObject?) -> _BridgeableMetatype { var result: _BridgeableMetatype? diff --git a/stdlib/public/core/NewtypeWrapper.swift b/stdlib/public/core/NewtypeWrapper.swift index 2d744efa6450a..090156fbff5c7 100644 --- a/stdlib/public/core/NewtypeWrapper.swift +++ b/stdlib/public/core/NewtypeWrapper.swift @@ -133,6 +133,7 @@ extension _SwiftNewtypeWrapper where Self.RawValue : _ObjectiveCBridgeable { } @inlinable // FIXME(sil-serialize-all) + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC( _ source: Self.RawValue._ObjectiveCType? ) -> Self { @@ -165,6 +166,7 @@ extension _SwiftNewtypeWrapper where Self.RawValue: AnyObject { } @inlinable // FIXME(sil-serialize-all) + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC( _ source: Self.RawValue? ) -> Self { diff --git a/stdlib/public/core/Optional.swift b/stdlib/public/core/Optional.swift index 2d82da37f0030..90914f0a71997 100644 --- a/stdlib/public/core/Optional.swift +++ b/stdlib/public/core/Optional.swift @@ -727,6 +727,7 @@ extension Optional : _ObjectiveCBridgeable { } @inlinable // FIXME(sil-serialize-all) + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: AnyObject?) -> Optional { if let nonnullSource = source { diff --git a/test/SILOptimizer/dead_bridging_code.swift b/test/SILOptimizer/dead_bridging_code.swift new file mode 100644 index 0000000000000..519e633a02a8a --- /dev/null +++ b/test/SILOptimizer/dead_bridging_code.swift @@ -0,0 +1,18 @@ +// RUN: %target-swift-frontend -O -module-name=test -emit-sil %s | %FileCheck %s + +// REQUIRES: objc_interop + +// Check if the optimizer can remove dead briding calls. + +import Foundation + +class Myclass : NSObject { + +// CHECK-LABEL: sil hidden [thunk] @$s4test7MyclassC3fooyySSFTo +// CHECK-NEXT: bb0(%0 : $NSString, %1 : $Myclass): +// CHECK-NEXT: tuple () +// CHECK-NEXT: return + @objc func foo(_ s: String) { + } +} +