I've been studying the cranelift and rustc_codegen_cranelift sources to see if and how stack space is optimized, for use in a toy compiler I'm writing, but it's possible the code I'm looking for just doesn't exist, so some pointers would be helpful. Basically, if two local variables exist with disjoint live ranges, then they can share a stack slot. This is done for registers, of course, as well as for "virtual registers" which covers most small variables, but for anything that requires an explicit stack slot, like arrays (not sure if small arrays like let x: [u8; 8];
will create a stack slot or be placed in a virtual register), the codegen just creates a StackSlotKind::ExplicitSlot
using create_stack_slot
, and layout_stack()
in cranelift doesn't seem to be doing (or even have access to) any live range analysis on the stack slots, so it just puts them in new slots. That would mean that code like this would seem like it would take up a large amount of stack space:
fn foo() -> [u8; 9] { [0; 9] }
fn bar() {
let _ = foo();
let _ = foo();
let _ = foo();
let _ = foo();
let _ = foo();
let _ = foo();
}
Could someone confirm if this is in fact how stack allocation works, and I haven't missed something in an earlier optimization that would cause reuse?
Last updated: Nov 22 2024 at 17:03 UTC