[llvm-dev] RFC: Add guard intrinsics to LLVM

Sanjoy Das via llvm-dev llvm-dev at lists.llvm.org
Mon Feb 22 22:26:30 PST 2016


Assuming everyone is on the same page, here's a rough high level agenda:


# step A: Introduce an `interposable` function attribute

We can bike shed on the name and the exact specification, but the
general idea is that you cannot do IPA / IPO over callsites calling
`interposable` functions without inlining them.  This attribute will
(usually) have to be used on function bodies that can deoptimize (e.g. has a
side exit / guard it in); but also has more general use cases.


# step B: Introduce a `side_exit` intrinsic

Specify an `@llvm.experimental.side_exit` intrinsic, polymorphic on the
return type:

 - Consumes a "deopt" continuation, and replaces the current physical
   stack frame with one or more interpreter frames (implementation
   provided by the runtime).
 - Calls to this intrinsic must be `musttail` (verifier will check this)
 - We'll have some minor logic in the inliner such that when inlining @f into @g
   in

     define i32 @f() {
       if (X) return side_exit() [ "deopt"(X) ];
       return i32 20;
     }

     define i64 @g() {
       if (Y) {
         r = f() [ "deopt"(Y) ];
         print(r);
     }

   We get

     define i64 @g() {
       if (Y) {
         if (X) return side_exit() [ "deopt"(Y, X) ];
         print(20);
       }
     }

   and not

     define i64 @g() {
       if (Y) {
         r = X ? (side_exit() [ "deopt"(Y, X) ]) : 20;
         print(r);
     }


# step C: Introduce a `guard_on` intrinsic

Will be based around what was discussed / is going to be discussed on
this thread.


(I think Philip was right in suggesting to split out a "step B" that
only introduces a `side_exit` intrinsic.  We *will* have to specify
them, since we'd like to optimize some after we've lowered guards into
explicit control flow, and for that we need a specification of side
exits.)


# aside: non-managed languages and guards

Chandler raised some points on IRC around making `guard_on` (and
possibly `side_exit`?) more generally applicable to unmanaged
languages; so we'd want to be careful to specify these in a way that
allows for implementations in an unmanaged environments (by function
cloning, for instance).

-- Sanjoy


More information about the llvm-dev mailing list