Skip to content

Latest commit

 

History

History
121 lines (93 loc) · 7.3 KB

README.md

File metadata and controls

121 lines (93 loc) · 7.3 KB

Talk to (Graal) Compiler (on JDK11+)

Sample project showing how to control Graal Compiler via Truffle API.

Talk2Compiler

Pre requirements

Setup

$ git clone https://github.com/jaroslavtulach/talk2compiler
$ cd talk2compiler
$ JAVA_HOME=/jdk-11 mvn package exec:exec -Dexec.appArgs=Truffle

Working with the sources

The project stands in its master state as a platform ready for your experimentations. Use it to get the Graal JIT compiler under your control. Use it to get the best from the dynamic just in time compiler surrouding your code. Just enclose your code into the Main.execute method and you'll be in direct contact with the assembly - code in Java, but directly influence the native code. That is what we are aiming at!

Look at the Compiler

Download GraalVM EE and launch Ideal Graph Visualizer. It starts listening on port 4445 and is ready to accept graphs showing progress of Graal compilations. Either run the program with -Pigv

$ JAVA_HOME=/jdk-11 mvn -Pigv process-classes exec:exec -Dexec.appArgs=Truffle

or run the tests to dump the execution graphs

$ JAVA_HOME=/jdk-11 mvn -Pigv test

The igv profile passes additional arguments to the JVM: -Dgraal.Dump=:1 -Dgraal.PrintGraph=Network. A tree of graphs representing Truffle::Main shall appear in the IGV. The most interesting phase is Graal Graphs/Before phase Lowering - it contains all the Graal optimizations, yet the vertexes still resemble bytecode instructions and are OS architecture neutral.

Exploring the Compilations

Try to add field into Main class called warmWelcome. Use different message format when it is true and different when it is false. When you look at the graph you shall see the load of the field value and if vertex.

Try to make the field final. The load and if disappears. Remove the final modifier and annotate the field as @CompilationFinal. The result is the same. Modify the value of the field (in the Main.execute method), but don't forget to call CompilerDirectives.transferToInterpreterAndInvalidate() to tell the compiler to recompile.

Rather than using these primitive operations, consider using profiles like ConditionProfile.createBinaryProfile(). Profiles are built with the above primitives, yet they are easier to use.

Speed a Graph Algorithm up

The BooleanNetwork branch contains a graph with states representing spreading of tumor in a brain. Let's search the graph for a state that matches certain pattern - nulls are ignored, true and false values must match. The algorithm counts how many nodes in the graph match.

The algorithm can run in regular HotSpot mode as well as in Truffle one entered via CallTarget. When in Truffle mode, one can apply additional hints - namely @CompilerDirectives.CompilationFinal(dimensions = 1), @ExplodeLoop and CompilerAsserts.partialEvaluationConstant - to speed the execution up by expanding the match loop and eliminating the null checks.

Build a Polymorphic Cache

The @ExplodeLoop annotation can be used to control the amount of generated code. Use it to build a polymorphic cache a phone book mapping between names and numbers. Control the size of the cache (e.g. generated code) fallback to regular (slow) lookup in a HashMap.

Truffle Nodes

Create simple AST to process array of numbers. Send the graph to IGV and see how the partial evaluation reduced it to three load and two plus instructions. Change the example to use Object[]. Rewrite Plus.compute to support not only int, but also double and/or any object. Observe the gigantic IGV graph. Use compiler directives, profiles & etc. to optimize the graph again. After realizing that it is too complex, use the Truffle DSL.

Truffle DSL

Use DSL specializations to do the hard work for you. Remove even more boilerplate code with Truffle DSL type system. Follow the remaining commits, commit-by-commit, of the Truffle DSL branch to learn more.

Control Flow

In this branch, which can be followed commit-by-commit, we implement simple infrastructure around expressions and statements and few control flow constructs to demonstrate how control flow can be implemented in Truffle based AST interpreters.

Abstractions & Truffle

In this branch, which can be followed commit-by-commit, we explore common patterns to build internal abstractions in Truffle based languages. One of the patterns with special support from Truffle DSL are Truffle libraries, which are also used for implementing the interoperability protocol between different Truffle languages.

GraalVM contribution opportunities

  • Radixsort for R interpreter
  • Jackpot rule integrated in Truffle API (runs as a part of mx jackpot command) that checks for common Truffle API usage issues (e.g., @Child field assignment outside of constructor without a call to insert).
  • Pick your favourite Python package, run its test suite on CPython and GraalPython, if there are failures specific to GraalPython, try to fix some of them. If it turns out to be too hard, report your findings in a GitHub issue.