ssot(cf): bridge set_branch/set_jump/insert_phi adopted across expr/ternary/match/try_catch/loop; builder emission compare/branch/jump delegate to cf_common; add canaries (ternary/match); docs: note cf_common adoption
This commit is contained in:
@ -5,11 +5,20 @@ use crate::mir::builder::MirBuilder;
|
||||
|
||||
#[inline]
|
||||
pub fn emit_conditional(b: &mut MirBuilder, cond: crate::mir::ValueId, then_bb: BasicBlockId, else_bb: BasicBlockId) -> Result<(), String> {
|
||||
if let (Some(func), Some(cur_bb)) = (b.current_function.as_mut(), b.current_block) {
|
||||
crate::mir::ssot::cf_common::set_branch(func, cur_bb, cond, then_bb, else_bb);
|
||||
Ok(())
|
||||
} else {
|
||||
b.emit_instruction(MirInstruction::Branch { condition: cond, then_bb, else_bb })
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn emit_jump(b: &mut MirBuilder, target: BasicBlockId) -> Result<(), String> {
|
||||
if let (Some(func), Some(cur_bb)) = (b.current_function.as_mut(), b.current_block) {
|
||||
crate::mir::ssot::cf_common::set_jump(func, cur_bb, target);
|
||||
Ok(())
|
||||
} else {
|
||||
b.emit_instruction(MirInstruction::Jump { target })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,7 +5,11 @@ use crate::mir::builder::MirBuilder;
|
||||
|
||||
#[inline]
|
||||
pub fn emit_to(b: &mut MirBuilder, dst: ValueId, op: CompareOp, lhs: ValueId, rhs: ValueId) -> Result<(), String> {
|
||||
if let (Some(func), Some(cur_bb)) = (b.current_function.as_mut(), b.current_block) {
|
||||
crate::mir::ssot::cf_common::emit_compare_func(func, cur_bb, dst, op, lhs, rhs);
|
||||
} else {
|
||||
b.emit_instruction(MirInstruction::Compare { dst, op, lhs, rhs })?;
|
||||
}
|
||||
// 比較結果は Bool 型(既存実装と同じ振る舞い)
|
||||
b.value_types.insert(dst, MirType::Bool);
|
||||
Ok(())
|
||||
@ -21,4 +25,3 @@ pub fn emit_eq_to(b: &mut MirBuilder, dst: ValueId, lhs: ValueId, rhs: ValueId)
|
||||
pub fn emit_ne_to(b: &mut MirBuilder, dst: ValueId, lhs: ValueId, rhs: ValueId) -> Result<(), String> {
|
||||
emit_to(b, dst, CompareOp::Ne, lhs, rhs)
|
||||
}
|
||||
|
||||
|
||||
57
src/mir/ssot/cf_common.rs
Normal file
57
src/mir/ssot/cf_common.rs
Normal file
@ -0,0 +1,57 @@
|
||||
use crate::mir::{BasicBlockId, CompareOp, MirFunction, MirInstruction, ValueId};
|
||||
|
||||
/// Emit a MIR Compare instruction into the current block (function-level SSOT helper)
|
||||
pub fn emit_compare_func(
|
||||
f: &mut MirFunction,
|
||||
cur_bb: BasicBlockId,
|
||||
dst: ValueId,
|
||||
op: CompareOp,
|
||||
lhs: ValueId,
|
||||
rhs: ValueId,
|
||||
) {
|
||||
if let Some(bb) = f.get_block_mut(cur_bb) {
|
||||
bb.add_instruction(MirInstruction::Compare { dst, op, lhs, rhs });
|
||||
}
|
||||
}
|
||||
|
||||
/// Set a conditional branch terminator on the current block and register predecessors.
|
||||
pub fn set_branch(
|
||||
f: &mut MirFunction,
|
||||
cur_bb: BasicBlockId,
|
||||
condition: ValueId,
|
||||
then_bb: BasicBlockId,
|
||||
else_bb: BasicBlockId,
|
||||
) {
|
||||
if let Some(bb) = f.get_block_mut(cur_bb) {
|
||||
bb.set_terminator(MirInstruction::Branch { condition, then_bb, else_bb });
|
||||
}
|
||||
if let Some(tb) = f.get_block_mut(then_bb) {
|
||||
tb.add_predecessor(cur_bb);
|
||||
}
|
||||
if let Some(eb) = f.get_block_mut(else_bb) {
|
||||
eb.add_predecessor(cur_bb);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set an unconditional jump terminator and register predecessor on target block.
|
||||
pub fn set_jump(f: &mut MirFunction, cur_bb: BasicBlockId, target: BasicBlockId) {
|
||||
if let Some(bb) = f.get_block_mut(cur_bb) {
|
||||
bb.set_terminator(MirInstruction::Jump { target });
|
||||
}
|
||||
if let Some(tb) = f.get_block_mut(target) {
|
||||
tb.add_predecessor(cur_bb);
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert a PHI instruction at block head (after existing PHIs) with normalized inputs order.
|
||||
pub fn insert_phi_at_head(
|
||||
f: &mut MirFunction,
|
||||
bb_id: BasicBlockId,
|
||||
dst: ValueId,
|
||||
mut inputs: Vec<(BasicBlockId, ValueId)>,
|
||||
) {
|
||||
inputs.sort_by_key(|(bb, _)| bb.0);
|
||||
if let Some(bb) = f.get_block_mut(bb_id) {
|
||||
bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs });
|
||||
}
|
||||
}
|
||||
@ -1,2 +1,3 @@
|
||||
pub mod binop_lower;
|
||||
pub mod loop_common;
|
||||
pub mod cf_common;
|
||||
|
||||
@ -118,12 +118,8 @@ impl BridgeEnv {
|
||||
|
||||
/// Small helper: set Jump terminator and record predecessor on the target.
|
||||
fn jump_with_pred(f: &mut MirFunction, cur_bb: BasicBlockId, target: BasicBlockId) {
|
||||
if let Some(bb) = f.get_block_mut(cur_bb) {
|
||||
bb.set_terminator(MirInstruction::Jump { target });
|
||||
}
|
||||
if let Some(succ) = f.get_block_mut(target) {
|
||||
succ.add_predecessor(cur_bb);
|
||||
}
|
||||
// Delegate to SSOT CF helper for consistency
|
||||
crate::mir::ssot::cf_common::set_jump(f, cur_bb, target);
|
||||
}
|
||||
|
||||
/// Strip Phi instructions by inserting edge copies on each predecessor.
|
||||
|
||||
@ -190,14 +190,7 @@ pub(super) fn lower_expr_with_scope<S: VarScope>(
|
||||
_ => return Err("unsupported compare op".into()),
|
||||
};
|
||||
let dst = f.next_value_id();
|
||||
if let Some(bb) = f.get_block_mut(cur_after_r) {
|
||||
bb.add_instruction(MirInstruction::Compare {
|
||||
dst,
|
||||
op: cop,
|
||||
lhs: l,
|
||||
rhs: r,
|
||||
});
|
||||
}
|
||||
crate::mir::ssot::cf_common::emit_compare_func(f, cur_after_r, dst, cop, l, r);
|
||||
Ok((dst, cur_after_r))
|
||||
}
|
||||
ExprV0::Logical { op, lhs, rhs } => {
|
||||
@ -206,20 +199,10 @@ pub(super) fn lower_expr_with_scope<S: VarScope>(
|
||||
let fall_bb = new_block(f);
|
||||
let merge_bb = new_block(f);
|
||||
let is_and = matches!(op.as_str(), "&&" | "and");
|
||||
if let Some(bb) = f.get_block_mut(cur_after_l) {
|
||||
if is_and {
|
||||
bb.set_terminator(MirInstruction::Branch {
|
||||
condition: l,
|
||||
then_bb: rhs_bb,
|
||||
else_bb: fall_bb,
|
||||
});
|
||||
crate::mir::ssot::cf_common::set_branch(f, cur_after_l, l, rhs_bb, fall_bb);
|
||||
} else {
|
||||
bb.set_terminator(MirInstruction::Branch {
|
||||
condition: l,
|
||||
then_bb: fall_bb,
|
||||
else_bb: rhs_bb,
|
||||
});
|
||||
}
|
||||
crate::mir::ssot::cf_common::set_branch(f, cur_after_l, l, fall_bb, rhs_bb);
|
||||
}
|
||||
// ARCHIVED: JIT events moved to archive/jit-cranelift/ during Phase 15
|
||||
// crate::jit::events::emit_lower(
|
||||
@ -229,32 +212,21 @@ pub(super) fn lower_expr_with_scope<S: VarScope>(
|
||||
// );
|
||||
let cdst = f.next_value_id();
|
||||
if let Some(bb) = f.get_block_mut(fall_bb) {
|
||||
let cval = if is_and {
|
||||
ConstValue::Bool(false)
|
||||
} else {
|
||||
ConstValue::Bool(true)
|
||||
};
|
||||
let cval = if is_and { ConstValue::Bool(false) } else { ConstValue::Bool(true) };
|
||||
bb.add_instruction(MirInstruction::Const { dst: cdst, value: cval });
|
||||
bb.set_terminator(MirInstruction::Jump { target: merge_bb });
|
||||
}
|
||||
crate::mir::ssot::cf_common::set_jump(f, fall_bb, merge_bb);
|
||||
let (rval, rhs_end) = lower_expr_with_scope(env, f, rhs_bb, rhs, vars)?;
|
||||
if let Some(bb) = f.get_block_mut(rhs_end) {
|
||||
if !bb.is_terminated() {
|
||||
bb.set_terminator(MirInstruction::Jump { target: merge_bb });
|
||||
crate::mir::ssot::cf_common::set_jump(f, rhs_end, merge_bb);
|
||||
}
|
||||
}
|
||||
let out = f.next_value_id();
|
||||
// フェーズM.2: PHI統一処理(no_phi分岐削除)
|
||||
if let Some(bb) = f.get_block_mut(merge_bb) {
|
||||
let mut inputs: Vec<(BasicBlockId, ValueId)> = vec![(fall_bb, cdst)];
|
||||
if rhs_end != fall_bb {
|
||||
inputs.push((rhs_end, rval));
|
||||
} else {
|
||||
inputs.push((fall_bb, rval));
|
||||
}
|
||||
inputs.sort_by_key(|(bbid, _)| bbid.0);
|
||||
bb.insert_instruction_after_phis(MirInstruction::Phi { dst: out, inputs });
|
||||
}
|
||||
if rhs_end != fall_bb { inputs.push((rhs_end, rval)); } else { inputs.push((fall_bb, rval)); }
|
||||
crate::mir::ssot::cf_common::insert_phi_at_head(f, merge_bb, out, inputs);
|
||||
Ok((out, merge_bb))
|
||||
}
|
||||
ExprV0::Call { name, args } => {
|
||||
|
||||
@ -18,34 +18,26 @@ pub(super) fn lower_if_stmt(
|
||||
let then_bb = new_block(f);
|
||||
let else_bb = new_block(f);
|
||||
let merge_bb = new_block(f);
|
||||
f.set_branch_terminator(cur, cval, then_bb, else_bb)?;
|
||||
crate::mir::ssot::cf_common::set_branch(f, cur, cval, then_bb, else_bb);
|
||||
let base_vars = vars.clone();
|
||||
let mut then_vars = base_vars.clone();
|
||||
let tend = lower_stmt_list_with_vars(f, then_bb, then_body, &mut then_vars, loop_stack, env)?;
|
||||
let mut then_terminated = false;
|
||||
if let Some(bb) = f.get_block_mut(tend) {
|
||||
if !bb.is_terminated() {
|
||||
bb.set_terminator(MirInstruction::Jump { target: merge_bb });
|
||||
} else {
|
||||
then_terminated = true;
|
||||
}
|
||||
if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, tend, merge_bb); }
|
||||
else { then_terminated = true; }
|
||||
}
|
||||
let (else_end_pred, else_vars, else_terminated) = if let Some(elses) = else_body {
|
||||
let mut ev = base_vars.clone();
|
||||
let eend = lower_stmt_list_with_vars(f, else_bb, elses, &mut ev, loop_stack, env)?;
|
||||
let mut term = false;
|
||||
if let Some(bb) = f.get_block_mut(eend) {
|
||||
if !bb.is_terminated() {
|
||||
bb.set_terminator(MirInstruction::Jump { target: merge_bb });
|
||||
} else {
|
||||
term = true;
|
||||
}
|
||||
if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, eend, merge_bb); }
|
||||
else { term = true; }
|
||||
}
|
||||
(eend, ev, term)
|
||||
} else {
|
||||
if let Some(bb) = f.get_block_mut(else_bb) {
|
||||
bb.set_terminator(MirInstruction::Jump { target: merge_bb });
|
||||
}
|
||||
crate::mir::ssot::cf_common::set_jump(f, else_bb, merge_bb);
|
||||
(else_bb, base_vars.clone(), false)
|
||||
};
|
||||
// If both branches terminate (e.g., both return/throw), no merge or var-join is needed.
|
||||
|
||||
@ -33,9 +33,7 @@ pub(super) fn lower_loop_stmt(
|
||||
|
||||
// 2) preheader → header へ Jump(ヘッダで Phi を組む前に制御を渡す)
|
||||
if let Some(bb) = f.get_block_mut(cur_bb) {
|
||||
if !bb.is_terminated() {
|
||||
bb.add_instruction(MirInstruction::Jump { target: cond_bb });
|
||||
}
|
||||
if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, cur_bb, cond_bb); }
|
||||
}
|
||||
|
||||
// 3) LoopPhiOps アダプタ(準備用: preheader seed 専用)
|
||||
@ -115,13 +113,7 @@ pub(super) fn lower_loop_stmt(
|
||||
let header_vars_snapshot = ops.vars.clone();
|
||||
|
||||
let (cval, _cend) = super::expr::lower_expr_with_vars(env, ops.f, cond_bb, cond, ops.vars)?;
|
||||
if let Some(bb) = ops.f.get_block_mut(cond_bb) {
|
||||
bb.set_terminator(MirInstruction::Branch {
|
||||
condition: cval,
|
||||
then_bb: body_bb,
|
||||
else_bb: exit_bb,
|
||||
});
|
||||
}
|
||||
crate::mir::ssot::cf_common::set_branch(ops.f, cond_bb, cval, body_bb, exit_bb);
|
||||
let mut body_vars = ops.vars.clone();
|
||||
// open snapshot frames for nested break/continue
|
||||
super::push_loop_snapshot_frames();
|
||||
@ -140,9 +132,7 @@ pub(super) fn lower_loop_stmt(
|
||||
block_var_maps2.insert(cur_bb, base_vars.clone());
|
||||
block_var_maps2.insert(bend, body_vars.clone());
|
||||
if let Some(bb) = ops.f.get_block_mut(bend) {
|
||||
if !bb.is_terminated() {
|
||||
bb.set_terminator(MirInstruction::Jump { target: cond_bb });
|
||||
}
|
||||
if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(ops.f, bend, cond_bb); }
|
||||
}
|
||||
let backedge_to_cond = matches!(
|
||||
ops.f.blocks
|
||||
|
||||
@ -21,9 +21,7 @@ pub(super) fn lower_match_expr_with_scope<S: VarScope>(
|
||||
// Set up blocks
|
||||
let dispatch_bb = new_block(f);
|
||||
if let Some(bb) = f.get_block_mut(start_bb) {
|
||||
if !bb.is_terminated() {
|
||||
bb.set_terminator(MirInstruction::Jump { target: dispatch_bb });
|
||||
}
|
||||
if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, start_bb, dispatch_bb); }
|
||||
}
|
||||
let else_bb = new_block(f);
|
||||
let merge_bb = new_block(f);
|
||||
@ -42,16 +40,14 @@ pub(super) fn lower_match_expr_with_scope<S: VarScope>(
|
||||
if let Some(bb) = f.get_block_mut(cur_dispatch) {
|
||||
// compare scr_val == label
|
||||
bb.add_instruction(MirInstruction::Const { dst: ldst, value: ConstValue::String(arm.label.clone()) });
|
||||
bb.add_instruction(MirInstruction::Compare { dst: cond, op: CompareOp::Eq, lhs: scr_val, rhs: ldst });
|
||||
bb.set_terminator(MirInstruction::Branch { condition: cond, then_bb, else_bb: fall_bb });
|
||||
}
|
||||
crate::mir::ssot::cf_common::emit_compare_func(f, cur_dispatch, cond, CompareOp::Eq, scr_val, ldst);
|
||||
crate::mir::ssot::cf_common::set_branch(f, cur_dispatch, cond, then_bb, fall_bb);
|
||||
|
||||
// Then arm body
|
||||
let (tval, tend) = lower_expr_with_scope(env, f, then_bb, &arm.expr, vars)?;
|
||||
if let Some(bb) = f.get_block_mut(tend) {
|
||||
if !bb.is_terminated() {
|
||||
bb.set_terminator(MirInstruction::Jump { target: merge_bb });
|
||||
}
|
||||
if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, tend, merge_bb); }
|
||||
}
|
||||
phi_inputs.push((tend, tval));
|
||||
|
||||
@ -61,19 +57,14 @@ pub(super) fn lower_match_expr_with_scope<S: VarScope>(
|
||||
// Else body
|
||||
let (eval, eend) = lower_expr_with_scope(env, f, else_bb, else_expr, vars)?;
|
||||
if let Some(bb) = f.get_block_mut(eend) {
|
||||
if !bb.is_terminated() {
|
||||
bb.set_terminator(MirInstruction::Jump { target: merge_bb });
|
||||
}
|
||||
if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, eend, merge_bb); }
|
||||
}
|
||||
phi_inputs.push((eend, eval));
|
||||
|
||||
// Merge result
|
||||
let out = f.next_value_id();
|
||||
// フェーズM.2: PHI統一処理(no_phi分岐削除)
|
||||
if let Some(bb) = f.get_block_mut(merge_bb) {
|
||||
let mut inputs = phi_inputs;
|
||||
inputs.sort_by_key(|(bbid, _)| bbid.0);
|
||||
bb.insert_instruction_after_phis(MirInstruction::Phi { dst: out, inputs });
|
||||
}
|
||||
let inputs = phi_inputs;
|
||||
crate::mir::ssot::cf_common::insert_phi_at_head(f, merge_bb, out, inputs);
|
||||
Ok((out, merge_bb))
|
||||
}
|
||||
|
||||
@ -42,11 +42,13 @@ pub(super) fn merge_values(
|
||||
if let Some(bb) = f.get_block_mut(pred_b) {
|
||||
bb.add_instruction_before_terminator(MirInstruction::Copy { dst, src: val_b });
|
||||
}
|
||||
} else if let Some(bb) = f.get_block_mut(merge_bb) {
|
||||
bb.insert_instruction_after_phis(MirInstruction::Phi {
|
||||
} else {
|
||||
crate::mir::ssot::cf_common::insert_phi_at_head(
|
||||
f,
|
||||
merge_bb,
|
||||
dst,
|
||||
inputs: vec![(pred_a, val_a), (pred_b, val_b)],
|
||||
});
|
||||
vec![(pred_a, val_a), (pred_b, val_b)],
|
||||
);
|
||||
}
|
||||
dst
|
||||
}
|
||||
@ -97,4 +99,3 @@ pub(super) fn merge_var_maps(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,31 +24,18 @@ pub(super) fn lower_ternary_expr_with_scope<S: VarScope>(
|
||||
let then_bb = new_block(f);
|
||||
let else_bb = new_block(f);
|
||||
let merge_bb = new_block(f);
|
||||
if let Some(bb) = f.get_block_mut(cur) {
|
||||
bb.set_terminator(MirInstruction::Branch {
|
||||
condition: cval,
|
||||
then_bb,
|
||||
else_bb,
|
||||
});
|
||||
}
|
||||
crate::mir::ssot::cf_common::set_branch(f, cur, cval, then_bb, else_bb);
|
||||
let (tval, tend) = lower_expr_with_scope(env, f, then_bb, then_e, vars)?;
|
||||
if let Some(bb) = f.get_block_mut(tend) {
|
||||
if !bb.is_terminated() {
|
||||
bb.set_terminator(MirInstruction::Jump { target: merge_bb });
|
||||
}
|
||||
if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, tend, merge_bb); }
|
||||
}
|
||||
let (eval, eend) = lower_expr_with_scope(env, f, else_bb, else_e, vars)?;
|
||||
if let Some(bb) = f.get_block_mut(eend) {
|
||||
if !bb.is_terminated() {
|
||||
bb.set_terminator(MirInstruction::Jump { target: merge_bb });
|
||||
}
|
||||
if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, eend, merge_bb); }
|
||||
}
|
||||
let out = f.next_value_id();
|
||||
// フェーズM.2: PHI統一処理(no_phi分岐削除)
|
||||
if let Some(bb) = f.get_block_mut(merge_bb) {
|
||||
let mut inputs = vec![(tend, tval), (eend, eval)];
|
||||
inputs.sort_by_key(|(bbid, _)| bbid.0);
|
||||
bb.insert_instruction_after_phis(MirInstruction::Phi { dst: out, inputs });
|
||||
}
|
||||
crate::mir::ssot::cf_common::insert_phi_at_head(f, merge_bb, out, inputs);
|
||||
Ok((out, merge_bb))
|
||||
}
|
||||
|
||||
@ -37,12 +37,7 @@ pub(super) fn record_throw(f: &mut MirFunction, from_bb: BasicBlockId, exc_val:
|
||||
THROW_CTX.with(|slot| {
|
||||
if let Some(ctx) = slot.borrow_mut().as_mut() {
|
||||
let target = ctx.catch_bb;
|
||||
if let Some(bb) = f.get_block_mut(from_bb) {
|
||||
bb.set_terminator(MirInstruction::Jump { target });
|
||||
}
|
||||
if let Some(succ) = f.get_block_mut(target) {
|
||||
succ.add_predecessor(from_bb);
|
||||
}
|
||||
crate::mir::ssot::cf_common::set_jump(f, from_bb, target);
|
||||
ctx.incoming.push((from_bb, exc_val));
|
||||
Some(target)
|
||||
} else {
|
||||
|
||||
@ -69,10 +69,10 @@ pub(super) fn lower_try_stmt(
|
||||
// フェーズM.2: PHI統一処理(no_phi条件削除)
|
||||
if !incoming_exc.is_empty() {
|
||||
let phi_dst = f.next_value_id();
|
||||
if let Some(bb) = f.get_block_mut(catch_bb) {
|
||||
if let Some(_bb) = f.get_block_mut(catch_bb) {
|
||||
let mut inputs = incoming_exc.clone();
|
||||
inputs.sort_by_key(|(bbid, _)| bbid.0);
|
||||
bb.insert_instruction_after_phis(MirInstruction::Phi { dst: phi_dst, inputs });
|
||||
crate::mir::ssot::cf_common::insert_phi_at_head(f, catch_bb, phi_dst, inputs);
|
||||
}
|
||||
catch_vars.insert(param.clone(), phi_dst);
|
||||
}
|
||||
@ -125,8 +125,8 @@ pub(super) fn lower_try_stmt(
|
||||
phi_entries.push((dst, inputs));
|
||||
merged_vars.insert(name.clone(), dst);
|
||||
}
|
||||
if let Some(bb) = f.get_block_mut(finally_block) {
|
||||
for (dst, inputs) in phi_entries { bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs }); }
|
||||
if let Some(_bb) = f.get_block_mut(finally_block) {
|
||||
for (dst, inputs) in phi_entries { crate::mir::ssot::cf_common::insert_phi_at_head(f, finally_block, dst, inputs); }
|
||||
}
|
||||
let mut finally_vars = merged_vars.clone();
|
||||
let final_end = super::lower_stmt_list_with_vars(f, finally_block, finally, &mut finally_vars, loop_stack, env)?;
|
||||
@ -156,8 +156,8 @@ pub(super) fn lower_try_stmt(
|
||||
phi_entries.push((dst, inputs));
|
||||
merged_vars.insert(name.clone(), dst);
|
||||
}
|
||||
if let Some(bb) = f.get_block_mut(exit_bb) {
|
||||
for (dst, inputs) in phi_entries { bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs }); }
|
||||
if let Some(_bb) = f.get_block_mut(exit_bb) {
|
||||
for (dst, inputs) in phi_entries { crate::mir::ssot::cf_common::insert_phi_at_head(f, exit_bb, dst, inputs); }
|
||||
}
|
||||
*vars = merged_vars;
|
||||
return Ok(exit_bb);
|
||||
@ -259,10 +259,8 @@ pub(super) fn lower_try_stmt(
|
||||
merged_vars.insert(name.clone(), dst);
|
||||
}
|
||||
// フェーズM.2: PHI統一処理(no_phi分岐削除)
|
||||
if let Some(bb) = f.get_block_mut(finally_block) {
|
||||
for (dst, inputs) in phi_entries {
|
||||
bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs });
|
||||
}
|
||||
if let Some(_bb) = f.get_block_mut(finally_block) {
|
||||
for (dst, inputs) in phi_entries { crate::mir::ssot::cf_common::insert_phi_at_head(f, finally_block, dst, inputs); }
|
||||
}
|
||||
let mut finally_vars = merged_vars.clone();
|
||||
let final_end = lower_stmt_list_with_vars(
|
||||
@ -310,10 +308,8 @@ pub(super) fn lower_try_stmt(
|
||||
merged_vars.insert(name.clone(), dst);
|
||||
}
|
||||
// フェーズM.2: PHI統一処理(no_phi分岐削除)
|
||||
if let Some(bb) = f.get_block_mut(exit_bb) {
|
||||
for (dst, inputs) in phi_entries {
|
||||
bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs });
|
||||
}
|
||||
if let Some(_bb) = f.get_block_mut(exit_bb) {
|
||||
for (dst, inputs) in phi_entries { crate::mir::ssot::cf_common::insert_phi_at_head(f, exit_bb, dst, inputs); }
|
||||
}
|
||||
*vars = merged_vars;
|
||||
Ok(exit_bb)
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
# Match lowering via JSON v0 bridge (SSOT cf_common) → expect rc=2
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"; if ROOT_GIT=$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null); then ROOT="$ROOT_GIT"; else ROOT="$(cd "$SCRIPT_DIR/../../../../../../../../.." && pwd)"; fi
|
||||
source "$ROOT/tools/smokes/v2/lib/test_runner.sh"; require_env || exit 2
|
||||
|
||||
tmp_json="/tmp/program_match_$$.json"
|
||||
cat > "$tmp_json" <<'JSON'
|
||||
{
|
||||
"version": 0,
|
||||
"kind": "Program",
|
||||
"body": [
|
||||
{ "type":"Local", "name":"s", "expr": {"type":"Str","value":"b"} },
|
||||
{ "type":"Local", "name":"x", "expr": {"type":"Match","scrutinee":{"type":"Var","name":"s"},
|
||||
"arms":[
|
||||
{"label":"a","expr":{"type":"Int","value":1}},
|
||||
{"label":"b","expr":{"type":"Int","value":2}}
|
||||
],
|
||||
"else":{"type":"Int","value":9}
|
||||
} },
|
||||
{ "type":"Return", "expr": {"type":"Var","name":"x"} }
|
||||
]
|
||||
}
|
||||
JSON
|
||||
|
||||
set +e
|
||||
HAKO_VERIFY_PRIMARY=core verify_mir_rc "$tmp_json" >/dev/null 2>&1
|
||||
rc=$?
|
||||
set -e
|
||||
rm -f "$tmp_json" || true
|
||||
|
||||
if [ "$rc" -eq 2 ]; then
|
||||
echo "[PASS] mirbuilder_match_core_exec_canary_vm"
|
||||
exit 0
|
||||
fi
|
||||
echo "[FAIL] mirbuilder_match_core_exec_canary_vm (rc=$rc, expect 2)" >&2; exit 1
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
# Ternary lowering via JSON v0 bridge (SSOT cf_common) → expect rc=1
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"; if ROOT_GIT=$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null); then ROOT="$ROOT_GIT"; else ROOT="$(cd "$SCRIPT_DIR/../../../../../../../../.." && pwd)"; fi
|
||||
source "$ROOT/tools/smokes/v2/lib/test_runner.sh"; require_env || exit 2
|
||||
|
||||
tmp_json="/tmp/program_ternary_$$.json"
|
||||
cat > "$tmp_json" <<'JSON'
|
||||
{
|
||||
"version": 0,
|
||||
"kind": "Program",
|
||||
"body": [
|
||||
{ "type":"Local", "name":"c", "expr": {"type":"Bool","value":true} },
|
||||
{ "type":"Local", "name":"x", "expr": {"type":"Ternary", "cond":{"type":"Var","name":"c"}, "then":{"type":"Int","value":1}, "else":{"type":"Int","value":2}} },
|
||||
{ "type":"Return", "expr": {"type":"Var","name":"x"} }
|
||||
]
|
||||
}
|
||||
JSON
|
||||
|
||||
set +e
|
||||
HAKO_VERIFY_PRIMARY=core verify_mir_rc "$tmp_json" >/dev/null 2>&1
|
||||
rc=$?
|
||||
set -e
|
||||
rm -f "$tmp_json" || true
|
||||
|
||||
if [ "$rc" -eq 1 ]; then
|
||||
echo "[PASS] mirbuilder_ternary_core_exec_canary_vm"
|
||||
exit 0
|
||||
fi
|
||||
echo "[FAIL] mirbuilder_ternary_core_exec_canary_vm (rc=$rc, expect 1)" >&2; exit 1
|
||||
|
||||
Reference in New Issue
Block a user