Good call. I checked river sand-bar width in the old code. It turns-out that it offset by random x and y. Currently, I have just x offset. The old code with y sandbar offset caused bigger bars.
It's good, now. Thanks for taking interest. It's true I was negligent not investigating.
Yes they're definitely close, but I don't know if there are subtle differences in semantics between what we have in LLVM and what Swift needs (since I'm not familiar with Swift).
The optimizer recognizes that the variable `condition` and the condition with the guard's if-statement are the same (edit: inverses actually), so within the if-statement's body, it can assume that `condition` is false. But when other guard cases are merged in, that's no longer the case.
In other words, the general optimization is to convert
bool A = condition();
if (!A) { f(A); }
to:
bool A = condition();
if (!A) { f(false); }
i.e., that we can assume an if-condition is true within the body of that if-statement. The problem is that the check-widening reuses the body of the if-statement: the code
bool A = condition();
if (!A) { f(A); }
bool B = condition();
if (!B) { f(A); }
is converted by check-widening to the first snippet above, which then becomes the second. Sanjoy's observation is that guard-widening is almost correct (we still want to pursue this route) because `f` (the deoptimization escape) is really what we want to call in both cases, but we just need to get the value of `A` right by somehow letting the optimizer know that we're reusing the if-body and that it can't assume anything about the condition that got us there.
Also, this is really really clever and I enjoyed the post, OP!
Why "discard the current runtime frame, and resume execution in the interpreter" rather than jump into a compiled but unoptimized version of the function?
Yup. The "obvious" downside to that is that you'll burn CPU cycles and memory by generating and keeping around a slow-but-correct compile for every function.
12 comments
[ 3.8 ms ] story [ 32.6 ms ] threadIt's good, now. Thanks for taking interest. It's true I was negligent not investigating.
How so? Why does the test change?
In other words, the general optimization is to convert
to: i.e., that we can assume an if-condition is true within the body of that if-statement. The problem is that the check-widening reuses the body of the if-statement: the code is converted by check-widening to the first snippet above, which then becomes the second. Sanjoy's observation is that guard-widening is almost correct (we still want to pursue this route) because `f` (the deoptimization escape) is really what we want to call in both cases, but we just need to get the value of `A` right by somehow letting the optimizer know that we're reusing the if-body and that it can't assume anything about the condition that got us there.Also, this is really really clever and I enjoyed the post, OP!