Skip to content

Commit

Permalink
Invalidate releases when optimizer inserts registers
Browse files Browse the repository at this point in the history
  • Loading branch information
voltrevo committed Jul 25, 2024
1 parent 77882f0 commit ae82029
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// //! test_output(1)
//! test_output(1)

export default function main() {
return f([1]);
Expand Down
16 changes: 15 additions & 1 deletion valuescript_compiler/src/optimization/kal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ pub struct FnState {
pub pointer_kals: HashMap<Pointer, Kal>,
pub mutable_this_established: bool,
pub registers: BTreeMap<String, Kal>,
pub register_releases: HashMap<String, Vec<usize>>,
pub invalidated_releases: Vec<usize>,
pub new_instructions: Vec<Instruction>,
}

Expand Down Expand Up @@ -404,6 +406,8 @@ impl FnState {
pointer_kals,
mutable_this_established: Default::default(),
registers: Default::default(),
register_releases: Default::default(),
invalidated_releases: Default::default(),
new_instructions: take(&mut self.new_instructions),
}
}
Expand Down Expand Up @@ -726,7 +730,17 @@ impl FnState {
| InstanceOf(_, _, dst)
| In(_, _, dst)
| Sub(_, _, dst) => {
if let Some(value) = self.get(dst.name.clone()).try_to_value() {
if let Some(mut value) = self.get(dst.name.clone()).try_to_value() {
value.visit_registers_mut_rev(&mut |rvm| {
if let Some(release_locations) = self.register_releases.get(&rvm.register.name) {
self
.invalidated_releases
.append(&mut release_locations.clone());

self.register_releases.remove(&rvm.register.name);
}
});

*instr = Instruction::Mov(value, dst.clone())
}
}
Expand Down
26 changes: 24 additions & 2 deletions valuescript_compiler/src/optimization/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ pub fn simplify(module: &mut Module, take_registers: bool) {
}
}

/**
* Handle releases due to mutation.
*
* When you write to a register:
* mov 123 %reg
*
* The content of that register at that point is unused, so we treat it as a
* release.
*/
fn handle_mutation_releases(body: &mut [FnLine], i: usize, take_registers: bool) {
let mut calls = Vec::<(Register, usize)>::new();

Expand Down Expand Up @@ -145,15 +154,28 @@ fn simplify_fn(mut state: FnState, fn_: &mut Function, take_registers: bool) {
FnLine::Instruction(instr) => {
state.eval_instruction(instr);

// FIXME: Hacky side effect mechanism (eval_instruction populates new_instructions)
// FIXME: Hacky side effect mechanisms (eval_instruction populates things to do up here)

for invalid_release_i in take(&mut state.invalidated_releases) {
fn_.body[invalid_release_i] = FnLine::Comment("invalidated release".into())
}

for instr in take(&mut state.new_instructions) {
fn_.body.insert(i, FnLine::Instruction(instr));
i += 1;
}
}
FnLine::Label(_) => state.clear_local(),
FnLine::Empty | FnLine::Comment(_) => {}
FnLine::Release(reg) => pending_releases.push(reg.clone()),
FnLine::Release(reg) => {
pending_releases.push(reg.clone());

state
.register_releases
.entry(reg.name.clone())
.or_default()
.push(i);
}
}

handle_mutation_releases(&mut fn_.body, i, take_registers);
Expand Down

0 comments on commit ae82029

Please sign in to comment.