mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 02:31:13 +08:00
b8611d2c4b
LiveInfo 四矩阵由逐位 Vec<bool>(1 字节/位,长度 = max_vreg+1)改为 u64 压缩位集(1 字 64 位,长度 ÷8),dataflow 不动点 out/input 缓冲 提为循环外复用(clear + 覆盖,免逐迭代逐块分配)。dce_precise / graph 建图 / call_window 三处消费方同步改为字内位移查询,越界语义 与旧 Vec<bool>::get 一致(越界 = 不 live)。位集遍历(call_window 存活上界)按 trailing_zeros 只走实际置位,活集小则近 O(活集) 而非 O(254)。 实测(debug,start-unicode-17.0.0.js):liveness 三趟合计 ~536ms → ~118ms(-78%),矩阵内存 ÷8;graph 全 node 扫描为剩余 瓶颈,另行跟进。
34 lines
1.3 KiB
Rust
34 lines
1.3 KiB
Rust
//! liveness 分析 pass:IRFunction + CFG → LiveInfo(只读)。
|
||
//!
|
||
//! 消费 `oxide_ir::IRFunction`(只读)与 `oxide_cfg::Cfg`(preds/succs + exit 哨兵),
|
||
//! 产出 LiveInfo 分析视图(pass 输出不住进 IR)。两阶段:`dataflow`(块级
|
||
//! liveIn/liveOut 不动点)→ `ranges`(块内反向扫描逐指令 live 集)。gen/kill 直接消费
|
||
//! contract.rs def_reg/use_regs,None→0 / This→254 / NewTarget→255 零重复映射。
|
||
|
||
mod dataflow;
|
||
mod live_info;
|
||
mod liveness_log;
|
||
mod ranges;
|
||
|
||
pub use live_info::{bitset_get, LiveInfo};
|
||
|
||
use oxide_cfg::Cfg;
|
||
use oxide_ir::IRFunction;
|
||
|
||
/// 计算 liveness:`&IRFunction + &Cfg → LiveInfo`。纯函数,只读 IR。
|
||
/// 空 IRFunction 退化:返回 LiveInfo::new()。
|
||
pub fn liveness(f: &IRFunction, cfg: &Cfg) -> LiveInfo {
|
||
if f.insts.is_empty() {
|
||
return LiveInfo::new();
|
||
}
|
||
liveness_debug!("liveness: {} blocks, {} insts", cfg.blocks.len(), f.insts.len());
|
||
let (block_in, block_out, reg_count) = dataflow::block_liveness(f, cfg);
|
||
let (inst_before, inst_after) = ranges::inst_liveness(f, cfg, &block_out, &block_in, reg_count);
|
||
LiveInfo {
|
||
block_live_in: block_in,
|
||
block_live_out: block_out,
|
||
inst_live_before: inst_before,
|
||
inst_live_after: inst_after,
|
||
}
|
||
}
|