Skip to content

Commit

Permalink
refactor(minifier): move dce conditional expression to `RemoveDeadCod…
Browse files Browse the repository at this point in the history
…e` (#5971)

This is aligned to closure compiler
  • Loading branch information
Boshen committed Sep 23, 2024
1 parent 860f108 commit 0a2f687
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 64 deletions.
6 changes: 6 additions & 0 deletions crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,13 @@ impl<'a> PeepholeFoldConstants {
match expr.operator {
UnaryOperator::Void => Self::try_reduce_void(expr, ctx),
UnaryOperator::Typeof => self.try_fold_type_of(expr, ctx),
#[allow(clippy::float_cmp)]
UnaryOperator::LogicalNot => {
if let Expression::NumericLiteral(n) = &expr.argument {
if n.value == 0.0 || n.value == 1.0 {
return None;
}
}
expr.argument.to_boolean().map(|b| ctx.ast.expression_boolean_literal(SPAN, !b))
}
// `-NaN` -> `NaN`
Expand Down
38 changes: 6 additions & 32 deletions crates/oxc_minifier/src/ast_passes/peephole_minimize_conditions.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use oxc_ast::ast::*;
use oxc_traverse::{Ancestor, Traverse, TraverseCtx};
use oxc_traverse::{Traverse, TraverseCtx};

use crate::{node_util::NodeUtil, tri::Tri, CompressorPass};
use crate::CompressorPass;

/// Minimize Conditions
///
Expand All @@ -16,44 +16,18 @@ impl<'a> CompressorPass<'a> for PeepholeMinimizeConditions {}

impl<'a> Traverse<'a> for PeepholeMinimizeConditions {
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
self.fold_expression(expr, ctx);
}
}

impl<'a> PeepholeMinimizeConditions {
pub fn new() -> Self {
Self
}

fn fold_expression(&self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
if let Some(folded_expr) = match expr {
Expression::ConditionalExpression(e) => self.try_fold_conditional_expression(e, ctx),
Expression::UnaryExpression(e) if e.operator.is_not() => self.try_minimize_not(e, ctx),
_ => None,
} {
*expr = folded_expr;
};
}
}

fn try_fold_conditional_expression(
&self,
expr: &mut ConditionalExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Option<Expression<'a>> {
match ctx.get_boolean_value(&expr.test) {
Tri::True => {
// Bail `let o = { f() { assert.ok(this !== o); } }; (true ? o.f : false)(); (true ? o.f : false)``;`
let parent = ctx.ancestry.parent();
if parent.is_tagged_template_expression()
|| matches!(parent, Ancestor::CallExpressionCallee(_))
{
return None;
}
Some(ctx.ast.move_expression(&mut expr.consequent))
}
Tri::False => Some(ctx.ast.move_expression(&mut expr.alternate)),
Tri::Unknown => None,
}
impl<'a> PeepholeMinimizeConditions {
pub fn new() -> Self {
Self
}

/// Try to minimize NOT nodes such as `!(x==y)`.
Expand Down
51 changes: 32 additions & 19 deletions crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use oxc_allocator::Vec;
use oxc_ast::{ast::*, Visit};
use oxc_span::SPAN;
use oxc_traverse::{Traverse, TraverseCtx};
use oxc_traverse::{Ancestor, Traverse, TraverseCtx};

use crate::{keep_var::KeepVar, node_util::NodeUtil, tri::Tri, CompressorPass};

Expand All @@ -23,6 +23,15 @@ impl<'a> Traverse<'a> for PeepholeRemoveDeadCode {
stmts.retain(|stmt| !matches!(stmt, Statement::EmptyStatement(_)));
self.dead_code_elimination(stmts, ctx);
}

fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
if let Some(folded_expr) = match expr {
Expression::ConditionalExpression(e) => self.try_fold_conditional_expression(e, ctx),
_ => None,
} {
*expr = folded_expr;
}
}
}

