Skip to content

Commit

Permalink
* Update and fix the sample code of the presets for LLVM (pull #1501)
Browse files Browse the repository at this point in the history
  • Loading branch information
Minding000 committed Jun 2, 2024
1 parent f8932a4 commit ba67cea
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 66 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

* Update and fix the sample code of the presets for LLVM ([pull #1501](https://github.com/bytedeco/javacpp-presets/pull/1501))
* Fix Vulkan GPU acceleration for FFmpeg ([pull #1497](https://github.com/bytedeco/javacpp-presets/pull/1497))
* Build FFmpeg with zimg to enable zscale filter ([pull #1481](https://github.com/bytedeco/javacpp-presets/pull/1481))
* Enable PulseAudio support for FFmpeg on Linux ([pull #1472](https://github.com/bytedeco/javacpp-presets/pull/1472))
Expand Down
18 changes: 8 additions & 10 deletions llvm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ We can use [Maven 3](http://maven.apache.org/) to download and install automatic

### The `Factorial.java` source file

This example is based on MCJIT. There is a newer alternative called ORC. You can find an example using ORC [here](samples/llvm/OrcJit.java).

```java
import org.bytedeco.javacpp.*;
import org.bytedeco.llvm.LLVM.*;
Expand All @@ -73,11 +75,8 @@ public class Factorial {

public static void main(String[] args) {
// Stage 1: Initialize LLVM components
LLVMInitializeCore(LLVMGetGlobalPassRegistry());
LLVMLinkInMCJIT();
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();

// Stage 2: Build the factorial function.
LLVMContextRef context = LLVMContextCreate();
Expand Down Expand Up @@ -119,6 +118,9 @@ public class Factorial {
LLVMAddIncoming(phi, phiValues, phiBlocks, /* pairCount */ 2);
LLVMBuildRet(builder, phi);

// Print generated LLVM-IR to console (optional)
LLVMDumpModule(module);

// Stage 3: Verify the module using LLVMVerifier
if (LLVMVerifyModule(module, LLVMPrintMessageAction, error) != 0) {
LLVMDisposeMessage(error);
Expand All @@ -127,11 +129,7 @@ public class Factorial {

// Stage 4: Create a pass pipeline using the legacy pass manager
LLVMPassManagerRef pm = LLVMCreatePassManager();
LLVMAddAggressiveInstCombinerPass(pm);
LLVMAddNewGVNPass(pm);
LLVMAddCFGSimplificationPass(pm);
LLVMRunPassManager(pm, module);
LLVMDumpModule(module);

// Stage 5: Execute the code using MCJIT
LLVMExecutionEngineRef engine = new LLVMExecutionEngineRef();
Expand All @@ -145,8 +143,8 @@ public class Factorial {
LLVMGenericValueRef argument = LLVMCreateGenericValueOfInt(i32Type, 10, /* signExtend */ 0);
LLVMGenericValueRef result = LLVMRunFunction(engine, factorial, /* argumentCount */ 1, argument);
System.out.println();
System.out.println("; Running factorial(10) with MCJIT...");
System.out.println("; Result: " + LLVMGenericValueToInt(result, /* signExtend */ 0));
System.out.println("Running factorial(10) with MCJIT...");
System.out.println("Result: " + LLVMGenericValueToInt(result, /* signExtend */ 0));

// Stage 6: Dispose of the allocated resources
LLVMDisposeExecutionEngine(engine);
Expand Down
20 changes: 6 additions & 14 deletions llvm/samples/llvm/EmitBitcode.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
* <p>
* The EvaluateBitcode sample depends on EmitBitcodeAndRelocatableObject
* <p>
* The samples should be ran in declaration order, meaning EmitBitcodeAndRelocatableObject
* The samples should be called in declaration order, meaning EmitBitcodeAndRelocatableObject
* should run before EvaluateBitcode.
*/
public class EmitBitcode {
Expand All @@ -54,7 +54,7 @@ public class EmitBitcode {
/**
* Sample for generating both LLVM bitcode and relocatable object file from an LLVM module
* <p>
* The generated module (and objec file) will have a single sum function, which returns
* The generated module (and object file) will have a single 'sum' function, which returns
* the sum of two integers.
* <p>
* declare i32 @sum(i32 %lhs, i32 %rhs)
Expand All @@ -69,11 +69,8 @@ public class EmitBitcode {
*/
public static void EmitBitcodeAndRelocatableObject() {
// Stage 1: Initialize LLVM components
// LLVMInitializeCore(LLVMGetGlobalPassRegistry());
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
LLVMInitializeNativeDisassembler();
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();

// Stage 2: Build the sum function
LLVMContextRef context = LLVMContextCreate();
Expand Down Expand Up @@ -143,10 +140,10 @@ public static void EmitBitcodeAndRelocatableObject() {

/**
* Sample code for importing a LLVM bitcode file and running a function
* inside of the imported module
* from the imported module
* <p>
* This sample depends on EmitBitcode to produce the bitcode file. Make sure
* you've ran the EmitBitcode sample and have the 'sum.bc' bitcode file.
* This sample depends on EmitBitcodeAndRelocatableObject to produce the bitcode file.
* Make sure you ran the EmitBitcodeAndRelocatableObject sample and have the 'sum.bc' bitcode file.
* <p>
* This sample contains code for the following steps:
* <p>
Expand All @@ -157,9 +154,6 @@ public static void EmitBitcodeAndRelocatableObject() {
*/
public static void EvaluateBitcode() {
// Stage 1: Initialize LLVM components
// LLVMInitializeCore(LLVMGetGlobalPassRegistry());
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
LLVMInitializeNativeTarget();

// Stage 2: Load and parse bitcode
Expand Down Expand Up @@ -210,8 +204,6 @@ public static void main(String[] args) {
case "-evaluate":
EvaluateBitcode();
System.exit(0);
default:
// Display help
}
System.err.println("Pass `-emit` or `-evaluate`.");
System.exit(1);
Expand Down
22 changes: 9 additions & 13 deletions llvm/samples/llvm/Factorial.java → llvm/samples/llvm/MCJIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,14 @@
* <p>
* TODO(supergrecko): Replace with new Pass Manager for LLVM 13
*/
public class Factorial {
// a 'char *' used to retrieve error messages from LLVM
public class MCJIT {
// A 'char *' used to retrieve error messages from LLVM
private static final BytePointer error = new BytePointer();

public static void main(String[] args) {
// Stage 1: Initialize LLVM components
// LLVMInitializeCore(LLVMGetGlobalPassRegistry());
LLVMLinkInMCJIT();
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();

// Stage 2: Build the factorial function.
LLVMContextRef context = LLVMContextCreate();
Expand Down Expand Up @@ -106,19 +103,18 @@ public static void main(String[] args) {
LLVMAddIncoming(phi, phiValues, phiBlocks, /* pairCount */ 2);
LLVMBuildRet(builder, phi);

// Stage 3: Verify the module using LLVMVerifier
// Print generated LLVM-IR to console (optional)
LLVMDumpModule(module);

// Stage 3: Verify the module (optional; recommended)
if (LLVMVerifyModule(module, LLVMPrintMessageAction, error) != 0) {
LLVMDisposeMessage(error);
return;
}

// Stage 4: Create a pass pipeline using the legacy pass manager
LLVMPassManagerRef pm = LLVMCreatePassManager();
// LLVMAddAggressiveInstCombinerPass(pm);
// LLVMAddNewGVNPass(pm);
// LLVMAddCFGSimplificationPass(pm);
LLVMRunPassManager(pm, module);
LLVMDumpModule(module);

// Stage 5: Execute the code using MCJIT
LLVMExecutionEngineRef engine = new LLVMExecutionEngineRef();
Expand All @@ -132,8 +128,8 @@ public static void main(String[] args) {
LLVMGenericValueRef argument = LLVMCreateGenericValueOfInt(i32Type, 10, /* signExtend */ 0);
LLVMGenericValueRef result = LLVMRunFunction(engine, factorial, /* argumentCount */ 1, argument);
System.out.println();
System.out.println("; Running factorial(10) with MCJIT...");
System.out.println("; Result: " + LLVMGenericValueToInt(result, /* signExtend */ 0));
System.out.println("Running factorial(10) with MCJIT...");
System.out.println("Result: " + LLVMGenericValueToInt(result, /* signExtend */ 0));

// Stage 6: Dispose of the allocated resources
LLVMDisposeExecutionEngine(engine);
Expand Down
63 changes: 36 additions & 27 deletions llvm/samples/llvm/OrcJit.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@
*/

import org.bytedeco.javacpp.IntPointer;
import org.bytedeco.javacpp.Loader;
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.LongPointer;
import org.bytedeco.javacpp.Pointer;
import org.bytedeco.javacpp.PointerPointer;
import org.bytedeco.libffi.ffi_cif;
import org.bytedeco.llvm.global.LLVM;
import org.bytedeco.llvm.LLVM.LLVMBasicBlockRef;
import org.bytedeco.llvm.LLVM.LLVMBuilderRef;
import org.bytedeco.llvm.LLVM.LLVMContextRef;
Expand All @@ -50,16 +49,15 @@
* <p>
* 1. Initializing required LLVM components
* 2. Generating LLVM IR for a sum function
* 3. Load the module into OrcJIT and get the address of "sum"
* 4. Call the sum function with libffi
* 5. Dispose of the allocated resources
* 3. Verify the module
* 4. Load the module into OrcJIT and get the address of "sum"
* 5. Call the sum function with libffi
* 6. Dispose of the allocated resources
*/
public class OrcJit {
public static LLVMErrorRef err = null;

public static void main(String[] args) {
// Stage 1: Initialize LLVM components
// LLVMInitializeCore(LLVMGetGlobalPassRegistry());
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();

Expand All @@ -86,54 +84,65 @@ public static void main(String[] args) {
LLVMValueRef result = LLVMBuildAdd(builder, lhs, rhs, "result = lhs + rhs");
LLVMBuildRet(builder, result);

// Print generated LLVM-IR to console (optional)
LLVMDumpModule(module);
LLVMOrcThreadSafeModuleRef threadModule = LLVMOrcCreateNewThreadSafeModule(module, threadContext);

// Stage 3: Execute using OrcJIT
// Stage 3: Verify the module (optional; recommended)
BytePointer errorMessageVariable = new BytePointer();
if (LLVMVerifyModule(module, LLVMPrintMessageAction, errorMessageVariable) != 0) {
LLVMDisposeMessage(errorMessageVariable);
return;
}

// Stage 4: Execute using OrcJIT
LLVMOrcLLJITRef jit = new LLVMOrcLLJITRef();
LLVMOrcLLJITBuilderRef jitBuilder = LLVMOrcCreateLLJITBuilder();
Loader.loadGlobal(Loader.load(LLVM.class));
if ((err = LLVMOrcCreateLLJIT(jit, jitBuilder)) != null) {
System.err.println("Failed to create LLJIT: " + LLVMGetErrorMessage(err).getString());
LLVMConsumeError(err);
LLVMErrorRef error;
if ((error = LLVMOrcCreateLLJIT(jit, jitBuilder)) != null) {
BytePointer errorMessage = LLVMGetErrorMessage(error);
System.err.println("Failed to create LLJIT: " + errorMessage.getString());
LLVMDisposeErrorMessage(errorMessage);
return;
}

LLVMOrcJITDylibRef mainDylib = LLVMOrcLLJITGetMainJITDylib(jit);
if ((err = LLVMOrcLLJITAddLLVMIRModule(jit, mainDylib, threadModule)) != null) {
System.err.println("Failed to add LLVM IR module: " + LLVMGetErrorMessage(err).getString());
LLVMConsumeError(err);
LLVMOrcThreadSafeModuleRef threadModule = LLVMOrcCreateNewThreadSafeModule(module, threadContext);
if ((error = LLVMOrcLLJITAddLLVMIRModule(jit, mainDylib, threadModule)) != null) {
BytePointer errorMessage = LLVMGetErrorMessage(error);
System.err.println("Failed to add LLVM IR module: " + errorMessage.getString());
LLVMDisposeErrorMessage(errorMessage);
return;
}

final LongPointer res = new LongPointer(1);
if ((err = LLVMOrcLLJITLookup(jit, res, "sum")) != null) {
System.err.println("Failed to look up 'sum' symbol: " + LLVMGetErrorMessage(err).getString());
LLVMConsumeError(err);
if ((error = LLVMOrcLLJITLookup(jit, res, "sum")) != null) {
BytePointer errorMessage = LLVMGetErrorMessage(error);
System.err.println("Failed to look up 'sum' symbol: " + errorMessage.getString());
LLVMDisposeErrorMessage(errorMessage);
return;
}

// Stage 4: Call the function with libffi
ffi_cif cif = new ffi_cif();
// Stage 5: Call the function with libffi
ffi_cif callInterface = new ffi_cif();
PointerPointer<Pointer> arguments = new PointerPointer<>(2)
.put(0, ffi_type_sint())
.put(1, ffi_type_sint());
PointerPointer<Pointer> values = new PointerPointer<>(2)
.put(0, new IntPointer(1).put(42))
.put(1, new IntPointer(1).put(30));
IntPointer returns = new IntPointer(1);
IntPointer resultVariable = new IntPointer(1);

if (ffi_prep_cif(cif, FFI_DEFAULT_ABI(), 2, ffi_type_sint(), arguments) != FFI_OK) {
System.err.println("Failed to prepare the libffi cif");
if (ffi_prep_cif(callInterface, FFI_DEFAULT_ABI(), 2, ffi_type_sint(), arguments) != FFI_OK) {
System.err.println("Failed to prepare the libffi call interface");
return;
}
Pointer function = new Pointer() {{
address = res.get();
}};
ffi_call(cif, function, returns, values);
System.out.println("Evaluating sum(42, 30) through OrcJIT results in: " + returns.get());
ffi_call(callInterface, function, resultVariable, values);
System.out.println("Evaluating sum(42, 30) through OrcJIT results in: " + resultVariable.get());

// Stage 5: Dispose of the allocated resources
// Stage 6: Dispose of the allocated resources
LLVMOrcDisposeLLJIT(jit);
LLVMShutdown();
}
Expand Down
4 changes: 2 additions & 2 deletions llvm/samples/llvm/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<artifactId>samples</artifactId>
<version>1.5.11-SNAPSHOT</version>
<properties>
<exec.mainClass>Factorial</exec.mainClass>
<exec.mainClass>MCJIT</exec.mainClass>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
Expand Down Expand Up @@ -47,7 +47,7 @@
<profile>
<id>factorial</id>
<properties>
<exec.mainClass>Factorial</exec.mainClass>
<exec.mainClass>MCJIT</exec.mainClass>
</properties>
</profile>
<profile>
Expand Down

0 comments on commit ba67cea

Please sign in to comment.