use crate::constants_table::ConstantsTable; use crate::ir::ir_expression::IrExpression; use crate::ir::ir_variable::IrVrVariableDescriptor; use crate::ir::register_allocation::{OffsetCounter, VrUser}; use dvm_lib::instruction::AddOperand; use std::collections::{HashMap, HashSet}; use std::fmt::{Display, Formatter}; pub struct IrAdd { left: Box, right: Box, } impl IrAdd { pub fn new(left: IrExpression, right: IrExpression) -> Self { Self { left: left.into(), right: right.into(), } } pub fn left(&self) -> &IrExpression { &self.left } pub fn right(&self) -> &IrExpression { &self.right } pub fn operand_pair(&self, constants_table: &mut ConstantsTable) -> (AddOperand, AddOperand) { ( self.left.add_operand(constants_table), self.right.add_operand(constants_table), ) } } impl Display for IrAdd { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{} + {}", self.left, self.right) } } impl VrUser for IrAdd { fn vr_definitions(&self) -> HashSet { [self.left.as_ref(), self.right.as_ref()] .iter() .flat_map(|e| e.vr_definitions()) .collect() } fn vr_uses(&self) -> HashSet { [self.left.as_ref(), self.right.as_ref()] .iter() .flat_map(|e| e.vr_uses()) .collect() } fn propagate_spills(&mut self, spills: &HashSet) { self.left.propagate_spills(spills); self.right.propagate_spills(spills); } fn propagate_register_assignments( &mut self, assignments: &HashMap, ) { self.left.propagate_register_assignments(assignments); self.right.propagate_register_assignments(assignments); } fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) { // no-op, no definitions here } }