Inlining in Graal

Lukas Stadler Lukas.Stadler at jku.at
Fri Nov 15 01:58:37 PST 2013


Hi Juan,


in your working example, the checkInline call is a private method that
can statically be bound to a specific target, without the help of
profiling information. Thus, it can be inlined.
The non-working example, however, contains an virtual/interface call,
which means that the compiler needs a hint from somewhere as to which
method could be the target of this call.
The inlining heuristics in Graal assume that all important code has been
running in the interpreter for a while (i.e. thousands of times).
I guess that you are compiling code that has never been executed in the
interpreter?


One solution would be to warm up the method in the interpreter. However,
the profiling information accumulates, so that the call site will become
polymorphic and again stop inlining at some point.
In your case, the closure that does the computation is known at the time
of compilation (I guess). You could replace the parameter with a
constant during your compilation process, which should allow the
compiler to devirtualize the call.
Is that a strategy that could work for you?


- Lukas

>>> Juan José Fumero Alfonso<jjfumero at gmail.com> 11/14/13 4:55 PM >>>
Hi,
  I am working on Inlining with Graal in my backend. Using the Log
information:

-XX:+BootstrapGraal -G:Log=InliningDecisions -XX:+PrintCompilation

I get this:

[thread:1] scope:
  [thread:1] scope: Inlining
    [thread:1] scope: Inlining.Inlining
      [thread:1] scope: Inlining.Inlining.InliningDecisions

* inlining MapEngineOpenCL.kernelComputation at 11: exact
com.edinburgh.parallel.map.MapEngineOpenCL.checkInline(int):int: trivial
(relevance=1.000000, probability=1.000000, bonus=1.000000, nodes=6) *

With this code:

    // Testing
    public void kernelComputation(int[] input, int[] output) {
        for (int i = 0; i < input.length; i++) {
*            output[i] = checkInline(input[i]);*
        }
    }

    private int checkInline(int a) {
        return 10 + a;
    }

So in this case the inlining is working and also the result in my
program
is correct. But what I want to do is the following:


    public void kernelComputation(T[] input, T[] output) {
        for (int i = 0; i < input.length; i++) {
            *output[i] = mInterface.f(input[i]);*
        }
    }


And the method f is defined dynamically by the user:


Integer[] result = Map.apply(data, new MapInterface<Integer>() {
            @Override


*            public Integer f(Integer data) {                return data
*
data;             }*

        }).executeOpenCL();


What I want to do is the inlining of the f method which is defined
dynamically by the user.

[thread:1] scope:
  [thread:1] scope: Inlining
    [thread:1] scope: Inlining.InliningDecisions
   * not inlining MapEngineOpenCL.kernelComputation at 14:
com.edinburgh.parallel.map.MapInterface.f(Object):Object (0 bytes): no
type
profile exists*


I do not understand why "no type profile exists". Any idea about this? I
am
doing the inlining as Graal shows in the tests
(com.oracle.graal.compiler.test.inlining).

Thank you very much
Juanjo






More information about the sumatra-dev mailing list