aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2017-12-01 05:52:33 +0800
committerGitHub <noreply@github.com>2017-12-01 05:52:33 +0800
commitb762f2d6f4e81dcbd49ffb4db4b1933953942999 (patch)
treed4fde8ea2685912d3fe73ff0ba7e41706cc7e5ce
parent172079a47f2f7bf09d2a5b4e4cf05691a1206358 (diff)
downloadtracifyjs-b762f2d6f4e81dcbd49ffb4db4b1933953942999.tar.gz
tracifyjs-b762f2d6f4e81dcbd49ffb4db4b1933953942999.zip
improve compression of loop conditions (#2543)
-rw-r--r--lib/compress.js95
-rw-r--r--test/compress/dead-code.js4
-rw-r--r--test/compress/issue-1656.js2
-rw-r--r--test/compress/issue-1833.js2
-rw-r--r--test/compress/loops.js4
-rw-r--r--test/compress/reduce_vars.js1
6 files changed, 63 insertions, 45 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 206c77f3..e6215f66 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -3020,34 +3020,40 @@ merge(Compressor.prototype, {
return self;
});
- OPT(AST_DWLoop, function(self, compressor){
+ OPT(AST_While, function(self, compressor){
+ return compressor.option("loops") ? make_node(AST_For, self, self).optimize(compressor) : self;
+ });
+
+ OPT(AST_Do, function(self, compressor){
if (!compressor.option("loops")) return self;
- var cond = self.condition.evaluate(compressor);
- if (cond !== self.condition) {
- if (cond) {
- return make_node(AST_For, self, {
- body: self.body
- });
- }
- if (compressor.option("dead_code") && self instanceof AST_While) {
- var a = [];
- extract_declarations_from_unreachable_code(compressor, self.body, a);
- return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
- }
- if (self instanceof AST_Do) {
- var has_loop_control = false;
- var tw = new TreeWalker(function(node) {
- if (node instanceof AST_Scope || has_loop_control) return true;
- if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === self)
- return has_loop_control = true;
- });
- var parent = compressor.parent();
- (parent instanceof AST_LabeledStatement ? parent : self).walk(tw);
- if (!has_loop_control) return self.body;
- }
- }
- if (self instanceof AST_While) {
- return make_node(AST_For, self, self).optimize(compressor);
+ var cond = self.condition.tail_node().evaluate(compressor);
+ if (!(cond instanceof AST_Node)) {
+ if (cond) return make_node(AST_For, self, {
+ body: make_node(AST_BlockStatement, self.body, {
+ body: [
+ self.body,
+ make_node(AST_SimpleStatement, self.condition, {
+ body: self.condition
+ })
+ ]
+ })
+ }).optimize(compressor);
+ var has_loop_control = false;
+ var tw = new TreeWalker(function(node) {
+ if (node instanceof AST_Scope || has_loop_control) return true;
+ if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === self)
+ return has_loop_control = true;
+ });
+ var parent = compressor.parent();
+ (parent instanceof AST_LabeledStatement ? parent : self).walk(tw);
+ if (!has_loop_control) return make_node(AST_BlockStatement, self.body, {
+ body: [
+ self.body,
+ make_node(AST_SimpleStatement, self.condition, {
+ body: self.condition
+ })
+ ]
+ }).optimize(compressor);
}
return self;
});
@@ -3101,22 +3107,31 @@ merge(Compressor.prototype, {
if (!compressor.option("loops")) return self;
if (self.condition) {
var cond = self.condition.evaluate(compressor);
- if (compressor.option("dead_code") && !cond) {
- var a = [];
- if (self.init instanceof AST_Statement) {
- a.push(self.init);
+ if (!(cond instanceof AST_Node)) {
+ if (cond) self.condition = null;
+ else if (!compressor.option("dead_code")) {
+ var orig = self.condition;
+ self.condition = make_node_from_constant(cond, self.condition);
+ self.condition = best_of_expression(self.condition.transform(compressor), orig);
}
- else if (self.init) {
- a.push(make_node(AST_SimpleStatement, self.init, {
- body: self.init
+ }
+ if (compressor.option("dead_code")) {
+ if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor);
+ if (!cond) {
+ var body = [];
+ extract_declarations_from_unreachable_code(compressor, self.body, body);
+ body.push(make_node(AST_SimpleStatement, self.condition, {
+ body: self.condition
}));
+ if (self.init instanceof AST_Statement) {
+ body.push(self.init);
+ } else if (self.init) {
+ body.push(make_node(AST_SimpleStatement, self.init, {
+ body: self.init
+ }));
+ }
+ return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
}
- extract_declarations_from_unreachable_code(compressor, self.body, a);
- return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
- }
- if (cond !== self.condition) {
- cond = make_node_from_constant(cond, self.condition).transform(compressor);
- self.condition = best_of_expression(cond, self.condition);
}
}
if_break_in_loop(self, compressor);
diff --git a/test/compress/dead-code.js b/test/compress/dead-code.js
index 9e7f489d..e0c30397 100644
--- a/test/compress/dead-code.js
+++ b/test/compress/dead-code.js
@@ -129,8 +129,8 @@ dead_code_constant_boolean_should_warn_more: {
function bar() {}
// nothing for the while
// as for the for, it should keep:
- var x = 10, y;
var moo;
+ var x = 10, y;
bar();
}
expect_stdout: true
@@ -165,8 +165,8 @@ dead_code_constant_boolean_should_warn_more_strict: {
var foo;
// nothing for the while
// as for the for, it should keep:
- var x = 10, y;
var moo;
+ var x = 10, y;
bar();
}
expect_stdout: true
diff --git a/test/compress/issue-1656.js b/test/compress/issue-1656.js
index 3971ceaa..27d87652 100644
--- a/test/compress/issue-1656.js
+++ b/test/compress/issue-1656.js
@@ -39,7 +39,7 @@ f7: {
"var b = 10;",
"",
"!function() {",
- " for (;b = 100, !1; ) ;",
+ " b = 100;",
"}(), console.log(100, b);",
]
expect_stdout: true
diff --git a/test/compress/issue-1833.js b/test/compress/issue-1833.js
index 4ffa9d5c..e3c385e8 100644
--- a/test/compress/issue-1833.js
+++ b/test/compress/issue-1833.js
@@ -134,5 +134,5 @@ label_while: {
L: while (0) continue L;
}
}
- expect_exact: "function f(){L:;}"
+ expect_exact: "function f(){L:0}"
}
diff --git a/test/compress/loops.js b/test/compress/loops.js
index bac40494..864276a3 100644
--- a/test/compress/loops.js
+++ b/test/compress/loops.js
@@ -148,9 +148,11 @@ parse_do_while_without_semicolon: {
evaluate: {
options = {
- loops: true,
dead_code: true,
evaluate: true,
+ loops: true,
+ passes: 2,
+ side_effects: true,
};
input: {
while (true) {
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index a8c151f1..bcfa7b35 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -1209,6 +1209,7 @@ toplevel_on_loops_2: {
loops: true,
reduce_funcs: true,
reduce_vars: true,
+ side_effects: true,
toplevel:true,
unused: true,
}