diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index 40634c9..04c366d 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -269,6 +269,7 @@ impl Builder { if let Some(term) = &other.data.terminator { match term { TerminatorKind::Ret(_) => {} + TerminatorKind::RetVoid => {} TerminatorKind::Br(other_val) => { if other_val == &block_v { return true; @@ -372,6 +373,7 @@ impl TerminatorKind { use TerminatorKind::*; match self { Ret(instr_val) => instr_val.get_type(builder), + RetVoid => Ok(Type::Void), Br(_) => Ok(Type::Void), CondBr(_, _, _) => Ok(Type::Void), } diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index e42e477..9a51167 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -356,6 +356,7 @@ impl TerminatorKind { let value = module.values.get(val).unwrap(); LLVMBuildRet(module.builder_ref, value.value_ref) } + TerminatorKind::RetVoid => LLVMBuildRetVoid(module.builder_ref), TerminatorKind::Br(block_value) => { let dest = *module.blocks.get(block_value).unwrap(); LLVMBuildBr(module.builder_ref, dest) diff --git a/reid-llvm-lib/src/debug.rs b/reid-llvm-lib/src/debug.rs index cb9dbf5..1592473 100644 --- a/reid-llvm-lib/src/debug.rs +++ b/reid-llvm-lib/src/debug.rs @@ -145,6 +145,7 @@ impl Debug for TerminatorKind { write!(f, "Ret ")?; val.fmt(f) } + Self::RetVoid => write!(f, "Void Ret"), Self::Br(val) => { write!(f, "Br ")?; val.fmt(f) diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 01a8398..b07826c 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -132,12 +132,14 @@ impl<'builder> Block<'builder> { unsafe { self.builder.terminate(&self.value, instruction) } } - pub fn delete_if_unused(&mut self) -> Result<(), ()> { + /// Delete block if it is unused. Return true if deleted, false if not. + pub fn delete_if_unused(&mut self) -> Result { unsafe { if !self.builder.is_block_used(self.value()) { - self.builder.delete_block(&self.value) + self.builder.delete_block(&self.value)?; + Ok(true) } else { - Ok(()) + Ok(false) } } } @@ -212,6 +214,7 @@ pub enum ConstValue { #[derive(Clone, Hash)] pub enum TerminatorKind { Ret(InstructionValue), + RetVoid, Br(BlockValue), CondBr(InstructionValue, BlockValue, BlockValue), } diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index 558106f..de56801 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -90,7 +90,11 @@ impl mir::Module { if let Some(ret) = block.codegen(&mut scope) { scope.block.terminate(Term::Ret(ret)).unwrap(); } else { - scope.block.delete_if_unused().unwrap(); + if !scope.block.delete_if_unused().unwrap() { + // Add a void return just in case if the block + // wasn't unused but didn't have a terminator yet + scope.block.terminate(Term::RetVoid).unwrap(); + } } } mir::FunctionDefinitionKind::Extern => {}