From d28cb6b0e3d36a3980b70f3545df5a44c8bca074 Mon Sep 17 00:00:00 2001 From: lenawanel Date: Sun, 16 Jun 2024 08:48:41 +0200 Subject: [PATCH 1/2] inline small memcpys --- crates/codegen/src/compiler/functions.rs | 94 +++++++++++++++++------- 1 file changed, 66 insertions(+), 28 deletions(-) diff --git a/crates/codegen/src/compiler/functions.rs b/crates/codegen/src/compiler/functions.rs index d37abc4..68199d5 100644 --- a/crates/codegen/src/compiler/functions.rs +++ b/crates/codegen/src/compiler/functions.rs @@ -29,6 +29,8 @@ use super::{ MetaTyLayoutArrays, }; +const MEMCPY_THREASHOLD: u64 = 64; + struct UnfinishedComptimeErr; // represents a single block containing multiple defer statements @@ -134,10 +136,27 @@ impl FunctionCompiler<'_> { let stack_slot_addr = self.builder.ins().stack_addr(self.ptr_ty, stack_slot, 0); - let size = self.builder.ins().iconst(self.ptr_ty, size as i64); + if size > 32 { + let size = self.builder.ins().iconst(self.ptr_ty, size as i64); - self.builder - .call_memcpy(self.module.target_config(), stack_slot_addr, value, size); + self.builder.call_memcpy( + self.module.target_config(), + stack_slot_addr, + value, + size, + ) + } else { + self.builder.emit_small_memory_copy( + self.module.target_config(), + stack_slot_addr, + value, + param_ty.stride() as u64, + param_ty.align() as u8, + param_ty.align() as u8, + true, + MemFlags::trusted(), + ) + } self.builder.def_var(var, stack_slot_addr); } else { @@ -151,19 +170,7 @@ impl FunctionCompiler<'_> { Some(body) => { if return_ty.is_aggregate() { let dest = self.builder.use_var(dest_param.unwrap()); - - let aggregate_size = return_ty.size(); - let aggregate_size = self - .builder - .ins() - .iconst(self.ptr_ty, aggregate_size as i64); - - self.builder.call_memcpy( - self.module.target_config(), - dest, - body, - aggregate_size, - ); + self.build_memcpy_ty(body, dest, return_ty, true); self.builder.ins().return_(&[dest]) } else { @@ -471,6 +478,47 @@ impl FunctionCompiler<'_> { self.create_global_data(&name, false, text.into_bytes().into_boxed_slice(), 1) } + fn build_memcpy_ty(&mut self, src: Value, dest: Value, ty: Intern, non_overlapping: bool) { + let size = ty.size(); + if size > (MEMCPY_THREASHOLD as u32) { + let size = self.builder.ins().iconst(self.ptr_ty, size as i64); + + self.builder + .call_memcpy(self.module.target_config(), dest, src, size) + } else { + self.builder.emit_small_memory_copy( + self.module.target_config(), + dest, + src, + ty.stride() as u64, + ty.align() as u8, + ty.align() as u8, + non_overlapping, + MemFlags::trusted(), + ) + } + } + + fn build_memcpy_size(&mut self, src: Value, dest: Value, size: u64, non_overlapping: bool) { + if size > MEMCPY_THREASHOLD { + let size = self.builder.ins().iconst(self.ptr_ty, size as i64); + + self.builder + .call_memcpy(self.module.target_config(), dest, src, size) + } else { + self.builder.emit_small_memory_copy( + self.module.target_config(), + dest, + src, + size, + 1, + 1, + non_overlapping, + MemFlags::trusted(), + ) + } + } + fn get_func_id(&mut self, fqn: hir::Fqn) -> FuncId { super::get_func_id( self.module, @@ -754,10 +802,7 @@ impl FunctionCompiler<'_> { let offset = self.builder.ins().iconst(self.ptr_ty, offset as i64); let actual_addr = self.builder.ins().iadd(addr, offset); - let size = self.builder.ins().iconst(self.ptr_ty, expr_size as i64); - - self.builder - .call_memcpy(self.module.target_config(), actual_addr, value, size); + self.build_memcpy_size(value, actual_addr, expr_size as u64, false); } else { self.builder .ins() @@ -820,14 +865,7 @@ impl FunctionCompiler<'_> { let actual_addr = self.builder.ins().iadd(addr, offset); - let size = self.builder.ins().iconst(self.ptr_ty, expr_size as i64); - - self.builder.call_memcpy( - self.module.target_config(), - actual_addr, - far_off_thing, - size, - ) + self.build_memcpy_size(far_off_thing, actual_addr, expr_size as u64, false); } _ => { if let Some(value) = self.compile_and_cast(expr, expected_ty) { From f35d601fca97294ab461dc27b6d6b8c53506f045 Mon Sep 17 00:00:00 2001 From: lenawanel Date: Mon, 17 Jun 2024 00:00:12 +0200 Subject: [PATCH 2/2] simplify the logic performed --- crates/codegen/src/compiler/functions.rs | 88 ++++++++---------------- 1 file changed, 30 insertions(+), 58 deletions(-) diff --git a/crates/codegen/src/compiler/functions.rs b/crates/codegen/src/compiler/functions.rs index 68199d5..c3a2a37 100644 --- a/crates/codegen/src/compiler/functions.rs +++ b/crates/codegen/src/compiler/functions.rs @@ -29,8 +29,6 @@ use super::{ MetaTyLayoutArrays, }; -const MEMCPY_THREASHOLD: u64 = 64; - struct UnfinishedComptimeErr; // represents a single block containing multiple defer statements @@ -136,27 +134,16 @@ impl FunctionCompiler<'_> { let stack_slot_addr = self.builder.ins().stack_addr(self.ptr_ty, stack_slot, 0); - if size > 32 { - let size = self.builder.ins().iconst(self.ptr_ty, size as i64); - - self.builder.call_memcpy( - self.module.target_config(), - stack_slot_addr, - value, - size, - ) - } else { - self.builder.emit_small_memory_copy( - self.module.target_config(), - stack_slot_addr, - value, - param_ty.stride() as u64, - param_ty.align() as u8, - param_ty.align() as u8, - true, - MemFlags::trusted(), - ) - } + self.builder.emit_small_memory_copy( + self.module.target_config(), + stack_slot_addr, + value, + param_ty.stride() as u64, + param_ty.align() as u8, + param_ty.align() as u8, + true, + MemFlags::trusted(), + ); self.builder.def_var(var, stack_slot_addr); } else { @@ -479,44 +466,29 @@ impl FunctionCompiler<'_> { } fn build_memcpy_ty(&mut self, src: Value, dest: Value, ty: Intern, non_overlapping: bool) { - let size = ty.size(); - if size > (MEMCPY_THREASHOLD as u32) { - let size = self.builder.ins().iconst(self.ptr_ty, size as i64); - - self.builder - .call_memcpy(self.module.target_config(), dest, src, size) - } else { - self.builder.emit_small_memory_copy( - self.module.target_config(), - dest, - src, - ty.stride() as u64, - ty.align() as u8, - ty.align() as u8, - non_overlapping, - MemFlags::trusted(), - ) - } + self.builder.emit_small_memory_copy( + self.module.target_config(), + dest, + src, + ty.stride() as u64, + ty.align() as u8, + ty.align() as u8, + non_overlapping, + MemFlags::trusted(), + ) } fn build_memcpy_size(&mut self, src: Value, dest: Value, size: u64, non_overlapping: bool) { - if size > MEMCPY_THREASHOLD { - let size = self.builder.ins().iconst(self.ptr_ty, size as i64); - - self.builder - .call_memcpy(self.module.target_config(), dest, src, size) - } else { - self.builder.emit_small_memory_copy( - self.module.target_config(), - dest, - src, - size, - 1, - 1, - non_overlapping, - MemFlags::trusted(), - ) - } + self.builder.emit_small_memory_copy( + self.module.target_config(), + dest, + src, + size, + 1, + 1, + non_overlapping, + MemFlags::trusted(), + ) } fn get_func_id(&mut self, fqn: hir::Fqn) -> FuncId {