Add a block garbage-collector that will delete an unused block at end

This commit is contained in:
Sofia 2025-07-09 21:57:48 +03:00
parent d757ac4eb3
commit 94c4ec0613
6 changed files with 88 additions and 16 deletions

View File

@ -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 {

View File

@ -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);

View File

@ -32,7 +32,11 @@ 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))
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()

View File

@ -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<TerminatorKind>,
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
}

View File

@ -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);
}
}

View File

@ -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,7 +300,7 @@ impl mir::Block {
}
if let Some((kind, expr)) = &self.return_expression {
let ret = expr.codegen(&mut scope).unwrap();
if let Some(ret) = expr.codegen(&mut scope) {
match kind {
mir::ReturnKind::Hard => {
scope.block.terminate(Term::Ret(ret)).unwrap();
@ -309,6 +311,9 @@ impl mir::Block {
} else {
None
}
} else {
None
}
}
}