LowerCore: stabilize minimal PHI by tracking Phi dst and pushing block param when that ValueId is requested; verified jit_phi_demo returns merged value under cranelift.

This commit is contained in:
Moe Charm
2025-08-27 17:58:50 +09:00
parent 633a073a30
commit 99e59e24e2
3 changed files with 30 additions and 2 deletions

View File

@ -30,7 +30,8 @@
3) 10_7: 分岐配線Cranelift— 進捗中
- LowerCore: BB整列・マッピング→builderの`prepare_blocks/switch/seal/br_if/jump`呼出 ✅
- CraneliftBuilder: ブロック配列管理、`brif/jump`実装、条件b1/`i64!=0`両対応 ✅
- 残: 最小PHI単純ダイアモンド導入`NYASH_JIT_PHI_MIN=1`ガード)/ 副作用命令の扱い方針当面VMへ
- 最小PHI単純ダイアモンド導入`NYASH_JIT_PHI_MIN=1`ガード)✅ 初期対応
- 残: 副作用命令の扱い方針当面VMへ、CFG可視化の拡張`NYASH_JIT_DUMP=1`
備考(制限と次の着手点)
- 返り値はi64VMValue::Integerに限定。f64はconst最小emit、boolはi64 0/1へ正規化分岐条件入力に対応

View File

@ -0,0 +1,18 @@
// JIT minimal PHI demo (single diamond)
// Enable: NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_PHI_MIN=1
static box Main {
main() {
local a, b, x
a = 3
b = 5
if (a < b) {
x = 10
} else {
x = 20
}
// Merge should pick 10
return x
}
}

View File

@ -10,10 +10,12 @@ pub struct LowerCore {
known_i64: std::collections::HashMap<ValueId, i64>,
/// Parameter index mapping for ValueId
param_index: std::collections::HashMap<ValueId, usize>,
/// Track values produced by Phi (for minimal PHI path)
phi_values: std::collections::HashSet<ValueId>,
}
impl LowerCore {
pub fn new() -> Self { Self { unsupported: 0, covered: 0, known_i64: std::collections::HashMap::new(), param_index: std::collections::HashMap::new() } }
pub fn new() -> Self { Self { unsupported: 0, covered: 0, known_i64: std::collections::HashMap::new(), param_index: std::collections::HashMap::new(), phi_values: std::collections::HashSet::new() } }
/// Walk the MIR function and count supported/unsupported instructions.
/// In the future, this will build CLIF via Cranelift builders.
@ -48,11 +50,13 @@ impl LowerCore {
builder.prepare_signature_i64(func.params.len(), true);
builder.begin_function(&func.signature.name);
// Iterate blocks in the sorted order to keep indices stable
self.phi_values.clear();
for (idx, bb_id) in bb_ids.iter().enumerate() {
let bb = func.blocks.get(bb_id).unwrap();
builder.switch_to_block(idx);
for instr in bb.instructions.iter() {
self.cover_if_supported(instr);
if let MirInstruction::Phi { dst, .. } = instr { self.phi_values.insert(*dst); }
self.try_emit(builder, instr);
}
if let Some(term) = &bb.terminator {
@ -107,6 +111,11 @@ impl LowerCore {
/// Push a value onto the builder stack if it is a known i64 const or a parameter.
fn push_value_if_known_or_param(&self, b: &mut dyn IRBuilder, id: &ValueId) {
if self.phi_values.contains(id) {
// Minimal PHI: read current block param
b.push_block_param_i64();
return;
}
if let Some(pidx) = self.param_index.get(id).copied() {
b.emit_param_i64(pidx);
return;