builder: pre-pin comparison operands in if_form and loop_builder (lower_if_in_loop/build_loop) to slots; utils: pin_to_slot pub(crate) and entry materialize for pinned slots only; continue JSON VM debug

This commit is contained in:
Selfhosting Dev
2025-09-26 04:17:56 +09:00
parent fd56b8049a
commit 6e1bf149fc
11 changed files with 1112 additions and 6 deletions

View File

@ -150,6 +150,22 @@ impl<'a> LoopBuilder<'a> {
self.prepare_loop_variables(header_id, preheader_id)?;
// 5. 条件評価Phi nodeの結果を使用
// Heuristic pre-pin: if condition is a comparison, evaluate its operands and pin them
// so that the loop body/next iterations can safely reuse these values across blocks.
if let ASTNode::BinaryOp { operator, left, right, .. } = &condition {
use crate::ast::BinaryOperator as BO;
match operator {
BO::Equal | BO::NotEqual | BO::Less | BO::LessEqual | BO::Greater | BO::GreaterEqual => {
if let Ok(lhs_v) = self.parent_builder.build_expression((**left).clone()) {
let _ = self.parent_builder.pin_to_slot(lhs_v, "@loop_if_lhs");
}
if let Ok(rhs_v) = self.parent_builder.build_expression((**right).clone()) {
let _ = self.parent_builder.pin_to_slot(rhs_v, "@loop_if_rhs");
}
}
_ => {}
}
}
let condition_value = self.build_expression_with_phis(condition)?;
// 6. 条件分岐
@ -450,6 +466,21 @@ impl<'a> LoopBuilder<'a> {
then_body: Vec<ASTNode>,
else_body: Option<Vec<ASTNode>>,
) -> Result<ValueId, String> {
// Pre-pin comparison operands to slots so repeated uses across blocks are safe
if let ASTNode::BinaryOp { operator, left, right, .. } = &condition {
use crate::ast::BinaryOperator as BO;
match operator {
BO::Equal | BO::NotEqual | BO::Less | BO::LessEqual | BO::Greater | BO::GreaterEqual => {
if let Ok(lhs_v) = self.parent_builder.build_expression((**left).clone()) {
let _ = self.parent_builder.pin_to_slot(lhs_v, "@loop_if_lhs");
}
if let Ok(rhs_v) = self.parent_builder.build_expression((**right).clone()) {
let _ = self.parent_builder.pin_to_slot(rhs_v, "@loop_if_rhs");
}
}
_ => {}
}
}
// Evaluate condition and create blocks
let cond_val = self.parent_builder.build_expression(condition)?;
let then_bb = self.new_block();