From 94c4ec061300fc8f25e2f74b752371cbcec2c84a Mon Sep 17 00:00:00 2001 From: sofia Date: Wed, 9 Jul 2025 21:57:48 +0300 Subject: [PATCH] Add a block garbage-collector that will delete an unused block at end --- reid-llvm-lib/src/builder.rs | 44 +++++++++++++++++++++++++++++++ reid-llvm-lib/src/compile.rs | 8 ++++++ reid-llvm-lib/src/debug.rs | 12 ++++++--- reid-llvm-lib/src/lib.rs | 12 +++++++++ reid/examples/reid/fibonacci.reid | 11 ++++---- reid/src/codegen.rs | 17 +++++++----- 6 files changed, 88 insertions(+), 16 deletions(-) diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index d6819fd..40634c9 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -143,6 +143,17 @@ impl Builder { } } + pub(crate) unsafe fn delete_block(&self, block: &BlockValue) -> Result<(), ()> { + unsafe { + let mut modules = self.modules.borrow_mut(); + let module = modules.get_unchecked_mut(block.0.0.0); + let function = module.functions.get_unchecked_mut(block.0.1); + let block = function.blocks.get_unchecked_mut(block.1); + block.data.deleted = true; + Ok(()) + } + } + #[allow(dead_code)] pub(crate) unsafe fn module_data(&self, value: &ModuleValue) -> ModuleData { unsafe { self.modules.borrow().get_unchecked(value.0).data.clone() } @@ -242,6 +253,39 @@ impl Builder { } } } + + pub fn is_block_used(&self, block_v: BlockValue) -> bool { + unsafe { + let modules = self.modules.borrow(); + let module = modules.get_unchecked(block_v.0.0.0); + let function = module.functions.get_unchecked(block_v.0.1); + let block = function.blocks.get_unchecked(block_v.1); + + if block.instructions.len() > 0 || block.data.terminator.is_some() { + return true; + } + + for other in &function.blocks { + if let Some(term) = &other.data.terminator { + match term { + TerminatorKind::Ret(_) => {} + TerminatorKind::Br(other_val) => { + if other_val == &block_v { + return true; + } + } + TerminatorKind::CondBr(_, then_other_v, else_other_v) => { + if then_other_v == &block_v || else_other_v == &block_v { + return true; + } + } + } + } + } + + false + } + } } impl InstructionValue { diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index c034402..e42e477 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -205,6 +205,10 @@ impl FunctionHolder { let own_function = *module.functions.get(&self.value).unwrap(); for block in &self.blocks { + if block.data.deleted { + continue; + } + let block_ref = LLVMCreateBasicBlockInContext( module.context_ref, into_cstring(&self.data.name).as_ptr(), @@ -223,6 +227,10 @@ impl FunctionHolder { impl BlockHolder { unsafe fn compile(&self, module: &mut LLVMModule, function: &LLVMFunction) { unsafe { + if self.data.deleted { + return; + } + let block_ref = *module.blocks.get(&self.value).unwrap(); LLVMPositionBuilderAtEnd(module.builder_ref, block_ref); diff --git a/reid-llvm-lib/src/debug.rs b/reid-llvm-lib/src/debug.rs index 9dd86ab..cb9dbf5 100644 --- a/reid-llvm-lib/src/debug.rs +++ b/reid-llvm-lib/src/debug.rs @@ -32,10 +32,14 @@ impl Debug for FunctionHolder { impl Debug for BlockHolder { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple(&format!("{}[{:?}]", &self.data.name, &self.value)) - .field(&self.instructions) - .field(&self.data.terminator) - .finish() + let deleted = if self.data.deleted { " (deleted)" } else { "" }; + f.debug_tuple(&format!( + "{}[{:?}]{} ", + &self.data.name, &self.value, deleted + )) + .field(&self.instructions) + .field(&self.data.terminator) + .finish() } } diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index af9e135..01a8398 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -95,6 +95,7 @@ impl<'ctx> Function<'ctx> { BlockData { name: name.to_owned(), terminator: None, + deleted: false, }, ), } @@ -110,6 +111,7 @@ impl<'ctx> Function<'ctx> { pub struct BlockData { name: String, terminator: Option, + deleted: bool, } pub struct Block<'builder> { @@ -130,6 +132,16 @@ impl<'builder> Block<'builder> { unsafe { self.builder.terminate(&self.value, instruction) } } + pub fn delete_if_unused(&mut self) -> Result<(), ()> { + unsafe { + if !self.builder.is_block_used(self.value()) { + self.builder.delete_block(&self.value) + } else { + Ok(()) + } + } + } + pub fn value(&self) -> BlockValue { self.value } diff --git a/reid/examples/reid/fibonacci.reid b/reid/examples/reid/fibonacci.reid index d3a3034..9eb4150 100644 --- a/reid/examples/reid/fibonacci.reid +++ b/reid/examples/reid/fibonacci.reid @@ -1,14 +1,13 @@ // Main fn main() -> bool { - return (5 == fibonacci(5)) && false; + return 5 == fibonacci(5); } // Fibonacci fn fibonacci(value: u16) -> u16 { - let ret = if value <= 2 { - 1 + if value <= 2 { + return 1; } else { - fibonacci(value - 1) + fibonacci(value - 2) - }; - ret + return fibonacci(value - 1) + fibonacci(value - 2); + } } diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index f0e62ba..558106f 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -89,6 +89,8 @@ impl mir::Module { mir::FunctionDefinitionKind::Local(block, _) => { if let Some(ret) = block.codegen(&mut scope) { scope.block.terminate(Term::Ret(ret)).unwrap(); + } else { + scope.block.delete_if_unused().unwrap(); } } mir::FunctionDefinitionKind::Extern => {} @@ -298,13 +300,16 @@ impl mir::Block { } if let Some((kind, expr)) = &self.return_expression { - let ret = expr.codegen(&mut scope).unwrap(); - match kind { - mir::ReturnKind::Hard => { - scope.block.terminate(Term::Ret(ret)).unwrap(); - None + if let Some(ret) = expr.codegen(&mut scope) { + match kind { + mir::ReturnKind::Hard => { + scope.block.terminate(Term::Ret(ret)).unwrap(); + None + } + mir::ReturnKind::Soft => Some(ret), } - mir::ReturnKind::Soft => Some(ret), + } else { + None } } else { None