-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-codegenArea: Code generationArea: Code generationC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.I-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
For this Rust code, we get some pretty bad assembly:
#[derive(Clone)]
pub enum Foo {
A(u8),
B(bool),
}
#[derive(Clone)]
pub enum Bar {
C(Foo),
D(u8),
}
pub fn clone_foo(f: &Foo) -> Foo {
f.clone()
}
pub fn clone_bar(b: &Bar) -> Bar {
b.clone()
}
Assembly:
playground::clone_bar:
movb 1(%rdi), %al
cmpb $1, (%rdi)
jne .LBB1_2
xorl %ecx, %ecx
movl $1, %edx
jmp .LBB1_3
.LBB1_2:
movzbl 2(%rdi), %edx
xorl %ecx, %ecx
testb %dl, %dl
setne %cl
cmpb $1, %al
sete %al
cmovnel %edx, %ecx
shll $16, %ecx
xorl %edx, %edx
.LBB1_3:
orl %edx, %ecx
movzbl %al, %eax
shll $8, %eax
orl %ecx, %eax
retq
To see that it's possibly to do better, we can simply add a Copy
instance to the types. Then the code even for Clone
gets much better:
#[derive(Clone, Copy)]
pub enum Foo {
A(u8),
B(bool),
}
#[derive(Clone, Copy)]
pub enum Bar {
C(Foo),
D(u8),
}
pub fn clone_foo(f: &Foo) -> Foo {
f.clone()
}
pub fn clone_bar(b: &Bar) -> Bar {
b.clone()
}
Assembly:
playground::clone_bar:
movzwl (%rdi), %ecx
movzbl 2(%rdi), %eax
shll $16, %eax
orl %ecx, %eax
retq
It's still not perfect (why are there two 2-byte loads instead of a single 4-byte load?) but it's much better.
Metadata
Metadata
Assignees
Labels
A-codegenArea: Code generationArea: Code generationC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.I-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.