mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-14 22:38:46 +00:00
HW8 (9)
This commit is contained in:
@@ -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(¬_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<usize>, start: usize) -> usize {
|
||||
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 {
|
||||
num_int_args: i32,
|
||||
num_float_args: i32,
|
||||
|
||||
Reference in New Issue
Block a user