This commit is contained in:
static
2025-06-18 04:39:26 +00:00
parent 0fea4027ad
commit f51053ce61

View File

@@ -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::<HashSet<_>>();
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(&not_spilled) {
println!("spilled! {:?}", reg);
let _ = spilled.insert(*reg);
}
}
let mut vertices_order = vertices let mut vertices_order = vertices
.keys() .keys()
.map(|rid| (*rid, num_of_edges.get(rid).cloned().unwrap_or_default())) .map(|rid| (*rid, num_of_edges.get(rid).cloned().unwrap_or_default()))
.sorted_by(|(_, v1), (_, v2)| v2.cmp(v1)); .sorted_by(|(_, v1), (_, v2)| v2.cmp(v1));
for (rid, count) in vertices_order { 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; continue;
} }
@@ -520,6 +567,39 @@ fn smallest_missing_integer(set: &HashSet<usize>, start: usize) -> usize {
i i
} }
fn find_large_integer_clique(
lives: &HashMap<ir::RegisterId, HashSet<ir::RegisterId>>,
vertices: &HashMap<ir::RegisterId, (ir::Dtype, asm::Register)>,
spilled: &HashSet<ir::RegisterId>,
visited: &HashSet<ir::RegisterId>,
) -> Option<(ir::RegisterId, HashSet<ir::RegisterId>)> {
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::<HashSet<_>>(),
)
})
}
struct Analysis { struct Analysis {
num_int_args: i32, num_int_args: i32,
num_float_args: i32, num_float_args: i32,