From f51053ce61f48813577fac821f7a9715f1366f7e Mon Sep 17 00:00:00 2001 From: static Date: Wed, 18 Jun 2025 04:39:26 +0000 Subject: [PATCH] HW8 (9) --- src/asmgen/mod.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/src/asmgen/mod.rs b/src/asmgen/mod.rs index 2700cf1..8a5e22a 100644 --- a/src/asmgen/mod.rs +++ b/src/asmgen/mod.rs @@ -277,13 +277,60 @@ impl InferenceGraph { } } + let mut spilled = HashSet::new(); + let mut visited = HashSet::new(); + + while let Some((loc, clique)) = + find_large_integer_clique(&lives, &vertices, &spilled, &visited) + { + let _ = visited.insert(loc); + let mut not_spilled = clique + .iter() + .filter(|reg| vertices[*reg].1 != asm::Register::Zero) + .cloned() + .collect::>(); + let mut usable_temp_regs = 4 - clique + .iter() + .filter(|reg| matches!(vertices[*reg].1, asm::Register::Temp(_, _,))) + .count(); + let mut usable_arg_regs = 8 - clique + .iter() + .filter(|reg| matches!(vertices[*reg].1, asm::Register::Arg(_, _,))) + .count(); + let mut usable_saved_regs = 11 + - clique + .iter() + .filter(|reg| matches!(vertices[*reg].1, asm::Register::Saved(_, _,))) + .count(); + for reg in &clique { + if not_spilled.contains(reg) { + continue; + } + if usable_temp_regs > 0 && analysis.is_temporary2(reg, &lives, false) { + usable_temp_regs -= 1; + let _ = not_spilled.insert(*reg); + } else if usable_arg_regs > 0 && analysis.is_temporary2(reg, &lives, true) { + usable_arg_regs -= 1; + let _ = not_spilled.insert(*reg); + } else if usable_saved_regs > 0 { + usable_saved_regs -= 1; + let _ = not_spilled.insert(*reg); + } + } + println!("clique: {:?}", clique); + for reg in clique.difference(¬_spilled) { + println!("spilled! {:?}", reg); + let _ = spilled.insert(*reg); + } + } + let mut vertices_order = vertices .keys() .map(|rid| (*rid, num_of_edges.get(rid).cloned().unwrap_or_default())) .sorted_by(|(_, v1), (_, v2)| v2.cmp(v1)); for (rid, count) in vertices_order { - if count == 0 || vertices[&rid].1 != asm::Register::Zero { + if count == 0 || vertices[&rid].1 != asm::Register::Zero || spilled.contains(&rid) { continue; } @@ -520,6 +567,39 @@ fn smallest_missing_integer(set: &HashSet, start: usize) -> usize { i } +fn find_large_integer_clique( + lives: &HashMap>, + vertices: &HashMap, + spilled: &HashSet, + visited: &HashSet, +) -> Option<(ir::RegisterId, HashSet)> { + lives + .iter() + .filter_map(|(loc, regs)| { + let count = regs + .iter() + .filter(|reg| is_integer(&vertices[*reg].0) && !spilled.contains(*reg)) + .count(); + if !visited.contains(loc) && count >= 12 { + Some((loc, regs, count)) + } else { + None + } + }) + .sorted_by(|(_, _, v1), (_, _, v2)| v2.cmp(v1)) + .take(1) + .next() + .map(|(loc, regs, _)| { + ( + *loc, + regs.iter() + .filter(|reg| is_integer(&vertices[*reg].0) && !spilled.contains(*reg)) + .cloned() + .collect::>(), + ) + }) +} + struct Analysis { num_int_args: i32, num_float_args: i32,