Skip to content

Commit

Permalink
fix calling with unit
Browse files Browse the repository at this point in the history
  • Loading branch information
glyh committed Oct 22, 2024
1 parent f784b4d commit 840d51d
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 136 deletions.
6 changes: 3 additions & 3 deletions src/externals.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ pub let externals_list : Array[(String, Type)] = [
("sin", Fun([Double], Double)),
("cos", Fun([Double], Double)),
("atan", Fun([Double], Double)),
("create_array", Fun([Int], Array(Int))),
("create_float_array", Fun([Int], Array(Double))),
("create_ptr_array", Fun([Int], Array(Ptr))),
("create_array", Fun([Int, Int], Array(Int))),
("create_float_array", Fun([Int, Double], Array(Double))),
("create_ptr_array", Fun([Int, Ptr], Array(Ptr))),
]

pub let externals : @immut/hashmap.T[String, Type] = externals_list.iter()
Expand Down
52 changes: 17 additions & 35 deletions src/riscv/codegen.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ fn CodegenBlock::assign_i(
return
}
guard let I(target) = self.find_reg(var) else {
_ => @util.die("assigning to non i reg with `assign_i`")
reg => @util.die("assigning to \{reg} with `assign_i` @ \{var}")
}
self.insert_asms(todo(target))
}
Expand All @@ -199,7 +199,8 @@ fn CodegenBlock::assign_f(
todo : (FReg) -> Array[RvAsm]
) -> Unit {
guard let F(target) = self.find_reg(var) else {
_ => @util.die("assigning to non f reg with `assign_f`")
I(Zero) => return // meaning the value is not used
reg => @util.die("assigning to \{reg} with `assign_f` @ \{var}")
}
self.insert_asms(todo(target))
}
Expand Down Expand Up @@ -439,42 +440,15 @@ fn get_tuple_offset(t : T, idx : Int) -> Int {
}
}

fn CodegenBlock::resolve_arg_regs(
_self : CodegenBlock,
args : Array[Value]
) -> Array[(Value, RegRef)] {
let args_regs_list : Array[(Value, RegRef)] = []
loop (args[:], reg_arg_list[:], freg_arg_list[:]) {
([], _, _) => break args_regs_list
([val, .. as args], reg_args, freg_args) => {
let (reg_next, reg_args, freg_args) = match get_reg_ty(val) {
F64 => {
guard let [freg, .. as freg_args] = freg_args else {
_ => @util.die("not enough freg")
}
(F(freg), reg_args, freg_args)
}
I32 | PTR64 => {
guard let [reg, .. as reg_args] = reg_args else {
_ => @util.die("not enough reg")
}
(I(reg), reg_args, freg_args)
}
Void => (I(Zero), reg_args, freg_args)
}
args_regs_list.push((val, reg_next))
continue (args, reg_args, freg_args)
}
}
}

fn CodegenBlock::new_label(self : CodegenBlock, prefix : String) -> String {
let var = self.cfg.new_named(prefix)
var.to_string()
}

// PERF: proritize the use of saved regs in stead of putting onto stack
// take care not to introduce a chain reaction where you dirty s regs

