use crate::constants_table::ConstantsTable; use crate::ir::assemble::{Assemble, InstructionsBuilder}; use crate::ir::ir_assign::IrAssign; use crate::ir::ir_call::IrCall; use crate::ir::ir_return::IrReturn; use crate::ir::ir_variable::IrVrVariableDescriptor; use crate::ir::register_allocation::{OffsetCounter, VrUser}; use std::collections::{HashMap, HashSet}; use std::fmt::{Display, Formatter}; pub enum IrStatement { Assign(IrAssign), Call(IrCall), Return(IrReturn), } impl VrUser for IrStatement { fn vr_definitions(&self) -> HashSet { match self { IrStatement::Assign(ir_assign) => ir_assign.vr_definitions(), IrStatement::Call(ir_call) => ir_call.vr_definitions(), IrStatement::Return(ir_return) => ir_return.vr_definitions(), } } fn vr_uses(&self) -> HashSet { match self { IrStatement::Assign(ir_assign) => ir_assign.vr_uses(), IrStatement::Call(ir_call) => ir_call.vr_uses(), IrStatement::Return(ir_return) => ir_return.vr_uses(), } } fn propagate_spills(&mut self, spills: &HashSet) { match self { IrStatement::Assign(ir_assign) => { ir_assign.propagate_spills(spills); } IrStatement::Call(ir_call) => { ir_call.propagate_spills(spills); } IrStatement::Return(ir_return) => { ir_return.propagate_spills(spills); } } } fn propagate_register_assignments( &mut self, assignments: &HashMap, ) { match self { IrStatement::Assign(ir_assign) => { ir_assign.propagate_register_assignments(assignments); } IrStatement::Call(ir_call) => { ir_call.propagate_register_assignments(assignments); } IrStatement::Return(ir_return) => { ir_return.propagate_register_assignments(assignments); } } } fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter) { match self { IrStatement::Assign(ir_assign) => { ir_assign.propagate_stack_offsets(counter); } IrStatement::Call(ir_call) => { ir_call.propagate_stack_offsets(counter); } IrStatement::Return(ir_return) => { ir_return.propagate_stack_offsets(counter); } } } } impl Assemble for IrStatement { fn assemble(&self, builder: &mut InstructionsBuilder, constants_table: &mut ConstantsTable) { match self { IrStatement::Assign(ir_assign) => { ir_assign.assemble(builder, constants_table); } IrStatement::Call(ir_call) => { ir_call.assemble(builder, constants_table); } IrStatement::Return(ir_return) => { ir_return.assemble(builder, constants_table); } } } } impl Display for IrStatement { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { IrStatement::Assign(ir_assign) => { write!(f, "{}", ir_assign) } IrStatement::Call(ir_call) => { write!(f, "{}", ir_call) } IrStatement::Return(ir_return) => { write!(f, "{}", ir_return) } } } }