aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Stover <benjamin.stover@gmail.com>2012-07-30 18:43:30 -0700
committerBenjamin Stover <benjamin.stover@gmail.com>2012-09-05 11:18:40 -0700
commit00338e07d6365fdf2f0ddfa55f95b89d3061f34c (patch)
treec667bb2730882a90ae75fc0839b7e7182e6463fb
parentef417d0e7f4d387e0dc378502651851a5f942a26 (diff)
Bitshift optimizer anticipates fns with switches
Conflicts: AUTHORS
-rw-r--r--AUTHORS1
-rwxr-xr-xtests/runner.py3
-rw-r--r--tools/js-optimizer.js9
-rw-r--r--tools/test-js-optimizer-t3.js49
4 files changed, 61 insertions, 1 deletions
diff --git a/AUTHORS b/AUTHORS
index 422380a3..adcb9b74 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -34,4 +34,5 @@ a license to everyone to use it as detailed in LICENSE.)
* Andrea Bedini <andrea.bedini@gmail.com>
* James Pike <totoro.friend@chilon.net>
* Mokhtar Naamani <mokhtar.naamani@gmail.com>
+* Benjamin Stover <benjamin.stover@gmail.com>
diff --git a/tests/runner.py b/tests/runner.py
index 2a22fa8b..5a45bfa3 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -7442,6 +7442,9 @@ f.close()
['simplifyExpressionsPre', 'optimizeShiftsConservative']),
(path_from_root('tools', 'test-js-optimizer-t2.js'), open(path_from_root('tools', 'test-js-optimizer-t2-output.js')).read(),
['simplifyExpressionsPre', 'optimizeShiftsAggressive']),
+ # Make sure that optimizeShifts handles functions with shift statements.
+ (path_from_root('tools', 'test-js-optimizer-t3.js'), open(path_from_root('tools', 'test-js-optimizer-t3.js')).read(),
+ ['optimizeShiftsAggressive']),
(path_from_root('tools', 'test-js-optimizer-regs.js'), open(path_from_root('tools', 'test-js-optimizer-regs-output.js')).read(),
['registerize']),
]:
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index d58c8c6c..e1cfbe65 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -485,13 +485,20 @@ function optimizeShiftsInternal(ast, conservative) {
}
// vars
// XXX if var has >>=, ignore it here? That means a previous pass already optimized it
- traverse(fun, function(node, type) {
+ var hasSwitch = traverse(fun, function(node, type) {
if (type == 'var') {
node[1].forEach(function(arg) {
newVar(arg[0], false, arg[1]);
});
+ } else if (type == 'switch') {
+ // The relooper can't always optimize functions, and we currently don't work with
+ // switch statements when optimizing shifts. Bail.
+ return true;
}
});
+ if (hasSwitch) {
+ break;
+ }
// uses and defs TODO: weight uses by being inside a loop (powers). without that, we
// optimize for code size, not speed.
traverse(fun, function(node, type, stack) {
diff --git a/tools/test-js-optimizer-t3.js b/tools/test-js-optimizer-t3.js
new file mode 100644
index 00000000..beef1f39
--- /dev/null
+++ b/tools/test-js-optimizer-t3.js
@@ -0,0 +1,49 @@
+function _png_create_write_struct_2($user_png_ver, $error_ptr, $error_fn, $warn_fn, $mem_ptr, $malloc_fn, $free_fn) {
+ var $png_ptr$s2;
+ var __label__;
+ __label__ = 2;
+ var setjmpTable = {
+ "2": (function(value) {
+ __label__ = 5;
+ $call1 = value;
+ }),
+ dummy: 0
+ };
+ while (1) try {
+ switch (__label__) {
+ case 2:
+ var $png_ptr;
+ var $call = _png_create_struct(1);
+ $png_ptr = $call;
+ var $call1 = (HEAP32[$png_ptr >> 2] = __label__, 0);
+ __label__ = 5;
+ break;
+ case 5:
+ var $2 = $png_ptr;
+ if (($call1 | 0) == 0) {
+ __label__ = 4;
+ break;
+ } else {
+ __label__ = 3;
+ break;
+ }
+ case 3:
+ var $4 = HEAP32[($png_ptr >> 2) + (148 >> 2)];
+ _png_free($2, $4);
+ HEAP32[($png_ptr >> 2) + (148 >> 2)] = 0;
+ _png_destroy_struct($png_ptr);
+ var $retval_0 = 0;
+ __label__ = 4;
+ break;
+ case 4:
+ var $retval_0;
+ return $retval_0;
+ default:
+ assert(0, "bad label: " + __label__);
+ }
+ } catch (e) {
+ if (!e.longjmp) throw e;
+ setjmpTable[e.label](e.value);
+ }
+}
+// EMSCRIPTEN_GENERATED_FUNCTIONS: ["_png_create_write_struct_2"]