mirror of
https://github.com/swc-project/swc.git
synced 2024-11-24 02:06:08 +03:00
refactor(es/minifier): Pre-calculate reassigned
(#7832)
This commit is contained in:
parent
662f236aa5
commit
65db1badff
@ -40,7 +40,7 @@ impl Optimizer<'_> {
|
||||
|
||||
let usage = self.data.vars.get(&obj.to_id())?;
|
||||
|
||||
if usage.reassigned() {
|
||||
if usage.reassigned {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ impl Optimizer<'_> {
|
||||
match &mut **param {
|
||||
Pat::Ident(param) => {
|
||||
if let Some(usage) = self.data.vars.get(¶m.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(¶m_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,
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user