speed up compress (#5219)

This commit is contained in:
Alex Lam S.L
2021-12-13 23:42:47 +00:00
committed by GitHub
parent 2c5e23506b
commit 7fe7c39a01

View File

@@ -1818,27 +1818,34 @@ Compressor.prototype.compress = function(node) {
function tighten_body(statements, compressor) {
var in_loop, in_try, scope;
find_loop_scope_try();
var CHANGED, max_iter = 10;
var changed, last_changed, max_iter = 10;
do {
CHANGED = false;
eliminate_spurious_blocks(statements);
last_changed = changed;
changed = 0;
if (eliminate_spurious_blocks(statements)) changed = 1;
if (!changed && last_changed == 1) break;
if (compressor.option("dead_code")) {
eliminate_dead_code(statements, compressor);
if (eliminate_dead_code(statements, compressor)) changed = 2;
if (!changed && last_changed == 2) break;
}
if (compressor.option("if_return")) {
handle_if_return(statements, compressor);
if (handle_if_return(statements, compressor)) changed = 3;
if (!changed && last_changed == 3) break;
}
if (compressor.sequences_limit > 0) {
sequencesize(statements, compressor);
sequencesize_2(statements, compressor);
if (sequencesize(statements, compressor)) changed = 4;
if (!changed && last_changed == 4) break;
if (sequencesize_2(statements, compressor)) changed = 5;
if (!changed && last_changed == 5) break;
}
if (compressor.option("join_vars")) {
join_consecutive_vars(statements);
if (join_consecutive_vars(statements)) changed = 6;
if (!changed && last_changed == 6) break;
}
if (compressor.option("collapse_vars")) {
collapse(statements, compressor);
if (collapse(statements, compressor)) changed = 7;
}
} while (CHANGED && max_iter-- > 0);
} while (changed && max_iter-- > 0);
return statements;
function find_loop_scope_try() {
@@ -1874,10 +1881,11 @@ Compressor.prototype.compress = function(node) {
// Will not attempt to collapse assignments into or past code blocks
// which are not sequentially executed, e.g. loops and conditionals.
function collapse(statements, compressor) {
if (scope.pinned()) return statements;
if (scope.pinned()) return;
var args;
var assignments = new Dictionary();
var candidates = [];
var changed = false;
var declare_only = new Dictionary();
var force_single;
var stat_index = statements.length;
@@ -1924,7 +1932,7 @@ Compressor.prototype.compress = function(node) {
} else {
replaced++;
}
CHANGED = abort = true;
changed = abort = true;
AST_Node.info("Collapsing {node} [{file}:{line},{col}]", {
node: node,
file: node.start.file,
@@ -2137,11 +2145,12 @@ Compressor.prototype.compress = function(node) {
&& !compressor.exposed(def);
value_def.last_ref = false;
value_def.single_use = false;
CHANGED = true;
changed = true;
}
if (replaced && !remove_candidate(candidate)) statements.splice(stat_index, 1);
}
}
return changed;
function signal_abort(node) {
if (abort) return node;
@@ -3094,12 +3103,12 @@ Compressor.prototype.compress = function(node) {
}
function eliminate_spurious_blocks(statements) {
var seen_dirs = [];
var changed = false, seen_dirs = [];
for (var i = 0; i < statements.length;) {
var stat = statements[i];
if (stat instanceof AST_BlockStatement) {
if (all(stat.body, safe_to_trim)) {
CHANGED = true;
changed = true;
eliminate_spurious_blocks(stat.body);
[].splice.apply(statements, [i, 1].concat(stat.body));
i += stat.body.length;
@@ -3108,22 +3117,24 @@ Compressor.prototype.compress = function(node) {
}
if (stat instanceof AST_Directive) {
if (member(stat.value, seen_dirs)) {
CHANGED = true;
changed = true;
statements.splice(i, 1);
continue;
}
seen_dirs.push(stat.value);
}
if (stat instanceof AST_EmptyStatement) {
CHANGED = true;
changed = true;
statements.splice(i, 1);
continue;
}
i++;
}
return changed;
}
function handle_if_return(statements, compressor) {
var changed = false;
var self = compressor.self();
var parent = compressor.parent();
var in_lambda = last_of(function(node) {
@@ -3138,13 +3149,13 @@ Compressor.prototype.compress = function(node) {
if (in_lambda && !next && stat instanceof AST_Return) {
if (!stat.value) {
CHANGED = true;
changed = true;
statements.splice(i, 1);
continue;
}
var tail = stat.value.tail_node();
if (tail instanceof AST_UnaryPrefix && tail.operator == "void") {
CHANGED = true;
changed = true;
var body;
if (tail === stat.value) {
body = tail.expression;
@@ -3163,7 +3174,7 @@ Compressor.prototype.compress = function(node) {
var ab = aborts(stat.body);
if (can_merge_flow(ab)) {
if (ab.label) remove(ab.label.thedef.references, ab);
CHANGED = true;
changed = true;
stat = stat.clone();
stat.condition = stat.condition.negate(compressor);
var body = as_statement_array_with_return(stat.body, ab);
@@ -3181,7 +3192,7 @@ Compressor.prototype.compress = function(node) {
if (ab && !stat.alternative && stat.body instanceof AST_BlockStatement && next instanceof AST_Jump) {
var negated = stat.condition.negate(compressor);
if (negated.print_to_string().length <= stat.condition.print_to_string().length) {
CHANGED = true;
changed = true;
stat = stat.clone();
stat.condition = negated;
statements[j] = stat.body;
@@ -3195,7 +3206,7 @@ Compressor.prototype.compress = function(node) {
var alt = aborts(stat.alternative);
if (can_merge_flow(alt)) {
if (alt.label) remove(alt.label.thedef.references, alt);
CHANGED = true;
changed = true;
stat = stat.clone();
stat.body = make_node(AST_BlockStatement, stat.body, {
body: as_statement_array(stat.body).concat(extract_functions())
@@ -3231,7 +3242,7 @@ Compressor.prototype.compress = function(node) {
// if (foo()) return; return; ---> foo(); return;
if (!value && !stat.alternative
&& (in_lambda && !next || next instanceof AST_Return && !next.value)) {
CHANGED = true;
changed = true;
statements[i] = make_node(AST_SimpleStatement, stat.condition, {
body: stat.condition
});
@@ -3240,7 +3251,7 @@ Compressor.prototype.compress = function(node) {
//---
// if (foo()) return x; return y; ---> return foo() ? x : y;
if (!stat.alternative && next instanceof AST_Return) {
CHANGED = true;
changed = true;
stat = stat.clone();
stat.alternative = next;
statements.splice(i, 1, stat.transform(compressor));
@@ -3250,7 +3261,7 @@ Compressor.prototype.compress = function(node) {
//---
// if (foo()) return x; [ return ; ] ---> return foo() ? x : undefined;
if (!stat.alternative && !next && in_lambda && (in_bool || value && multiple_if_returns)) {
CHANGED = true;
changed = true;
stat = stat.clone();
stat.alternative = make_node(AST_Return, stat, {
value: null
@@ -3268,7 +3279,7 @@ Compressor.prototype.compress = function(node) {
if (compressor.option("sequences") && in_lambda && !stat.alternative
&& (!prev && in_iife || prev instanceof AST_If && prev.body instanceof AST_Return)
&& next_index(j) == statements.length && next instanceof AST_SimpleStatement) {
CHANGED = true;
changed = true;
stat = stat.clone();
stat.alternative = make_node(AST_BlockStatement, next, {
body: [
@@ -3284,6 +3295,7 @@ Compressor.prototype.compress = function(node) {
}
}
}
return changed;
function has_multiple_if_returns(statements) {
var n = 0;
@@ -3411,7 +3423,7 @@ Compressor.prototype.compress = function(node) {
if (has_quit) has_quit.forEach(function(stat) {
extract_declarations_from_unreachable_code(compressor, stat, statements);
});
CHANGED = statements.length != len;
return statements.length != len;
}
function sequencesize(statements, compressor) {
@@ -3439,7 +3451,7 @@ Compressor.prototype.compress = function(node) {
}
push_seq();
statements.length = n;
if (n != len) CHANGED = true;
return n != len;
}
function to_simple_statement(block, decls) {
@@ -3459,13 +3471,7 @@ Compressor.prototype.compress = function(node) {
}
function sequencesize_2(statements, compressor) {
function cons_seq(right) {
n--;
CHANGED = true;
var left = prev.body;
return make_sequence(left, [ left, right ]);
}
var n = 0, prev;
var changed = false, n = 0, prev;
for (var i = 0; i < statements.length; i++) {
var stat = statements[i];
if (prev) {
@@ -3488,7 +3494,7 @@ Compressor.prototype.compress = function(node) {
else {
stat.init = prev.body;
n--;
CHANGED = true;
changed = true;
}
}
}
@@ -3518,7 +3524,7 @@ Compressor.prototype.compress = function(node) {
i += len;
n += len + 1;
prev = null;
CHANGED = true;
changed = true;
continue;
}
}
@@ -3526,6 +3532,14 @@ Compressor.prototype.compress = function(node) {
prev = stat instanceof AST_SimpleStatement ? stat : null;
}
statements.length = n;
return changed;
function cons_seq(right) {
n--;
changed = true;
var left = prev.body;
return make_sequence(left, [ left, right ]);
}
}
function extract_exprs(body) {
@@ -3680,17 +3694,17 @@ Compressor.prototype.compress = function(node) {
}
function join_consecutive_vars(statements) {
var defs;
var changed = false, defs;
for (var i = 0, j = -1; i < statements.length; i++) {
var stat = statements[i];
var prev = statements[j];
if (stat instanceof AST_Definitions) {
if (prev && prev.TYPE == stat.TYPE) {
prev.definitions = prev.definitions.concat(stat.definitions);
CHANGED = true;
changed = true;
} else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) {
defs.definitions = defs.definitions.concat(stat.definitions);
CHANGED = true;
changed = true;
} else if (stat instanceof AST_Var) {
var exprs = merge_assigns(prev, stat);
if (exprs) {
@@ -3698,7 +3712,7 @@ Compressor.prototype.compress = function(node) {
prev.body = make_sequence(prev, exprs);
j++;
}
CHANGED = true;
changed = true;
} else {
j++;
}
@@ -3712,7 +3726,7 @@ Compressor.prototype.compress = function(node) {
} else if (stat instanceof AST_For) {
var exprs = join_assigns(prev, stat.init);
if (exprs) {
CHANGED = true;
changed = true;
stat.init = exprs.length ? make_sequence(stat.init, exprs) : null;
} else if (prev instanceof AST_Var && (!stat.init || stat.init.TYPE == prev.TYPE)) {
if (stat.init) {
@@ -3720,17 +3734,17 @@ Compressor.prototype.compress = function(node) {
}
defs = stat.init = prev;
statements[j] = merge_defns(stat);
CHANGED = true;
changed = true;
continue;
} else if (defs && stat.init && defs.TYPE == stat.init.TYPE && declarations_only(stat.init)) {
defs.definitions = defs.definitions.concat(stat.init.definitions);
stat.init = null;
CHANGED = true;
changed = true;
} else if (stat.init instanceof AST_Var) {
defs = stat.init;
exprs = merge_assigns(prev, stat.init);
if (exprs) {
CHANGED = true;
changed = true;
if (exprs.length == 0) {
statements[j] = merge_defns(stat);
continue;
@@ -3749,7 +3763,7 @@ Compressor.prototype.compress = function(node) {
name.definition().references.push(ref);
});
defs.definitions = defns;
CHANGED = true;
changed = true;
}
stat.object = join_assigns_expr(stat.object);
} else if (stat instanceof AST_If) {
@@ -3757,7 +3771,7 @@ Compressor.prototype.compress = function(node) {
} else if (stat instanceof AST_SimpleStatement) {
var exprs = join_assigns(prev, stat.body);
if (exprs) {
CHANGED = true;
changed = true;
if (!exprs.length) continue;
stat.body = make_sequence(stat.body, exprs);
}
@@ -3769,11 +3783,12 @@ Compressor.prototype.compress = function(node) {
statements[++j] = defs ? merge_defns(stat) : stat;
}
statements.length = j + 1;
return changed;
function join_assigns_expr(value) {
var exprs = join_assigns(prev, value, 1);
if (!exprs) return value;
CHANGED = true;
changed = true;
var tail = value.tail_node();
if (exprs[exprs.length - 1] !== tail) exprs.push(tail.left);
return make_sequence(value, exprs);
@@ -3788,7 +3803,7 @@ Compressor.prototype.compress = function(node) {
if (parent instanceof AST_ForEnumeration && parent.init === node) return node;
if (!declarations_only(node)) return node;
defs.definitions = defs.definitions.concat(node.definitions);
CHANGED = true;
changed = true;
if (parent instanceof AST_For && parent.init === node) return null;
return in_list ? List.skip : make_node(AST_EmptyStatement, node);
}