Skip to content

Commit

Permalink
fix bug with return types
Browse files Browse the repository at this point in the history
  • Loading branch information
oflatt committed Oct 30, 2024
1 parent b0e91a2 commit 5832cb7
Showing 1 changed file with 30 additions and 7 deletions.
37 changes: 30 additions & 7 deletions bril-rs/brillvm/src/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,19 @@ impl<'a, 'b> Heap<'a, 'b> {
name: &'b String,
ty: &Type,
) -> WrappedPointer<'a> {
self.map
let result = self
.map
.entry(name)
.or_insert_with(|| WrappedPointer::new(builder, context, name, ty))
.clone()
.clone();
if result.ty != *ty {
println!(
"`{}` had type `{}` but is now being assigned type `{}`",
name, result.ty, ty
);
unimplemented!("brillvm does not currently support variables within a function having different types. Implementing this might require a control flow analysis? Feel free to try and implement this.")
}
result
}

fn get(&self, name: &String) -> WrappedPointer<'a> {
Expand Down Expand Up @@ -1483,7 +1492,7 @@ pub fn create_module_from_program<'a>(
}
});

(llvm_func, instrs, block, heap)
(llvm_func, instrs, block, heap, return_type)
},
)
.collect(); // Important to collect, can't be done lazily because we need all functions to be loaded in before a call instruction of a function is processed.
Expand All @@ -1493,9 +1502,13 @@ pub fn create_module_from_program<'a>(
let mut ticks_start_ref = None;
funcs
.into_iter()
.for_each(|(llvm_func, instrs, mut block, heap)| {
.for_each(|(llvm_func, instrs, mut block, heap, return_type)| {
let mut last_instr = None;

// Maps labels to llvm blocks for jumps
let mut block_map = HashMap::new();


// If there are actually instructions, proceed
if !instrs.is_empty() {
builder.position_at_end(block);
Expand Down Expand Up @@ -1525,8 +1538,6 @@ pub fn create_module_from_program<'a>(
func.add_attribute(AttributeLoc::Function, context.create_enum_attribute(3, 1));*/
}

// Maps labels to llvm blocks for jumps
let mut block_map = HashMap::new();
let mut index = 0;
while index < instrs.len() {
// for main, we expect the last instruction to be a print
Expand Down Expand Up @@ -1687,7 +1698,19 @@ pub fn create_module_from_program<'a>(

// Make sure every function is terminated with a return if not already
if !is_terminating_instr(&last_instr) {
builder.build_return(None).unwrap();
if return_type.is_none() {
builder.build_return(None).unwrap();
} else {
// This block did not have a terminating instruction
// Returning void is ill-typed for this function
// This code should be unreachable in well-formed Bril
// Let's just arbitrarily jump to avoid needing to
// instantiate a valid return value.
assert!(!block_map.is_empty());
builder
.build_unconditional_branch(*block_map.values().next().unwrap())
.unwrap();
}
}
});

Expand Down

0 comments on commit 5832cb7

Please sign in to comment.