[Pkg-javascript-commits] [uglifyjs] 29/49: Optimize unmodified variables

Jonas Smedegaard dr at jones.dk
Fri Dec 9 11:43:27 UTC 2016


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository uglifyjs.

commit 4761d07e0bc3d4c53e0c9c72fc9c322c95cb090e
Author: alexlamsl <alexlamsl at gmail.com>
Date:   Tue Sep 20 22:23:27 2016 +0800

    Optimize unmodified variables
---
 README.md                    |   3 +
 lib/compress.js              |   3 +-
 lib/scope.js                 |  12 ++-
 test/compress/reduce_vars.js | 171 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 184 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index e0aa4ba..ed2630f 100644
--- a/README.md
+++ b/README.md
@@ -348,6 +348,9 @@ to set `true`; it's effectively a shortcut for `foo=true`).
 - `collapse_vars` -- default `false`. Collapse single-use `var` and `const`
   definitions when possible.
 
+- `reduce_vars` -- default `false`. Improve optimization on variables assigned
+  with and used as constant values.
+
 - `warnings` -- display warnings when dropping unreachable code or unused
   declarations etc.
 
diff --git a/lib/compress.js b/lib/compress.js
index 8a08572..14fb8f1 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -67,6 +67,7 @@ function Compressor(options, false_by_default) {
         if_return     : !false_by_default,
         join_vars     : !false_by_default,
         collapse_vars : false,
+        reduce_vars   : false,
         cascade       : !false_by_default,
         side_effects  : !false_by_default,
         pure_getters  : false,
@@ -1107,7 +1108,7 @@ merge(Compressor.prototype, {
             this._evaluating = true;
             try {
                 var d = this.definition();
-                if (d && d.constant && d.init) {
+                if (d && (d.constant || compressor.option("reduce_vars") && !d.modified) && d.init) {
                     return ev(d.init, compressor);
                 }
             } finally {
diff --git a/lib/scope.js b/lib/scope.js
index 606a5a2..fb58329 100644
--- a/lib/scope.js
+++ b/lib/scope.js
@@ -197,7 +197,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
         }
         if (node instanceof AST_SymbolRef) {
             var name = node.name;
-            if (name == "eval" && tw.parent() instanceof AST_Call) {
+            var parent = tw.parent();
+            if (name == "eval" && parent instanceof AST_Call) {
                 for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) {
                     s.uses_eval = true;
                 }
@@ -213,12 +214,15 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
                     g.global = true;
                     globals.set(name, g);
                 }
-                node.thedef = g;
+                sym = g;
                 if (func && name == "arguments") {
                     func.uses_arguments = true;
                 }
-            } else {
-                node.thedef = sym;
+            }
+            node.thedef = sym;
+            if (parent instanceof AST_Unary && (parent.operator === '++' || parent.operator === '--')
+             || parent instanceof AST_Assign && parent.left === node) {
+                sym.modified = true;
             }
             node.reference();
             return true;
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
new file mode 100644
index 0000000..a1d0501
--- /dev/null
+++ b/test/compress/reduce_vars.js
@@ -0,0 +1,171 @@
+reduce_vars: {
+    options = {
+        conditionals  : true,
+        evaluate      : true,
+        global_defs   : {
+            C : 0
+        },
+        reduce_vars   : true,
+        unused        : true
+    }
+    input: {
+        var A = 1;
+        (function f0() {
+            var a = 2;
+            console.log(a - 5);
+            console.log(A - 5);
+        })();
+        (function f1() {
+            var a = 2;
+            console.log(a - 5);
+            eval("console.log(a);");
+        })();
+        (function f2(eval) {
+            var a = 2;
+            console.log(a - 5);
+            eval("console.log(a);");
+        })(eval);
+        (function f3() {
+            var b = typeof C !== "undefined";
+            var c = 4;
+            if (b) {
+                return 'yes';
+            } else {
+                return 'no';
+            }
+        })();
+        console.log(A + 1);
+    }
+    expect: {
+        var A = 1;
+        (function() {
+            console.log(-3);
+            console.log(-4);
+        })();
+        (function f1() {
+            var a = 2;
+            console.log(-3);
+            eval("console.log(a);");
+        })();
+        (function f2(eval) {
+            var a = 2;
+            console.log(-3);
+            eval("console.log(a);");
+        })(eval);
+        (function() {
+            return "yes";
+        })();
+        console.log(2);
+    }
+}
+
+modified: {
+    options = {
+        conditionals  : true,
+        evaluate      : true,
+        reduce_vars   : true,
+        unused        : true
+    }
+    input: {
+        function f0() {
+            var a = 1, b = 2;
+            b++;
+            console.log(a + 1);
+            console.log(b + 1);
+        }
+
+        function f1() {
+            var a = 1, b = 2;
+            --b;
+            console.log(a + 1);
+            console.log(b + 1);
+        }
+
+        function f2() {
+            var a = 1, b = 2, c = 3;
+            b = c;
+            console.log(a + b);
+            console.log(b + c);
+            console.log(a + c);
+            console.log(a + b + c);
+        }
+
+        function f3() {
+            var a = 1, b = 2, c = 3;
+            b *= c;
+            console.log(a + b);
+            console.log(b + c);
+            console.log(a + c);
+            console.log(a + b + c);
+        }
+
+        function f4() {
+            var a = 1, b = 2, c = 3;
+            if (a) {
+                b = c;
+            } else {
+                c = b;
+            }
+            console.log(a + b);
+            console.log(b + c);
+            // TODO: as "modified" is determined in "figure_out_scope",
+            // even "passes" wouldn't improve this any further
+            console.log(a + c);
+            console.log(a + b + c);
+        }
+
+        function f5(a) {
+            B = a;
+            console.log(A ? 'yes' : 'no');
+            console.log(B ? 'yes' : 'no');
+        }
+    }
+    expect: {
+        function f0() {
+            var b = 2;
+            b++;
+            console.log(2);
+            console.log(b + 1);
+        }
+
+        function f1() {
+            var b = 2;
+            --b;
+            console.log(2);
+            console.log(b + 1);
+        }
+
+        function f2() {
+            var a = 1, b = 2, c = 3;
+            b = c;
+            console.log(a + b);
+            console.log(b + c);
+            console.log(4);
+            console.log(a + b + c);
+        }
+
+        function f3() {
+            var a = 1, b = 2, c = 3;
+            b *= c;
+            console.log(a + b);
+            console.log(b + c);
+            console.log(4);
+            console.log(a + b + c);
+        }
+
+        function f4() {
+            var a = 1, b = 2, c = 3;
+            b = c;
+            console.log(a + b);
+            console.log(b + c);
+            console.log(a + c);
+            console.log(a + b + c);
+        }
+
+        function f5(a) {
+            B = a;
+            console.log(A ? 'yes' : 'no');
+            console.log(B ? 'yes' : 'no');
+        }
+   }
+}
\ No newline at end of file

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git



More information about the Pkg-javascript-commits mailing list