[llvm-dev] RFC: Strong GC References in LLVM

Sanjoy Das via llvm-dev llvm-dev at lists.llvm.org
Thu Jul 14 17:45:51 PDT 2016


Hi Andy,

Andrew Trick wrote:
 >
 >> On Jul 14, 2016, at 3:40 PM, Sanjoy Das
 >> <sanjoy at playingwithpointers.com
 >> <mailto:sanjoy at playingwithpointers.com>> wrote:
 >>
 >> interface I {
 >> void func();
 >> }
 >>
 >> class F {
 >> Object o;
 >> void func() {
 >> Object val = this.o;
 >> }
 >> }
 >>
 >> class G {
 >> public static void f(I instance) {
 >> instance.func();
 >> }
 >> }
 >>
 >> then when compiling func() separately there is nothing the load of val
 >> is control dependent on, but in G::f if we do some form of predicated
 >> devirtualization and then inline the body of F::func then the safety
 >> of the load is predicated on the devirtualization predicate passing
 >> too. If the predicated devirt. was itself conditional on some control
 >> flow based type refinement, then the safety of the load is control
 >> dependent on that control flow as well, and so on.
 >
 > Yeah, the devirtualizer needs to insert a type cast, then inlining the
 > load just inherits it. Isn’t that all done before LLVM IR?

We do some devirtualization "incrementally" (i.e. while inlining /
optimizing the IR), but I think I was over-complicating -- this looks
like it is doable.  Intuitively, since Java's type system is
verifiable, we should be able to model it directly in the IR without
too many complications.

However, I'm still worried about the scope.  Going by your suggestion,
IIUC this is how the above devirtualization transform will look like:

void G::f(I instance) {
   invoke_interface(I::func, instance);
}

== predicated devirt ==>

void G::f(I instance) {
   if (get_klass(instance) == F.klass) {
     instance_casted = cast_to_type(instance, !type)
     F::func(instance_casted);
   } else {
     blah();
   }
}

!type = !descriptor_for_F


== inline F::func etc ==>

...


and to get back to our "baseline" performance (i.e. hoist loads of
non-GCREF type as usual, but don't touch GCREF loads), we'd have to
teach LLVM that it is okay to speculate non-GCREF loads through
cast_to_type, but not GCREF loads.  We will also have to teach LLVM
about aliasing properties of these intrinsics.

I think cast_to_type is a good second step we can take when we start
modeling Java's type system in LLVM IR, but it looks too complex to do
as an initial step.

-- Sanjoy


More information about the llvm-dev mailing list