Skip to content

Commit

Permalink
fix(minifier): dce if statement should keep side effects and vars (#8433
Browse files Browse the repository at this point in the history
)

closes #7209

Note: Current output is sub-optimal.
  • Loading branch information
Boshen committed Jan 11, 2025
1 parent 9a03bd2 commit 3c93549
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 16 deletions.
37 changes: 24 additions & 13 deletions crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,22 +204,33 @@ impl<'a, 'b> PeepholeRemoveDeadCode {
return Some(ctx.ast.statement_expression(if_stmt.span, expr));
}

match ctx.get_boolean_value(&if_stmt.test) {
Some(true) => Some(ctx.ast.move_statement(&mut if_stmt.consequent)),
Some(false) => {
Some(if let Some(alternate) = &mut if_stmt.alternate {
ctx.ast.move_statement(alternate)
if let Some(boolean) = ctx.get_side_free_boolean_value(&if_stmt.test) {
let mut keep_var = KeepVar::new(ctx.ast);
if boolean {
if let Some(alternate) = &if_stmt.alternate {
keep_var.visit_statement(alternate);
}
} else {
keep_var.visit_statement(&if_stmt.consequent);
};
if let Some(var_stmt) = keep_var.get_variable_declaration_statement() {
if boolean {
if_stmt.alternate = Some(var_stmt);
} else {
// Keep hoisted `vars` from the consequent block.
let mut keep_var = KeepVar::new(ctx.ast);
keep_var.visit_statement(&if_stmt.consequent);
keep_var
.get_variable_declaration_statement()
.unwrap_or_else(|| ctx.ast.statement_empty(SPAN))
})
if_stmt.consequent = var_stmt;
}
return None;
}
None => None,
return Some(if boolean {
ctx.ast.move_statement(&mut if_stmt.consequent)
} else {
if_stmt.alternate.as_mut().map_or_else(
|| ctx.ast.statement_empty(SPAN),
|alternate| ctx.ast.move_statement(alternate),
)
});
}
None
}

fn try_fold_for(
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_minifier/tests/ast_passes/dead_code_elimination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn dce_if_statement() {
);
test(
"if (xxx) { foo } else if (false) { var a; var b; } else if (false) { var c; var d; }",
"if (xxx) foo; else var c, d;",
"if (xxx) foo; else if (false) var a, b; else if (false) var c, d;",
);

test("if (!false) { foo }", "foo");
Expand Down Expand Up @@ -229,7 +229,7 @@ fn dce_from_terser() {
console.log(foo, bar, Baz);
",
"
var qux;
if (0) var qux;
console.log(foo, bar, Baz);
",
);
Expand Down
13 changes: 13 additions & 0 deletions crates/oxc_minifier/tests/ast_passes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ fn integration() {
);

test_same("a && (b && (c && (d && (e && (f && (g && (h && i && j && k && l && m && n && o && p && q && r && s && t && u && v && w && x && y && z)))))))");

test(
"if (((() => console.log('effect'))(), true)) {
} else {
var c = 1;
for (var c; unknownGlobal && true; unknownGlobal && true) var d;
}
console.log(c, d);
",
"if ((() => console.log('effect'))(), !0) {} else for (var c = 1, c; unknownGlobal; unknownGlobal && !0) var d;
console.log(c, d);
",
);
}

#[test] // https://github.com/oxc-project/oxc/issues/4341
Expand Down
2 changes: 1 addition & 1 deletion tasks/minsize/minsize.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Original | minified | minified | gzip | gzip | Fixture

3.20 MB | 1.01 MB | 1.01 MB | 331.79 kB | 331.56 kB | echarts.js

6.69 MB | 2.32 MB | 2.31 MB | 492.63 kB | 488.28 kB | antd.js
6.69 MB | 2.32 MB | 2.31 MB | 492.64 kB | 488.28 kB | antd.js

10.95 MB | 3.49 MB | 3.49 MB | 907.42 kB | 915.50 kB | typescript.js

0 comments on commit 3c93549

Please sign in to comment.