From 4a7bd538ab640ba65cc5a6c5dec6ae04bcfc10ec Mon Sep 17 00:00:00 2001 From: Yey007 Date: Fri, 10 May 2024 23:46:25 -0400 Subject: [PATCH] Add stack locations to spill --- README.md | 2 +- lib/backend/regalloc/regalloc.ml | 20 ++++++++++++++++---- lib/backend/regalloc/regalloc.mli | 2 +- source/regalloc_spill_test.x86istmb | 4 +++- test/test_regalloc.ml | 2 +- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2cb0c55..dd3b20f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![CI Status](https://github.com/ethanuppal/cs3110_compiler/actions/workflows/ci.yaml/badge.svg) > "x86 is simple trust me bro" -> Last updated: 2024-05-10 22:08:20.895180 +> Last updated: 2024-05-10 23:44:05.745284 ``` $ ./main -h diff --git a/lib/backend/regalloc/regalloc.ml b/lib/backend/regalloc/regalloc.ml index 77b8920..1cf751d 100644 --- a/lib/backend/regalloc/regalloc.ml +++ b/lib/backend/regalloc/regalloc.ml @@ -16,7 +16,7 @@ type interval = { type allocation = | Register of Asm.Register.t - | Spill + | Spill of int module BBAnalysis = Liveliness.BasicBlockAnalysis @@ -83,6 +83,13 @@ let linear_scan (intervals : (Variable.t * interval) list) (* must remain sorted by increasing end point *) let active : (Variable.t * interval) BatRefList.t = BatRefList.empty () in + let cur_loc = ref 0 in + let next_spill_loc () = + let result = !cur_loc in + cur_loc := !cur_loc + 8; + result + in + let expire_old_intervals (current : interval) = (* this is also really annoying because BatRefList has no partition *) BatRefList.filter @@ -92,7 +99,7 @@ let linear_scan (intervals : (Variable.t * interval) list) let alloc = VarTbl.find assigned_alloc var in match alloc with | Register r -> free_registers := RegSet.add r !free_registers - | Spill -> failwith "Interval in active cannot be spilled"); + | Spill _ -> failwith "Interval in active cannot be spilled"); keep) active in @@ -103,8 +110,13 @@ let linear_scan (intervals : (Variable.t * interval) list) if compare_instr_id spill_interval.stop interval.stop > 0 then ( (* spill guaranteed to be assigned an actual register *) let alloc = VarTbl.find assigned_alloc spill_var in + assert ( + match alloc with + | Spill _ -> false + | _ -> true); + VarTbl.replace assigned_alloc var alloc; - VarTbl.replace assigned_alloc spill_var Spill; + VarTbl.replace assigned_alloc spill_var (Spill (next_spill_loc ())); (* this sucks. can we maybe keep active in reverse order? *) BatRefList.Index.remove_at active (BatRefList.length active - 1); @@ -112,7 +124,7 @@ let linear_scan (intervals : (Variable.t * interval) list) (* add_sort is buggy... TODO: new impl *) BatRefList.push active (var, interval); BatRefList.sort ~cmp:compare_pair_end active) - else VarTbl.replace assigned_alloc var Spill + else VarTbl.replace assigned_alloc var (Spill (next_spill_loc ())) in List.iter diff --git a/lib/backend/regalloc/regalloc.mli b/lib/backend/regalloc/regalloc.mli index 93ed1fd..3311bd4 100644 --- a/lib/backend/regalloc/regalloc.mli +++ b/lib/backend/regalloc/regalloc.mli @@ -3,7 +3,7 @@ module VarTbl : Hashtbl.S with type key = Variable.t type allocation = | Register of Asm.Register.t - | Spill + | Spill of int val registers : Asm.Register.t list diff --git a/source/regalloc_spill_test.x86istmb b/source/regalloc_spill_test.x86istmb index cfa0537..fd8c6ed 100644 --- a/source/regalloc_spill_test.x86istmb +++ b/source/regalloc_spill_test.x86istmb @@ -14,8 +14,9 @@ func main() { let m = 12 let n = 13 let o = 14 - let q = 16 let p = 15 + let q = 16 + let r = 17 print a print b print c @@ -33,4 +34,5 @@ func main() { print o print p print q + print r } diff --git a/test/test_regalloc.ml b/test/test_regalloc.ml index e523930..8ed9e99 100644 --- a/test/test_regalloc.ml +++ b/test/test_regalloc.ml @@ -4,7 +4,7 @@ open Alcotest let allocations_same alloc1 alloc2 = match (alloc1, alloc2) with - | Regalloc.Spill, Regalloc.Spill -> false + | Regalloc.Spill loc1, Regalloc.Spill loc2 -> loc1 = loc2 | reg1, reg2 -> reg1 = reg2 let add_ir_list bb lst = List.iter (Basic_block.add_ir bb) lst