diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-10-27 14:54:51 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-10-27 14:54:51 -0700 |
commit | a4b7fbc5507813ea1be365e1d931da37f06778c3 (patch) | |
tree | 6c17718a9448c238b29781118c03b39a3371c59f | |
parent | 8b0dd454512a617d901194c09029e47ef4954567 (diff) |
eliminate into one-time do-while loops
-rw-r--r-- | src/utility.js | 6 | ||||
-rw-r--r-- | tools/eliminator/eliminator-test-output.js | 8 | ||||
-rw-r--r-- | tools/eliminator/eliminator-test.js | 9 | ||||
-rw-r--r-- | tools/js-optimizer.js | 17 |
4 files changed, 36 insertions, 4 deletions
diff --git a/src/utility.js b/src/utility.js index 42e8ede4..5019e117 100644 --- a/src/utility.js +++ b/src/utility.js @@ -108,6 +108,12 @@ function zeros(size) { return ret; } +function spaces(size) { + var ret = ''; + for (var i = 0; i < size; i++) ret += ' '; + return ret; +} + function keys(x) { var ret = []; for (var a in x) ret.push(a); diff --git a/tools/eliminator/eliminator-test-output.js b/tools/eliminator/eliminator-test-output.js index fbecbf73..f0fe3f68 100644 --- a/tools/eliminator/eliminator-test-output.js +++ b/tools/eliminator/eliminator-test-output.js @@ -70,6 +70,14 @@ function a($directory) { } var $26 = __ZL3minIiET_S0_S0_12(4096, 4096 - $16 | 0); print(FUNCTION_TABLE[$22]($18, $16 + ($this + 27) | 0, $26)); + chak(); + do { + print(10); + } while (0); + var zzz1 = 10; + do { + print(zzz1); + } while (1); } function b() { var $148 = _sqlite3Strlen30($147); diff --git a/tools/eliminator/eliminator-test.js b/tools/eliminator/eliminator-test.js index 8a7f3d72..c968d4d7 100644 --- a/tools/eliminator/eliminator-test.js +++ b/tools/eliminator/eliminator-test.js @@ -89,6 +89,15 @@ function a($directory) { var $26 = __ZL3minIiET_S0_S0_12(4096, 4096 - $16 | 0); // cannot eliminate this because the call might modify FUNCTION_TABLE var $27 = FUNCTION_TABLE[$22]($18, $this + ($16 + 27) | 0, $26); print($27); + chak(); + var zzz = 10; + do { + print(zzz); + } while (0); + var zzz1 = 10; + do { + print(zzz1); + } while (1); // cannot eliminate a do-while that is not one-time } function b() { var $148 = _sqlite3Strlen30($147); diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index b9a0bce8..b65617e1 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -1366,7 +1366,7 @@ function registerize(ast) { }); } -var ELIMINATION_SAFE_NODES = set('var', 'assign', 'call', 'if', 'toplevel'); +var ELIMINATION_SAFE_NODES = set('var', 'assign', 'call', 'if', 'toplevel', 'do'); // do is checked carefully, however var NODES_WITHOUT_ELIMINATION_SIDE_EFFECTS = set('name', 'num', 'string', 'binary', 'sub', 'unary-prefix'); var IGNORABLE_ELIMINATOR_SCAN_NODES = set('num', 'toplevel', 'string', 'break', 'continue', 'dot', 'return'); // dot can only be STRING_TABLE.* var ABORTING_ELIMINATOR_SCAN_NODES = set('new', 'object', 'function', 'defun', 'switch', 'for', 'while', 'array', 'throw'); // we could handle some of these, TODO, but nontrivial (e.g. for while, the condition is hit multiple times after the body) @@ -1550,9 +1550,11 @@ function eliminate(ast) { //printErr('scan: ' + JSON.stringify(node).substr(0, 50) + ' : ' + keys(tracked)); var abort = false; var allowTracking = true; // false inside an if; also prevents recursing in an if + //var nesting = 1; // printErr-related function traverseInOrder(node, ignoreSub, ignoreName) { if (abort) return; - //printErr(' trav: ' + JSON.stringify(node).substr(0, 50) + ' : ' + keys(tracked)); + //nesting++; // printErr-related + //printErr(spaces(2*(nesting+1)) + 'trav: ' + JSON.stringify(node).substr(0, 50) + ' : ' + keys(tracked) + ' : ' + [allowTracking, ignoreSub, ignoreName]); var type = node[0]; if (type == 'assign') { var target = node[2]; @@ -1658,8 +1660,12 @@ function eliminate(ast) { traverseInOrder(node[1]); traverseInOrder(node[2]); } else if (type == 'do') { - traverseInOrder(node[1]); - if (node[2]) traverseInOrder(node[2]); + if (node[1][0] == 'num' && node[1][1] == 0) { // one-time loop + traverseInOrder(node[2]); + } else { + tracked = {}; + abort = true; + } } else if (type == 'conditional') { traverseInOrder(node[1]); traverseInOrder(node[2]); @@ -1671,6 +1677,7 @@ function eliminate(ast) { tracked = {}; abort = true; } + //nesting--; // printErr-related } traverseInOrder(node); } @@ -1705,8 +1712,10 @@ function eliminate(ast) { var stats = getStatements(block); if (!stats) return; tracked = {}; + //printErr('new StatBlock'); for (var i = 0; i < stats.length; i++) { var node = stats[i]; + //printErr('StatBlock[' + i + '] => ' + JSON.stringify(node)); var type = node[0]; if (type == 'stat') { node = node[1]; |