mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
refactor: 清除 color() 冗余干涉图构建 + use_points 改用精确 use 判定
- color() 入口移除无用的 graph::build(run 内重建),删掉 _graph 参数 - graph.rs reg_count 改名 inst_count(实为指令数) - use_points 由 live_before 活集改为 inst.use_regs() 精确 use 点,消除冗余 UNSPILL,spill 压力测试 38s→6s
This commit is contained in:
@@ -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<AllocMap, String> {
|
||||
pub(super) fn run(f: &IRFunction, live: &LiveInfo) -> Result<AllocMap, String> {
|
||||
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<usize> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// use 点:`live_before[i][v]`(v 的活点)。RMW 指令同时是 def 与 use,各建一个 fresh。
|
||||
fn use_points(live: &LiveInfo, v: u32) -> Vec<usize> {
|
||||
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<usize> {
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -80,7 +80,8 @@ pub(super) fn build(
|
||||
f: &IRFunction, live: &LiveInfo, spill_set: &BTreeSet<u32>, 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<u32, u32> = 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<u32> = Vec::new();
|
||||
for &v in &node_ids {
|
||||
if live.inst_live_before[i].get(v as usize).copied().unwrap_or(false) {
|
||||
|
||||
@@ -24,8 +24,7 @@ pub fn color(f: &IRFunction, live: &LiveInfo) -> Result<AllocMap, String> {
|
||||
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)。
|
||||
|
||||
Reference in New Issue
Block a user