That's a good point; it appears to be doing legit dead code analysis, but the point still remains that if it's custom-tailored to detect that as dead code when it won't do it in the general case, it's cheating.
I may be eating my hat here, because I just replaced the cordicsincos() with the following:
function numNumNum() {
var I;
var num = 10;
for (I = 0; I < 10; I++) {
num = num * num * num * num * num % num;
}
}
Using the same benchmarking framework, I get these times:
Chrome: 849.5ms
IE: 1226.4ms
That would seem to satisfy all the previous conditions - no leaked scope, no return, no external functions - but it doesn't get optimized away. I'd assumed that by "cheating", it would be hot-swapping that benchmark's bytecode for optimized bytecode, or running a function in C or something, rather than just cheating on the dead code optimization. Bad assumptions make for bad benchmarks!
--- tests/sunspider-0.9.1/math-cordic.js 2010-11-17 00:55:29.000000000 -0700
+++ tests/sunspider-0.9.1-deadcode/math-cordic.js 2010-11-17 15:08:43.000000000 -0700
@@ -80,11 +80,15 @@
///// End CORDIC
+function numNumNum() { var I; var num = 10; for (I = 0; I < 10; I++) { num = num + num + num + num + num - num; } }
+
+///// End CORDIC
+
function cordic( runs ) {
var start = new Date();
for ( var i = 0 ; i < runs ; i++ ) {
- cordicsincos();
+ numNumNum();
}
var end = new Date();
Chrome: 19.2ms
IE: 1.0ms
I think this is just fragility, not cheating. I don't know JS super well, but in some languages you might see some rules associated with certain operations and preserving over/under flow exceptions and such.
In any case I think a few things happened here:
1) For whatever reason the "true" statement caused the compiler to think there was a side-effect potential. I suspect the compiler simply didn't know what to do with it, and they hadn't handled 'true;' or 'false;' as standalone statements in their optimizer. I bet if you put 'true;' in the middle of that loop it will break the DCE.
2) The probably don't do liveness analysis. So they can see that a block doesn't change global state, but don't look to see if the proceeding blocks use any of the variables. So if there is any code after a block they assume that they can't DCE that block.
3) '*' and '%' causing problems may be very specific to those operations, and I'm guessing '/' too.
All in all I'd say it is a target incomplete implementation, but not cheating. Based on what I've seen thus far.
I may be eating my hat here, because I just replaced the cordicsincos() with the following:
Using the same benchmarking framework, I get these times: That would seem to satisfy all the previous conditions - no leaked scope, no return, no external functions - but it doesn't get optimized away. I'd assumed that by "cheating", it would be hot-swapping that benchmark's bytecode for optimized bytecode, or running a function in C or something, rather than just cheating on the dead code optimization. Bad assumptions make for bad benchmarks!Witch hunt on!