impl<'a> PeepholeRemoveDeadCode {
Expand Down Expand Up @@ -114,22 +123,26 @@ impl<'a> PeepholeRemoveDeadCode {
Tri::Unknown => {}
}
}
}

// /// <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/PeepholeRemoveDeadCode.java>
// #[cfg(test)]
// mod test {
// use oxc_allocator::Allocator;

// use crate::{tester, CompressOptions};

// fn test(source_text: &str, expected: &str) {
// let allocator = Allocator::default();
// let mut pass = super::PeepholeRemoveDeadCode::new();
// tester::test(&allocator, source_text, expected, &mut pass);
// }

// fn test_same(source_text: &str) {
// test(source_text, source_text);
// }
// }
/// Try folding conditional expression (?:) if the condition results of the condition is known.
fn try_fold_conditional_expression(
&self,
expr: &mut ConditionalExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Option<Expression<'a>> {
match ctx.get_boolean_value(&expr.test) {
Tri::True => {
// Bail `let o = { f() { assert.ok(this !== o); } }; (true ? o.f : false)(); (true ? o.f : false)``;`
let parent = ctx.ancestry.parent();
if parent.is_tagged_template_expression()
|| matches!(parent, Ancestor::CallExpressionCallee(_))
{
return None;
}
Some(ctx.ast.move_expression(&mut expr.consequent))
}
Tri::False => Some(ctx.ast.move_expression(&mut expr.alternate)),
Tri::Unknown => None,
}
}
}
17 changes: 14 additions & 3 deletions crates/oxc_minifier/src/compressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,24 @@ impl<'a> Compressor<'a> {
return;
}

self.fold_constants(program, &mut ctx);
// earlyPeepholeOptimizations
// TODO: MinimizeExitPoints
self.minimize_conditions(program, &mut ctx);
self.substitute_alternate_syntax(program, &mut ctx);
// TODO: PeepholeReplaceKnownMethods
self.remove_dead_code(program, &mut ctx);
self.fold_constants(program, &mut ctx);

// latePeepholeOptimizations
// TODO: StatementFusion
self.remove_dead_code(program, &mut ctx);
// self.statement_fusion(program, &mut ctx);
self.minimize_conditions(program, &mut ctx);
self.substitute_alternate_syntax(program, &mut ctx);
self.collapse_variable_declarations(program, &mut ctx);
// TODO: PeepholeReplaceKnownMethods
self.fold_constants(program, &mut ctx);

self.exploit_assigns(program, &mut ctx);
self.collapse_variable_declarations(program, &mut ctx);
}

fn dead_code_elimination(self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) {
Expand Down
11 changes: 1 addition & 10 deletions tasks/coverage/snapshots/minifier_test262.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,4 @@ commit: d62fa93c

minifier_test262 Summary:
AST Parsed : 43765/43765 (100.00%)
Positive Passed: 43756/43765 (99.98%)
Compress: tasks/coverage/test262/test/language/expressions/conditional/S11.12_A3_T2.js
Compress: tasks/coverage/test262/test/language/expressions/conditional/S11.12_A3_T3.js
Compress: tasks/coverage/test262/test/language/expressions/conditional/S11.12_A3_T4.js
Compress: tasks/coverage/test262/test/language/expressions/conditional/S11.12_A4_T2.js
Compress: tasks/coverage/test262/test/language/expressions/conditional/S11.12_A4_T3.js
Compress: tasks/coverage/test262/test/language/expressions/conditional/S11.12_A4_T4.js
Compress: tasks/coverage/test262/test/language/statements/if/S12.5_A12_T1.js
Compress: tasks/coverage/test262/test/language/statements/if/S12.5_A12_T3.js
Compress: tasks/coverage/test262/test/language/statements/if/S12.5_A12_T4.js
Positive Passed: 43765/43765 (100.00%)

0 comments on commit 0a2f687

Please sign in to comment.