diff --git a/src/js/clops2js.mbt b/src/js/clops2js.mbt index 28e11d9..7ddeaf2 100644 --- a/src/js/clops2js.mbt +++ b/src/js/clops2js.mbt @@ -182,12 +182,11 @@ pub fn JsEmitter::emit(self : JsEmitter) -> String { output += line_start // B. emit all functions output += line_start + "const compiled_functions = [" - + let line_start = "\n " // 1. emit root output += line_start + "function() { // root" output += self.indent().indent().emit_cps(self.clops.root) output += line_start + "}," - // 2. emit all functions for label in self.lid2label { let cur_fn = self.clops.fnblocks[label].unwrap() @@ -197,7 +196,7 @@ pub fn JsEmitter::emit(self : JsEmitter) -> String { let args_with_closure_emitted = args_with_closure.map(emit_var).join(", ") output += line_start + "function(\{args_with_closure_emitted}) { // \{label}" - // i. emit body + // ii. emit body output += self.indent().indent().emit_cps(cur_fn.body) output += line_start + "}," } diff --git a/src/riscv/codegen.mbt b/src/riscv/codegen.mbt index afa02c7..fac9166 100644 --- a/src/riscv/codegen.mbt +++ b/src/riscv/codegen.mbt @@ -89,7 +89,11 @@ fn CodegenBlock::new( let params = cfg.fn_args[name_var].unwrap() for param in params { let alloc_reg = allocation[param].unwrap() - dirtied.insert(alloc_reg) + if cfg.spilled.contains(param) { + @util.die("param \{param} of fn \{name_var} spilled") + } else { + dirtied.insert(alloc_reg) + } } // 3. collect spilled vars diff --git a/src/riscv/reg_allocation.mbt b/src/riscv/reg_allocation.mbt index 76f4d88..5546b38 100644 --- a/src/riscv/reg_allocation.mbt +++ b/src/riscv/reg_allocation.mbt @@ -66,14 +66,22 @@ fn reg_allocate_on_fn( vars_f, graph_f, alloc_fregs, allocation_f, simplify_stack_f, ) if should_spill_i { + let vars_i_spillable = vars_i + .iter() + .filter(fn(var) { not(allocation_i.contains(var)) }) + |> @hashset.from_iter() let i_spilled = reg_spill_fn( - input, vars_i, simplify_stack_i, graph_i, fn_label, + input, vars_i_spillable, simplify_stack_i, graph_i, fn_label, ) spilled_set.insert(i_spilled) } if should_spill_f { + let vars_f_spillable = vars_i + .iter() + .filter(fn(var) { not(allocation_f.contains(var)) }) + |> @hashset.from_iter() let f_spilled = reg_spill_fn( - input, vars_f, simplify_stack_f, graph_f, fn_label, + input, vars_f_spillable, simplify_stack_f, graph_f, fn_label, ) spilled_set.insert(f_spilled) } diff --git a/src/riscv/reg_spill.mbt b/src/riscv/reg_spill.mbt index 3c477c9..0ddc14e 100644 --- a/src/riscv/reg_spill.mbt +++ b/src/riscv/reg_spill.mbt @@ -1,11 +1,11 @@ fn reg_spill_fn( cfg : @ssacfg.SsaCfg, - all_vars : @hashset.T[Var], - can_allocate : Array[Var], + all_vars_not_preallocated : @hashset.T[Var], + can_allocate : Array[Var], // vars that can be allocated but not yet interference : InterferenceGraph, fn_name : Var ) -> Var { - let spill_candidates = all_vars + let spill_candidates = all_vars_not_preallocated .iter() .filter(fn(var) { not(can_allocate.contains(var)) }) .collect()