Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions crates/oxc_minifier/src/peephole/minimize_exit_points.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,3 @@
use oxc_allocator::Vec;
use oxc_ast::ast::*;

use crate::ctx::Ctx;

use super::PeepholeOptimizations;

impl<'a> PeepholeOptimizations {
/// Transform the structure of the AST so that the number of explicit exits
/// are minimized and instead flows to implicit exits conditions.
///
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/MinimizeExitPoints.java>
pub fn minimize_exit_points(&mut self, body: &mut FunctionBody<'_>, _ctx: Ctx<'a, '_>) {
self.remove_last_return(&mut body.statements);
}

// `function foo() { return }` -> `function foo() {}`
fn remove_last_return(&mut self, stmts: &mut Vec<'a, Statement<'a>>) {
if let Some(last) = stmts.last() {
if matches!(last, Statement::ReturnStatement(ret) if ret.argument.is_none()) {
stmts.pop();
self.mark_current_function_as_changed();
}
}
}
}

#[cfg(test)]
mod test {
use crate::tester::{test, test_same};
Expand Down
5 changes: 3 additions & 2 deletions crates/oxc_minifier/src/peephole/minimize_statements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ impl<'a> PeepholeOptimizations {
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/StatementFusion.java>
///
/// ## Collapse variable declarations
///
/// ## Join Vars
/// `var a; var b = 1; var c = 2` => `var a, b = 1; c = 2`
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/CollapseVariableDeclarations.java>
///
/// ## Collapse into for statements:
/// `var a = 0; for(;a<0;a++) {}` => `for(var a = 0;a<0;a++) {}`
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/Denormalize.java>
///
/// ## MinimizeExitPoints:
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/MinimizeExitPoints.java>
pub fn minimize_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: Ctx<'a, '_>) {
let mut result: Vec<'a, Statement<'a>> = ctx.ast.vec_with_capacity(stmts.len());
let mut is_control_flow_dead = false;
Expand Down
8 changes: 0 additions & 8 deletions crates/oxc_minifier/src/peephole/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,6 @@ impl<'a> Traverse<'a> for PeepholeOptimizations {
self.substitute_return_statement(stmt, ctx);
}

fn exit_function_body(&mut self, body: &mut FunctionBody<'a>, ctx: &mut TraverseCtx<'a>) {
if !self.is_prev_function_changed() {
return;
}
let ctx = Ctx(ctx);
self.minimize_exit_points(body, ctx);
}

fn exit_variable_declaration(
&mut self,
decl: &mut VariableDeclaration<'a>,
Expand Down
28 changes: 7 additions & 21 deletions crates/oxc_minifier/src/peephole/remove_dead_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,6 @@ use super::{LatePeepholeOptimizations, PeepholeOptimizations};
/// See `KeepVar` at the end of this file for `var` hoisting logic.
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeRemoveDeadCode.java>
impl<'a, 'b> PeepholeOptimizations {
pub fn remove_dead_code_exit_statements(
&mut self,
stmts: &mut Vec<'a, Statement<'a>>,
ctx: Ctx<'a, '_>,
) {
self.dead_code_elimination(stmts, ctx);
}

pub fn remove_dead_code_exit_statement(&mut self, stmt: &mut Statement<'a>, ctx: Ctx<'a, '_>) {
if let Some(new_stmt) = match stmt {
Statement::BlockStatement(s) => Self::try_optimize_block(s, ctx),
Expand Down Expand Up @@ -66,18 +58,22 @@ impl<'a, 'b> PeepholeOptimizations {
}

/// Removes dead code thats comes after `return`, `throw`, `continue` and `break` statements.
fn dead_code_elimination(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: Ctx<'a, 'b>) {
pub fn remove_dead_code_exit_statements(
&mut self,
stmts: &mut Vec<'a, Statement<'a>>,
ctx: Ctx<'a, '_>,
) {
// Remove code after `return` and `throw` statements
let mut index = None;
'outer: for (i, stmt) in stmts.iter().enumerate() {
if Self::is_unreachable_statement(stmt) {
if stmt.is_jump_statement() {
index.replace(i);
break;
}
// Double check block statements folded by if statements above
if let Statement::BlockStatement(block_stmt) = stmt {
for stmt in &block_stmt.body {
if Self::is_unreachable_statement(stmt) {
if stmt.is_jump_statement() {
index.replace(i);
break 'outer;
}
Expand Down Expand Up @@ -125,16 +121,6 @@ impl<'a, 'b> PeepholeOptimizations {
}
}

fn is_unreachable_statement(stmt: &Statement<'a>) -> bool {
matches!(
stmt,
Statement::ReturnStatement(_)
| Statement::ThrowStatement(_)
| Statement::BreakStatement(_)
| Statement::ContinueStatement(_)
)
}

/// Remove block from single line blocks
/// `{ block } -> block`
fn try_optimize_block(
Expand Down
Loading