Skip to content

Commit 5b3c412

Browse files
authored
perf(minifier): only run optimizations on local changes (#8644)
Previously all code are ran in a fixed point loop when ast changes. This PR changes running code when a function changes its enclosing ast only.
1 parent b75d491 commit 5b3c412

14 files changed

Lines changed: 205 additions & 70 deletions

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/oxc_minifier/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ oxc_syntax = { workspace = true }
3333
oxc_traverse = { workspace = true }
3434

3535
cow-utils = { workspace = true }
36+
rustc-hash = { workspace = true }
3637

3738
[dev-dependencies]
3839
oxc_parser = { workspace = true }

crates/oxc_minifier/src/peephole/collapse_variable_declarations.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl<'a> PeepholeOptimizations {
9393
}
9494

9595
*stmts = new_stmts;
96-
self.changed = true;
96+
self.mark_current_function_as_changed();
9797
}
9898
}
9999

@@ -133,7 +133,7 @@ impl<'a> PeepholeOptimizations {
133133
}
134134
}
135135

136-
if self.changed {
136+
if self.is_current_function_changed() {
137137
stmts.retain(|stmt| !matches!(stmt, Statement::EmptyStatement(_)));
138138
}
139139
}
@@ -147,7 +147,7 @@ impl<'a> PeepholeOptimizations {
147147
if let Statement::ExpressionStatement(expr_stmt) = ctx.ast.move_statement(&mut stmts[i]) {
148148
if let Statement::ForStatement(for_stmt) = &mut stmts[i + 1] {
149149
for_stmt.init = Some(ForStatementInit::from(expr_stmt.unbox().expression));
150-
self.changed = true;
150+
self.mark_current_function_as_changed();
151151
};
152152
}
153153
}
@@ -163,11 +163,11 @@ impl<'a> PeepholeOptimizations {
163163
match for_stmt.init.as_mut() {
164164
Some(ForStatementInit::VariableDeclaration(for_var)) => {
165165
for_var.declarations.splice(0..0, var.unbox().declarations);
166-
self.changed = true;
166+
self.mark_current_function_as_changed();
167167
}
168168
None => {
169169
for_stmt.init = Some(ForStatementInit::VariableDeclaration(var));
170-
self.changed = true;
170+
self.mark_current_function_as_changed();
171171
}
172172
_ => {
173173
unreachable!()
@@ -209,7 +209,7 @@ impl<'a> PeepholeOptimizations {
209209
_ => unreachable!(),
210210
};
211211
*left = ForStatementLeft::VariableDeclaration(var);
212-
self.changed = true;
212+
self.mark_current_function_as_changed();
213213
}
214214
}
215215
}

crates/oxc_minifier/src/peephole/convert_to_dotted_properties.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl<'a> PeepholeOptimizations {
3535
*expr = MemberExpression::StaticMemberExpression(
3636
ctx.ast.alloc_static_member_expression(e.span, object, property, e.optional),
3737
);
38-
self.changed = true;
38+
self.mark_current_function_as_changed();
3939
return;
4040
}
4141
let v = s.value.as_str();

crates/oxc_minifier/src/peephole/fold_constants.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl<'a, 'b> PeepholeOptimizations {
3636
_ => None,
3737
} {
3838
*expr = folded_expr;
39-
self.changed = true;
39+
self.mark_current_function_as_changed();
4040
};
4141
}
4242

@@ -706,7 +706,7 @@ impl<'a, 'b> PeepholeOptimizations {
706706
true
707707
});
708708
if e.properties.len() != len {
709-
self.changed = true;
709+
self.mark_current_function_as_changed();
710710
}
711711
None
712712
}

crates/oxc_minifier/src/peephole/minimize_conditions.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,20 @@ impl<'a> PeepholeOptimizations {
2121
stmts: &mut oxc_allocator::Vec<'a, Statement<'a>>,
2222
ctx: &mut TraverseCtx<'a>,
2323
) {
24-
self.try_replace_if(stmts, ctx);
25-
let changed = self.changed;
26-
while self.changed {
27-
self.changed = false;
28-
self.try_replace_if(stmts, ctx);
24+
let mut changed = false;
25+
let mut changed2 = false;
26+
Self::try_replace_if(stmts, &mut changed2, ctx);
27+
while changed2 {
28+
changed2 = false;
29+
Self::try_replace_if(stmts, &mut changed2, ctx);
2930
if stmts.iter().any(|stmt| matches!(stmt, Statement::EmptyStatement(_))) {
3031
stmts.retain(|stmt| !matches!(stmt, Statement::EmptyStatement(_)));
3132
}
33+
changed = changed2;
34+
}
35+
if changed {
36+
self.mark_current_function_as_changed();
3237
}
33-
self.changed = self.changed || changed;
3438
}
3539

3640
pub fn minimize_conditions_exit_statement(
@@ -64,7 +68,7 @@ impl<'a> PeepholeOptimizations {
6468
_ => None,
6569
} {
6670
*stmt = folded_stmt;
67-
self.changed = true;
71+
self.mark_current_function_as_changed();
6872
};
6973
}
7074

@@ -87,7 +91,7 @@ impl<'a> PeepholeOptimizations {
8791
}
8892
}
8993
if changed {
90-
self.changed = true;
94+
self.mark_current_function_as_changed();
9195
} else {
9296
break;
9397
}
@@ -99,7 +103,7 @@ impl<'a> PeepholeOptimizations {
99103
_ => None,
100104
} {
101105
*expr = folded_expr;
102-
self.changed = true;
106+
self.mark_current_function_as_changed();
103107
};
104108
}
105109

@@ -236,7 +240,11 @@ impl<'a> PeepholeOptimizations {
236240
None
237241
}
238242

239-
fn try_replace_if(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
243+
fn try_replace_if(
244+
stmts: &mut Vec<'a, Statement<'a>>,
245+
changed: &mut bool,
246+
ctx: &mut TraverseCtx<'a>,
247+
) {
240248
for i in 0..stmts.len() {
241249
let Statement::IfStatement(if_stmt) = &stmts[i] else {
242250
continue;
@@ -268,15 +276,15 @@ impl<'a> PeepholeOptimizations {
268276
alternate,
269277
);
270278
stmts[i] = ctx.ast.statement_return(if_stmt.span, Some(argument));
271-
self.changed = true;
279+
*changed = true;
272280
break;
273281
} else if else_branch.is_some() && Self::statement_must_exit_parent(then_branch) {
274282
let Statement::IfStatement(if_stmt) = &mut stmts[i] else {
275283
unreachable!();
276284
};
277285
let else_branch = if_stmt.alternate.take().unwrap();
278286
stmts.insert(i + 1, else_branch);
279-
self.changed = true;
287+
*changed = true;
280288
}
281289
}
282290
}

crates/oxc_minifier/src/peephole/minimize_exit_points.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ impl<'a> PeepholeOptimizations {
2222
if let Some(last) = stmts.last() {
2323
if matches!(last, Statement::ReturnStatement(ret) if ret.argument.is_none()) {
2424
stmts.pop();
25-
self.changed = true;
25+
self.mark_current_function_as_changed();
2626
}
2727
}
2828
}

0 commit comments

Comments
 (0)