mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-01-08 21:18:04 -05:00
Invalidate releases when optimizer inserts registers
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// //! test_output(1)
|
||||
//! test_output(1)
|
||||
|
||||
export default function main() {
|
||||
return f([1]);
|
||||
@@ -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>,
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -145,7 +154,12 @@ 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;
|
||||
@@ -153,7 +167,15 @@ fn simplify_fn(mut state: FnState, fn_: &mut Function, take_registers: bool) {
|
||||
}
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user