Hello everyone,
I’ve noticed an optimization gap when casting a value to AnyObject inside a generic function compared to a direct cast at the call site. Even when the generic function is specialized for a final class, the compiler still emits a call to the bridging runtime.
func cast<T>(_ v: T) -> AnyObject {
v as AnyObject
}
final class C: AnyObject {}
func test1(_ v: C) -> AnyObject {
cast(v)
}
func test2(_ v: C) -> AnyObject {
v as AnyObject
}
output.test1(output.C) -> Swift.AnyObject:
sub sp, sp, #32
stp x29, x30, [sp, #16]
add x29, sp, #16
ldr x1, [x0]
str x0, [sp, #8]
add x0, sp, #8
bl ($ss27_bridgeAnythingToObjectiveCyyXlxlF)
ldp x29, x30, [sp, #16]
add sp, sp, #32
ret
output.test2(output.C) -> Swift.AnyObject:
b swift_retain
Is it possible to "convince" the optimizer that a specialized version of cast<T> where T: AnyObject doesn't need the full bridging logic?
I can workaround it with an overload - func cast<T: AnyObject>(_ v: T) -> AnyObject. But in the actual code, the cast happens several calls deeper than the functions receiving the values, so I'd have to write a considerable amount of overloads.