fix llvm build

This commit is contained in:
Folkert 2021-01-01 16:28:35 +01:00
parent 5a6bd1e187
commit ca24f1cd38
2 changed files with 110 additions and 111 deletions

View file

@ -40,7 +40,7 @@ use roc_collections::all::{ImMap, MutSet};
use roc_module::ident::TagName;
use roc_module::low_level::LowLevel;
use roc_module::symbol::{Interns, ModuleId, Symbol};
use roc_mono::ir::{JoinPointId, Wrapped};
use roc_mono::ir::{CallType, JoinPointId, Wrapped};
use roc_mono::layout::{Builtin, ClosureLayout, Layout, LayoutIds, MemoryMode};
use target_lexicon::CallingConvention;
@ -618,18 +618,75 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
layout: &Layout<'a>,
expr: &roc_mono::ir::Expr<'a>,
) -> BasicValueEnum<'ctx> {
use roc_mono::ir::CallType::*;
use roc_mono::ir::Expr::*;
match expr {
Literal(literal) => build_exp_literal(env, literal),
RunLowLevel(op, symbols) => {
run_low_level(env, layout_ids, scope, parent, layout, *op, symbols)
Call(roc_mono::ir::Call {
call_type,
arguments,
}) => match call_type {
CallType::ByName {
name, full_layout, ..
} => {
let mut arg_tuples: Vec<BasicValueEnum> =
Vec::with_capacity_in(arguments.len(), env.arena);
for symbol in arguments.iter() {
arg_tuples.push(load_symbol(env, scope, symbol));
}
ForeignCall {
call_with_args(
env,
layout_ids,
&full_layout,
*name,
parent,
arg_tuples.into_bump_slice(),
)
}
CallType::ByPointer { name, .. } => {
let sub_expr = load_symbol(env, scope, name);
let mut arg_vals: Vec<BasicValueEnum> =
Vec::with_capacity_in(arguments.len(), env.arena);
for arg in arguments.iter() {
arg_vals.push(load_symbol(env, scope, arg));
}
let call = match sub_expr {
BasicValueEnum::PointerValue(ptr) => {
env.builder.build_call(ptr, arg_vals.as_slice(), "tmp")
}
non_ptr => {
panic!(
"Tried to call by pointer, but encountered a non-pointer: {:?}",
non_ptr
);
}
};
if env.exposed_to_host.contains(name) {
// If this is an external-facing function, use the C calling convention.
call.set_call_convention(C_CALL_CONV);
} else {
// If it's an internal-only function, use the fast calling convention.
call.set_call_convention(FAST_CALL_CONV);
}
call.try_as_basic_value()
.left()
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
}
CallType::LowLevel { op } => {
run_low_level(env, layout_ids, scope, parent, layout, *op, arguments)
}
CallType::Foreign {
foreign_symbol,
arguments,
ret_layout,
} => {
let mut arg_vals: Vec<BasicValueEnum> =
@ -638,7 +695,8 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
let mut arg_types = Vec::with_capacity_in(arguments.len() + 1, env.arena);
// crude approximation of the C calling convention
let pass_result_by_pointer = ret_layout.stack_size(env.ptr_bytes) > 2 * env.ptr_bytes;
let pass_result_by_pointer =
ret_layout.stack_size(env.ptr_bytes) > 2 * env.ptr_bytes;
if pass_result_by_pointer {
// the return value is too big to pass through a register, so the caller must
@ -696,65 +754,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
}
}
FunctionCall {
call_type: ByName(name),
full_layout,
args,
..
} => {
let mut arg_tuples: Vec<BasicValueEnum> = Vec::with_capacity_in(args.len(), env.arena);
for symbol in args.iter() {
arg_tuples.push(load_symbol(env, scope, symbol));
}
call_with_args(
env,
layout_ids,
&full_layout,
*name,
parent,
arg_tuples.into_bump_slice(),
)
}
FunctionCall {
call_type: ByPointer(name),
args,
..
} => {
let sub_expr = load_symbol(env, scope, name);
let mut arg_vals: Vec<BasicValueEnum> = Vec::with_capacity_in(args.len(), env.arena);
for arg in args.iter() {
arg_vals.push(load_symbol(env, scope, arg));
}
let call = match sub_expr {
BasicValueEnum::PointerValue(ptr) => {
env.builder.build_call(ptr, arg_vals.as_slice(), "tmp")
}
non_ptr => {
panic!(
"Tried to call by pointer, but encountered a non-pointer: {:?}",
non_ptr
);
}
};
if env.exposed_to_host.contains(name) {
// If this is an external-facing function, use the C calling convention.
call.set_call_convention(C_CALL_CONV);
} else {
// If it's an internal-only function, use the fast calling convention.
call.set_call_convention(FAST_CALL_CONV);
}
call.try_as_basic_value()
.left()
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
}
},
Struct(sorted_fields) => {
let ctx = env.context;

View file

@ -866,8 +866,7 @@ impl<'a> Call<'a> {
.append(alloc.intersperse(it, " "))
}
Foreign {
foreign_symbol: ref foreign_symbol,
..
ref foreign_symbol, ..
} => {
let it = arguments.iter().map(|s| symbol_to_doc(alloc, *s));