Skip to content

Commit

Permalink
Optimize unmodified variables
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlamsl authored and rvanvelzen committed Oct 1, 2016
1 parent 0111497 commit 4761d07
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 5 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
3 changes: 2 additions & 1 deletion lib/compress.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
12 changes: 8 additions & 4 deletions lib/scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
Expand Down
171 changes: 171 additions & 0 deletions test/compress/reduce_vars.js
Original file line number Diff line number Diff line change
@@ -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');
}
}
}

0 comments on commit 4761d07

Please sign in to comment.