Skip to content

WhenPerformanceMatters/llvm-jnr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LLVM-JNR library

A small library to compile LLVM IR in Java and invoke any resulting native function with the Java Native Runtime. It is possible to create LLVM IR with the LLVM C-API (Java wrappers are provided here) or to compile C/C++ code to LLVM IR with Clang. It is not necessary to install clang since some online compiler are more than sufficient for this task.

Compiling a file with LLVM IR Code

Reading and compiling LLVM IR code from a file takes three lines of code. We first setup a LLVMStoredModuleBuilder which can load and parse the file. Afterwards an instance of the LLVMCompiler is created. It retrieves the parsed LLVM module and compiles it to an LLVMProgram.

LLVMStoredModuleBuilder<MatMulInterface> moduleBuilder = new LLVMStoredModuleBuilder<>(file, MatMulInterface.class);
LLVMCompiler compiler = new LLVMCompiler(true, false);
LLVMProgram<MatMulInterface> program = compiler.compile(moduleBuilder)

Lifecycle of the LLVMProgram

The LLVMProgram is a wrapper for the underlying LLVMExecutionEngine containing all the machine code. If those functions are no longer needed the program should be disposed. The program class also implements AutoCloseable so we can conveniently use a try-with-resource statement.

try(LLVMProgram<MatMulInterface> program = compiler.compile(moduleBuilder)) {
   ...
}

Invoking generated native functions

The native function inside the LLVM engine are invoked with the help of JNR. It creates an implementation of aany Java interface and maps all the methods to native functions. The MatMulInterface from above might look like this:

public static interface MatMulInterface {
   public void matmul(float[] a, float[] b, float[] c, int M, int N, int K);
}

The LLVMProgram takes the interface and the LLVMExecutionEngine with all the machine code in it and searches for every method in the interface a corresponding native function which have the same name and signature. No method overloading is allowed in the interface and all methods must be present in the LLVMExecutionEngine otherwise an IllegalClassFormatException or NoSuchMethodException is thrown.

Calling invoke() on the LLVMProgram returns the implementation of the interface and all the methods are now calling native functions.

LLVMStoredModuleBuilder<MatMulInterface> moduleBuilder = new LLVMStoredModuleBuilder<>(file, MatMulInterface.class);
LLVMCompiler compiler = new LLVMCompiler(true, false);
try(LLVMProgram<MatMulInterface> program = compiler.compile(moduleBuilder)) {
   program.invoke().matmul(a, b, c, M, N, K);
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published