For example, see how switching from a concrete to a generic type increases the size of clone() by 4x: https://rust.godbolt.org/z/qbYr3v
This is because at the point the compiler synthesizes clone() it has less information about the type.
For example, see how switching from a concrete to a generic type increases the size of clone() by 4x: https://rust.godbolt.org/z/qbYr3v
This is because at the point the compiler synthesizes clone() it has less information about the type.
It's a bit of a chicken-and-egg problem. To monomorphize clone(), someone must emit an implementation first. But an optimal implementation requires analyses that aren't available until later in the pipeline. Here the optimization kicks in for types deriving Copy, but a generic parameter is enough to defeat it.
I'd be interested in an example where LLVM can't optimize the general version, as it means we might want to do this through MIR shims instead (which can be generated when collecting the monomorphic instances to codegen - this is what happens when you clone a tuple or closure, for example).
The link you provide shows only one function, because LLVM has optimized both to be identical, and deduplicated them.
(If you disable the "Directives" filter, you can see a `.set example::clone_concrete, example::clone_abstract`, which aliases one to the other)
The output with 1.45.2 is as follows:
example::clone_concrete:
mov eax, edi
ret
example::clone_abstract:
mov ecx, edi
and ecx, -256
xor eax, eax
xor edx, edx
cmp dil, 1
sete dl
cmove eax, ecx
or eax, edx
ret