From 4e0fd762c2b845dd88e8eaf7a535691438aff627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E7=89=B9=E6=AF=8F=E7=BE=8A=E9=98=9F?= Date: Thu, 6 Aug 2026 20:41:01 +0800 Subject: [PATCH] =?UTF-8?q?refactor(regalloc):=20=E6=B8=85=E9=99=A4=20colo?= =?UTF-8?q?r()=20=E5=86=97=E4=BD=99=E5=B9=B2=E6=B6=89=E5=9B=BE=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=20+=20use=5Fpoints=20=E6=94=B9=E7=94=A8=E7=B2=BE?= =?UTF-8?q?=E7=A1=AE=20use=20=E5=88=A4=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - color() 入口移除无用的 graph::build(run 内重建),删掉 _graph 参数 - graph.rs reg_count 改名 inst_count(实为指令数) - use_points 由 live_before 活集改为 inst.use_regs() 精确 use 点,消除冗余 UNSPILL,spill 压力测试 38s→6s --- crates/oxide_regalloc/src/color.rs | 15 +++++++++------ crates/oxide_regalloc/src/graph.rs | 5 +++-- crates/oxide_regalloc/src/lib.rs | 3 +-- 3 files changed, 13 insertions(+), 10 deletions(-) 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)。