// BUG: we didn't consider spilled registers here
fn CodegenBlock::call_c_conv_aligned(
self : CodegenBlock,
target : String,
Expand All @@ -487,7 +461,9 @@ fn CodegenBlock::call_c_conv_aligned(
.iter()
.filter(
fn(reg) {
not(is_reg_saved(reg) || [I(reg_swap), F(freg_swap)].contains(reg))
not(
is_reg_saved(reg) || [I(reg_swap), F(freg_swap), I(Sp)].contains(reg),
)
},
)
.collect()
Expand All @@ -508,7 +484,7 @@ fn CodegenBlock::call_c_conv_aligned(
}
}
// 2. Fill in the params to regs
let args_regs_list = self.resolve_arg_regs(args)
let args_regs_list = resolve_arg_regs(args)
// 2. Generate an assign order
// WARN: these steps may dirty too many regs
// so we don't use insert_asm/insert_asms
Expand Down Expand Up @@ -940,7 +916,13 @@ fn CodegenBlock::codegen(self : CodegenBlock) -> Unit {
MakeArray(len, elem, continuation) => {
// 1. call to generate an array
// we keep the result at 1st reg so we call the continuation immediately
self.call_c_conv_aligned("minimbt_create_array", [len, elem], I(A0))
let create_array_fn = "minimbt_" +
(match get_reg_ty(elem) {
F64 => "create_float_array"
I32 | Void => "create_array"
PTR64 => "create_ptr_array"
})
self.call_c_conv_aligned(create_array_fn, [len, elem], I(A0))

// 2. prepare regs for continuation. A0 is already the array
self.resolve_loop([(continuation, I(A1))])
Expand All @@ -952,7 +934,7 @@ fn CodegenBlock::codegen(self : CodegenBlock) -> Unit {
}
Call(f, args) => {
// 1. Fill in the params to regs
let args_regs_list = self.resolve_arg_regs(args)
let args_regs_list = resolve_arg_regs(args)
// 2. Generate an assign order
self.resolve_loop(args_regs_list)
// 3. Generate the call
Expand Down
2 changes: 2 additions & 0 deletions src/riscv/collect_labels.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ fn collect_externals(cfg : @ssacfg.SsaCfg) -> ExternalLabels {
collect_label_val(len)
collect_label_val(elem)
collect_label_val(kont)
// NOTE: make array itself doesn't count because we generate direct call
// to unwrapped functions
}
Exit => ()
}
Expand Down
52 changes: 33 additions & 19 deletions src/riscv/reg_allocation.mbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
// REF:
// - Modern Compiler Implementation in ML - Andrew W. Appel

fn resolve_arg_regs(args : Array[Value]) -> Array[(Value, RegRef)] {
let args_regs_list : Array[(Value, RegRef)] = []
loop (args[:], reg_arg_list[:], freg_arg_list[:]) {
([], _, _) => break args_regs_list
([val, .. as args], reg_args, freg_args) => {
let (reg_next, reg_args, freg_args) = match get_reg_ty(val) {
F64 => {
guard let [freg, .. as freg_args] = freg_args else {
_ => @util.die("not enough freg")
}
(F(freg), reg_args, freg_args)
}
I32 | PTR64 => {
guard let [reg, .. as reg_args] = reg_args else {
_ => @util.die("not enough reg")
}
(I(reg), reg_args, freg_args)
}
Void => (I(Zero), reg_args, freg_args)
}
args_regs_list.push((val, reg_next))
continue (args, reg_args, freg_args)
}
}
}

fn reg_allocate_on_fn(
input : @ssacfg.SsaCfg,
fn_label : Var
Expand All @@ -12,25 +38,13 @@ fn reg_allocate_on_fn(
let allocation_f : @hashmap.T[Var, FReg] = @hashmap.new()
// allocate for args
let params = input.fn_args[fn_label].unwrap()
loop (params[:], reg_arg_list[:], freg_arg_list[:]) {
([], _, _) => break
([param, .. as param_rest], iregs, fregs) =>
match param.ty.val {
Double => {
guard let [freg, .. as fregs] = fregs else {
_ => @util.die("no i64 register can be assigned to \{param}")
}
allocation_f[param] = freg
continue (param_rest, iregs, fregs)
}
_ => {
guard let [ireg, .. as iregs] = iregs else {
_ => @util.die("no i64 register can be assigned to \{param}")
}
allocation_i[param] = ireg
continue (param_rest, iregs, fregs)
}
}
for item in resolve_arg_regs(params.map(@cps.Value::Var)) {
let (value, reg) = item
guard let Var(var) = value else { v => @util.die("got \{v}") }
match reg {
I(ireg) => allocation_i[var] = ireg
F(freg) => allocation_f[var] = freg
}
}
let simplify_stack_i = []
let simplify_stack_f = []
Expand Down
4 changes: 4 additions & 0 deletions test/build_and_run
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash

./build_all $1
./run_exe $1
79 changes: 0 additions & 79 deletions test/test_src/array.mbt

This file was deleted.

0 comments on commit 840d51d

Please sign in to comment.