Add function to call bitcode

This commit is contained in:
Dimitar Apostolov 2020-09-17 13:37:30 +02:00
parent e89af31015
commit 9276fd8c9d
2 changed files with 27 additions and 34 deletions

View file

@ -33,6 +33,8 @@ the `cargo rustc` command above to regenerate it.
> $ 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
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
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.

View file

@ -2270,17 +2270,24 @@ fn build_int_binop<'a, 'ctx, 'env>(
NumLte => bd.build_int_compare(SLE, lhs, rhs, "int_lte").into(),
NumRemUnchecked => bd.build_int_signed_rem(lhs, rhs, "rem_int").into(),
NumDivUnchecked => bd.build_int_signed_div(lhs, rhs, "div_int").into(),
NumPowInt => {
let builtin_fn_name = "pow_int_";
NumPowInt => call_bitcode_fn(NumPowInt, env, &[lhs.into(), rhs.into()], "pow_int_"),
_ => {
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(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");
.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());
@ -2288,11 +2295,6 @@ fn build_int_binop<'a, 'ctx, 'env>(
.left()
.unwrap_or_else(|| panic!("LLVM error: Invalid call for low-level op {:?}", op))
}
_ => {
unreachable!("Unrecognized int binary operation: {:?}", op);
}
}
}
fn build_float_binop<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
@ -2375,22 +2377,7 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
}
NumToFloat => {
// TODO specialize this to be not just for i64!
let builtin_fn_name = "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))
call_bitcode_fn(NumToFloat, env, &[arg.into()], "i64_to_f64_")
}
_ => {
unreachable!("Unrecognized int unary operation: {:?}", op);