Explicitly set calling convention

This commit is contained in:
Richard Feldman 2020-03-26 22:54:07 -04:00
parent 7bb2a4e3b8
commit 76fd347801
2 changed files with 17 additions and 0 deletions

View file

@ -24,6 +24,10 @@ const PRINT_FN_VERIFICATION_OUTPUT: bool = true;
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
const PRINT_FN_VERIFICATION_OUTPUT: bool = false; const PRINT_FN_VERIFICATION_OUTPUT: bool = false;
// 0 is the C calling convention - see https://llvm.org/doxygen/namespacellvm_1_1CallingConv.html
// TODO: experiment with different internal calling conventions, e.g. "fast"
const DEFAULT_CALLING_CONVENTION: u32 = 0;
type Scope<'a, 'ctx> = ImMap<Symbol, (Layout<'a>, PointerValue<'ctx>)>; type Scope<'a, 'ctx> = ImMap<Symbol, (Layout<'a>, PointerValue<'ctx>)>;
pub struct Env<'a, 'ctx, 'env> { pub struct Env<'a, 'ctx, 'env> {
@ -211,6 +215,8 @@ pub fn build_expr<'a, 'ctx, 'env>(
} }
}; };
call.set_call_convention(DEFAULT_CALLING_CONVENTION);
call.try_as_basic_value() call.try_as_basic_value()
.left() .left()
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer.")) .unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
@ -865,6 +871,8 @@ pub fn build_proc_header<'a, 'ctx, 'env>(
Some(Linkage::Private), Some(Linkage::Private),
); );
fn_val.set_call_conventions(DEFAULT_CALLING_CONVENTION);
(fn_val, arg_basic_types) (fn_val, arg_basic_types)
} }
@ -1103,6 +1111,8 @@ fn call_with_args<'a, 'ctx, 'env>(
.builder .builder
.build_call(fn_val, arg_vals.into_bump_slice(), "call"); .build_call(fn_val, arg_vals.into_bump_slice(), "call");
call.set_call_convention(DEFAULT_CALLING_CONVENTION);
call.try_as_basic_value() call.try_as_basic_value()
.left() .left()
.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))

View file

@ -31,6 +31,9 @@ mod test_gen {
// Pointer size on current system // Pointer size on current system
const POINTER_SIZE: u32 = std::mem::size_of::<usize>() as u32; const POINTER_SIZE: u32 = std::mem::size_of::<usize>() as u32;
// 0 is the C calling convention - see https://llvm.org/doxygen/namespacellvm_1_1CallingConv.html
const MAIN_CALLING_CONVENTION: u32 = 0;
macro_rules! assert_llvm_evals_to { macro_rules! assert_llvm_evals_to {
($src:expr, $expected:expr, $ty:ty, $transform:expr) => { ($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
let arena = Bump::new(); let arena = Bump::new();
@ -128,6 +131,8 @@ mod test_gen {
// Add main to the module. // Add main to the module.
let main_fn = env.module.add_function(main_fn_name, main_fn_type, None); let main_fn = env.module.add_function(main_fn_name, main_fn_type, None);
main_fn.set_call_conventions(MAIN_CALLING_CONVENTION);
// Add main's body // Add main's body
let basic_block = context.append_basic_block(main_fn, "entry"); let basic_block = context.append_basic_block(main_fn, "entry");
@ -272,6 +277,8 @@ mod test_gen {
// Add main to the module. // Add main to the module.
let main_fn = env.module.add_function(main_fn_name, main_fn_type, None); let main_fn = env.module.add_function(main_fn_name, main_fn_type, None);
main_fn.set_call_conventions(MAIN_CALLING_CONVENTION);
// Add main's body // Add main's body
let basic_block = context.append_basic_block(main_fn, "entry"); let basic_block = context.append_basic_block(main_fn, "entry");