Improve stack allocation code

This commit is contained in:
Brian Carroll 2021-09-29 21:19:57 +01:00
parent f1b14c14e3
commit 79ac2f04b8

View file

@ -160,8 +160,7 @@ impl<'a> WasmBackend<'a> {
symbol: Symbol, symbol: Symbol,
kind: LocalKind, kind: LocalKind,
) -> SymbolStorage { ) -> SymbolStorage {
let local_index = (self.arg_types.len() + self.locals.len()) as u32; let local_id = LocalId((self.arg_types.len() + self.locals.len()) as u32);
let local_id = LocalId(local_index);
let storage = match kind { let storage = match kind {
LocalKind::Parameter => { LocalKind::Parameter => {
@ -208,20 +207,28 @@ impl<'a> WasmBackend<'a> {
} => { } => {
let offset = let offset =
round_up_to_alignment(self.stack_memory, alignment_bytes as i32); round_up_to_alignment(self.stack_memory, alignment_bytes as i32);
self.stack_memory = offset + size as i32; self.stack_memory = offset + size as i32;
// TODO: if we're creating the frame pointer just reuse the same local_id! match self.stack_frame_pointer {
let frame_pointer = self.get_or_create_frame_pointer(); None => {
// This is the first stack-memory variable in the function
// That means we can reuse it as the stack frame pointer,
// and it will get initialised at the start of the function
self.stack_frame_pointer = Some(local_id);
}
// initialise the local with the appropriate address Some(frame_ptr_id) => {
// TODO: skip this the first time, no point generating code to add zero offset! // This local points to the base of a struct, at an offset from the stack frame pointer
self.instructions.extend([ // Having one local per variable means params and locals work the same way in code gen.
GetLocal(frame_pointer.0), // (alternatively we could use one frame pointer + offset for all struct variables)
I32Const(offset), self.instructions.extend([
I32Add, GetLocal(frame_ptr_id.0),
SetLocal(local_index), I32Const(offset),
]); I32Add,
SetLocal(local_id.0),
]);
}
};
SymbolStorage::VarStackMemory { SymbolStorage::VarStackMemory {
local_id, local_id,
@ -239,19 +246,6 @@ impl<'a> WasmBackend<'a> {
storage storage
} }
fn get_or_create_frame_pointer(&mut self) -> LocalId {
match self.stack_frame_pointer {
Some(local_id) => local_id,
None => {
let local_index = (self.arg_types.len() + self.locals.len()) as u32;
let local_id = LocalId(local_index);
self.stack_frame_pointer = Some(local_id);
self.locals.push(Local::new(1, ValueType::I32));
local_id
}
}
}
fn get_symbol_storage(&self, sym: &Symbol) -> Result<&SymbolStorage, String> { fn get_symbol_storage(&self, sym: &Symbol) -> Result<&SymbolStorage, String> {
self.symbol_storage_map.get(sym).ok_or_else(|| { self.symbol_storage_map.get(sym).ok_or_else(|| {
format!( format!(