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:
@ -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`)
|
||||
|
||||
備考(制限と次の着手点)
|
||||
- 返り値はi64(VMValue::Integer)に限定。f64はconst最小emit、boolはi64 0/1へ正規化(分岐条件入力に対応)
|
||||
|
||||
18
examples/jit_phi_demo.nyash
Normal file
18
examples/jit_phi_demo.nyash
Normal 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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user