mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
working, but generates more code
This commit is contained in:
parent
2ff3a97ada
commit
1d1bd3d051
1 changed files with 42 additions and 20 deletions
|
@ -4398,26 +4398,30 @@ fn call_roc_function<'a, 'ctx, 'env>(
|
||||||
result_layout: &Layout<'a>,
|
result_layout: &Layout<'a>,
|
||||||
arguments: &[BasicValueEnum<'ctx>],
|
arguments: &[BasicValueEnum<'ctx>],
|
||||||
) -> 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) {
|
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 => {
|
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 mut arguments = Vec::from_iter_in(arguments.iter().copied(), env.arena);
|
||||||
|
|
||||||
let result_type = basic_type_from_layout(env, result_layout);
|
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")
|
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 {
|
impl RocReturn {
|
||||||
fn roc_return_by_pointer(layout: Layout) -> bool {
|
fn roc_return_by_pointer(layout: Layout) -> bool {
|
||||||
match layout {
|
match layout {
|
||||||
Layout::Union(union_layout) => matches!(union_layout, UnionLayout::NonRecursive(_)),
|
Layout::Union(UnionLayout::NonRecursive(_)) => true,
|
||||||
Layout::LambdaSet(lambda_set) => {
|
Layout::LambdaSet(lambda_set) => {
|
||||||
RocReturn::roc_return_by_pointer(lambda_set.runtime_representation())
|
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 {
|
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
|
RocReturn::ByPointer
|
||||||
} else {
|
} else {
|
||||||
RocReturn::Return
|
RocReturn::Return
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue