use super::*;
pub(crate) fn lower_short_circuit_subject(
lowering: &ProtoLowering<'_>,
block: BlockRef,
) -> Option<HirExpr> {
let instr_ref = lowering.cfg.blocks[block.index()].instrs.last()?;
let LowInstr::Branch(branch) = &lowering.proto.instrs[instr_ref.index()] else {
return None;
};
Some(lower_branch_subject(
lowering,
block,
instr_ref,
branch.cond,
))
}
pub(crate) fn lower_short_circuit_subject_inline(
lowering: &ProtoLowering<'_>,
block: BlockRef,
) -> Option<HirExpr> {
let instr_ref = lowering.cfg.blocks[block.index()].instrs.last()?;
let LowInstr::Branch(branch) = &lowering.proto.instrs[instr_ref.index()] else {
return None;
};
Some(lower_branch_subject_inline(
lowering,
block,
instr_ref,
branch.cond,
))
}
pub(crate) fn lower_short_circuit_subject_single_eval(
lowering: &ProtoLowering<'_>,
block: BlockRef,
) -> Option<HirExpr> {
let instr_ref = lowering.cfg.blocks[block.index()].instrs.last()?;
let LowInstr::Branch(branch) = &lowering.proto.instrs[instr_ref.index()] else {
return None;
};
Some(lower_branch_subject_single_eval(
lowering,
block,
instr_ref,
branch.cond,
))
}
pub(crate) fn lower_value_leaf_expr(
lowering: &ProtoLowering<'_>,
short: &ShortCircuitCandidate,
block: BlockRef,
) -> Option<HirExpr> {
if short.nodes.iter().any(|node| node.header == block) {
return lower_short_circuit_subject_single_eval(lowering, block);
}
let def = value_leaf_latest_local_def(short, block)?;
expr_for_fixed_def(lowering, def).or_else(|| expr_for_fixed_def_single_eval(lowering, def))
}
pub(crate) fn lower_materialized_value_leaf_expr(
lowering: &ProtoLowering<'_>,
short: &ShortCircuitCandidate,
block: BlockRef,
) -> Option<HirExpr> {
let reg = short.result_reg?;
if short.nodes.iter().any(|node| node.header == block) {
return lower_short_circuit_subject(lowering, block);
}
if let Some(def) = value_leaf_latest_local_def(short, block) {
return Some(HirExpr::TempRef(lowering.bindings.fixed_temps[def.index()]));
}
Some(expr_for_reg_at_block_entry(lowering, block, reg))
}
fn value_leaf_latest_local_def(short: &ShortCircuitCandidate, block: BlockRef) -> Option<DefId> {
short
.value_incomings
.iter()
.find(|incoming| incoming.pred == block)
.and_then(|incoming| incoming.latest_local_def)
}