From 10b0357140361dd815d27376d32792c932fec8c5 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 5 Nov 2023 23:48:42 +0000 Subject: [PATCH] Trim load_symbols_for_call --- crates/compiler/gen_wasm/src/backend.rs | 2 - crates/compiler/gen_wasm/src/low_level.rs | 10 ---- crates/compiler/gen_wasm/src/storage.rs | 69 ++--------------------- 3 files changed, 4 insertions(+), 77 deletions(-) diff --git a/crates/compiler/gen_wasm/src/backend.rs b/crates/compiler/gen_wasm/src/backend.rs index 63440c108f..ff860931fa 100644 --- a/crates/compiler/gen_wasm/src/backend.rs +++ b/crates/compiler/gen_wasm/src/backend.rs @@ -1329,7 +1329,6 @@ impl<'a, 'r> WasmBackend<'a, 'r> { let name = foreign_symbol.as_str(); let wasm_layout = WasmLayout::new(self.layout_interner, *ret_layout); self.storage.load_symbols_for_call( - self.env.arena, &mut self.code_builder, arguments, ret_sym, @@ -1359,7 +1358,6 @@ impl<'a, 'r> WasmBackend<'a, 'r> { } self.storage.load_symbols_for_call( - self.env.arena, &mut self.code_builder, arguments, ret_sym, diff --git a/crates/compiler/gen_wasm/src/low_level.rs b/crates/compiler/gen_wasm/src/low_level.rs index 8edbfb5364..683fbd61c6 100644 --- a/crates/compiler/gen_wasm/src/low_level.rs +++ b/crates/compiler/gen_wasm/src/low_level.rs @@ -136,7 +136,6 @@ impl<'a> LowLevelCall<'a> { /// Result is the type signature of the call fn load_args(&self, backend: &mut WasmBackend<'a, '_>) { backend.storage.load_symbols_for_call( - backend.env.arena, &mut backend.code_builder, self.arguments, self.ret_symbol, @@ -248,7 +247,6 @@ impl<'a> LowLevelCall<'a> { // loads arg, start, count backend.storage.load_symbols_for_call( - backend.env.arena, &mut backend.code_builder, self.arguments, self.ret_symbol, @@ -470,7 +468,6 @@ impl<'a> LowLevelCall<'a> { // Load the arguments that have symbols backend.storage.load_symbols_for_call( - backend.env.arena, &mut backend.code_builder, self.arguments, self.ret_symbol, @@ -509,7 +506,6 @@ impl<'a> LowLevelCall<'a> { // return pointer and list backend.storage.load_symbols_for_call( - backend.env.arena, &mut backend.code_builder, &[list], self.ret_symbol, @@ -548,7 +544,6 @@ impl<'a> LowLevelCall<'a> { // return pointer and list backend.storage.load_symbols_for_call( - backend.env.arena, &mut backend.code_builder, &[list], self.ret_symbol, @@ -583,7 +578,6 @@ impl<'a> LowLevelCall<'a> { // return pointer and list backend.storage.load_symbols_for_call( - backend.env.arena, &mut backend.code_builder, &[list], self.ret_symbol, @@ -622,7 +616,6 @@ impl<'a> LowLevelCall<'a> { // return pointer and list backend.storage.load_symbols_for_call( - backend.env.arena, &mut backend.code_builder, &[list], self.ret_symbol, @@ -674,7 +667,6 @@ impl<'a> LowLevelCall<'a> { // dec: Dec, i32 backend.storage.load_symbols_for_call( - backend.env.arena, &mut backend.code_builder, &[list], self.ret_symbol, @@ -721,7 +713,6 @@ impl<'a> LowLevelCall<'a> { // Load the return pointer and the list backend.storage.load_symbols_for_call( - backend.env.arena, &mut backend.code_builder, &[list], self.ret_symbol, @@ -759,7 +750,6 @@ impl<'a> LowLevelCall<'a> { // Load the return pointer and the list backend.storage.load_symbols_for_call( - backend.env.arena, &mut backend.code_builder, &[list], self.ret_symbol, diff --git a/crates/compiler/gen_wasm/src/storage.rs b/crates/compiler/gen_wasm/src/storage.rs index 7e3ce8fc37..1276570363 100644 --- a/crates/compiler/gen_wasm/src/storage.rs +++ b/crates/compiler/gen_wasm/src/storage.rs @@ -49,25 +49,6 @@ pub enum StoredValue { }, } -impl StoredValue { - /// Value types to pass to Wasm functions - /// One Roc value can become 0, 1, or 2 Wasm arguments - pub fn arg_types(&self) -> &'static [ValueType] { - use ValueType::*; - match self { - // Simple numbers: 1 Roc argument => 1 Wasm argument - Self::Local { value_type, .. } => match value_type { - I32 => &[I32], - I64 => &[I64], - F32 => &[F32], - F64 => &[F64], - }, - // Stack memory values: 1 Roc argument => 0-2 Wasm arguments - Self::StackMemory { size, format, .. } => stack_memory_arg_types(*size, *format), - } - } -} - pub enum AddressValue { /// The address value has been loaded to the VM stack Loaded, @@ -150,14 +131,8 @@ impl<'a> Storage<'a> { /// Allocate storage for a Roc variable /// - /// Wasm primitives (i32, i64, f32, f64) are allocated "storage" on the VM stack. - /// This is really just a way to model how the stack machine works as a sort of - /// temporary storage. It doesn't result in any code generation. - /// For some values, this initial storage allocation may need to be upgraded later - /// to a Local. See `load_symbols`. - /// - /// Structs and Tags are stored in memory rather than in Wasm primitives. - /// They are allocated a certain offset and size in the stack frame. + /// Wasm primitives (i32, i64, f32, f64) are allocated local variables. + /// Data structures are stored in memory, with an offset and size in the stack frame. pub fn allocate_var( &mut self, interner: &STLayoutInterner<'a>, @@ -313,7 +288,6 @@ impl<'a> Storage<'a> { } /// Load a single symbol using the C Calling Convention - /// *Private* because external code should always load symbols in bulk (see load_symbols) fn load_symbol_ccc(&mut self, code_builder: &mut CodeBuilder, sym: Symbol) { let storage = self.get(&sym).to_owned(); match storage { @@ -382,8 +356,6 @@ impl<'a> Storage<'a> { } /// Load symbols to the top of the VM stack - /// Avoid calling this method in a loop with one symbol at a time! It will work, - /// but it generates very inefficient Wasm code. pub fn load_symbols(&mut self, code_builder: &mut CodeBuilder, symbols: &[Symbol]) { for sym in symbols.iter() { self.load_symbol_ccc(code_builder, *sym); @@ -393,51 +365,18 @@ impl<'a> Storage<'a> { /// Load symbols for a function call pub fn load_symbols_for_call( &mut self, - arena: &'a Bump, code_builder: &mut CodeBuilder, arguments: &[Symbol], return_symbol: Symbol, return_layout: &WasmLayout, - ) -> (usize, bool) { - use ReturnMethod::*; - - let mut num_wasm_args = 0; - let mut symbols_to_load = Vec::with_capacity_in(arguments.len() * 2 + 1, arena); - - let return_method = return_layout.return_method(); - let has_return_val = match return_method { - Primitive(..) => true, - NoReturnValue => false, - WriteToPointerArg => { - num_wasm_args += 1; - symbols_to_load.push(return_symbol); - false - } - }; - - for arg in arguments { - let stored = self.symbol_storage_map.get(arg).unwrap(); - let arg_types = stored.arg_types(); - num_wasm_args += arg_types.len(); - match arg_types.len() { - 0 => {} - 1 => symbols_to_load.push(*arg), - 2 => symbols_to_load.extend_from_slice(&[*arg, *arg]), - n => internal_error!("Cannot have {} Wasm arguments for 1 Roc argument", n), - } - } - - // If the symbols were already at the top of the stack, do nothing! - // Should be common for simple cases, due to the structure of the Mono IR - if matches!(return_method, WriteToPointerArg) { + ) { + if return_layout.return_method() == ReturnMethod::WriteToPointerArg { self.load_return_address_ccc(code_builder, return_symbol); }; for arg in arguments { self.load_symbol_ccc(code_builder, *arg); } - - (num_wasm_args, has_return_val) } /// Generate code to copy a StoredValue to an arbitrary memory location