Skip to content

Commit

Permalink
refactor(es/minifier): Decouple assign_count from reassigned (#8137)
Browse files Browse the repository at this point in the history
  • Loading branch information
Austaras committed Oct 19, 2023
1 parent a18ffc1 commit 13106e0
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 39 deletions.
4 changes: 2 additions & 2 deletions crates/swc_ecma_minifier/src/compress/optimize/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ impl Optimizer<'_> {
// new variant is added for multi inline, think carefully
if is_inline_enabled
&& usage.declared_count == 1
&& usage.assign_count == 0
&& usage.assign_count == 1
&& (!usage.has_property_mutation || !usage.reassigned)
&& match init {
Expr::Ident(Ident { sym, .. }) if &**sym == "eval" => false,
Expand Down Expand Up @@ -326,7 +326,7 @@ impl Optimizer<'_> {
&& usage.declared
&& may_remove
&& !usage.reassigned
&& usage.assign_count == 0
&& usage.assign_count == 1
&& ref_count == 1
{
match init {
Expand Down
3 changes: 1 addition & 2 deletions crates/swc_ecma_minifier/src/compress/optimize/sequences.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2327,8 +2327,7 @@ impl Optimizer<'_> {
if let Some(usage) = self.data.vars.get(&left_id.to_id()) {
// We are eliminating one usage, so we use 1 instead of
// 0
if !$force_drop && usage.usage_count == 1 && usage.assign_count == 0
{
if !$force_drop && usage.usage_count == 1 && !usage.reassigned {
report_change!("sequences: Dropping inlined variable");
a.name.take();
}
Expand Down
43 changes: 20 additions & 23 deletions crates/swc_ecma_minifier/src/program_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub(crate) struct VarUsageInfo {

pub(crate) declared_as_for_init: bool,

/// The number of assign and initialization to this identifier.
pub(crate) assign_count: u32,

/// The number of direct and indirect reference to this identifier.
Expand Down Expand Up @@ -171,7 +172,7 @@ impl VarUsageInfo {

/// The variable itself or a property of it is modified.
pub(crate) fn mutated(&self) -> bool {
self.assign_count > 0 || self.has_property_mutation
self.assign_count > 1 || self.has_property_mutation
}

pub(crate) fn can_inline_fn_once(&self) -> bool {
Expand Down Expand Up @@ -221,11 +222,16 @@ impl Storage for ProgramData {
let var_assigned = var_info.assign_count > 0
|| (var_info.var_initialized && !e.get().var_initialized);

if var_info.assign_count > 0 {
if e.get().initialized() {
e.get_mut().reassigned = true
}
}

if var_info.var_initialized {
// If it is inited in some other child scope and also inited in current
// scope
if e.get().var_initialized || e.get().ref_count > 0 {
e.get_mut().assign_count += 1;
e.get_mut().reassigned = true;
} else {
// If it is referred outside child scope, it will
Expand All @@ -237,7 +243,6 @@ impl Storage for ProgramData {
// current child scope
if !inited && e.get().var_initialized && var_info.ref_count > 0 {
e.get_mut().var_initialized = false;
e.get_mut().assign_count += 1;
e.get_mut().reassigned = true
}
}
Expand All @@ -246,12 +251,6 @@ impl Storage for ProgramData {

e.get_mut().reassigned |= var_info.reassigned;

if var_info.assign_count > 0 {
if e.get().initialized() {
e.get_mut().reassigned = true
}
}

e.get_mut().has_property_access |= var_info.has_property_access;
e.get_mut().has_property_mutation |= var_info.has_property_mutation;
e.get_mut().exported |= var_info.exported;
Expand Down Expand Up @@ -349,13 +348,16 @@ impl Storage for ProgramData {
v.is_top_level |= ctx.is_top_level;

// assigned or declared before this declaration
if has_init && (v.declared || v.var_initialized || v.assign_count > 0) {
#[cfg(feature = "debug")]
{
tracing::trace!("declare_decl(`{}`): Already declared", i);
if has_init {
if v.declared || v.var_initialized || v.assign_count > 0 {
#[cfg(feature = "debug")]
{
tracing::trace!("declare_decl(`{}`): Already declared", i);
}

v.reassigned = true;
}

v.reassigned = true;
v.assign_count += 1;
}

Expand Down Expand Up @@ -403,7 +405,7 @@ impl Storage for ProgramData {

for other in to_mark_mutate {
let other = self.vars.entry(other).or_insert_with(|| {
let simple_assign = ctx.is_exact_reassignment && !ctx.is_op_assign;
let simple_assign = ctx.is_exact_assignment && !ctx.is_op_assign;

VarUsageInfo {
used_above_decl: !simple_assign,
Expand Down Expand Up @@ -570,7 +572,7 @@ impl ProgramData {
let e = self.vars.entry(i.clone()).or_insert_with(|| {
// trace!("insert({}{:?})", i.0, i.1);

let simple_assign = ctx.is_exact_reassignment && !ctx.is_op_assign;
let simple_assign = ctx.is_exact_assignment && !ctx.is_op_assign;

VarUsageInfo {
used_above_decl: !simple_assign,
Expand Down Expand Up @@ -601,7 +603,7 @@ impl ProgramData {
e.executed_multiple_time |= ctx.executed_multiple_time;
e.used_in_cond |= ctx.in_cond;

if is_modify && ctx.is_exact_reassignment {
if is_modify && ctx.is_exact_assignment {
if is_first {
if e.assign_count > 0 || e.initialized() {
e.reassigned = true
Expand All @@ -610,13 +612,8 @@ impl ProgramData {
e.assign_count += 1;

if !ctx.is_op_assign {
if e.ref_count == 1
&& ctx.in_assign_lhs
&& e.var_kind != Some(VarDeclKind::Const)
&& !inited
{
if e.ref_count == 1 && e.var_kind != Some(VarDeclKind::Const) && !inited {
self.initialized_vars.insert(i.clone());
e.assign_count -= 1;
e.var_initialized = true;
} else {
e.reassigned = true
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_usage_analyzer/src/analyzer/ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub struct Ctx {
pub in_pat_of_param: bool,
pub in_catch_param: bool,
/// `true` for `foo.bar` and `false` for `foo` in `foo.bar++`
pub is_exact_reassignment: bool,
pub is_exact_assignment: bool,

pub is_callee: bool,

Expand Down
22 changes: 11 additions & 11 deletions crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ where
fn visit_assign_expr(&mut self, n: &AssignExpr) {
let ctx = Ctx {
in_assign_lhs: true,
is_exact_reassignment: true,
is_exact_assignment: true,
is_op_assign: n.op != op!("="),
is_delete_arg: false,
..self.ctx
Expand All @@ -227,7 +227,7 @@ where

let ctx = Ctx {
in_assign_lhs: false,
is_exact_reassignment: false,
is_exact_assignment: false,
is_delete_arg: false,
// We mark bar in
//
Expand Down Expand Up @@ -407,7 +407,7 @@ where
},
is_delete_arg: false,
is_exact_arg: true,
is_exact_reassignment: false,
is_exact_assignment: false,
is_callee: false,
is_id_ref: true,
..self.ctx
Expand Down Expand Up @@ -750,7 +750,7 @@ where

self.with_child(n.span.ctxt, ScopeKind::Block, |child| {
let ctx = Ctx {
is_exact_reassignment: true,
is_exact_assignment: true,
is_delete_arg: false,
in_left_of_for_loop: true,
..child.ctx
Expand All @@ -777,7 +777,7 @@ where
self.with_child(n.span.ctxt, ScopeKind::Block, |child| {
let ctx = Ctx {
in_left_of_for_loop: true,
is_exact_reassignment: true,
is_exact_assignment: true,
is_delete_arg: false,
..child.ctx
};
Expand Down Expand Up @@ -884,7 +884,7 @@ where
{
let ctx = Ctx {
is_exact_arg: false,
is_exact_reassignment: false,
is_exact_assignment: false,
is_callee: false,
is_id_ref: false,
..self.ctx
Expand All @@ -895,7 +895,7 @@ where
if let MemberProp::Computed(c) = &e.prop {
let ctx = Ctx {
is_exact_arg: false,
is_exact_reassignment: false,
is_exact_assignment: false,
is_callee: false,
is_delete_arg: false,
..self.ctx
Expand Down Expand Up @@ -1067,7 +1067,7 @@ where
fn visit_prop(&mut self, n: &Prop) {
let ctx = Ctx {
is_exact_arg: false,
is_exact_reassignment: false,
is_exact_assignment: false,
is_id_ref: true,
..self.ctx
};
Expand Down Expand Up @@ -1151,7 +1151,7 @@ where
if let SuperProp::Computed(c) = &e.prop {
let ctx = Ctx {
is_exact_arg: false,
is_exact_reassignment: false,
is_exact_assignment: false,
is_delete_arg: false,
is_id_ref: false,
..self.ctx
Expand Down Expand Up @@ -1217,7 +1217,7 @@ where
fn visit_unary_expr(&mut self, n: &UnaryExpr) {
let ctx = Ctx {
in_update_arg: false,
is_exact_reassignment: false,
is_exact_assignment: false,
is_delete_arg: n.op == op!("delete"),
..self.ctx
};
Expand All @@ -1228,7 +1228,7 @@ where
fn visit_update_expr(&mut self, n: &UpdateExpr) {
let ctx = Ctx {
in_update_arg: true,
is_exact_reassignment: true,
is_exact_assignment: true,
is_delete_arg: false,
..self.ctx
};
Expand Down

1 comment on commit 13106e0

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 13106e0 Previous: 8d7894c Ratio
es/full/bugs-1 284560 ns/iter (± 3390) 288688 ns/iter (± 5595) 0.99
es/full/minify/libraries/antd 1383193821 ns/iter (± 13560992) 1383350684 ns/iter (± 11788999) 1.00
es/full/minify/libraries/d3 295542397 ns/iter (± 3617008) 296319155 ns/iter (± 2253807) 1.00
es/full/minify/libraries/echarts 1109847825 ns/iter (± 6939487) 1109579854 ns/iter (± 4405740) 1.00
es/full/minify/libraries/jquery 89467381 ns/iter (± 771486) 88987302 ns/iter (± 168124) 1.01
es/full/minify/libraries/lodash 104195677 ns/iter (± 241040) 104271650 ns/iter (± 479429) 1.00
es/full/minify/libraries/moment 52319062 ns/iter (± 148940) 52421190 ns/iter (± 99243) 1.00
es/full/minify/libraries/react 18788957 ns/iter (± 43939) 18862789 ns/iter (± 70621) 1.00
es/full/minify/libraries/terser 230107110 ns/iter (± 944521) 229662182 ns/iter (± 736719) 1.00
es/full/minify/libraries/three 408363859 ns/iter (± 2399893) 407653860 ns/iter (± 2586256) 1.00
es/full/minify/libraries/typescript 2736354242 ns/iter (± 6486448) 2779689950 ns/iter (± 9224924) 0.98
es/full/minify/libraries/victory 589740453 ns/iter (± 4873132) 594793169 ns/iter (± 2543440) 0.99
es/full/minify/libraries/vue 125492488 ns/iter (± 193039) 125814658 ns/iter (± 204118) 1.00
es/full/codegen/es3 33588 ns/iter (± 151) 34569 ns/iter (± 56) 0.97
es/full/codegen/es5 33671 ns/iter (± 189) 34621 ns/iter (± 165) 0.97
es/full/codegen/es2015 33457 ns/iter (± 91) 34559 ns/iter (± 95) 0.97
es/full/codegen/es2016 33536 ns/iter (± 111) 34608 ns/iter (± 147) 0.97
es/full/codegen/es2017 33644 ns/iter (± 96) 34592 ns/iter (± 151) 0.97
es/full/codegen/es2018 33506 ns/iter (± 151) 34644 ns/iter (± 90) 0.97
es/full/codegen/es2019 33438 ns/iter (± 96) 34592 ns/iter (± 201) 0.97
es/full/codegen/es2020 33415 ns/iter (± 59) 34597 ns/iter (± 108) 0.97
es/full/all/es3 176370241 ns/iter (± 1138533) 176204224 ns/iter (± 709095) 1.00
es/full/all/es5 170723592 ns/iter (± 1033427) 168609182 ns/iter (± 473897) 1.01
es/full/all/es2015 127382600 ns/iter (± 419235) 127574293 ns/iter (± 613526) 1.00
es/full/all/es2016 126985337 ns/iter (± 951262) 126459668 ns/iter (± 1749259) 1.00
es/full/all/es2017 126074714 ns/iter (± 616334) 125908328 ns/iter (± 795191) 1.00
es/full/all/es2018 123968281 ns/iter (± 678247) 123950332 ns/iter (± 1267294) 1.00
es/full/all/es2019 124023376 ns/iter (± 930039) 122742495 ns/iter (± 511746) 1.01
es/full/all/es2020 119918511 ns/iter (± 511295) 119476634 ns/iter (± 426357) 1.00
es/full/parser 559131 ns/iter (± 3507) 559583 ns/iter (± 3375) 1.00
es/full/base/fixer 18015 ns/iter (± 242) 18925 ns/iter (± 90) 0.95
es/full/base/resolver_and_hygiene 83844 ns/iter (± 260) 83590 ns/iter (± 136) 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.