diff --git a/src/main.rs b/src/main.rs index 36df734..e9e1b42 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,11 @@ use std::io; use ir::{ - builder::{GlobalValueBuilder, LocalBlockBuilder, LocalValueBuilder}, + builder::{ConstantBuilder, GlobalValueBuilder, LocalBlockBuilder, LocalValueBuilder}, module::Module, pass::GlobalPass, types::Type, + values::{BinaryOp, ICmpCond}, }; use passes::printer::Printer; @@ -13,31 +14,99 @@ pub mod ir; pub mod passes; fn main() -> io::Result<()> { - let mut module = Module::new("test".to_string()); - let function = module + let mut module = Module::new("fibonacci".to_string()); + + let fn_fib = module .builder() .function_def( - "test_func".to_string(), - Type::mk_function(vec![], Type::mk_void()), + "fib".to_string(), + Type::mk_function(vec![Type::mk_int(32)], Type::mk_int(32)), ) .unwrap(); - let function_data = module.function_data_mut(function).unwrap(); + let dfg = module.function_data_mut(fn_fib).unwrap().dfg_mut(); + + let entry_block_param = dfg.builder().block_param(Type::mk_int(32)).unwrap(); + let ret_block_param = dfg.builder().block_param(Type::mk_int(32)).unwrap(); + let else_block_param = dfg.builder().block_param(Type::mk_int(32)).unwrap(); + + let entry_block = dfg.builder().block(vec![entry_block_param.into()]).unwrap(); + let ret_block = dfg.builder().block(vec![ret_block_param.into()]).unwrap(); + let else_block = dfg.builder().block(vec![else_block_param]).unwrap(); + + let one0 = dfg.builder().bytes(Type::mk_int(32), vec![1]).unwrap(); + let one1 = dfg.builder().bytes(Type::mk_int(32), vec![1]).unwrap(); + let one2 = dfg.builder().bytes(Type::mk_int(32), vec![1]).unwrap(); + let two0 = dfg.builder().bytes(Type::mk_int(32), vec![2]).unwrap(); + + let icmp = dfg + .builder() + .binary( + BinaryOp::ICmp(ICmpCond::Sle), + entry_block_param, + one0.into(), + ) + .unwrap(); + let br = dfg + .builder() + .branch( + icmp, + ret_block, + else_block, + vec![one1], + vec![entry_block_param], + ) + .unwrap(); + + let sub0 = dfg + .builder() + .binary(BinaryOp::Sub, else_block_param, one2.into()) + .unwrap(); + let sub1 = dfg + .builder() + .binary(BinaryOp::Sub, else_block_param, two0.into()) + .unwrap(); + let call0 = dfg + .builder() + .call(Type::mk_int(32), fn_fib.into(), vec![sub0.into()]) + .unwrap(); + let call1 = dfg + .builder() + .call(Type::mk_int(32), fn_fib.into(), vec![sub1.into()]) + .unwrap(); + let add = dfg + .builder() + .binary(BinaryOp::Add, call0.into(), call1.into()) + .unwrap(); + let jump = dfg.builder().jump(ret_block, vec![add.into()]).unwrap(); + + let ret = dfg.builder().return_(Some(ret_block_param)).unwrap(); + + dfg.assign_block_name(entry_block, "entry".to_string()).ok(); + dfg.assign_block_name(ret_block, "ret".to_string()).ok(); + dfg.assign_block_name(else_block, "else".to_string()).ok(); + + dfg.assign_local_value_name(icmp, "cond".to_string()).ok(); + dfg.assign_local_value_name(ret_block_param, "result".to_string()) + .ok(); - let block = function_data.dfg_mut().builder().block(vec![]).unwrap(); + let layout = module.function_data_mut(fn_fib).unwrap().layout_mut(); - let dfg = function_data.dfg_mut(); + layout.append_block(entry_block).ok(); + layout.append_block(else_block).ok(); + layout.append_block(ret_block).ok(); - let alloc0 = dfg.builder().alloc(Type::mk_int(32)).unwrap(); - let alloc1 = dfg.builder().alloc(Type::mk_float()).unwrap(); - let alloc2 = dfg.builder().alloc(Type::mk_double()).unwrap(); + layout.append_inst(icmp.into(), entry_block).ok(); + layout.append_inst(br.into(), entry_block).ok(); - let layout = function_data.layout_mut(); + layout.append_inst(sub0.into(), else_block).ok(); + layout.append_inst(sub1.into(), else_block).ok(); + layout.append_inst(call0.into(), else_block).ok(); + layout.append_inst(call1.into(), else_block).ok(); + layout.append_inst(add.into(), else_block).ok(); + layout.append_inst(jump.into(), else_block).ok(); - layout.append_block(block).ok(); - layout.append_inst(alloc0.into(), block).ok(); - layout.append_inst(alloc1.into(), block).ok(); - layout.append_inst(alloc2.into(), block).ok(); + layout.append_inst(ret.into(), ret_block).ok(); let mut stdout = io::stdout(); let mut printer = Printer::new(&mut stdout); diff --git a/src/passes/printer.rs b/src/passes/printer.rs index 2572944..e292b7a 100644 --- a/src/passes/printer.rs +++ b/src/passes/printer.rs @@ -54,7 +54,7 @@ where write!(self.buf, "\n")?; - write!(self.buf, "fn {} {}\n", data.name(), data.ty())?; + write!(self.buf, "fn {}{} {{\n", data.name(), data.ty())?; if let FunctionKind::Declaration = data.kind() { return Ok(()); @@ -74,7 +74,12 @@ where if i != 0 { write!(self.buf, ", ")?; } - write!(self.buf, "{}", dfg.value_name(*param))?; + write!( + self.buf, + "{} {}", + dfg.local_value_data(*param).unwrap().ty(), + dfg.value_name(*param) + )?; } write!(self.buf, "):\n")?; } else { @@ -82,7 +87,7 @@ where } for (inst, _) in node.insts().iter() { - write!(self.buf, " ")?; + write!(self.buf, " ")?; self.print_local_value(inst.into(), dfg)?; write!(self.buf, "\n")?; } @@ -209,8 +214,10 @@ where } ValueKind::Jump(jump) => { write!(self.buf, "jump {}(", dfg.block_name(jump.dst().into()))?; - for arg in jump.args() { - write!(self.buf, ", ")?; + for (i, arg) in jump.args().iter().enumerate() { + if i != 0 { + write!(self.buf, ", ")?; + } self.print_operand(*arg, dfg)?; } write!(self.buf, ")") @@ -219,13 +226,17 @@ where write!(self.buf, "br ")?; self.print_operand(branch.cond(), dfg)?; write!(self.buf, ", {}(", dfg.block_name(branch.then_dst()))?; - for arg in branch.then_args() { - write!(self.buf, ", ")?; + for (i, arg) in branch.then_args().iter().enumerate() { + if i != 0 { + write!(self.buf, ", ")?; + } self.print_operand(*arg, dfg)?; } write!(self.buf, "), {}(", dfg.block_name(branch.else_dst()))?; - for arg in branch.else_args() { - write!(self.buf, ", ")?; + for (i, arg) in branch.else_args().iter().enumerate() { + if i != 0 { + write!(self.buf, ", ")?; + } self.print_operand(*arg, dfg)?; } write!(self.buf, ")")