refactor(es/minifier): Pre-calculate reassigned (#7832)

This commit is contained in:
Austaras 2023-08-24 15:35:26 +08:00 committed by GitHub
parent 662f236aa5
commit 65db1badff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 58 additions and 58 deletions

View File

@ -40,7 +40,7 @@ impl Optimizer<'_> {
let usage = self.data.vars.get(&obj.to_id())?;
if usage.reassigned() {
if usage.reassigned {
return None;
}

View File

@ -181,7 +181,7 @@ impl Optimizer<'_> {
match &mut **param {
Pat::Ident(param) => {
if let Some(usage) = self.data.vars.get(&param.to_id()) {
if usage.reassigned() {
if usage.reassigned {
continue;
}
if usage.ref_count != 1 {
@ -222,7 +222,7 @@ impl Optimizer<'_> {
Pat::Rest(rest_pat) => {
if let Pat::Ident(param_id) = &*rest_pat.arg {
if let Some(usage) = self.data.vars.get(&param_id.to_id()) {
if usage.reassigned()
if usage.reassigned
|| usage.ref_count != 1
|| !usage.has_property_access
{
@ -906,7 +906,7 @@ impl Optimizer<'_> {
if let Some(arg) = arg {
if let Some(usage) = self.data.vars.get(&orig_params[idx].to_id()) {
if usage.ref_count == 1
&& !usage.reassigned()
&& !usage.reassigned
&& !usage.has_property_mutation
&& matches!(
&*arg,

View File

@ -98,7 +98,7 @@ impl Optimizer<'_> {
//
// TODO: Allow `length` in usage.accessed_props
if usage.declared
&& !usage.reassigned()
&& !usage.reassigned
&& !usage.mutated
&& !usage.has_property_mutation
&& usage.accessed_props.is_empty()
@ -153,7 +153,7 @@ impl Optimizer<'_> {
}
}
if !usage.reassigned() {
if !usage.reassigned {
match init {
Expr::Fn(..) | Expr::Arrow(..) => {
self.typeofs.insert(ident.to_id(), js_word!("function"));
@ -188,7 +188,7 @@ impl Optimizer<'_> {
if !usage.assigned_fn_local {
false
} else if let Some(u) = self.data.vars.get(&id.to_id()) {
let mut should_inline = !u.reassigned() && u.declared;
let mut should_inline = !u.reassigned && u.declared;
should_inline &=
// Function declarations are hoisted
@ -322,7 +322,7 @@ impl Optimizer<'_> {
&& is_inline_enabled
&& usage.declared
&& may_remove
&& !usage.reassigned()
&& !usage.reassigned
&& (usage.can_inline_var() || usage.is_mutated_only_by_one_call())
&& ref_count == 1
{
@ -371,7 +371,7 @@ impl Optimizer<'_> {
continue;
}
if let Some(v_usage) = self.data.vars.get(&id) {
if v_usage.reassigned() {
if v_usage.reassigned {
return;
}
} else {
@ -388,7 +388,7 @@ impl Optimizer<'_> {
continue;
}
if let Some(v_usage) = self.data.vars.get(&id) {
if v_usage.reassigned() {
if v_usage.reassigned {
return;
}
} else {
@ -400,7 +400,7 @@ impl Optimizer<'_> {
Expr::Object(..) if self.options.pristine_globals => {
for id in idents_used_by_ignoring_nested(init) {
if let Some(v_usage) = self.data.vars.get(&id) {
if v_usage.reassigned() {
if v_usage.reassigned {
return;
}
}
@ -413,7 +413,7 @@ impl Optimizer<'_> {
}
if let Some(init_usage) = self.data.vars.get(&id.to_id()) {
if init_usage.reassigned() || !init_usage.declared {
if init_usage.reassigned || !init_usage.declared {
return;
}
}
@ -422,7 +422,7 @@ impl Optimizer<'_> {
_ => {
for id in idents_used_by(init) {
if let Some(v_usage) = self.data.vars.get(&id) {
if v_usage.reassigned() || v_usage.has_property_mutation {
if v_usage.reassigned || v_usage.has_property_mutation {
return;
}
}
@ -534,7 +534,7 @@ impl Optimizer<'_> {
}
if let Some(usage) = self.data.vars.get(&i.to_id()) {
if !usage.reassigned() {
if !usage.reassigned {
trace_op!("typeofs: Storing typeof `{}{:?}`", i.sym, i.span.ctxt);
match &*decl {
Decl::Fn(..) => {
@ -601,10 +601,10 @@ impl Optimizer<'_> {
return;
}
if usage.reassigned() || usage.inline_prevented {
if usage.reassigned || usage.inline_prevented {
log_abort!(
"inline: [x] reassigned = {}, inline_prevented = {}",
usage.reassigned(),
usage.reassigned,
usage.inline_prevented
);
return;

View File

@ -842,7 +842,7 @@ impl Optimizer<'_> {
if let Expr::Ident(callee) = &**callee {
if self.options.reduce_vars && self.options.side_effects {
if let Some(usage) = self.data.vars.get(&callee.to_id()) {
if !usage.reassigned() && usage.pure_fn {
if !usage.reassigned && usage.pure_fn {
self.changed = true;
report_change!("Reducing function call to a variable");

View File

@ -35,7 +35,7 @@ impl Optimizer<'_> {
&& !v.used_as_arg
&& !v.used_in_cond
&& (!v.is_fn_local || !self.mode.should_be_very_correct())
&& !v.reassigned()
&& !v.reassigned
&& !v.is_infected()
})
.unwrap_or(false)

View File

@ -1469,7 +1469,7 @@ impl Optimizer<'_> {
}
_ => a.may_have_side_effects(&self.expr_ctx),
};
if has_side_effect && !usgae.is_fn_local && (usgae.exported || usgae.reassigned()) {
if has_side_effect && !usgae.is_fn_local && (usgae.exported || usgae.reassigned) {
log_abort!("a (expr) has side effect");
return false;
}
@ -1478,7 +1478,7 @@ impl Optimizer<'_> {
if let Some(init) = &a.init {
if init.may_have_side_effects(&self.expr_ctx)
&& !usgae.is_fn_local
&& (usgae.exported || usgae.reassigned())
&& (usgae.exported || usgae.reassigned)
{
log_abort!("a (var) init has side effect");
return false;
@ -2210,7 +2210,7 @@ impl Optimizer<'_> {
}
// We can remove this variable same as unused pass
if !usage.reassigned()
if !usage.reassigned
&& usage.usage_count == 1
&& usage.declared
&& !usage.used_recursively
@ -2239,7 +2239,7 @@ impl Optimizer<'_> {
_ => false,
};
if usage.ref_count != 1 || usage.reassigned() || !usage.is_fn_local {
if usage.ref_count != 1 || usage.reassigned || !usage.is_fn_local {
if is_lit {
can_take_init = false
} else {
@ -2271,7 +2271,7 @@ impl Optimizer<'_> {
Mergable::FnDecl(a) => {
if let Some(usage) = self.data.vars.get(&a.ident.to_id()) {
if usage.ref_count != 1 || usage.reassigned() || !usage.is_fn_local {
if usage.ref_count != 1 || usage.reassigned || !usage.is_fn_local {
return Ok(false);
}

View File

@ -150,7 +150,7 @@ impl Optimizer<'_> {
if let Some(v) = self.data.vars.get(&i.to_id()).cloned() {
if v.ref_count == 0
&& v.usage_count == 0
&& !v.reassigned()
&& !v.reassigned
&& !v.has_property_mutation
&& !v.declared_as_catch_param
{
@ -215,9 +215,7 @@ impl Optimizer<'_> {
return true;
}
if !usage.mutated
&& !usage.reassigned()
&& usage.no_side_effect_for_member_access
if !usage.mutated && !usage.reassigned && usage.no_side_effect_for_member_access
{
return false;
}

View File

@ -74,7 +74,7 @@ pub(crate) struct VarUsageInfo {
pub(crate) usage_count: u32,
/// The variable itself is assigned after reference.
reassigned: bool,
pub(crate) reassigned: bool,
/// The variable itself or a property of it is modified.
pub(crate) mutated: bool,
@ -178,23 +178,18 @@ impl VarUsageInfo {
!self.infects_to.is_empty()
}
pub(crate) fn reassigned(&self) -> bool {
self.reassigned
|| (u32::from(self.var_initialized)
+ u32::from(self.declared_as_catch_param)
+ u32::from(self.declared_as_fn_param)
+ self.assign_count)
> 1
}
pub(crate) fn can_inline_var(&self) -> bool {
!self.mutated || (self.assign_count == 0 && !self.reassigned())
!self.mutated || (self.assign_count == 0 && !self.reassigned)
}
pub(crate) fn can_inline_fn_once(&self) -> bool {
self.callee_count > 0
|| !self.executed_multiple_time && (self.is_fn_local || !self.used_in_non_child_fn)
}
fn initialized(&self) -> bool {
self.var_initialized || self.declared_as_fn_param || self.declared_as_catch_param
}
}
impl Storage for ProgramData {
@ -255,6 +250,12 @@ 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().mutated |= var_info.mutated;
e.get_mut().has_property_access |= var_info.has_property_access;
@ -354,7 +355,8 @@ impl Storage for ProgramData {
let v = self.vars.entry(i.to_id()).or_default();
v.is_top_level |= ctx.is_top_level;
if has_init && (v.declared || v.var_initialized) {
// 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);
@ -486,10 +488,6 @@ impl VarDataLike for VarUsageInfo {
self.mutated = true;
}
fn mark_reassigned(&mut self) {
self.reassigned = true;
}
fn mark_used_as_ref(&mut self) {
self.used_as_ref = true;
}
@ -620,23 +618,29 @@ impl ProgramData {
if is_modify && ctx.is_exact_reassignment {
if is_first {
if e.assign_count > 0 || e.initialized() {
e.reassigned = true
}
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
{
self.initialized_vars.insert(i.clone());
e.assign_count -= 1;
e.var_initialized = true;
} else {
e.reassigned = true
}
}
}
if ctx.is_op_assign {
e.usage_count += 1;
} else if is_first {
if e.ref_count == 1
&& ctx.in_assign_lhs
&& 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
}
}
for other in e.infects_to.clone() {

File diff suppressed because one or more lines are too long

View File

@ -67,8 +67,6 @@ pub trait VarDataLike: Sized {
fn mark_mutated(&mut self);
fn mark_reassigned(&mut self);
fn mark_used_as_ref(&mut self);
fn add_infects_to(&mut self, other: Access);