diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d25a69fe48..970bc6b7ae6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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)) diff --git a/llvm/README.md b/llvm/README.md index 748bfbd62d2..e3a23b8694c 100644 --- a/llvm/README.md +++ b/llvm/README.md @@ -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.*; @@ -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(); @@ -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); @@ -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(); @@ -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); diff --git a/llvm/samples/llvm/EmitBitcode.java b/llvm/samples/llvm/EmitBitcode.java index b308e8d4260..0386e0017de 100644 --- a/llvm/samples/llvm/EmitBitcode.java +++ b/llvm/samples/llvm/EmitBitcode.java @@ -45,7 +45,7 @@ *
* The EvaluateBitcode sample depends on EmitBitcodeAndRelocatableObject *
- * 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 { @@ -54,7 +54,7 @@ public class EmitBitcode { /** * Sample for generating both LLVM bitcode and relocatable object file from an LLVM module *
- * 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. *
* declare i32 @sum(i32 %lhs, i32 %rhs) @@ -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(); @@ -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 *
- * 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. *
* This sample contains code for the following steps: *
@@ -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 @@ -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); diff --git a/llvm/samples/llvm/Factorial.java b/llvm/samples/llvm/MCJIT.java similarity index 91% rename from llvm/samples/llvm/Factorial.java rename to llvm/samples/llvm/MCJIT.java index f0a9e62c0db..c4f315c2700 100644 --- a/llvm/samples/llvm/Factorial.java +++ b/llvm/samples/llvm/MCJIT.java @@ -54,17 +54,14 @@ *
* 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(); @@ -106,7 +103,10 @@ 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; @@ -114,11 +114,7 @@ public static void main(String[] args) { // 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(); @@ -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); diff --git a/llvm/samples/llvm/OrcJit.java b/llvm/samples/llvm/OrcJit.java index bb64d360444..c79da1bee6f 100644 --- a/llvm/samples/llvm/OrcJit.java +++ b/llvm/samples/llvm/OrcJit.java @@ -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; @@ -50,16 +49,15 @@ *
* 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();
@@ -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