Add a block garbage-collector that will delete an unused block at end
This commit is contained in:
parent
d757ac4eb3
commit
94c4ec0613
@ -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)]
|
#[allow(dead_code)]
|
||||||
pub(crate) unsafe fn module_data(&self, value: &ModuleValue) -> ModuleData {
|
pub(crate) unsafe fn module_data(&self, value: &ModuleValue) -> ModuleData {
|
||||||
unsafe { self.modules.borrow().get_unchecked(value.0).data.clone() }
|
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 {
|
impl InstructionValue {
|
||||||
|
@ -205,6 +205,10 @@ impl FunctionHolder {
|
|||||||
let own_function = *module.functions.get(&self.value).unwrap();
|
let own_function = *module.functions.get(&self.value).unwrap();
|
||||||
|
|
||||||
for block in &self.blocks {
|
for block in &self.blocks {
|
||||||
|
if block.data.deleted {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let block_ref = LLVMCreateBasicBlockInContext(
|
let block_ref = LLVMCreateBasicBlockInContext(
|
||||||
module.context_ref,
|
module.context_ref,
|
||||||
into_cstring(&self.data.name).as_ptr(),
|
into_cstring(&self.data.name).as_ptr(),
|
||||||
@ -223,6 +227,10 @@ impl FunctionHolder {
|
|||||||
impl BlockHolder {
|
impl BlockHolder {
|
||||||
unsafe fn compile(&self, module: &mut LLVMModule, function: &LLVMFunction) {
|
unsafe fn compile(&self, module: &mut LLVMModule, function: &LLVMFunction) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
if self.data.deleted {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let block_ref = *module.blocks.get(&self.value).unwrap();
|
let block_ref = *module.blocks.get(&self.value).unwrap();
|
||||||
LLVMPositionBuilderAtEnd(module.builder_ref, block_ref);
|
LLVMPositionBuilderAtEnd(module.builder_ref, block_ref);
|
||||||
|
|
||||||
|
@ -32,10 +32,14 @@ impl Debug for FunctionHolder {
|
|||||||
|
|
||||||
impl Debug for BlockHolder {
|
impl Debug for BlockHolder {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
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 { "" };
|
||||||
.field(&self.instructions)
|
f.debug_tuple(&format!(
|
||||||
.field(&self.data.terminator)
|
"{}[{:?}]{} ",
|
||||||
.finish()
|
&self.data.name, &self.value, deleted
|
||||||
|
))
|
||||||
|
.field(&self.instructions)
|
||||||
|
.field(&self.data.terminator)
|
||||||
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@ impl<'ctx> Function<'ctx> {
|
|||||||
BlockData {
|
BlockData {
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
terminator: None,
|
terminator: None,
|
||||||
|
deleted: false,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -110,6 +111,7 @@ impl<'ctx> Function<'ctx> {
|
|||||||
pub struct BlockData {
|
pub struct BlockData {
|
||||||
name: String,
|
name: String,
|
||||||
terminator: Option<TerminatorKind>,
|
terminator: Option<TerminatorKind>,
|
||||||
|
deleted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Block<'builder> {
|
pub struct Block<'builder> {
|
||||||
@ -130,6 +132,16 @@ impl<'builder> Block<'builder> {
|
|||||||
unsafe { self.builder.terminate(&self.value, instruction) }
|
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 {
|
pub fn value(&self) -> BlockValue {
|
||||||
self.value
|
self.value
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
// Main
|
// Main
|
||||||
fn main() -> bool {
|
fn main() -> bool {
|
||||||
return (5 == fibonacci(5)) && false;
|
return 5 == fibonacci(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fibonacci
|
// Fibonacci
|
||||||
fn fibonacci(value: u16) -> u16 {
|
fn fibonacci(value: u16) -> u16 {
|
||||||
let ret = if value <= 2 {
|
if value <= 2 {
|
||||||
1
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
fibonacci(value - 1) + fibonacci(value - 2)
|
return fibonacci(value - 1) + fibonacci(value - 2);
|
||||||
};
|
}
|
||||||
ret
|
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,8 @@ impl mir::Module {
|
|||||||
mir::FunctionDefinitionKind::Local(block, _) => {
|
mir::FunctionDefinitionKind::Local(block, _) => {
|
||||||
if let Some(ret) = block.codegen(&mut scope) {
|
if let Some(ret) = block.codegen(&mut scope) {
|
||||||
scope.block.terminate(Term::Ret(ret)).unwrap();
|
scope.block.terminate(Term::Ret(ret)).unwrap();
|
||||||
|
} else {
|
||||||
|
scope.block.delete_if_unused().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::FunctionDefinitionKind::Extern => {}
|
mir::FunctionDefinitionKind::Extern => {}
|
||||||
@ -298,13 +300,16 @@ impl mir::Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some((kind, expr)) = &self.return_expression {
|
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 {
|
match kind {
|
||||||
mir::ReturnKind::Hard => {
|
mir::ReturnKind::Hard => {
|
||||||
scope.block.terminate(Term::Ret(ret)).unwrap();
|
scope.block.terminate(Term::Ret(ret)).unwrap();
|
||||||
None
|
None
|
||||||
|
}
|
||||||
|
mir::ReturnKind::Soft => Some(ret),
|
||||||
}
|
}
|
||||||
mir::ReturnKind::Soft => Some(ret),
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
Loading…
Reference in New Issue
Block a user