mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
gen_wasm: Get rid of individual locals for values in stack memory
All values in stack memory can share the stack frame pointer, with different offsets. This avoids having to generate initialisation code for individual pointers we used to have. It should also make things more efficient when the runtime compiles Wasm to machine code. It can just assign the stack frame pointer to a single CPU register and leave it there. The original idea was to make params and local variables work the same. (A struct param will be passed as a pointer to caller stack memory.) But now I don't think that's worth it. Some match expressions get more awkward this way but we might be able to refactor that to be nicer.
This commit is contained in:
parent
4aa2452e01
commit
ffa6ff0a62
3 changed files with 134 additions and 97 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::{copy_memory, LocalId, ALIGN_1, ALIGN_2, ALIGN_4, ALIGN_8};
|
||||
use crate::{LocalId, MemoryCopy, ALIGN_1, ALIGN_2, ALIGN_4, ALIGN_8};
|
||||
use parity_wasm::elements::{Instruction, Instruction::*, ValueType};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -14,7 +14,6 @@ pub enum SymbolStorage {
|
|||
size: u32,
|
||||
},
|
||||
VarStackMemory {
|
||||
local_id: LocalId,
|
||||
size: u32,
|
||||
offset: u32,
|
||||
alignment_bytes: u32,
|
||||
|
@ -30,12 +29,12 @@ pub enum SymbolStorage {
|
|||
}
|
||||
|
||||
impl SymbolStorage {
|
||||
pub fn local_id(&self) -> LocalId {
|
||||
pub fn local_id(&self, stack_frame_pointer: Option<LocalId>) -> LocalId {
|
||||
match self {
|
||||
Self::ParamPrimitive { local_id, .. } => *local_id,
|
||||
Self::ParamStackMemory { local_id, .. } => *local_id,
|
||||
Self::VarPrimitive { local_id, .. } => *local_id,
|
||||
Self::VarStackMemory { local_id, .. } => *local_id,
|
||||
Self::VarStackMemory { .. } => stack_frame_pointer.unwrap(),
|
||||
Self::VarHeapMemory { local_id, .. } => *local_id,
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +59,16 @@ impl SymbolStorage {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn address_offset(&self) -> Option<u32> {
|
||||
match self {
|
||||
Self::ParamStackMemory { .. } => Some(0),
|
||||
Self::VarStackMemory { offset, .. } => Some(*offset),
|
||||
Self::ParamPrimitive { .. } => None,
|
||||
Self::VarPrimitive { .. } => None,
|
||||
Self::VarHeapMemory { .. } => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stack_size_and_alignment(&self) -> (u32, u32) {
|
||||
match self {
|
||||
Self::VarStackMemory {
|
||||
|
@ -82,6 +91,7 @@ impl SymbolStorage {
|
|||
instructions: &mut Vec<Instruction>,
|
||||
to_pointer: LocalId,
|
||||
to_offset: u32,
|
||||
stack_frame_pointer: Option<LocalId>,
|
||||
) -> u32 {
|
||||
match self {
|
||||
Self::ParamPrimitive {
|
||||
|
@ -117,21 +127,34 @@ impl SymbolStorage {
|
|||
local_id,
|
||||
size,
|
||||
alignment_bytes,
|
||||
} => {
|
||||
let copy = MemoryCopy {
|
||||
from_ptr: *local_id,
|
||||
from_offset: 0,
|
||||
to_ptr: to_pointer,
|
||||
to_offset,
|
||||
size: *size,
|
||||
alignment_bytes: *alignment_bytes,
|
||||
};
|
||||
copy.generate(instructions);
|
||||
*size
|
||||
}
|
||||
| Self::VarStackMemory {
|
||||
local_id,
|
||||
|
||||
Self::VarStackMemory {
|
||||
size,
|
||||
alignment_bytes,
|
||||
offset,
|
||||
..
|
||||
} => {
|
||||
copy_memory(
|
||||
instructions,
|
||||
*local_id,
|
||||
to_pointer,
|
||||
*size,
|
||||
*alignment_bytes,
|
||||
let copy = MemoryCopy {
|
||||
from_ptr: stack_frame_pointer.unwrap(),
|
||||
from_offset: *offset,
|
||||
to_ptr: to_pointer,
|
||||
to_offset,
|
||||
);
|
||||
size: *size,
|
||||
alignment_bytes: *alignment_bytes,
|
||||
};
|
||||
copy.generate(instructions);
|
||||
*size
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue