[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