diff --git a/valuescript_compiler/src/optimization/mod.rs b/valuescript_compiler/src/optimization/mod.rs index abd5266..67d7d38 100644 --- a/valuescript_compiler/src/optimization/mod.rs +++ b/valuescript_compiler/src/optimization/mod.rs @@ -2,8 +2,8 @@ mod collapse_pointers_of_pointers; mod extract_constants; mod kal; mod optimize; +mod reduce_instructions; mod remove_meta_lines; -mod remove_noops; mod shake_tree; mod simplify; pub mod try_to_kal; diff --git a/valuescript_compiler/src/optimization/optimize.rs b/valuescript_compiler/src/optimization/optimize.rs index 6aa75fa..1b954d5 100644 --- a/valuescript_compiler/src/optimization/optimize.rs +++ b/valuescript_compiler/src/optimization/optimize.rs @@ -3,8 +3,8 @@ use crate::name_allocator::NameAllocator; use super::collapse_pointers_of_pointers::collapse_pointers_of_pointers; use super::extract_constants::extract_constants; +use super::reduce_instructions::reduce_instructions; use super::remove_meta_lines::remove_meta_lines; -use super::remove_noops::remove_noops; use super::shake_tree::shake_tree; use super::simplify::simplify; @@ -14,7 +14,7 @@ pub fn optimize(module: &mut Module, pointer_allocator: &mut NameAllocator) { for _ in 0..2 { simplify(module); - remove_noops(module); + reduce_instructions(module); } remove_meta_lines(module); diff --git a/valuescript_compiler/src/optimization/remove_noops.rs b/valuescript_compiler/src/optimization/reduce_instructions.rs similarity index 64% rename from valuescript_compiler/src/optimization/remove_noops.rs rename to valuescript_compiler/src/optimization/reduce_instructions.rs index 97dac5a..9860b5e 100644 --- a/valuescript_compiler/src/optimization/remove_noops.rs +++ b/valuescript_compiler/src/optimization/reduce_instructions.rs @@ -5,29 +5,29 @@ use crate::{ instruction::Instruction, }; -pub fn remove_noops(module: &mut Module) { +pub fn reduce_instructions(module: &mut Module) { for defn in &mut module.definitions { if let DefinitionContent::Function(fn_) = &mut defn.content { for line in take(&mut fn_.body) { - if let FnLine::Instruction(instr) = &line { - if is_noop(instr) { - continue; + if let FnLine::Instruction(instr) = line { + if let Some(instr) = reduce(instr) { + fn_.body.push(FnLine::Instruction(instr)); } + } else { + fn_.body.push(line); } - - fn_.body.push(line); } } } } -fn is_noop(instr: &Instruction) -> bool { +fn reduce(instr: Instruction) -> Option { use Instruction::*; - match instr { + match &instr { End | OpInc(..) | OpDec(..) | Call(..) | Apply(..) | SubCall(..) | Jmp(..) | New(..) | Throw(..) | SetCatch(..) | UnsetCatch | ConstSubCall(..) | RequireMutableThis - | ThisSubCall(..) | Next(..) | Yield(..) | YieldStar(..) => false, + | ThisSubCall(..) | Next(..) | Yield(..) | YieldStar(..) => Some(instr), Mov(_, dst) | OpPlus(_, _, dst) @@ -66,9 +66,26 @@ fn is_noop(instr: &Instruction) -> bool { | UnaryMinus(_, dst) | Import(_, dst) | ImportStar(_, dst) - | Cat(_, dst) => dst.is_ignore(), + | Cat(_, dst) => { + if dst.is_ignore() { + None + } else { + Some(instr) + } + } - JmpIf(cond, _) => *cond == Value::Bool(false), - UnpackIterRes(_, value_dst, done_dst) => value_dst.is_ignore() && done_dst.is_ignore(), + JmpIf(cond, label_ref) => match cond { + // TODO: Kal::from_value(cond).is_truthy() + Value::Bool(false) => None, + Value::Bool(true) => Some(Instruction::Jmp(label_ref.clone())), + _ => Some(instr), + }, + UnpackIterRes(_, value_dst, done_dst) => { + if value_dst.is_ignore() && done_dst.is_ignore() { + None + } else { + Some(instr) + } + } } }