mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Add function to call bitcode
This commit is contained in:
parent
e89af31015
commit
9276fd8c9d
2 changed files with 27 additions and 34 deletions
|
@ -33,6 +33,8 @@ the `cargo rustc` command above to regenerate it.
|
||||||
> $ cargo rustc --release --lib -- --emit=llvm-ir
|
> $ cargo rustc --release --lib -- --emit=llvm-ir
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
|
**Note**: In order to be able to address the bitcode functions by name, they need to be defined with the `#[no_mangle]` attribute.
|
||||||
|
|
||||||
## Importing the bitcode
|
## Importing the bitcode
|
||||||
|
|
||||||
The bitcode is a bunch of bytes that aren't particularly human-readable.
|
The bitcode is a bunch of bytes that aren't particularly human-readable.
|
||||||
|
@ -54,3 +56,7 @@ compiler/gen/src/llvm/builtins.bc
|
||||||
|
|
||||||
Once that's done, `git status` should show that the `builtins.bc` file
|
Once that's done, `git status` should show that the `builtins.bc` file
|
||||||
has been changed. Commit that change and you're done!
|
has been changed. Commit that change and you're done!
|
||||||
|
|
||||||
|
## Calling bitcode functions
|
||||||
|
|
||||||
|
Use the `call_bitcode_fn` function defined in `llvm/src/build.rs` to call bitcode funcitons.
|
||||||
|
|
|
@ -2270,30 +2270,32 @@ fn build_int_binop<'a, 'ctx, 'env>(
|
||||||
NumLte => bd.build_int_compare(SLE, lhs, rhs, "int_lte").into(),
|
NumLte => bd.build_int_compare(SLE, lhs, rhs, "int_lte").into(),
|
||||||
NumRemUnchecked => bd.build_int_signed_rem(lhs, rhs, "rem_int").into(),
|
NumRemUnchecked => bd.build_int_signed_rem(lhs, rhs, "rem_int").into(),
|
||||||
NumDivUnchecked => bd.build_int_signed_div(lhs, rhs, "div_int").into(),
|
NumDivUnchecked => bd.build_int_signed_div(lhs, rhs, "div_int").into(),
|
||||||
NumPowInt => {
|
NumPowInt => call_bitcode_fn(NumPowInt, env, &[lhs.into(), rhs.into()], "pow_int_"),
|
||||||
let builtin_fn_name = "pow_int_";
|
|
||||||
|
|
||||||
let fn_val = env
|
|
||||||
.module
|
|
||||||
.get_function(builtin_fn_name)
|
|
||||||
.unwrap_or_else(|| panic!("Unrecognized builtin function: {:?} - if you're working on the Roc compiler, do you need to rebuild the bitcode? See compiler/builtins/bitcode/README.md", builtin_fn_name));
|
|
||||||
|
|
||||||
let call = env
|
|
||||||
.builder
|
|
||||||
.build_call(fn_val, &[lhs.into(), rhs.into()], "call_builtin");
|
|
||||||
|
|
||||||
call.set_call_convention(fn_val.get_call_conventions());
|
|
||||||
|
|
||||||
call.try_as_basic_value()
|
|
||||||
.left()
|
|
||||||
.unwrap_or_else(|| panic!("LLVM error: Invalid call for low-level op {:?}", op))
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!("Unrecognized int binary operation: {:?}", op);
|
unreachable!("Unrecognized int binary operation: {:?}", op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn call_bitcode_fn<'a, 'ctx, 'env>(
|
||||||
|
op: LowLevel,
|
||||||
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
args: &[BasicValueEnum<'ctx>],
|
||||||
|
fn_name: &str,
|
||||||
|
) -> BasicValueEnum<'ctx> {
|
||||||
|
let fn_val = env
|
||||||
|
.module
|
||||||
|
.get_function(fn_name)
|
||||||
|
.unwrap_or_else(|| panic!("Unrecognized builtin function: {:?} - if you're working on the Roc compiler, do you need to rebuild the bitcode? See compiler/builtins/bitcode/README.md", fn_name));
|
||||||
|
let call = env.builder.build_call(fn_val, args, "call_builtin");
|
||||||
|
|
||||||
|
call.set_call_convention(fn_val.get_call_conventions());
|
||||||
|
|
||||||
|
call.try_as_basic_value()
|
||||||
|
.left()
|
||||||
|
.unwrap_or_else(|| panic!("LLVM error: Invalid call for low-level op {:?}", op))
|
||||||
|
}
|
||||||
|
|
||||||
fn build_float_binop<'a, 'ctx, 'env>(
|
fn build_float_binop<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
lhs: FloatValue<'ctx>,
|
lhs: FloatValue<'ctx>,
|
||||||
|
@ -2375,22 +2377,7 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
NumToFloat => {
|
NumToFloat => {
|
||||||
// TODO specialize this to be not just for i64!
|
// TODO specialize this to be not just for i64!
|
||||||
let builtin_fn_name = "i64_to_f64_";
|
call_bitcode_fn(NumToFloat, env, &[arg.into()], "i64_to_f64_")
|
||||||
|
|
||||||
let fn_val = env
|
|
||||||
.module
|
|
||||||
.get_function(builtin_fn_name)
|
|
||||||
.unwrap_or_else(|| panic!("Unrecognized builtin function: {:?} - if you're working on the Roc compiler, do you need to rebuild the bitcode? See compiler/builtins/bitcode/README.md", builtin_fn_name));
|
|
||||||
|
|
||||||
let call = env
|
|
||||||
.builder
|
|
||||||
.build_call(fn_val, &[arg.into()], "call_builtin");
|
|
||||||
|
|
||||||
call.set_call_convention(fn_val.get_call_conventions());
|
|
||||||
|
|
||||||
call.try_as_basic_value()
|
|
||||||
.left()
|
|
||||||
.unwrap_or_else(|| panic!("LLVM error: Invalid call for low-level op {:?}", op))
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!("Unrecognized int unary operation: {:?}", op);
|
unreachable!("Unrecognized int unary operation: {:?}", op);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue