Commits

Chris Lattner committed c6a334ab6e8
teach SILGenFunction::emitLoad that clients allowing +0 results don't need the load (and temporary, and cleanup) to actually be emitted for address-only operands. They can just use the physical lvalue as the +0 base. In this example: struct GenericStruct<T> { var a : T var b : Int func getA() -> T { return a } func getB() -> Int { return b } } we used to produce: sil @_TFV2t213GenericStruct4getAU__fGS0_Q__FT_Q_ : $@cc(method) @thin <$T_0_0> (@out $T_0_0, @in GenericStruct<$T_0_0>) -> () { bb0(%0 : $*T, %1 : $*GenericStruct<T>): debug_value_addr %1 : $*GenericStruct<T> // let self // id: %2 %3 = alloc_stack $GenericStruct<T> // users: %8, %7, %5, %4 copy_addr %1 to [initialization] %3#1 : $*GenericStruct<T> // id: %4 %5 = struct_element_addr %3#1 : $*GenericStruct<T>, #a // user: %6 copy_addr %5 to [initialization] %0 : $*T // id: %6 destroy_addr %3#1 : $*GenericStruct<T> // id: %7 dealloc_stack %3#0 : $*@local_storage GenericStruct<T> // id: %8 destroy_addr %1 : $*GenericStruct<T> // id: %9 %10 = tuple () // user: %11 return %10 : $() // id: %11 } sil @_TFV2t213GenericStruct4getBU__fGS0_Q__FT_Si : $@cc(method) @thin <$T_0_0> (@in GenericStruct<$T_0_0>) -> Int64 { bb0(%0 : $*GenericStruct<T>): debug_value_addr %0 : $*GenericStruct<T> // let self // id: %1 %2 = alloc_stack $GenericStruct<T> // users: %7, %6, %4, %3 copy_addr %0 to [initialization] %2#1 : $*GenericStruct<T> // id: %3 %4 = struct_element_addr %2#1 : $*GenericStruct<T>, #b // user: %5 %5 = load %4 : $*Int64 // user: %9 destroy_addr %2#1 : $*GenericStruct<T> // id: %6 dealloc_stack %2#0 : $*@local_storage GenericStruct<T> // id: %7 destroy_addr %0 : $*GenericStruct<T> // id: %8 return %5 : $Int64 // id: %9 } now we produce: sil @_TFV2t213GenericStruct4getAU__fGS0_Q__FT_Q_ : $@cc(method) @thin <$T_0_0> (@out $T_0_0, @in GenericStruct<$T_0_0>) -> () { bb0(%0 : $*T, %1 : $*GenericStruct<T>): debug_value_addr %1 : $*GenericStruct<T> // let self // id: %2 %3 = struct_element_addr %1 : $*GenericStruct<T>, #a // user: %4 copy_addr %3 to [initialization] %0 : $*T // id: %4 destroy_addr %1 : $*GenericStruct<T> // id: %5 %6 = tuple () // user: %7 return %6 : $() // id: %7 } sil @_TFV2t213GenericStruct4getBU__fGS0_Q__FT_Si : $@cc(method) @thin <$T_0_0> (@in GenericStruct<$T_0_0>) -> Int64 { bb0(%0 : $*GenericStruct<T>): debug_value_addr %0 : $*GenericStruct<T> // let self // id: %1 %2 = struct_element_addr %0 : $*GenericStruct<T>, #b // user: %3 %3 = load %2 : $*Int64 // user: %5 destroy_addr %0 : $*GenericStruct<T> // id: %4 return %3 : $Int64 // id: %5 } This cuts about 120 lines out of the stdlib (so, about 40 temporaries). Swift SVN r12871