Clean up ir vr_user trait and implementations.

This commit is contained in:
Jesse Brault 2026-03-15 13:15:31 -05:00
parent f9373a687f
commit 4a0a6b8425
13 changed files with 71 additions and 279 deletions

View File

@ -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<IrVrVariableDescriptor> {
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<IrVrVariableDescriptor> {
@ -38,39 +37,21 @@ impl VrUser for IrAssign {
}
fn propagate_spills(&mut self, spills: &HashSet<IrVrVariableDescriptor>) {
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<IrVrVariableDescriptor, usize>,
) {
// 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) {

View File

@ -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<IrVrVariableDescriptor> {
todo!()
}
fn vr_uses(&self) -> HashSet<IrVrVariableDescriptor> {
[self.left.as_ref(), self.right.as_ref()]
.iter()
.flat_map(|e| e.vr_uses())
.collect()
}
fn propagate_spills(&mut self, spills: &HashSet<IrVrVariableDescriptor>) {
todo!()
}
fn propagate_register_assignments(
&mut self,
assignments: &HashMap<IrVrVariableDescriptor, usize>,
) {
todo!()
}
fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter) {
todo!()
}
}

View File

@ -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<IrVrVariableDescriptor> {
HashSet::new()
}
fn vr_uses(&self) -> HashSet<IrVrVariableDescriptor> {
self.arguments.iter().flat_map(|a| a.vr_uses()).collect()
}
fn propagate_spills(&mut self, spills: &HashSet<IrVrVariableDescriptor>) {
for argument in &mut self.arguments {
argument.propagate_spills(spills);
}
}
fn propagate_register_assignments(
&mut self,
assignments: &HashMap<IrVrVariableDescriptor, usize>,
) {
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 {

View File

@ -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<IrVrVariableDescriptor> {
// no defs for an expression
HashSet::new()
}
fn vr_uses(&self) -> HashSet<IrVrVariableDescriptor> {
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<IrVrVariableDescriptor>) {
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<IrVrVariableDescriptor, usize>,
) {
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
}
}

View File

@ -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<IrVrVariableDescriptor> {
HashSet::new()
}
fn vr_uses(&self) -> HashSet<IrVrVariableDescriptor> {
HashSet::new()
self.self_parameter_or_variable().vr_uses()
}
fn propagate_spills(&mut self, spills: &HashSet<IrVrVariableDescriptor>) {}
fn propagate_register_assignments(
&mut self,
assignments: &HashMap<IrVrVariableDescriptor, usize>,
) {
}
fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter) {}
}

View File

@ -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<IrVrVariableDescriptor> {
HashSet::new()
}
fn vr_uses(&self) -> HashSet<IrVrVariableDescriptor> {
HashSet::new()
self.self_parameter_or_variable.vr_uses()
}
fn propagate_spills(&mut self, spills: &HashSet<IrVrVariableDescriptor>) {}
fn propagate_register_assignments(
&mut self,
assignments: &HashMap<IrVrVariableDescriptor, usize>,
) {
}
fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter) {}
}

View File

@ -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<IrVrVariableDescriptor> {
HashSet::new()
}
fn vr_uses(&self) -> HashSet<IrVrVariableDescriptor> {
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<IrVrVariableDescriptor>) {
// no-op
}
fn propagate_register_assignments(
&mut self,
_assignments: &HashMap<IrVrVariableDescriptor, usize>,
) {
// no-op
}
fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) {
// no-op
}
}

View File

@ -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<IrVrVariableDescriptor> {
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 {

View File

@ -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<IrVrVariableDescriptor> {
HashSet::new()
}
fn vr_uses(&self) -> HashSet<IrVrVariableDescriptor> {
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<IrVrVariableDescriptor>) {}
fn propagate_register_assignments(
&mut self,
assignments: &HashMap<IrVrVariableDescriptor, usize>,
) {
}
fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter) {}
}

View File

@ -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<IrVrVariableDescriptor> {
HashSet::new()
}
fn vr_uses(&self) -> HashSet<IrVrVariableDescriptor> {
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<IrVrVariableDescriptor>) {
if let Some(ir_expression) = self.value.as_mut() {
ir_expression.propagate_spills(spills);
}
}
fn propagate_register_assignments(
&mut self,
assignments: &HashMap<IrVrVariableDescriptor, usize>,
) {
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 {

View File

@ -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<IrVrVariableDescriptor> {
// only this, because the target_object is technically not a definition
self.initializer.vr_definitions()
}
fn vr_uses(&self) -> HashSet<IrVrVariableDescriptor> {
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<IrVrVariableDescriptor>) {
propagate_spills(&mut self.field_ref_variable, spills);
self.initializer.propagate_spills(spills);
}
fn propagate_register_assignments(
&mut self,
_assignments: &HashMap<IrVrVariableDescriptor, usize>,
) {
// no definitions
}
fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) {
// no definitions
}
}
impl Assemble for IrSetField {

View File

@ -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<IrVrVariableDescriptor> {
if let IrVariableDescriptor::VirtualRegister(register_variable) = self {
HashSet::from([register_variable.clone()])
} else {
HashSet::new()
}
}
}
#[derive(Clone, Hash, PartialEq, Eq)]

View File

@ -135,14 +135,26 @@ pub trait HasVrUsers {
}
pub trait VrUser {
fn vr_definitions(&self) -> HashSet<IrVrVariableDescriptor>;
fn vr_definitions(&self) -> HashSet<IrVrVariableDescriptor> {
HashSet::new()
}
fn vr_uses(&self) -> HashSet<IrVrVariableDescriptor>;
fn propagate_spills(&mut self, spills: &HashSet<IrVrVariableDescriptor>);
fn propagate_spills(&mut self, _spills: &HashSet<IrVrVariableDescriptor>) {
// default no-op
}
fn propagate_register_assignments(
&mut self,
assignments: &HashMap<IrVrVariableDescriptor, usize>,
);
fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter);
_assignments: &HashMap<IrVrVariableDescriptor, usize>,
) {
// default no-op
}
fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) {
// default no-op
}
}
pub struct OffsetCounter {