Skip to content

Commit 7329824

Browse files
authoredJan 12, 2025··
perf(es/minifier): Make the first run of DCE more efficient (#9868)
**Description:** We can drop constant branches from precompress pass to make the pass after it faster.
1 parent caed78a commit 7329824

File tree

3 files changed

+53
-12
lines changed

3 files changed

+53
-12
lines changed
 

‎.changeset/stale-apricots-dream.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
swc_core: minor
3+
swc_ecma_minifier: minor
4+
---
5+
6+
perf(es/minifier): Make the first run of DCE more efficient

‎crates/swc_ecma_minifier/src/lib.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ use swc_common::{comments::Comments, pass::Repeated, sync::Lrc, SourceMap, Synta
4444
use swc_ecma_ast::*;
4545
use swc_ecma_transforms_optimization::debug_assert_valid;
4646
use swc_ecma_usage_analyzer::marks::Marks;
47+
use swc_ecma_utils::ExprCtx;
4748
use swc_ecma_visit::VisitMutWith;
4849
use swc_timer::timer;
4950

@@ -126,7 +127,11 @@ pub fn optimize(
126127
if let Some(_options) = &options.compress {
127128
let _timer = timer!("precompress");
128129

129-
n.visit_mut_with(&mut precompress_optimizer());
130+
n.visit_mut_with(&mut precompress_optimizer(ExprCtx {
131+
unresolved_ctxt: SyntaxContext::empty().apply_mark(marks.unresolved_mark),
132+
is_unresolved_ref_safe: false,
133+
in_strict: false,
134+
}));
130135
debug_assert_valid(&n);
131136
}
132137

‎crates/swc_ecma_minifier/src/pass/precompress.rs

+41-11
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,50 @@
11
use std::vec::Vec;
22

3+
use swc_common::util::take::Take;
34
use swc_ecma_ast::*;
45
use swc_ecma_transforms_base::perf::{Parallel, ParallelExt};
6+
use swc_ecma_utils::{ExprCtx, ExprExt, Value::Known};
57
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};
68

7-
use crate::HEAVY_TASK_PARALLELS;
9+
use crate::CPU_COUNT;
810

911
/// Optimizer invoked before invoking compressor.
1012
///
1113
/// - Remove parens.
1214
///
1315
/// TODO: remove completely after #8333
14-
pub(crate) fn precompress_optimizer<'a>() -> impl 'a + VisitMut {
15-
PrecompressOptimizer {}
16+
pub(crate) fn precompress_optimizer<'a>(expr_ctx: ExprCtx) -> impl 'a + VisitMut {
17+
PrecompressOptimizer { expr_ctx }
1618
}
1719

1820
#[derive(Debug)]
19-
pub(crate) struct PrecompressOptimizer {}
21+
pub(crate) struct PrecompressOptimizer {
22+
expr_ctx: ExprCtx,
23+
}
24+
25+
impl PrecompressOptimizer {
26+
/// Drops RHS from `null && foo`
27+
fn optimize_bin_expr(&mut self, n: &mut Expr) {
28+
let Expr::Bin(b) = n else {
29+
return;
30+
};
31+
32+
if b.op == op!("&&") && b.left.as_pure_bool(&self.expr_ctx) == Known(false) {
33+
*n = *b.left.take();
34+
return;
35+
}
36+
37+
if b.op == op!("||") && b.left.as_pure_bool(&self.expr_ctx) == Known(true) {
38+
*n = *b.left.take();
39+
}
40+
}
41+
}
2042

2143
impl Parallel for PrecompressOptimizer {
2244
fn create(&self) -> Self {
23-
Self {}
45+
Self {
46+
expr_ctx: self.expr_ctx.clone(),
47+
}
2448
}
2549

2650
fn merge(&mut self, _: Self) {}
@@ -29,38 +53,44 @@ impl Parallel for PrecompressOptimizer {
2953
impl VisitMut for PrecompressOptimizer {
3054
noop_visit_mut_type!();
3155

56+
fn visit_mut_expr(&mut self, n: &mut Expr) {
57+
n.visit_mut_children_with(self);
58+
59+
self.optimize_bin_expr(n);
60+
}
61+
3262
fn visit_mut_stmts(&mut self, n: &mut Vec<Stmt>) {
33-
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
63+
self.maybe_par(*CPU_COUNT, n, |v, n| {
3464
n.visit_mut_with(v);
3565
});
3666
}
3767

3868
fn visit_mut_module_items(&mut self, n: &mut Vec<ModuleItem>) {
39-
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
69+
self.maybe_par(*CPU_COUNT, n, |v, n| {
4070
n.visit_mut_with(v);
4171
});
4272
}
4373

4474
fn visit_mut_exprs(&mut self, n: &mut Vec<Box<Expr>>) {
45-
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
75+
self.maybe_par(*CPU_COUNT, n, |v, n| {
4676
n.visit_mut_with(v);
4777
});
4878
}
4979

5080
fn visit_mut_opt_vec_expr_or_spreads(&mut self, n: &mut Vec<Option<ExprOrSpread>>) {
51-
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
81+
self.maybe_par(*CPU_COUNT, n, |v, n| {
5282
n.visit_mut_with(v);
5383
});
5484
}
5585

5686
fn visit_mut_expr_or_spreads(&mut self, n: &mut Vec<ExprOrSpread>) {
57-
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
87+
self.maybe_par(*CPU_COUNT, n, |v, n| {
5888
n.visit_mut_with(v);
5989
});
6090
}
6191

6292
fn visit_mut_var_declarators(&mut self, n: &mut Vec<VarDeclarator>) {
63-
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
93+
self.maybe_par(*CPU_COUNT, n, |v, n| {
6494
n.visit_mut_with(v);
6595
});
6696
}

0 commit comments

Comments
 (0)
Please sign in to comment.