Optimize access to struct fields when converting index to struct field
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.2k
- PR merge metrics
- PR metrics pending
Description
The following code converts an index integer into a struct field:
pub struct X {
a: u64,
b: u64,
c: u64,
d: u64,
e: u64,
f: u64,
}
impl X {
pub fn from_ix(&mut self, v: u64, ix: usize) {
match ix {
0 => self.a = v,
1 => self.b = v,
2 => self.c = v,
3 => self.d = v,
4 => self.e = v,
5 => self.f = v,
_ => unreachable!(),
}
}
}
Because the fields are ordered the same as the integers, one would expect this to be optimized into an array-like write. e.g. <X as array>[ix] = v. Instead, it generates redundant code like the following:
playground::X::from_ix:
cmp rdx, 5
ja .LBB0_2
lea rax, [rip + .LJTI0_0]
movsxd rcx, dword ptr [rax + 4*rdx]
add rcx, rax
jmp rcx
.LBB0_3:
add rdi, 8
mov qword ptr [rdi], rsi
ret
.LBB0_4:
add rdi, 16
mov qword ptr [rdi], rsi
ret
.LBB0_5:
add rdi, 24
mov qword ptr [rdi], rsi
ret
.LBB0_6:
add rdi, 32
mov qword ptr [rdi], rsi
ret
.LBB0_7:
add rdi, 40
.LBB0_8:
mov qword ptr [rdi], rsi
ret
Rust 1.74 on Intel, Debian 12
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the linked Rust Playground example with Rust 1.74 or a current compiler, then inspect the generated assembly for the indexed struct-field write. Trace the relevant compiler optimization path to determine why equivalent field offsets are not combined; done means the example generates the expected array-like access and has regression coverage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100