Skip to content

SR-10294: convertBoolToDarwinBool and friends should be inlined #23802

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions stdlib/public/Darwin/ObjectiveC/ObjectiveC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,30 @@ import _SwiftObjectiveCOverlayShims
public struct ObjCBool : ExpressibleByBooleanLiteral {
#if os(macOS) || (os(iOS) && (arch(i386) || arch(arm)))
// On OS X and 32-bit iOS, Objective-C's BOOL type is a "signed char".
var _value: Int8
@usableFromInline var _value: Int8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is technically cheating because this wasn't ABI in 5.0 and therefore there wasn't a symbol there, so we have to really cross our fingers that nothing will stay referencing the symbol. That seems pretty likely, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah hm good point >.<

What about at -Onone? Seems like there’s more risk there maybe?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think since the struct is fixed-layout it should be okay. It's still usable-from-inline and not public so it's not like it can be used in arbitrary ways.


@_transparent
init(_ value: Int8) {
self._value = value
}

@_transparent
public init(_ value: Bool) {
self._value = value ? 1 : 0
}

#else
// Everywhere else it is C/C++'s "Bool"
var _value: Bool
@usableFromInline var _value: Bool

@_transparent
public init(_ value: Bool) {
self._value = value
}
#endif

/// The value of `self`, expressed as a `Bool`.
@_transparent
public var boolValue: Bool {
#if os(macOS) || (os(iOS) && (arch(i386) || arch(arm)))
return _value != 0
Expand Down Expand Up @@ -78,11 +82,13 @@ extension ObjCBool : CustomStringConvertible {

// Functions used to implicitly bridge ObjCBool types to Swift's Bool type.

@_transparent
public // COMPILER_INTRINSIC
func _convertBoolToObjCBool(_ x: Bool) -> ObjCBool {
return ObjCBool(x)
}

@_transparent
public // COMPILER_INTRINSIC
func _convertObjCBoolToBool(_ x: ObjCBool) -> Bool {
return x.boolValue
Expand Down
8 changes: 7 additions & 1 deletion stdlib/public/Platform/Platform.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ public var noErr: OSStatus { return 0 }
/// The C type is a typedef for `unsigned char`.
@_fixed_layout
public struct DarwinBoolean : ExpressibleByBooleanLiteral {
var _value: UInt8
@usableFromInline var _value: UInt8

@_transparent
public init(_ value: Bool) {
self._value = value ? 1 : 0
}

/// The value of `self`, expressed as a `Bool`.
@_transparent
public var boolValue: Bool {
return _value != 0
}
Expand All @@ -63,15 +65,19 @@ extension DarwinBoolean : CustomStringConvertible {
}

extension DarwinBoolean : Equatable {
@_transparent
public static func ==(lhs: DarwinBoolean, rhs: DarwinBoolean) -> Bool {
return lhs.boolValue == rhs.boolValue
}
}

@_transparent
public // COMPILER_INTRINSIC
func _convertBoolToDarwinBoolean(_ x: Bool) -> DarwinBoolean {
return DarwinBoolean(x)
}

@_transparent
public // COMPILER_INTRINSIC
func _convertDarwinBooleanToBool(_ x: DarwinBoolean) -> Bool {
return x.boolValue
Expand Down
42 changes: 24 additions & 18 deletions test/SILOptimizer/definite_init_failable_initializers_objc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,48 +95,54 @@ class Cat : FakeNSObject {
// CHECK: store %2 to [[SELF_BOX]] : $*Cat
// CHECK-NEXT: [[COND:%.+]] = struct_extract %0 : $Bool, #Bool._value
// CHECK-NEXT: cond_br [[COND]], bb1, bb2

// CHECK: bb1:
// CHECK-NEXT: br bb5

// CHECK: bb2:
// CHECK-NEXT: br bb8

// CHECK: bb3:
// CHECK: br bb5

// CHECK: bb4:
// CHECK: br bb5

// CHECK: bb5
// CHECK: [[SELF_INIT:%.+]] = objc_method %2 : $Cat, #Cat.init!initializer.1.foreign : (Cat.Type) -> (Int, Bool) -> Cat?
// CHECK: [[NEW_OPT_SELF:%.+]] = apply [[SELF_INIT]]({{%.+}}, {{%.+}}, %2) : $@convention(objc_method) (Int, ObjCBool, @owned Cat) -> @owned Optional<Cat>
// CHECK: [[COND:%.+]] = select_enum [[NEW_OPT_SELF]] : $Optional<Cat>
// CHECK-NEXT: cond_br [[COND]], bb4, bb3
// CHECK-NEXT: cond_br [[COND]], bb7, bb6

// CHECK: bb3:
// CHECK: bb6:
// CHECK-NEXT: release_value [[NEW_OPT_SELF]]
// CHECK-NEXT: br bb5
// CHECK-NEXT: br bb8

// CHECK: bb4:
// CHECK: bb7:
// CHECK-NEXT: [[NEW_SELF:%.+]] = unchecked_enum_data [[NEW_OPT_SELF]] : $Optional<Cat>, #Optional.some!enumelt.1
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] : $*Cat
// TODO: Once we re-enable arbitrary take promotion, this retain and the associated destroy_addr will go away.
// CHECK-NEXT: strong_retain [[NEW_SELF]]
// CHECK-NEXT: [[RESULT:%.+]] = enum $Optional<Cat>, #Optional.some!enumelt.1, [[NEW_SELF]] : $Cat
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]] : $*Cat
// CHECK-NEXT: br bb9([[RESULT]] : $Optional<Cat>)
// CHECK-NEXT: br bb12([[RESULT]] : $Optional<Cat>)

// CHECK: bb5:
// CHECK: bb8:
// CHECK-NEXT: [[COND:%.+]] = load [[HAS_RUN_INIT_BOX]] : $*Builtin.Int1
// CHECK-NEXT: cond_br [[COND]], bb6, bb7
// CHECK-NEXT: cond_br [[COND]], bb9, bb10

// CHECK: bb6:
// CHECK-NEXT: br bb8
// CHECK: bb9:
// CHECK-NEXT: br bb11

// CHECK: bb7:
// CHECK: bb10:
// CHECK-NEXT: [[MOST_DERIVED_TYPE:%.+]] = value_metatype $@thick Cat.Type, %2 : $Cat
// CHECK-NEXT: dealloc_partial_ref %2 : $Cat, [[MOST_DERIVED_TYPE]] : $@thick Cat.Type
// CHECK-NEXT: br bb8
// CHECK-NEXT: br bb11

// CHECK: bb8:
// CHECK: bb11:
// CHECK-NEXT: dealloc_stack [[SELF_BOX]] : $*Cat
// CHECK-NEXT: [[NIL_RESULT:%.+]] = enum $Optional<Cat>, #Optional.none!enumelt
// CHECK-NEXT: br bb9([[NIL_RESULT]] : $Optional<Cat>)
// CHECK-NEXT: br bb12([[NIL_RESULT]] : $Optional<Cat>)

// CHECK: bb9([[RESULT:%.+]] : $Optional<Cat>):
// CHECK: bb12([[RESULT:%.+]] : $Optional<Cat>):
// CHECK-NEXT: dealloc_stack [[HAS_RUN_INIT_BOX]] : $*Builtin.Int1
// CHECK-NEXT: return [[RESULT]] : $Optional<Cat>

Expand Down