From 4a0a6b8425dbaf692237122826012fb2e5af631a Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Sun, 15 Mar 2026 13:15:31 -0500 Subject: [PATCH] Clean up ir vr_user trait and implementations. --- dmc-lib/src/ir/ir_assign.rs | 41 +++-------- dmc-lib/src/ir/ir_binary_operation.rs | 23 +------ dmc-lib/src/ir/ir_call.rs | 27 +------- dmc-lib/src/ir/ir_expression.rs | 80 +--------------------- dmc-lib/src/ir/ir_get_field_ref.rs | 20 +----- dmc-lib/src/ir/ir_get_field_ref_mut.rs | 20 +----- dmc-lib/src/ir/ir_operation.rs | 23 +------ dmc-lib/src/ir/ir_parameter_or_variable.rs | 14 +++- dmc-lib/src/ir/ir_read_field.rs | 18 +---- dmc-lib/src/ir/ir_return.rs | 27 +------- dmc-lib/src/ir/ir_set_field.rs | 26 +------ dmc-lib/src/ir/ir_variable.rs | 9 +++ dmc-lib/src/ir/register_allocation.rs | 22 ++++-- 13 files changed, 71 insertions(+), 279 deletions(-) diff --git a/dmc-lib/src/ir/ir_assign.rs b/dmc-lib/src/ir/ir_assign.rs index 0c0a126..32709e1 100644 --- a/dmc-lib/src/ir/ir_assign.rs +++ b/dmc-lib/src/ir/ir_assign.rs @@ -3,6 +3,7 @@ use crate::ir::assemble::{Assemble, InstructionsBuilder}; use crate::ir::ir_operation::IrOperation; use crate::ir::ir_variable::{IrVariable, IrVariableDescriptor, IrVrVariableDescriptor}; use crate::ir::register_allocation::{OffsetCounter, VrUser}; +use crate::ir::util::propagate_spills; use dvm_lib::instruction::Instruction; use std::cell::RefCell; use std::collections::{HashMap, HashSet}; @@ -25,12 +26,10 @@ impl IrAssign { impl VrUser for IrAssign { fn vr_definitions(&self) -> HashSet { - match self.destination.borrow().descriptor() { - IrVariableDescriptor::VirtualRegister(vr_descriptor) => { - HashSet::from([vr_descriptor.clone()]) - } - IrVariableDescriptor::Stack(_) => HashSet::new(), - } + self.destination + .borrow() + .descriptor() + .vr_variable_descriptors() } fn vr_uses(&self) -> HashSet { @@ -38,39 +37,21 @@ impl VrUser for IrAssign { } fn propagate_spills(&mut self, spills: &HashSet) { - let borrowed_destination = self.destination.borrow(); - if let IrVariableDescriptor::VirtualRegister(vr_variable) = - borrowed_destination.descriptor() - { - if spills.contains(vr_variable) { - let replacement = IrVariable::new_stack( - vr_variable.name().into(), - vr_variable.block_id(), - borrowed_destination.type_info().clone(), - ); - drop(borrowed_destination); - self.destination.replace(replacement); - } - } + propagate_spills(&mut self.destination, spills); } fn propagate_register_assignments( &mut self, assignments: &HashMap, ) { - // Have to isolate the following, because when the destination and the value are the same, - // we get a BorrowMutError + let mut borrowed_destination = self.destination.borrow_mut(); + if let IrVariableDescriptor::VirtualRegister(vr_variable) = + borrowed_destination.descriptor_mut() { - let mut borrowed_destination = self.destination.borrow_mut(); - if let IrVariableDescriptor::VirtualRegister(vr_variable) = - borrowed_destination.descriptor_mut() - { - if assignments.contains_key(vr_variable) { - vr_variable.set_assigned_register(assignments[vr_variable]); - } + if assignments.contains_key(vr_variable) { + vr_variable.set_assigned_register(assignments[vr_variable]); } } - self.initializer.propagate_register_assignments(assignments); } fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter) { diff --git a/dmc-lib/src/ir/ir_binary_operation.rs b/dmc-lib/src/ir/ir_binary_operation.rs index f053f60..5d61c25 100644 --- a/dmc-lib/src/ir/ir_binary_operation.rs +++ b/dmc-lib/src/ir/ir_binary_operation.rs @@ -2,9 +2,9 @@ use crate::constants_table::ConstantsTable; use crate::ir::assemble::InstructionsBuilder; use crate::ir::ir_expression::IrExpression; use crate::ir::ir_variable::IrVrVariableDescriptor; -use crate::ir::register_allocation::{OffsetCounter, VrUser}; +use crate::ir::register_allocation::VrUser; use dvm_lib::instruction::{Instruction, Location}; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use std::fmt::{Display, Formatter}; pub enum IrBinaryOperator { @@ -79,29 +79,10 @@ impl Display for IrBinaryOperation { } impl VrUser for IrBinaryOperation { - fn vr_definitions(&self) -> HashSet { - todo!() - } - 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) { - todo!() - } - - fn propagate_register_assignments( - &mut self, - assignments: &HashMap, - ) { - todo!() - } - - fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter) { - todo!() - } } diff --git a/dmc-lib/src/ir/ir_call.rs b/dmc-lib/src/ir/ir_call.rs index 93710d8..0fc4091 100644 --- a/dmc-lib/src/ir/ir_call.rs +++ b/dmc-lib/src/ir/ir_call.rs @@ -2,9 +2,9 @@ use crate::constants_table::ConstantsTable; use crate::ir::assemble::{Assemble, InstructionsBuilder}; use crate::ir::ir_expression::IrExpression; use crate::ir::ir_variable::IrVrVariableDescriptor; -use crate::ir::register_allocation::{OffsetCounter, VrUser}; +use crate::ir::register_allocation::VrUser; use dvm_lib::instruction::Instruction; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use std::fmt::{Display, Formatter}; use std::rc::Rc; @@ -25,32 +25,9 @@ impl IrCall { } impl VrUser for IrCall { - fn vr_definitions(&self) -> HashSet { - HashSet::new() - } - fn vr_uses(&self) -> HashSet { self.arguments.iter().flat_map(|a| a.vr_uses()).collect() } - - fn propagate_spills(&mut self, spills: &HashSet) { - for argument in &mut self.arguments { - argument.propagate_spills(spills); - } - } - - fn propagate_register_assignments( - &mut self, - assignments: &HashMap, - ) { - for argument in &mut self.arguments { - argument.propagate_register_assignments(assignments); - } - } - - fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) { - // no-op, because no definitions here - } } impl Assemble for IrCall { diff --git a/dmc-lib/src/ir/ir_expression.rs b/dmc-lib/src/ir/ir_expression.rs index b228cea..bb94286 100644 --- a/dmc-lib/src/ir/ir_expression.rs +++ b/dmc-lib/src/ir/ir_expression.rs @@ -1,16 +1,14 @@ use crate::constants_table::ConstantsTable; use crate::ir::ir_parameter::IrParameter; -use crate::ir::ir_variable::{ - IrStackVariableDescriptor, IrVariable, IrVariableDescriptor, IrVrVariableDescriptor, -}; -use crate::ir::register_allocation::{OffsetCounter, VrUser}; +use crate::ir::ir_variable::{IrVariable, IrVariableDescriptor, IrVrVariableDescriptor}; +use crate::ir::register_allocation::VrUser; use crate::type_info::TypeInfo; use dvm_lib::instruction::{ AddOperand, Location, MoveOperand, MultiplyOperand, PushOperand, ReturnOperand, SetFieldOperand, SubtractOperand, }; use std::cell::RefCell; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use std::fmt::{Display, Formatter}; use std::rc::Rc; @@ -231,11 +229,6 @@ impl Display for IrExpression { } impl VrUser for IrExpression { - fn vr_definitions(&self) -> HashSet { - // no defs for an expression - HashSet::new() - } - fn vr_uses(&self) -> HashSet { match self { IrExpression::Parameter(_) => HashSet::new(), @@ -253,71 +246,4 @@ impl VrUser for IrExpression { IrExpression::String(_) => HashSet::new(), } } - - fn propagate_spills(&mut self, spills: &HashSet) { - match self { - IrExpression::Parameter(_) => { - // no-op - } - IrExpression::Variable(ir_variable) => { - if let IrVariableDescriptor::VirtualRegister(vr_variable) = - ir_variable.borrow().descriptor() - { - if spills.contains(&vr_variable) { - ir_variable - .borrow_mut() - .set_descriptor(IrVariableDescriptor::Stack( - IrStackVariableDescriptor::new( - vr_variable.name().into(), - vr_variable.block_id(), - ), - )); - } - } - } - IrExpression::Int(_) => { - // no-op - } - IrExpression::Double(_) => { - // no-op - } - IrExpression::String(_) => { - // no-op - } - } - } - - fn propagate_register_assignments( - &mut self, - assignments: &HashMap, - ) { - match self { - IrExpression::Parameter(_) => { - // no-op - } - IrExpression::Variable(ir_variable) => { - let mut borrowed = ir_variable.borrow_mut(); - if let IrVariableDescriptor::VirtualRegister(vr_variable) = - borrowed.descriptor_mut() - { - if assignments.contains_key(vr_variable) { - vr_variable.set_assigned_register(assignments[vr_variable]); - } - } - } - IrExpression::Int(_) => { - // no-op - } - IrExpression::Double(_) => { - // no-op - } - IrExpression::String(_) => { - // no-op - } - } - } - - fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) { - // no-op - } } diff --git a/dmc-lib/src/ir/ir_get_field_ref.rs b/dmc-lib/src/ir/ir_get_field_ref.rs index 3dcf46e..b1ece0e 100644 --- a/dmc-lib/src/ir/ir_get_field_ref.rs +++ b/dmc-lib/src/ir/ir_get_field_ref.rs @@ -1,7 +1,7 @@ use crate::ir::ir_parameter_or_variable::IrParameterOrVariable; use crate::ir::ir_variable::IrVrVariableDescriptor; -use crate::ir::register_allocation::{OffsetCounter, VrUser}; -use std::collections::{HashMap, HashSet}; +use crate::ir::register_allocation::VrUser; +use std::collections::HashSet; use std::fmt::{Display, Formatter}; pub struct IrGetFieldRef { @@ -37,21 +37,7 @@ impl Display for IrGetFieldRef { } impl VrUser for IrGetFieldRef { - fn vr_definitions(&self) -> HashSet { - HashSet::new() - } - fn vr_uses(&self) -> HashSet { - HashSet::new() + self.self_parameter_or_variable().vr_uses() } - - fn propagate_spills(&mut self, spills: &HashSet) {} - - fn propagate_register_assignments( - &mut self, - assignments: &HashMap, - ) { - } - - fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter) {} } diff --git a/dmc-lib/src/ir/ir_get_field_ref_mut.rs b/dmc-lib/src/ir/ir_get_field_ref_mut.rs index ff854f0..9771653 100644 --- a/dmc-lib/src/ir/ir_get_field_ref_mut.rs +++ b/dmc-lib/src/ir/ir_get_field_ref_mut.rs @@ -1,7 +1,7 @@ use crate::ir::ir_parameter_or_variable::IrParameterOrVariable; use crate::ir::ir_variable::IrVrVariableDescriptor; -use crate::ir::register_allocation::{OffsetCounter, VrUser}; -use std::collections::{HashMap, HashSet}; +use crate::ir::register_allocation::VrUser; +use std::collections::HashSet; use std::fmt::{Display, Formatter}; pub struct IrGetFieldRefMut { @@ -38,21 +38,7 @@ impl Display for IrGetFieldRefMut { } impl VrUser for IrGetFieldRefMut { - fn vr_definitions(&self) -> HashSet { - HashSet::new() - } - fn vr_uses(&self) -> HashSet { - HashSet::new() + self.self_parameter_or_variable.vr_uses() } - - fn propagate_spills(&mut self, spills: &HashSet) {} - - fn propagate_register_assignments( - &mut self, - assignments: &HashMap, - ) { - } - - fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter) {} } diff --git a/dmc-lib/src/ir/ir_operation.rs b/dmc-lib/src/ir/ir_operation.rs index 0d3ca3e..6ecb947 100644 --- a/dmc-lib/src/ir/ir_operation.rs +++ b/dmc-lib/src/ir/ir_operation.rs @@ -6,8 +6,8 @@ use crate::ir::ir_get_field_ref::IrGetFieldRef; use crate::ir::ir_get_field_ref_mut::IrGetFieldRefMut; use crate::ir::ir_read_field::IrReadField; use crate::ir::ir_variable::IrVrVariableDescriptor; -use crate::ir::register_allocation::{OffsetCounter, VrUser}; -use std::collections::{HashMap, HashSet}; +use crate::ir::register_allocation::VrUser; +use std::collections::HashSet; use std::fmt::{Display, Formatter}; pub enum IrOperation { @@ -49,10 +49,6 @@ impl Display for IrOperation { } impl VrUser for IrOperation { - fn vr_definitions(&self) -> HashSet { - HashSet::new() - } - fn vr_uses(&self) -> HashSet { match self { IrOperation::GetFieldRef(ir_get_field_ref) => ir_get_field_ref.vr_uses(), @@ -64,19 +60,4 @@ impl VrUser for IrOperation { IrOperation::Allocate(_) => HashSet::new(), } } - - fn propagate_spills(&mut self, _spills: &HashSet) { - // no-op - } - - fn propagate_register_assignments( - &mut self, - _assignments: &HashMap, - ) { - // no-op - } - - fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) { - // no-op - } } diff --git a/dmc-lib/src/ir/ir_parameter_or_variable.rs b/dmc-lib/src/ir/ir_parameter_or_variable.rs index 895e7cf..cf39697 100644 --- a/dmc-lib/src/ir/ir_parameter_or_variable.rs +++ b/dmc-lib/src/ir/ir_parameter_or_variable.rs @@ -1,7 +1,8 @@ use crate::ir::ir_parameter::IrParameter; -use crate::ir::ir_variable::IrVariable; +use crate::ir::ir_variable::{IrVariable, IrVariableDescriptor, IrVrVariableDescriptor}; use dvm_lib::instruction::Location; use std::cell::RefCell; +use std::collections::HashSet; use std::fmt::{Display, Formatter}; use std::rc::Rc; @@ -22,6 +23,17 @@ impl IrParameterOrVariable { } } } + + pub fn vr_uses(&self) -> HashSet { + if let IrParameterOrVariable::Variable(ir_variable) = &self { + if let IrVariableDescriptor::VirtualRegister(vr_variable) = + ir_variable.borrow().descriptor() + { + return HashSet::from([vr_variable.clone()]); + } + } + HashSet::new() + } } impl Display for IrParameterOrVariable { diff --git a/dmc-lib/src/ir/ir_read_field.rs b/dmc-lib/src/ir/ir_read_field.rs index 2e13670..1e4a1df 100644 --- a/dmc-lib/src/ir/ir_read_field.rs +++ b/dmc-lib/src/ir/ir_read_field.rs @@ -1,7 +1,7 @@ use crate::ir::ir_variable::{IrVariable, IrVariableDescriptor, IrVrVariableDescriptor}; -use crate::ir::register_allocation::{OffsetCounter, VrUser}; +use crate::ir::register_allocation::VrUser; use std::cell::RefCell; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use std::fmt::{Display, Formatter}; use std::rc::Rc; @@ -26,10 +26,6 @@ impl Display for IrReadField { } impl VrUser for IrReadField { - fn vr_definitions(&self) -> HashSet { - HashSet::new() - } - fn vr_uses(&self) -> HashSet { let mut set = HashSet::new(); if let IrVariableDescriptor::VirtualRegister(vr_variable) = @@ -39,14 +35,4 @@ impl VrUser for IrReadField { } set } - - fn propagate_spills(&mut self, spills: &HashSet) {} - - fn propagate_register_assignments( - &mut self, - assignments: &HashMap, - ) { - } - - fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter) {} } diff --git a/dmc-lib/src/ir/ir_return.rs b/dmc-lib/src/ir/ir_return.rs index f2faca2..42c9692 100644 --- a/dmc-lib/src/ir/ir_return.rs +++ b/dmc-lib/src/ir/ir_return.rs @@ -2,9 +2,9 @@ use crate::constants_table::ConstantsTable; use crate::ir::assemble::{Assemble, InstructionsBuilder}; use crate::ir::ir_expression::IrExpression; use crate::ir::ir_variable::IrVrVariableDescriptor; -use crate::ir::register_allocation::{OffsetCounter, VrUser}; +use crate::ir::register_allocation::VrUser; use dvm_lib::instruction::Instruction; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use std::fmt::{Display, Formatter}; pub struct IrReturn { @@ -18,10 +18,6 @@ impl IrReturn { } impl VrUser for IrReturn { - fn vr_definitions(&self) -> HashSet { - HashSet::new() - } - fn vr_uses(&self) -> HashSet { if let Some(ir_expression) = self.value.as_ref() { ir_expression.vr_uses() @@ -29,25 +25,6 @@ impl VrUser for IrReturn { HashSet::new() } } - - fn propagate_spills(&mut self, spills: &HashSet) { - if let Some(ir_expression) = self.value.as_mut() { - ir_expression.propagate_spills(spills); - } - } - - fn propagate_register_assignments( - &mut self, - assignments: &HashMap, - ) { - if let Some(ir_expression) = self.value.as_mut() { - ir_expression.propagate_register_assignments(assignments); - } - } - - fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) { - // no-op - } } impl Assemble for IrReturn { diff --git a/dmc-lib/src/ir/ir_set_field.rs b/dmc-lib/src/ir/ir_set_field.rs index ed5d0e7..4690287 100644 --- a/dmc-lib/src/ir/ir_set_field.rs +++ b/dmc-lib/src/ir/ir_set_field.rs @@ -2,11 +2,10 @@ use crate::constants_table::ConstantsTable; use crate::ir::assemble::{Assemble, InstructionsBuilder}; use crate::ir::ir_expression::IrExpression; use crate::ir::ir_variable::{IrVariable, IrVariableDescriptor, IrVrVariableDescriptor}; -use crate::ir::register_allocation::{OffsetCounter, VrUser}; -use crate::ir::util::propagate_spills; +use crate::ir::register_allocation::VrUser; use dvm_lib::instruction::Instruction; use std::cell::RefCell; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use std::fmt::{Display, Formatter}; use std::rc::Rc; @@ -25,11 +24,6 @@ impl IrSetField { } impl VrUser for IrSetField { - fn vr_definitions(&self) -> HashSet { - // only this, because the target_object is technically not a definition - self.initializer.vr_definitions() - } - fn vr_uses(&self) -> HashSet { let mut set = HashSet::new(); match self.field_ref_variable.borrow().descriptor() { @@ -41,22 +35,6 @@ impl VrUser for IrSetField { set.extend(self.initializer.vr_uses()); set } - - fn propagate_spills(&mut self, spills: &HashSet) { - propagate_spills(&mut self.field_ref_variable, spills); - self.initializer.propagate_spills(spills); - } - - fn propagate_register_assignments( - &mut self, - _assignments: &HashMap, - ) { - // no definitions - } - - fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) { - // no definitions - } } impl Assemble for IrSetField { diff --git a/dmc-lib/src/ir/ir_variable.rs b/dmc-lib/src/ir/ir_variable.rs index f36b1ed..b0106d1 100644 --- a/dmc-lib/src/ir/ir_variable.rs +++ b/dmc-lib/src/ir/ir_variable.rs @@ -1,5 +1,6 @@ use crate::type_info::TypeInfo; use dvm_lib::instruction::Location; +use std::collections::HashSet; use std::fmt::{Debug, Display, Formatter}; use std::hash::Hash; use std::rc::Rc; @@ -90,6 +91,14 @@ impl IrVariableDescriptor { IrVariableDescriptor::Stack(stack_variable) => stack_variable.as_location(), } } + + pub fn vr_variable_descriptors(&self) -> HashSet { + if let IrVariableDescriptor::VirtualRegister(register_variable) = self { + HashSet::from([register_variable.clone()]) + } else { + HashSet::new() + } + } } #[derive(Clone, Hash, PartialEq, Eq)] diff --git a/dmc-lib/src/ir/register_allocation.rs b/dmc-lib/src/ir/register_allocation.rs index 0f77f0c..9be61ef 100644 --- a/dmc-lib/src/ir/register_allocation.rs +++ b/dmc-lib/src/ir/register_allocation.rs @@ -135,14 +135,26 @@ pub trait HasVrUsers { } pub trait VrUser { - fn vr_definitions(&self) -> HashSet; + fn vr_definitions(&self) -> HashSet { + HashSet::new() + } + fn vr_uses(&self) -> HashSet; - fn propagate_spills(&mut self, spills: &HashSet); + + fn propagate_spills(&mut self, _spills: &HashSet) { + // default no-op + } + fn propagate_register_assignments( &mut self, - assignments: &HashMap, - ); - fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter); + _assignments: &HashMap, + ) { + // default no-op + } + + fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) { + // default no-op + } } pub struct OffsetCounter {