implement compress option reduce_funcs

- inline single-use function declarations as expressions when permissible
- depend on `reduce_vars`
- enabled by default
- disable for speed critical code

fixes #2464
This commit is contained in:
alexlamsl 2017-11-11 03:15:14 +08:00
parent 94525d859f
commit 69ecb57201
10 changed files with 142 additions and 0 deletions

View File

@ -689,6 +689,11 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
Specify `"strict"` to treat `foo.bar` as side-effect-free only when Specify `"strict"` to treat `foo.bar` as side-effect-free only when
`foo` is certain to not throw, i.e. not `null` or `undefined`. `foo` is certain to not throw, i.e. not `null` or `undefined`.
- `reduce_funcs` (default: `true`) -- Allows single-use functions
to be inlined as function expressions when permissible.
Enabled by default. Option depends on `reduce_vars` being enabled.
For speed critical code this option should be disabled.
- `reduce_vars` (default: `true`) -- Improve optimization on variables assigned with and - `reduce_vars` (default: `true`) -- Improve optimization on variables assigned with and
used as constant values. used as constant values.

View File

@ -75,6 +75,7 @@ function Compressor(options, false_by_default) {
properties : !false_by_default, properties : !false_by_default,
pure_getters : !false_by_default && "strict", pure_getters : !false_by_default && "strict",
pure_funcs : null, pure_funcs : null,
reduce_funcs : !false_by_default,
reduce_vars : !false_by_default, reduce_vars : !false_by_default,
sequences : !false_by_default, sequences : !false_by_default,
side_effects : !false_by_default, side_effects : !false_by_default,
@ -4255,6 +4256,7 @@ merge(Compressor.prototype, {
var fixed = self.fixed_value(); var fixed = self.fixed_value();
if (fixed instanceof AST_Defun) { if (fixed instanceof AST_Defun) {
d.fixed = fixed = make_node(AST_Function, fixed, fixed); d.fixed = fixed = make_node(AST_Function, fixed, fixed);
if (!compressor.option("reduce_funcs")) d.single_use = false;
} }
if (d.single_use && fixed instanceof AST_Function) { if (d.single_use && fixed instanceof AST_Function) {
if (d.escaped && d.scope !== self.scope || recursive_ref(compressor, d)) { if (d.escaped && d.scope !== self.scope || recursive_ref(compressor, d)) {

View File

@ -2369,6 +2369,7 @@ duplicate_argname: {
issue_2298: { issue_2298: {
options = { options = {
collapse_vars: true, collapse_vars: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -3037,6 +3038,7 @@ issue_2437: {
inline: true, inline: true,
join_vars: true, join_vars: true,
passes: 2, passes: 2,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
sequences: true, sequences: true,

View File

@ -673,6 +673,7 @@ issue_1539: {
vardef_value: { vardef_value: {
options = { options = {
keep_fnames: false, keep_fnames: false,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -1080,6 +1081,7 @@ var_catch_toplevel: {
options = { options = {
conditionals: true, conditionals: true,
negate_iife: true, negate_iife: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
toplevel: true, toplevel: true,
@ -1114,6 +1116,7 @@ issue_2105_1: {
collapse_vars: true, collapse_vars: true,
inline: true, inline: true,
passes: 3, passes: 3,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
unused: true, unused: true,
@ -1156,6 +1159,7 @@ issue_2105_2: {
passes: 3, passes: 3,
properties: true, properties: true,
pure_getters: "strict", pure_getters: "strict",
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
unsafe: true, unsafe: true,

View File

@ -305,6 +305,7 @@ issue_2084: {
evaluate: true, evaluate: true,
inline: true, inline: true,
passes: 2, passes: 2,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
sequences: true, sequences: true,
side_effects: true, side_effects: true,
@ -340,6 +341,7 @@ issue_2084: {
issue_2097: { issue_2097: {
options = { options = {
negate_iife: true, negate_iife: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -515,6 +517,7 @@ issue_2428: {
inline: true, inline: true,
passes: 3, passes: 3,
pure_getters: "strict", pure_getters: "strict",
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
toplevel: true, toplevel: true,

View File

@ -15,6 +15,7 @@ f7: {
negate_iife: true, negate_iife: true,
passes: 3, passes: 3,
properties: true, properties: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
sequences: true, sequences: true,
side_effects: true, side_effects: true,

View File

@ -1,5 +1,6 @@
side_effects_catch: { side_effects_catch: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
unused: true, unused: true,
@ -34,6 +35,7 @@ side_effects_catch: {
side_effects_else: { side_effects_else: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
unused: true, unused: true,
@ -62,6 +64,7 @@ side_effects_else: {
side_effects_finally: { side_effects_finally: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
unused: true, unused: true,
@ -98,6 +101,7 @@ side_effects_finally: {
side_effects_label: { side_effects_label: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
unused: true, unused: true,
@ -130,6 +134,7 @@ side_effects_label: {
side_effects_switch: { side_effects_switch: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
unused: true, unused: true,

View File

@ -1,6 +1,7 @@
iife_for: { iife_for: {
options = { options = {
negate_iife: true, negate_iife: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -26,6 +27,7 @@ iife_for: {
iife_for_in: { iife_for_in: {
options = { options = {
negate_iife: true, negate_iife: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -51,6 +53,7 @@ iife_for_in: {
iife_do: { iife_do: {
options = { options = {
negate_iife: true, negate_iife: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -80,6 +83,7 @@ iife_do: {
iife_while: { iife_while: {
options = { options = {
negate_iife: true, negate_iife: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,

View File

@ -185,6 +185,7 @@ issue_2110_1: {
pure_getters: "strict", pure_getters: "strict",
sequences: true, sequences: true,
side_effects: true, side_effects: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -215,6 +216,7 @@ issue_2110_2: {
options = { options = {
collapse_vars: true, collapse_vars: true,
pure_getters: "strict", pure_getters: "strict",
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }

View File

@ -1292,6 +1292,7 @@ defun_reference: {
defun_inline_1: { defun_inline_1: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -1320,6 +1321,7 @@ defun_inline_1: {
defun_inline_2: { defun_inline_2: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -1351,6 +1353,7 @@ defun_inline_3: {
evaluate: true, evaluate: true,
inline: true, inline: true,
passes: 2, passes: 2,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
unused: true, unused: true,
@ -1460,6 +1463,7 @@ func_inline: {
func_modified: { func_modified: {
options = { options = {
inline: true, inline: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -1487,6 +1491,7 @@ func_modified: {
defun_label: { defun_label: {
options = { options = {
passes: 2, passes: 2,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -1629,6 +1634,7 @@ iife_eval_2: {
iife_func_side_effects: { iife_func_side_effects: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -2001,6 +2007,7 @@ redefine_arguments_1: {
options = { options = {
evaluate: true, evaluate: true,
keep_fargs: false, keep_fargs: false,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -2041,6 +2048,7 @@ redefine_arguments_2: {
evaluate: true, evaluate: true,
inline: true, inline: true,
keep_fargs: false, keep_fargs: false,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
toplevel: true, toplevel: true,
@ -2079,6 +2087,7 @@ redefine_arguments_3: {
inline: true, inline: true,
keep_fargs: false, keep_fargs: false,
passes: 3, passes: 3,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
toplevel: true, toplevel: true,
@ -2115,6 +2124,7 @@ redefine_farg_1: {
options = { options = {
evaluate: true, evaluate: true,
keep_fargs: false, keep_fargs: false,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -2154,6 +2164,7 @@ redefine_farg_2: {
evaluate: true, evaluate: true,
inline: true, inline: true,
keep_fargs: false, keep_fargs: false,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
toplevel: true, toplevel: true,
@ -2192,6 +2203,7 @@ redefine_farg_3: {
inline: true, inline: true,
keep_fargs: false, keep_fargs: false,
passes: 2, passes: 2,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
sequences: true, sequences: true,
side_effects: true, side_effects: true,
@ -2701,6 +2713,7 @@ iife_assign: {
issue_1850_1: { issue_1850_1: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: false, toplevel: false,
unused: true, unused: true,
@ -2724,6 +2737,7 @@ issue_1850_1: {
issue_1850_2: { issue_1850_2: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: "funcs", toplevel: "funcs",
unused: true, unused: true,
@ -2746,6 +2760,7 @@ issue_1850_2: {
issue_1850_3: { issue_1850_3: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: "vars", toplevel: "vars",
unused: true, unused: true,
@ -2769,6 +2784,7 @@ issue_1850_3: {
issue_1850_4: { issue_1850_4: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3002,6 +3018,7 @@ obj_arg_1: {
evaluate: true, evaluate: true,
inline: true, inline: true,
passes: 2, passes: 2,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3033,6 +3050,7 @@ obj_arg_2: {
inline: true, inline: true,
passes: 2, passes: 2,
properties: true, properties: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
toplevel: true, toplevel: true,
@ -3105,6 +3123,7 @@ func_arg_2: {
regex_loop: { regex_loop: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3277,6 +3296,7 @@ escaped_prop_1: {
evaluate: true, evaluate: true,
inline: true, inline: true,
pure_getters: "strict", pure_getters: "strict",
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
toplevel: true, toplevel: true,
@ -3302,6 +3322,7 @@ escaped_prop_1: {
escaped_prop_2: { escaped_prop_2: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3420,6 +3441,7 @@ issue_2420_2: {
issue_2423_1: { issue_2423_1: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3444,6 +3466,7 @@ issue_2423_1: {
issue_2423_2: { issue_2423_2: {
options = { options = {
inline: true, inline: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3467,6 +3490,7 @@ issue_2423_2: {
issue_2423_3: { issue_2423_3: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3485,6 +3509,7 @@ issue_2423_3: {
issue_2423_4: { issue_2423_4: {
options = { options = {
inline: true, inline: true,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
toplevel: true, toplevel: true,
@ -3505,6 +3530,7 @@ issue_2423_5: {
options = { options = {
inline: true, inline: true,
passes: 2, passes: 2,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
toplevel: true, toplevel: true,
@ -3543,6 +3569,7 @@ issue_2423_6: {
options = { options = {
inline: true, inline: true,
passes: 2, passes: 2,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
side_effects: true, side_effects: true,
toplevel: true, toplevel: true,
@ -3583,6 +3610,7 @@ issue_2423_6: {
issue_2440_eval_1: { issue_2440_eval_1: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3613,6 +3641,7 @@ issue_2440_eval_1: {
issue_2440_eval_2: { issue_2440_eval_2: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3643,6 +3672,7 @@ issue_2440_eval_2: {
issue_2440_with_1: { issue_2440_with_1: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3669,6 +3699,7 @@ issue_2440_with_1: {
issue_2440_with_2: { issue_2440_with_2: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3695,6 +3726,7 @@ issue_2440_with_2: {
issue_2442: { issue_2442: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3709,6 +3741,7 @@ issue_2442: {
recursive_inlining_1: { recursive_inlining_1: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -3729,6 +3762,7 @@ recursive_inlining_1: {
recursive_inlining_2: { recursive_inlining_2: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -3751,6 +3785,7 @@ recursive_inlining_2: {
recursive_inlining_3: { recursive_inlining_3: {
options = { options = {
passes: 2, passes: 2,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -3788,6 +3823,7 @@ recursive_inlining_3: {
recursive_inlining_4: { recursive_inlining_4: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -3834,6 +3870,7 @@ recursive_inlining_4: {
recursive_inlining_5: { recursive_inlining_5: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -3887,6 +3924,7 @@ recursive_inlining_5: {
issue_2450_1: { issue_2450_1: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3910,6 +3948,7 @@ issue_2450_1: {
issue_2450_2: { issue_2450_2: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3932,6 +3971,7 @@ issue_2450_2: {
issue_2450_3: { issue_2450_3: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
@ -3962,6 +4002,7 @@ issue_2450_3: {
issue_2450_4: { issue_2450_4: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -3995,6 +4036,7 @@ issue_2450_4: {
issue_2450_5: { issue_2450_5: {
options = { options = {
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -4030,6 +4072,7 @@ issue_2450_5: {
issue_2449: { issue_2449: {
options = { options = {
passes: 10, passes: 10,
reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
@ -4061,3 +4104,74 @@ issue_2449: {
} }
expect_stdout: "PASS" expect_stdout: "PASS"
} }
perf_1: {
options = {
passes: 10,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function foo(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
function indirect_foo(x, y, z) {
return foo(x, y, z);
}
var sum = 0;
for (var i = 0; i < 100; ++i) {
sum += indirect_foo(i, i+1, i*3);
}
console.log(sum);
}
expect: {
function indirect_foo(x, y, z) {
return function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}(x, y, z);
}
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
console.log(sum);
}
expect_stdout: "348150"
}
perf_2: {
options = {
passes: 10,
reduce_funcs: false,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function foo(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
function indirect_foo(x, y, z) {
return foo(x, y, z);
}
var sum = 0;
for (var i = 0; i < 100; ++i) {
sum += indirect_foo(i, i+1, i*3);
}
console.log(sum);
}
expect: {
function foo(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
function indirect_foo(x, y, z) {
return foo(x, y, z);
}
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
console.log(sum);
}
expect_stdout: "348150"
}