diff --git a/crates/oxide_regalloc/src/color.rs b/crates/oxide_regalloc/src/color.rs index 668205e..79e4f9d 100644 --- a/crates/oxide_regalloc/src/color.rs +++ b/crates/oxide_regalloc/src/color.rs @@ -15,7 +15,7 @@ use crate::alloc_map::{Alloc, AllocMap, FreshKind, FreshVreg, SpillPlan}; use crate::graph::{self, InterferenceGraph}; /// 主染色循环:产出 AllocMap。 -pub(super) fn run(f: &IRFunction, live: &LiveInfo, _graph: &InterferenceGraph) -> Result { +pub(super) fn run(f: &IRFunction, live: &LiveInfo) -> Result { let max_real = graph::collect_real_vregs(f).into_iter().max().unwrap_or(0); let mut next_fresh_id = max_real + 1; let mut next_slot: u16 = 0; @@ -44,7 +44,7 @@ pub(super) fn run(f: &IRFunction, live: &LiveInfo, _graph: &InterferenceGraph) - fresh.push(FreshVreg { id: next_fresh_id, at: d, kind: FreshKind::Def, owner: v }); next_fresh_id += 1; } - for u in use_points(live, v) { + for u in use_points(f, v) { fresh.push(FreshVreg { id: next_fresh_id, at: u, kind: FreshKind::Use, owner: v }); next_fresh_id += 1; } @@ -69,12 +69,15 @@ fn def_points(f: &IRFunction, v: u32) -> Vec { .collect() } -/// use 点:`live_before[i][v]`(v 的活点)。RMW 指令同时是 def 与 use,各建一个 fresh。 -fn use_points(live: &LiveInfo, v: u32) -> Vec { - live.inst_live_before +/// use 点:`inst.use_regs()` 含 v 的指令下标(精确 use,非 live_before 活集—— +/// 活集包含"仅经过不读取"的指令,会产生多余 UNSPILL)。RMW 指令(如 COMPOUND_ADD +/// rd 读旧值写新值)同时是 def 与 use,此处与 def_points 各建一个 fresh,由 rewrite 判 +/// rmw_v 决定用 def-fresh(rewrite.rs RMW 分支)。 +fn use_points(f: &IRFunction, v: u32) -> Vec { + f.insts .iter() .enumerate() - .filter(|(_, set)| set.get(v as usize).copied().unwrap_or(false)) + .filter(|(_, i)| i.use_regs().contains(&v)) .map(|(i, _)| i) .collect() } diff --git a/crates/oxide_regalloc/src/graph.rs b/crates/oxide_regalloc/src/graph.rs index 4742b46..1f7e5a8 100644 --- a/crates/oxide_regalloc/src/graph.rs +++ b/crates/oxide_regalloc/src/graph.rs @@ -80,7 +80,8 @@ pub(super) fn build( f: &IRFunction, live: &LiveInfo, spill_set: &BTreeSet, fresh: &[FreshVreg], ) -> InterferenceGraph { let real = collect_real_vregs(f); - let reg_count = live.inst_live_before.len(); + // inst_live_before 长度 = 指令数(逐指令活集索引) + let inst_count = live.inst_live_before.len(); // ── 预着色 ── let mut pre_colors: BTreeMap = BTreeMap::new(); @@ -143,7 +144,7 @@ pub(super) fn build( for &v in &node_ids { adj_sets.entry(v).or_default(); } - for i in 0..reg_count { + for i in 0..inst_count { let mut at_i: Vec = Vec::new(); for &v in &node_ids { if live.inst_live_before[i].get(v as usize).copied().unwrap_or(false) { diff --git a/crates/oxide_regalloc/src/lib.rs b/crates/oxide_regalloc/src/lib.rs index f60e3e2..0397c8c 100644 --- a/crates/oxide_regalloc/src/lib.rs +++ b/crates/oxide_regalloc/src/lib.rs @@ -24,8 +24,7 @@ pub fn color(f: &IRFunction, live: &LiveInfo) -> Result { if f.insts.is_empty() { return Ok(AllocMap::new()); } - let graph = graph::build(f, live, &std::collections::BTreeSet::new(), &[]); - color::run(f, live, &graph) + color::run(f, live) } /// 寄存器分配改写:`&mut IRFunction + &LiveInfo → Result<(), String>`(D-16)。