mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 07:14:46 +00:00
Simplify call_intrinsic
This commit is contained in:
parent
1efc386e5a
commit
bbbf5de6a5
1 changed files with 46 additions and 40 deletions
|
@ -98,6 +98,46 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
|
||||||
pub fn small_str_bytes(&self) -> u32 {
|
pub fn small_str_bytes(&self) -> u32 {
|
||||||
self.ptr_bytes * 2
|
self.ptr_bytes * 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn build_intrinsic_call(
|
||||||
|
&self,
|
||||||
|
intrinsic_name: &'static str,
|
||||||
|
args: &[BasicValueEnum<'ctx>],
|
||||||
|
) -> CallSiteValue<'ctx> {
|
||||||
|
let fn_val = self
|
||||||
|
.module
|
||||||
|
.get_function(intrinsic_name)
|
||||||
|
.unwrap_or_else(|| panic!("Unrecognized intrinsic function: {}", intrinsic_name));
|
||||||
|
|
||||||
|
let mut arg_vals: Vec<BasicValueEnum> = Vec::with_capacity_in(args.len(), self.arena);
|
||||||
|
|
||||||
|
for arg in args.iter() {
|
||||||
|
arg_vals.push(*arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
let call = self
|
||||||
|
.builder
|
||||||
|
.build_call(fn_val, arg_vals.into_bump_slice(), "call");
|
||||||
|
|
||||||
|
call.set_call_convention(fn_val.get_call_conventions());
|
||||||
|
|
||||||
|
call
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call_intrinsic(
|
||||||
|
&self,
|
||||||
|
intrinsic_name: &'static str,
|
||||||
|
args: &[BasicValueEnum<'ctx>],
|
||||||
|
) -> BasicValueEnum<'ctx> {
|
||||||
|
let call = self.build_intrinsic_call(intrinsic_name, args);
|
||||||
|
|
||||||
|
call.try_as_basic_value().left().unwrap_or_else(|| {
|
||||||
|
panic!(
|
||||||
|
"LLVM error: Invalid call by name for intrinsic {}",
|
||||||
|
intrinsic_name
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn module_from_builtins<'ctx>(ctx: &'ctx Context, module_name: &str) -> Module<'ctx> {
|
pub fn module_from_builtins<'ctx>(ctx: &'ctx Context, module_name: &str) -> Module<'ctx> {
|
||||||
|
@ -233,11 +273,8 @@ pub fn build_exp_literal<'a, 'ctx, 'env>(
|
||||||
} else {
|
} else {
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
|
|
||||||
let len_u64 = str_literal.len() as u64;
|
let len_u64 = str_literal.len() as u64;
|
||||||
|
|
||||||
let elem_bytes = CHAR_LAYOUT.stack_size(env.ptr_bytes) as u64;
|
let elem_bytes = CHAR_LAYOUT.stack_size(env.ptr_bytes) as u64;
|
||||||
|
|
||||||
let ptr_bytes = env.ptr_bytes;
|
let ptr_bytes = env.ptr_bytes;
|
||||||
|
|
||||||
let populate_str = |ptr| {
|
let populate_str = |ptr| {
|
||||||
|
@ -1492,36 +1529,6 @@ fn call_with_args<'a, 'ctx, 'env>(
|
||||||
.unwrap_or_else(|| panic!("LLVM error: Invalid call by name for name {:?}", symbol))
|
.unwrap_or_else(|| panic!("LLVM error: Invalid call by name for name {:?}", symbol))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_intrinsic<'a, 'ctx, 'env>(
|
|
||||||
intrinsic_name: &'static str,
|
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
|
||||||
args: &[(BasicValueEnum<'ctx>, &'a Layout<'a>)],
|
|
||||||
) -> BasicValueEnum<'ctx> {
|
|
||||||
let fn_val = env
|
|
||||||
.module
|
|
||||||
.get_function(intrinsic_name)
|
|
||||||
.unwrap_or_else(|| panic!("Unrecognized intrinsic function: {}", intrinsic_name));
|
|
||||||
|
|
||||||
let mut arg_vals: Vec<BasicValueEnum> = Vec::with_capacity_in(args.len(), env.arena);
|
|
||||||
|
|
||||||
for (arg, _layout) in args.iter() {
|
|
||||||
arg_vals.push(*arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
let call = env
|
|
||||||
.builder
|
|
||||||
.build_call(fn_val, arg_vals.into_bump_slice(), "call");
|
|
||||||
|
|
||||||
call.set_call_convention(fn_val.get_call_conventions());
|
|
||||||
|
|
||||||
call.try_as_basic_value().left().unwrap_or_else(|| {
|
|
||||||
panic!(
|
|
||||||
"LLVM error: Invalid call by name for intrinsic {}",
|
|
||||||
intrinsic_name
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum InPlace {
|
pub enum InPlace {
|
||||||
InPlace,
|
InPlace,
|
||||||
Clone,
|
Clone,
|
||||||
|
@ -1699,7 +1706,7 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
build_int_unary_op(env, arg.into_int_value(), arg_layout, op)
|
build_int_unary_op(env, arg.into_int_value(), arg_layout, op)
|
||||||
}
|
}
|
||||||
Float128 | Float64 | Float32 | Float16 => {
|
Float128 | Float64 | Float32 | Float16 => {
|
||||||
build_float_unary_op(env, arg.into_float_value(), arg_layout, op)
|
build_float_unary_op(env, arg.into_float_value(), op)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!("Compiler bug: tried to run numeric operation {:?} on invalid builtin layout: ({:?})", op, arg_layout);
|
unreachable!("Compiler bug: tried to run numeric operation {:?} on invalid builtin layout: ({:?})", op, arg_layout);
|
||||||
|
@ -2099,7 +2106,6 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
||||||
fn build_float_unary_op<'a, 'ctx, 'env>(
|
fn build_float_unary_op<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
arg: FloatValue<'ctx>,
|
arg: FloatValue<'ctx>,
|
||||||
arg_layout: &Layout<'a>,
|
|
||||||
op: LowLevel,
|
op: LowLevel,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
use roc_module::low_level::LowLevel::*;
|
use roc_module::low_level::LowLevel::*;
|
||||||
|
@ -2108,11 +2114,11 @@ fn build_float_unary_op<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
NumNeg => bd.build_float_neg(arg, "negate_float").into(),
|
NumNeg => bd.build_float_neg(arg, "negate_float").into(),
|
||||||
NumAbs => call_intrinsic(LLVM_FABS_F64, env, &[(arg.into(), arg_layout)]),
|
NumAbs => env.call_intrinsic(LLVM_FABS_F64, &[arg.into()]),
|
||||||
NumSqrtUnchecked => call_intrinsic(LLVM_SQRT_F64, env, &[(arg.into(), arg_layout)]),
|
NumSqrtUnchecked => env.call_intrinsic(LLVM_SQRT_F64, &[arg.into()]),
|
||||||
NumRound => call_intrinsic(LLVM_LROUND_I64_F64, env, &[(arg.into(), arg_layout)]),
|
NumRound => env.call_intrinsic(LLVM_LROUND_I64_F64, &[arg.into()]),
|
||||||
NumSin => call_intrinsic(LLVM_SIN_F64, env, &[(arg.into(), arg_layout)]),
|
NumSin => env.call_intrinsic(LLVM_SIN_F64, &[arg.into()]),
|
||||||
NumCos => call_intrinsic(LLVM_COS_F64, env, &[(arg.into(), arg_layout)]),
|
NumCos => env.call_intrinsic(LLVM_COS_F64, &[arg.into()]),
|
||||||
NumToFloat => arg.into(), /* Converting from Float to Float is a no-op */
|
NumToFloat => arg.into(), /* Converting from Float to Float is a no-op */
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!("Unrecognized int unary operation: {:?}", op);
|
unreachable!("Unrecognized int unary operation: {:?}", op);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue