refactor(minifier): change ast passes order, !in_fixed_loop happen last (#8380)

This commit is contained in:
Boshen 2025-01-09 07:45:20 +00:00
parent c0a3ddac28
commit 1c4658d617
2 changed files with 57 additions and 52 deletions

View file

@ -42,12 +42,12 @@ pub struct PeepholeOptimizations {
x1_minimize_exit_points: MinimizeExitPoints,
x2_exploit_assigns: ExploitAssigns,
x3_collapse_variable_declarations: CollapseVariableDeclarations,
x4_peephole_remove_dead_code: PeepholeRemoveDeadCode,
x5_peephole_minimize_conditions: PeepholeMinimizeConditions,
x6_peephole_substitute_alternate_syntax: PeepholeSubstituteAlternateSyntax,
x4_peephole_fold_constants: PeepholeFoldConstants,
x5_peephole_remove_dead_code: PeepholeRemoveDeadCode,
x6_peephole_minimize_conditions: PeepholeMinimizeConditions,
x7_peephole_replace_known_methods: PeepholeReplaceKnownMethods,
x8_peephole_fold_constants: PeepholeFoldConstants,
x9_convert_to_dotted_properties: ConvertToDottedProperties,
x8_convert_to_dotted_properties: ConvertToDottedProperties,
x9_peephole_substitute_alternate_syntax: PeepholeSubstituteAlternateSyntax,
}
impl PeepholeOptimizations {
@ -59,15 +59,15 @@ impl PeepholeOptimizations {
x1_minimize_exit_points: MinimizeExitPoints::new(),
x2_exploit_assigns: ExploitAssigns::new(),
x3_collapse_variable_declarations: CollapseVariableDeclarations::new(),
x4_peephole_remove_dead_code: PeepholeRemoveDeadCode::new(),
x5_peephole_minimize_conditions: PeepholeMinimizeConditions::new(),
x6_peephole_substitute_alternate_syntax: PeepholeSubstituteAlternateSyntax::new(
x4_peephole_fold_constants: PeepholeFoldConstants::new(),
x5_peephole_remove_dead_code: PeepholeRemoveDeadCode::new(),
x6_peephole_minimize_conditions: PeepholeMinimizeConditions::new(),
x7_peephole_replace_known_methods: PeepholeReplaceKnownMethods::new(),
x8_convert_to_dotted_properties: ConvertToDottedProperties::new(in_fixed_loop),
x9_peephole_substitute_alternate_syntax: PeepholeSubstituteAlternateSyntax::new(
options.target,
in_fixed_loop,
),
x7_peephole_replace_known_methods: PeepholeReplaceKnownMethods::new(),
x8_peephole_fold_constants: PeepholeFoldConstants::new(),
x9_convert_to_dotted_properties: ConvertToDottedProperties::new(in_fixed_loop),
}
}
@ -76,11 +76,11 @@ impl PeepholeOptimizations {
self.x1_minimize_exit_points.changed = false;
self.x2_exploit_assigns.changed = false;
self.x3_collapse_variable_declarations.changed = false;
self.x4_peephole_remove_dead_code.changed = false;
self.x5_peephole_minimize_conditions.changed = false;
self.x6_peephole_substitute_alternate_syntax.changed = false;
self.x4_peephole_fold_constants.changed = false;
self.x5_peephole_remove_dead_code.changed = false;
self.x6_peephole_minimize_conditions.changed = false;
self.x7_peephole_replace_known_methods.changed = false;
self.x8_peephole_fold_constants.changed = false;
self.x9_peephole_substitute_alternate_syntax.changed = false;
}
fn changed(&self) -> bool {
@ -88,11 +88,11 @@ impl PeepholeOptimizations {
|| self.x1_minimize_exit_points.changed
|| self.x2_exploit_assigns.changed
|| self.x3_collapse_variable_declarations.changed
|| self.x4_peephole_remove_dead_code.changed
|| self.x5_peephole_minimize_conditions.changed
|| self.x6_peephole_substitute_alternate_syntax.changed
|| self.x4_peephole_fold_constants.changed
|| self.x5_peephole_remove_dead_code.changed
|| self.x6_peephole_minimize_conditions.changed
|| self.x7_peephole_replace_known_methods.changed
|| self.x8_peephole_fold_constants.changed
|| self.x9_peephole_substitute_alternate_syntax.changed
}
pub fn run_in_loop<'a>(
@ -124,7 +124,7 @@ impl<'a> CompressorPass<'a> for PeepholeOptimizations {
impl<'a> Traverse<'a> for PeepholeOptimizations {
fn exit_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) {
self.x4_peephole_remove_dead_code.exit_program(program, ctx);
self.x5_peephole_remove_dead_code.exit_program(program, ctx);
}
fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
@ -132,17 +132,17 @@ impl<'a> Traverse<'a> for PeepholeOptimizations {
self.x1_minimize_exit_points.exit_statements(stmts, ctx);
self.x2_exploit_assigns.exit_statements(stmts, ctx);
self.x3_collapse_variable_declarations.exit_statements(stmts, ctx);
self.x4_peephole_remove_dead_code.exit_statements(stmts, ctx);
self.x5_peephole_minimize_conditions.exit_statements(stmts, ctx);
self.x5_peephole_remove_dead_code.exit_statements(stmts, ctx);
self.x6_peephole_minimize_conditions.exit_statements(stmts, ctx);
}
fn exit_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
self.x4_peephole_remove_dead_code.exit_statement(stmt, ctx);
self.x5_peephole_minimize_conditions.exit_statement(stmt, ctx);
self.x5_peephole_remove_dead_code.exit_statement(stmt, ctx);
self.x6_peephole_minimize_conditions.exit_statement(stmt, ctx);
}
fn exit_return_statement(&mut self, stmt: &mut ReturnStatement<'a>, ctx: &mut TraverseCtx<'a>) {
self.x6_peephole_substitute_alternate_syntax.exit_return_statement(stmt, ctx);
self.x9_peephole_substitute_alternate_syntax.exit_return_statement(stmt, ctx);
}
fn exit_function_body(&mut self, body: &mut FunctionBody<'a>, ctx: &mut TraverseCtx<'a>) {
@ -154,23 +154,23 @@ impl<'a> Traverse<'a> for PeepholeOptimizations {
decl: &mut VariableDeclaration<'a>,
ctx: &mut TraverseCtx<'a>,
) {
self.x6_peephole_substitute_alternate_syntax.exit_variable_declaration(decl, ctx);
self.x9_peephole_substitute_alternate_syntax.exit_variable_declaration(decl, ctx);
}
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
self.x4_peephole_remove_dead_code.exit_expression(expr, ctx);
self.x5_peephole_minimize_conditions.exit_expression(expr, ctx);
self.x6_peephole_substitute_alternate_syntax.exit_expression(expr, ctx);
self.x4_peephole_fold_constants.exit_expression(expr, ctx);
self.x5_peephole_remove_dead_code.exit_expression(expr, ctx);
self.x6_peephole_minimize_conditions.exit_expression(expr, ctx);
self.x7_peephole_replace_known_methods.exit_expression(expr, ctx);
self.x8_peephole_fold_constants.exit_expression(expr, ctx);
self.x9_peephole_substitute_alternate_syntax.exit_expression(expr, ctx);
}
fn enter_call_expression(&mut self, expr: &mut CallExpression<'a>, ctx: &mut TraverseCtx<'a>) {
self.x6_peephole_substitute_alternate_syntax.enter_call_expression(expr, ctx);
self.x9_peephole_substitute_alternate_syntax.enter_call_expression(expr, ctx);
}
fn exit_call_expression(&mut self, expr: &mut CallExpression<'a>, ctx: &mut TraverseCtx<'a>) {
self.x6_peephole_substitute_alternate_syntax.exit_call_expression(expr, ctx);
self.x9_peephole_substitute_alternate_syntax.exit_call_expression(expr, ctx);
}
fn exit_member_expression(
@ -178,11 +178,11 @@ impl<'a> Traverse<'a> for PeepholeOptimizations {
expr: &mut MemberExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
self.x9_convert_to_dotted_properties.exit_member_expression(expr, ctx);
self.x8_convert_to_dotted_properties.exit_member_expression(expr, ctx);
}
fn exit_object_property(&mut self, prop: &mut ObjectProperty<'a>, ctx: &mut TraverseCtx<'a>) {
self.x6_peephole_substitute_alternate_syntax.exit_object_property(prop, ctx);
self.x9_peephole_substitute_alternate_syntax.exit_object_property(prop, ctx);
}
fn exit_assignment_target_property_property(
@ -190,12 +190,12 @@ impl<'a> Traverse<'a> for PeepholeOptimizations {
prop: &mut AssignmentTargetPropertyProperty<'a>,
ctx: &mut TraverseCtx<'a>,
) {
self.x6_peephole_substitute_alternate_syntax
self.x9_peephole_substitute_alternate_syntax
.exit_assignment_target_property_property(prop, ctx);
}
fn exit_binding_property(&mut self, prop: &mut BindingProperty<'a>, ctx: &mut TraverseCtx<'a>) {
self.x6_peephole_substitute_alternate_syntax.exit_binding_property(prop, ctx);
self.x9_peephole_substitute_alternate_syntax.exit_binding_property(prop, ctx);
}
fn exit_method_definition(
@ -203,7 +203,7 @@ impl<'a> Traverse<'a> for PeepholeOptimizations {
prop: &mut MethodDefinition<'a>,
ctx: &mut TraverseCtx<'a>,
) {
self.x6_peephole_substitute_alternate_syntax.exit_method_definition(prop, ctx);
self.x9_peephole_substitute_alternate_syntax.exit_method_definition(prop, ctx);
}
fn exit_property_definition(
@ -211,7 +211,7 @@ impl<'a> Traverse<'a> for PeepholeOptimizations {
prop: &mut PropertyDefinition<'a>,
ctx: &mut TraverseCtx<'a>,
) {
self.x6_peephole_substitute_alternate_syntax.exit_property_definition(prop, ctx);
self.x9_peephole_substitute_alternate_syntax.exit_property_definition(prop, ctx);
}
fn exit_accessor_property(
@ -219,11 +219,11 @@ impl<'a> Traverse<'a> for PeepholeOptimizations {
prop: &mut AccessorProperty<'a>,
ctx: &mut TraverseCtx<'a>,
) {
self.x6_peephole_substitute_alternate_syntax.exit_accessor_property(prop, ctx);
self.x9_peephole_substitute_alternate_syntax.exit_accessor_property(prop, ctx);
}
fn exit_catch_clause(&mut self, catch: &mut CatchClause<'a>, ctx: &mut TraverseCtx<'a>) {
self.x6_peephole_substitute_alternate_syntax.exit_catch_clause(catch, ctx);
self.x9_peephole_substitute_alternate_syntax.exit_catch_clause(catch, ctx);
}
}

View file

@ -140,8 +140,6 @@ impl<'a> Traverse<'a> for PeepholeSubstituteAlternateSyntax {
// Fold
if let Some(folded_expr) = match expr {
Expression::Identifier(ident) => self.try_compress_undefined(ident, ctx),
Expression::BooleanLiteral(_) => self.try_compress_boolean(expr, ctx),
Expression::AssignmentExpression(e) => {
Self::try_compress_assignment_to_update_expression(e, ctx)
}
@ -168,6 +166,20 @@ impl<'a> Traverse<'a> for PeepholeSubstituteAlternateSyntax {
*expr = folded_expr;
self.changed = true;
}
// Out of fixed loop syntax changes happen last.
if self.in_fixed_loop {
return;
}
if let Some(folded_expr) = match expr {
Expression::Identifier(ident) => self.try_compress_undefined(ident, ctx),
Expression::BooleanLiteral(_) => self.try_compress_boolean(expr, ctx),
_ => None,
} {
*expr = folded_expr;
self.changed = true;
}
}
}
@ -224,9 +236,7 @@ impl<'a, 'b> PeepholeSubstituteAlternateSyntax {
ident: &IdentifierReference<'a>,
ctx: Ctx<'a, 'b>,
) -> Option<Expression<'a>> {
if self.in_fixed_loop {
return None;
}
debug_assert!(!self.in_fixed_loop);
if !ctx.is_identifier_undefined(ident) {
return None;
}
@ -240,9 +250,7 @@ impl<'a, 'b> PeepholeSubstituteAlternateSyntax {
expr: &mut Expression<'a>,
ctx: Ctx<'a, 'b>,
) -> Option<Expression<'a>> {
if self.in_fixed_loop {
return None;
}
debug_assert!(!self.in_fixed_loop);
let Expression::BooleanLiteral(lit) = expr else { return None };
if self.in_define_export {
return None;
@ -1016,9 +1024,6 @@ impl<'a, 'b> PeepholeSubstituteAlternateSyntax {
computed: &mut bool,
ctx: &mut TraverseCtx<'a>,
) {
if self.in_fixed_loop {
return;
}
if let PropertyKey::NumericLiteral(_) = key {
if *computed {
*computed = false;
@ -1817,7 +1822,7 @@ mod test {
// Don't fold the existence check to preserve behavior
test_same("var a = Boolean?.({})");
test("var a = Boolean()", "var a = false;");
test("var a = Boolean()", "var a = !1;");
test_same("var a = Boolean(!0, !1);");
}