I'm working on LLVM tutorial in Rust now. I have implemented some parts of Kaleidoscope REPL already. It worked for me well, but suddenly it stopped to work and every attempt to calculate a value ends in LLVM ERROR: Target does not support MC emission!
now. It seems it happend after updating of Rust compiler to the latest nightly (but I am not sure here).
Relevant pieces of code follow.
Initialization function:
#[allow(non_snake_case)]
pub unsafe fn LLVMInitializeNativeTarget() {
llvm::LLVMInitializeX86TargetInfo();
llvm::LLVMInitializeX86Target();
llvm::LLVMInitializeX86TargetMC();
}
Module creation:
let module = llvm::LLVMModuleCreateWithNameInContext(module_name.to_c_str().as_ptr(), context);
Execution engine creation:
let mut exec_engine = 0 as llvm::ExecutionEngineRef;
let mut error = 0 as *const c_char;
LLVMCreateExecutionEngineForModule(&mut exec_engine, module, &mut error);
assert!(exec_engine != 0 as llvm::ExecutionEngineRef);
Compilation and running of function:
pub fn run(value: llvm::ValueRef, context: &Context) -> f64 {
unsafe {
let result = LLVMRunFunction(context.exec_engine,
value,
0,
0 as *const GenericValueRef);
let ty = llvm::LLVMDoubleTypeInContext(context.context);
LLVMGenericValueToFloat(ty, result)
}
}
LLVM functions prefexed by llvm:: are imported by rustc, those not prefexed by llvm:: are imported by my code, see https://github.com/jauhien/iron-kaleidoscope/blob/master/src/missing_llvm_bindings/mod.rs.
To see full code listing, look at https://github.com/jauhien/iron-kaleidoscope/blob/master/src/builder.rs
I'm using the latest nightly Rust and LLVM 3.5.0.
UPD: After commenting out of the call to LLVMInitializeNativeTarget, JIT started to work again. But I am still wondering what is the reason of the problem and how JIT should be used correctly.
UPD2: after commenting out line with initialization not everything started to work again: calls to the function defined in the Rust code fail with LLVM ERROR: Tried to execute an unknown external function
now.
Function I'm trying to call (this worked before):
#[no_mangle]
pub extern fn print(x: f64) -> f64 {
println!("> {} <", x);
x
}
Example session:
jauhien@zcj iron-repl % ./target/iron_kaleidoscope
>extern print(x)
declare double @print(double)
>print(1)
LLVM ERROR: Tried to execute an unknown external function: print
I had the same problem and could solve it by also running
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
after initializing X86Target. I found this in the source code of lli
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With