-
Notifications
You must be signed in to change notification settings - Fork 315
Description
Problem
Even after being updated to handle aliases within arrays (in an experimental branch), the mem2reg pass still fails to fully remove all loads and stores from the following code:
fn main() {
let mut var = 0;
let ref = &mut &mut var;
let mut array = [ref, ref];
**array[0] = 1;
**array[1] = 2;
assert(var == 2);
assert(**ref == 2);
assert(**array[0] == 2);
assert(**array[1] == 2);
}
This is because when optimizing out references stored in arrays, mem2reg can only do one step at a time. That is, it can optimize until it finds a v3 = array_get [v1, v2], index 1
. It cannot see which reference is returned until the constant folding pass is done, so it counts v3
as opaque which prevents further optimizations on it.
The problem occurs when v3
is later loaded/stored to. We now need another mem2reg pass after the constant folding pass. Then, if there are more gets/sets to the array we'd need another constant folding pass and so on. Each time we run an entire pass, only 1 additional step of this will be optimized each time.
Happy Case
We should apply instruction simplifications while running the mem2reg pass, like we do with most other optimization passes. This would enable the pass to optimize the code in the snippet in one run without the need of another mem2reg pass or even a constant folding pass after.
Alternatives Considered
No response
Additional Context
No response
Would you like to submit a PR for this Issue?
No
Support Needs
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Status