use of org.bytedeco.llvm.LLVM.LLVMContextRef in project javacpp-presets by bytedeco.
the class EmitBitcode method EvaluateBitcode.
/**
* Sample code for importing a LLVM bitcode file and running a function
* inside of 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.
* <p>
* This sample contains code for the following steps:
* <p>
* 1. Initializing required LLVM components
* 2. Load and parse the bitcode
* 3. Run the 'sum' function inside the module
* 4. Dispose of the allocated resources
*/
public static void EvaluateBitcode() {
// Stage 1: Initialize LLVM components
LLVMInitializeCore(LLVMGetGlobalPassRegistry());
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
LLVMInitializeNativeTarget();
// Stage 2: Load and parse bitcode
LLVMContextRef context = LLVMContextCreate();
LLVMTypeRef i32Type = LLVMInt32TypeInContext(context);
LLVMModuleRef module = new LLVMModuleRef();
LLVMMemoryBufferRef membuf = new LLVMMemoryBufferRef();
BytePointer inputFile = new BytePointer("./sum.bc");
if (LLVMCreateMemoryBufferWithContentsOfFile(inputFile, membuf, error) != 0) {
System.err.println("Failed to read file into memory buffer: " + error.getString());
LLVMDisposeMessage(error);
return;
}
if (LLVMParseBitcodeInContext2(context, membuf, module) != 0) {
System.err.println("Failed to parser module from bitcode");
return;
}
LLVMExecutionEngineRef engine = new LLVMExecutionEngineRef();
if (LLVMCreateInterpreterForModule(engine, module, error) != 0) {
System.err.println("Failed to create LLVM interpreter: " + error.getString());
LLVMDisposeMessage(error);
return;
}
LLVMValueRef sum = LLVMGetNamedFunction(module, "sum");
PointerPointer<Pointer> arguments = new PointerPointer<>(2).put(0, LLVMCreateGenericValueOfInt(i32Type, 42, /* signExtend */
0)).put(1, LLVMCreateGenericValueOfInt(i32Type, 30, /* signExtend */
0));
LLVMGenericValueRef result = LLVMRunFunction(engine, sum, 2, arguments);
System.out.println();
System.out.print("The result of add(42, 30) imported from bitcode and executed with LLVM interpreter is: ");
System.out.println(LLVMGenericValueToInt(result, /* signExtend */
0));
// Stage 4: Dispose of the allocated resources
LLVMDisposeModule(module);
LLVMContextDispose(context);
}
use of org.bytedeco.llvm.LLVM.LLVMContextRef in project javacpp-presets by bytedeco.
the class EmitBitcode method EmitBitcodeAndRelocatableObject.
/**
* 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 sum of two integers.
* <p>
* declare i32 @sum(i32 %lhs, i32 %rhs)
* <p>
* This sample contains code for the following steps
* <p>
* 1. Initializing required LLVM components
* 2. Generating LLVM IR for a sum function
* 3. Write the LLVM bitcode to a file on disk
* 4. Write the relocatable object file to a file on disk
* 5. Dispose of the allocated resources
*/
public static void EmitBitcodeAndRelocatableObject() {
// Stage 1: Initialize LLVM components
LLVMInitializeCore(LLVMGetGlobalPassRegistry());
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
LLVMInitializeNativeDisassembler();
LLVMInitializeNativeTarget();
// Stage 2: Build the sum function
LLVMContextRef context = LLVMContextCreate();
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("sum", context);
LLVMBuilderRef builder = LLVMCreateBuilderInContext(context);
LLVMTypeRef i32Type = LLVMInt32TypeInContext(context);
PointerPointer<Pointer> sumArgumentTypes = new PointerPointer<>(2).put(0, i32Type).put(1, i32Type);
LLVMTypeRef sumType = LLVMFunctionType(i32Type, sumArgumentTypes, /* argumentCount */
2, /* isVariadic */
0);
LLVMValueRef sum = LLVMAddFunction(module, "sum", sumType);
LLVMSetFunctionCallConv(sum, LLVMCCallConv);
LLVMValueRef lhs = LLVMGetParam(sum, 0);
LLVMValueRef rhs = LLVMGetParam(sum, 1);
LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(context, sum, "entry");
LLVMPositionBuilderAtEnd(builder, entry);
LLVMValueRef result = LLVMBuildAdd(builder, lhs, rhs, "result = lhs + rhs");
LLVMBuildRet(builder, result);
LLVMDumpModule(module);
if (LLVMVerifyModule(module, LLVMPrintMessageAction, error) != 0) {
System.out.println("Failed to validate module: " + error.getString());
return;
}
// Stage 3: Dump the module to file
if (LLVMWriteBitcodeToFile(module, "./sum.bc") != 0) {
System.err.println("Failed to write bitcode to file");
return;
}
// Stage 4: Create the relocatable object file
BytePointer triple = LLVMGetDefaultTargetTriple();
LLVMTargetRef target = new LLVMTargetRef();
if (LLVMGetTargetFromTriple(triple, target, error) != 0) {
System.out.println("Failed to get target from triple: " + error.getString());
LLVMDisposeMessage(error);
return;
}
String cpu = "generic";
String cpuFeatures = "";
int optimizationLevel = 0;
LLVMTargetMachineRef tm = LLVMCreateTargetMachine(target, triple.getString(), cpu, cpuFeatures, optimizationLevel, LLVMRelocDefault, LLVMCodeModelDefault);
BytePointer outputFile = new BytePointer("./sum.o");
if (LLVMTargetMachineEmitToFile(tm, module, outputFile, LLVMObjectFile, error) != 0) {
System.err.println("Failed to emit relocatable object file: " + error.getString());
LLVMDisposeMessage(error);
return;
}
// Stage 5: Dispose of allocated resources
outputFile.deallocate();
LLVMDisposeMessage(triple);
LLVMDisposeBuilder(builder);
LLVMDisposeModule(module);
LLVMContextDispose(context);
}
use of org.bytedeco.llvm.LLVM.LLVMContextRef in project javacpp-presets by bytedeco.
the class Factorial method main.
public static void main(String[] args) {
// Stage 1: Initialize LLVM components
LLVMInitializeCore(LLVMGetGlobalPassRegistry());
LLVMLinkInMCJIT();
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
LLVMInitializeNativeTarget();
// Stage 2: Build the factorial function.
LLVMContextRef context = LLVMContextCreate();
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("factorial", context);
LLVMBuilderRef builder = LLVMCreateBuilderInContext(context);
LLVMTypeRef i32Type = LLVMInt32TypeInContext(context);
LLVMTypeRef factorialType = LLVMFunctionType(i32Type, i32Type, /* argumentCount */
1, /* isVariadic */
0);
LLVMValueRef factorial = LLVMAddFunction(module, "factorial", factorialType);
LLVMSetFunctionCallConv(factorial, LLVMCCallConv);
LLVMValueRef n = LLVMGetParam(factorial, /* parameterIndex */
0);
LLVMValueRef zero = LLVMConstInt(i32Type, 0, /* signExtend */
0);
LLVMValueRef one = LLVMConstInt(i32Type, 1, /* signExtend */
0);
LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(context, factorial, "entry");
LLVMBasicBlockRef ifFalse = LLVMAppendBasicBlockInContext(context, factorial, "if_false");
LLVMBasicBlockRef exit = LLVMAppendBasicBlockInContext(context, factorial, "exit");
LLVMPositionBuilderAtEnd(builder, entry);
LLVMValueRef condition = LLVMBuildICmp(builder, LLVMIntEQ, n, zero, "condition = n == 0");
LLVMBuildCondBr(builder, condition, exit, ifFalse);
LLVMPositionBuilderAtEnd(builder, ifFalse);
LLVMValueRef nMinusOne = LLVMBuildSub(builder, n, one, "nMinusOne = n - 1");
PointerPointer<Pointer> arguments = new PointerPointer<>(1).put(0, nMinusOne);
LLVMValueRef factorialResult = LLVMBuildCall2(builder, factorialType, factorial, arguments, 1, "factorialResult = factorial(nMinusOne)");
LLVMValueRef resultIfFalse = LLVMBuildMul(builder, n, factorialResult, "resultIfFalse = n * factorialResult");
LLVMBuildBr(builder, exit);
LLVMPositionBuilderAtEnd(builder, exit);
LLVMValueRef phi = LLVMBuildPhi(builder, i32Type, "result");
PointerPointer<Pointer> phiValues = new PointerPointer<>(2).put(0, one).put(1, resultIfFalse);
PointerPointer<Pointer> phiBlocks = new PointerPointer<>(2).put(0, entry).put(1, ifFalse);
LLVMAddIncoming(phi, phiValues, phiBlocks, /* pairCount */
2);
LLVMBuildRet(builder, phi);
// Stage 3: Verify the module using LLVMVerifier
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();
LLVMMCJITCompilerOptions options = new LLVMMCJITCompilerOptions();
if (LLVMCreateMCJITCompilerForModule(engine, module, options, 3, error) != 0) {
System.err.println("Failed to create JIT compiler: " + error.getString());
LLVMDisposeMessage(error);
return;
}
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));
// Stage 6: Dispose of the allocated resources
LLVMDisposeExecutionEngine(engine);
LLVMDisposePassManager(pm);
LLVMDisposeBuilder(builder);
LLVMContextDispose(context);
}
use of org.bytedeco.llvm.LLVM.LLVMContextRef in project javacpp-presets by bytedeco.
the class OrcJit method main.
public static void main(String[] args) {
// Stage 1: Initialize LLVM components
LLVMInitializeCore(LLVMGetGlobalPassRegistry());
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
// Stage 2: Generate LLVM IR
LLVMOrcThreadSafeContextRef threadContext = LLVMOrcCreateNewThreadSafeContext();
LLVMContextRef context = LLVMOrcThreadSafeContextGetContext(threadContext);
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("sum", context);
LLVMBuilderRef builder = LLVMCreateBuilderInContext(context);
LLVMTypeRef i32Type = LLVMInt32TypeInContext(context);
PointerPointer<Pointer> sumArgumentTypes = new PointerPointer<>(2).put(0, i32Type).put(1, i32Type);
LLVMTypeRef sumType = LLVMFunctionType(i32Type, sumArgumentTypes, /* argumentCount */
2, /* isVariadic */
0);
LLVMValueRef sum = LLVMAddFunction(module, "sum", sumType);
LLVMSetFunctionCallConv(sum, LLVMCCallConv);
LLVMValueRef lhs = LLVMGetParam(sum, 0);
LLVMValueRef rhs = LLVMGetParam(sum, 1);
LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(context, sum, "entry");
LLVMPositionBuilderAtEnd(builder, entry);
LLVMValueRef result = LLVMBuildAdd(builder, lhs, rhs, "result = lhs + rhs");
LLVMBuildRet(builder, result);
LLVMDumpModule(module);
LLVMOrcThreadSafeModuleRef threadModule = LLVMOrcCreateNewThreadSafeModule(module, threadContext);
// Stage 3: Execute using OrcJIT
LLVMOrcLLJITRef jit = new LLVMOrcLLJITRef();
LLVMOrcLLJITBuilderRef jitBuilder = LLVMOrcCreateLLJITBuilder();
if ((err = LLVMOrcCreateLLJIT(jit, jitBuilder)) != null) {
System.err.println("Failed to create LLJIT: " + LLVMGetErrorMessage(err));
LLVMConsumeError(err);
return;
}
LLVMOrcJITDylibRef mainDylib = LLVMOrcLLJITGetMainJITDylib(jit);
if ((err = LLVMOrcLLJITAddLLVMIRModule(jit, mainDylib, threadModule)) != null) {
System.err.println("Failed to add LLVM IR module: " + LLVMGetErrorMessage(err));
LLVMConsumeError(err);
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));
LLVMConsumeError(err);
return;
}
// Stage 4: Call the function with libffi
ffi_cif cif = 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);
if (ffi_prep_cif(cif, FFI_DEFAULT_ABI(), 2, ffi_type_sint(), arguments) != FFI_OK) {
System.err.println("Failed to prepare the libffi cif");
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());
// Stage 5: Dispose of the allocated resources
LLVMOrcDisposeLLJIT(jit);
LLVMShutdown();
}
Aggregations