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)— 進捗中
|
3) 10_7: 分岐配線(Cranelift)— 進捗中
|
||||||
- LowerCore: BB整列・マッピング→builderの`prepare_blocks/switch/seal/br_if/jump`呼出 ✅
|
- LowerCore: BB整列・マッピング→builderの`prepare_blocks/switch/seal/br_if/jump`呼出 ✅
|
||||||
- CraneliftBuilder: ブロック配列管理、`brif/jump`実装、条件b1/`i64!=0`両対応 ✅
|
- 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へ正規化(分岐条件入力に対応)
|
- 返り値は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>,
|
known_i64: std::collections::HashMap<ValueId, i64>,
|
||||||
/// Parameter index mapping for ValueId
|
/// Parameter index mapping for ValueId
|
||||||
param_index: std::collections::HashMap<ValueId, usize>,
|
param_index: std::collections::HashMap<ValueId, usize>,
|
||||||
|
/// Track values produced by Phi (for minimal PHI path)
|
||||||
|
phi_values: std::collections::HashSet<ValueId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LowerCore {
|
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.
|
/// Walk the MIR function and count supported/unsupported instructions.
|
||||||
/// In the future, this will build CLIF via Cranelift builders.
|
/// 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.prepare_signature_i64(func.params.len(), true);
|
||||||
builder.begin_function(&func.signature.name);
|
builder.begin_function(&func.signature.name);
|
||||||
// Iterate blocks in the sorted order to keep indices stable
|
// Iterate blocks in the sorted order to keep indices stable
|
||||||
|
self.phi_values.clear();
|
||||||
for (idx, bb_id) in bb_ids.iter().enumerate() {
|
for (idx, bb_id) in bb_ids.iter().enumerate() {
|
||||||
let bb = func.blocks.get(bb_id).unwrap();
|
let bb = func.blocks.get(bb_id).unwrap();
|
||||||
builder.switch_to_block(idx);
|
builder.switch_to_block(idx);
|
||||||
for instr in bb.instructions.iter() {
|
for instr in bb.instructions.iter() {
|
||||||
self.cover_if_supported(instr);
|
self.cover_if_supported(instr);
|
||||||
|
if let MirInstruction::Phi { dst, .. } = instr { self.phi_values.insert(*dst); }
|
||||||
self.try_emit(builder, instr);
|
self.try_emit(builder, instr);
|
||||||
}
|
}
|
||||||
if let Some(term) = &bb.terminator {
|
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.
|
/// 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) {
|
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() {
|
if let Some(pidx) = self.param_index.get(id).copied() {
|
||||||
b.emit_param_i64(pidx);
|
b.emit_param_i64(pidx);
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user