From b762f2d6f4e81dcbd49ffb4db4b1933953942999 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Fri, 1 Dec 2017 05:52:33 +0800 Subject: [PATCH] improve compression of loop conditions (#2543) --- lib/compress.js | 95 +++++++++++++++++++++--------------- test/compress/dead-code.js | 4 +- test/compress/issue-1656.js | 2 +- test/compress/issue-1833.js | 2 +- test/compress/loops.js | 4 +- test/compress/reduce_vars.js | 1 + 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, } -- 2.34.1