working, but generates more code

This commit is contained in:
Folkert 2021-10-22 14:54:15 +02:00
parent 2ff3a97ada
commit 1d1bd3d051

View file

@ -4398,26 +4398,30 @@ fn call_roc_function<'a, 'ctx, 'env>(
result_layout: &Layout<'a>,
arguments: &[BasicValueEnum<'ctx>],
) -> BasicValueEnum<'ctx> {
let pass_by_pointer = roc_function.get_type().get_param_types().len() == arguments.len() + 1;
match RocReturn::from_layout(env, result_layout) {
RocReturn::Return => {
debug_assert_eq!(
roc_function.get_type().get_param_types().len(),
arguments.len()
);
let call = env.builder.build_call(roc_function, arguments, "call");
// roc functions should have the fast calling convention
debug_assert_eq!(roc_function.get_call_conventions(), FAST_CALL_CONV);
call.set_call_convention(FAST_CALL_CONV);
call.try_as_basic_value().left().unwrap_or_else(|| {
panic!(
"LLVM error: Invalid call by name for name {:?}",
roc_function.get_name()
)
})
}
RocReturn::ByPointer => {
if !pass_by_pointer {
let mut arguments = Vec::from_iter_in(arguments.iter().copied(), env.arena);
let result_type = basic_type_from_layout(env, result_layout);
let result_alloca = env.builder.build_alloca(result_type, "result_value");
//arguments.push(result_alloca.into());
debug_assert_eq!(
roc_function.get_type().get_param_types().len(),
arguments.len()
);
let call = env.builder.build_call(roc_function, &arguments, "call");
// roc functions should have the fast calling convention
debug_assert_eq!(roc_function.get_call_conventions(), FAST_CALL_CONV);
call.set_call_convention(FAST_CALL_CONV);
return env.builder.build_load(result_alloca, "load_result");
}
let mut arguments = Vec::from_iter_in(arguments.iter().copied(), env.arena);
let result_type = basic_type_from_layout(env, result_layout);
@ -4437,6 +4441,24 @@ fn call_roc_function<'a, 'ctx, 'env>(
env.builder.build_load(result_alloca, "load_result")
}
RocReturn::Return => {
debug_assert_eq!(
roc_function.get_type().get_param_types().len(),
arguments.len()
);
let call = env.builder.build_call(roc_function, arguments, "call");
// roc functions should have the fast calling convention
debug_assert_eq!(roc_function.get_call_conventions(), FAST_CALL_CONV);
call.set_call_convention(FAST_CALL_CONV);
call.try_as_basic_value().left().unwrap_or_else(|| {
panic!(
"LLVM error: Invalid call by name for name {:?}",
roc_function.get_name()
)
})
}
}
}
@ -5778,7 +5800,7 @@ enum RocReturn {
impl RocReturn {
fn roc_return_by_pointer(layout: Layout) -> bool {
match layout {
Layout::Union(union_layout) => matches!(union_layout, UnionLayout::NonRecursive(_)),
Layout::Union(UnionLayout::NonRecursive(_)) => true,
Layout::LambdaSet(lambda_set) => {
RocReturn::roc_return_by_pointer(lambda_set.runtime_representation())
}
@ -5787,7 +5809,7 @@ impl RocReturn {
}
fn from_layout<'a, 'ctx, 'env>(_env: &Env<'a, 'ctx, 'env>, layout: &Layout<'a>) -> Self {
if false && Self::roc_return_by_pointer(*layout) {
if Self::roc_return_by_pointer(*layout) {
RocReturn::ByPointer
} else {
RocReturn::Return