Skip to main content

Module lljit

Module lljit 

Source
Expand description

Safe(r) wrappers around llvm_sys::lljit

§Example

 use pliron_llvm::llvm_sys::target::initialize_native;
 use pliron_llvm::llvm_sys::core::{LLVMContext, LLVMModule, LLVMMemoryBuffer};
 use pliron_llvm::llvm_sys::lljit::{LLVMLLJIT, JITSymbolGenericFlags};
 fn main() -> Result<(), String> {
    initialize_native()?;
    let context = LLVMContext::default();

    fn my_rust_adder(a: i32, b: i32) -> i32 {
        a + b
    }

    let ir = r#"
      declare i32 @my_rust_adder(i32, i32)
      define i32 @add(i32 %a, i32 %b) {
          %sum = call i32 @my_rust_adder(i32 %a, i32 %b)
          ret i32 %sum
      }"#;
    let ir_mb = LLVMMemoryBuffer::from_str(ir, "test_buffer");
    let module = LLVMModule::from_ir_in_memory_buffer(&context, ir_mb)?;

    let jit = LLVMLLJIT::new_with_default_builder()?;
    jit.add_module(module)?;
    // Add the Rust function as a symbol mapping
    let rust_adder_addr = my_rust_adder as *const () as u64;
    jit.add_symbol_mapping
     ("my_rust_adder", rust_adder_addr,
       JITSymbolGenericFlags::JITSymbolGenericFlagsCallable
         | JITSymbolGenericFlags::JITSymbolGenericFlagsExported)?;

    // Get symbol address for 'add' in the LLVM module
    let symbol_addr = jit.lookup_symbol("add")?;
    assert!(symbol_addr != 0);

    let adder = unsafe { std::mem::transmute::<u64, fn(i32, i32) -> i32>(symbol_addr) };
    assert_eq!(adder(2, 3), 5);
    Ok(())
 }

Structs§

JITSymbolGenericFlags
LLVMLLJIT