
Check Widening in LLVM - sanjoy_das
http://www.playingwithpointers.com/check-widening-in-llvm.html
======
chrisseaton
If you know Ruby more than you know LLVM and want to see a practical example,
I gave a talk about the same idea in the context of Ruby
[http://chrisseaton.com/rubytruffle/deoptimizing/](http://chrisseaton.com/rubytruffle/deoptimizing/)

------
drfuchs
Why "discard the current runtime frame, and resume execution in the
interpreter" rather than jump into a compiled but unoptimized version of the
function?

~~~
pcwalton
You could do the latter too, and that's what V8 does for example (at least
until they roll out the interpreter).

~~~
sanjoy_das
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.

------
mattiemass
Fascinating stuff! Reminds me very much of swift's guard statement.

~~~
sanjoy_das
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).

------
tedunangst
> Now if arr.length is 1 then we’ll deoptimize to the interpreter with false
> as the value of 0 u< arr.length

How so? Why does the test change?

~~~
cfallin
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!

~~~
tedunangst
Thanks. I think I understand, but would have liked to see the lowered version
with the reused/rewritten condition.

~~~
sanjoy_das
Is this what you're looking for: [http://www.playingwithpointers.com/check-
widening-in-llvm.ht...](http://www.playingwithpointers.com/check-widening-in-
llvm.html#final-example) ?

