From 9c27535ceee114b3b78799f75ebe78e964b8e10a Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 18 Aug 2021 15:13:48 +0200 Subject: [PATCH] some work, some don't --- compiler/gen_llvm/src/llvm/build.rs | 97 ++++++++++++++++++++++++----- compiler/mono/src/ir.rs | 31 ++++++++- compiler/mono/src/layout.rs | 47 +++++++++----- 3 files changed, 141 insertions(+), 34 deletions(-) diff --git a/compiler/gen_llvm/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs index f04064cdcb..97f476beff 100644 --- a/compiler/gen_llvm/src/llvm/build.rs +++ b/compiler/gen_llvm/src/llvm/build.rs @@ -3621,15 +3621,6 @@ pub fn build_closure_caller<'a, 'ctx, 'env>( let context = &env.context; let builder = env.builder; - // STEP 1: build function header - - // e.g. `roc__main_1_Fx_caller` - let function_name = format!( - "roc__{}_{}_caller", - def_name, - alias_symbol.as_str(&env.interns) - ); - let mut argument_types = Vec::with_capacity_in(arguments.len() + 3, env.arena); for layout in arguments { @@ -3646,6 +3637,29 @@ pub fn build_closure_caller<'a, 'ctx, 'env>( }; argument_types.push(closure_argument_type.into()); + build_closure_caller_help( + env, + def_name, + evaluator, + alias_symbol, + argument_types, + lambda_set.runtime_representation(), + result, + ) +} + +pub fn build_closure_caller_help<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + def_name: &str, + evaluator: FunctionValue<'ctx>, + alias_symbol: Symbol, + mut argument_types: Vec<'_, BasicTypeEnum<'ctx>>, + lambda_set_runtime_layout: Layout<'a>, + result: &Layout<'a>, +) { + let context = &env.context; + let builder = env.builder; + let result_type = basic_type_from_layout(env, result); let roc_call_result_type = @@ -3654,6 +3668,15 @@ pub fn build_closure_caller<'a, 'ctx, 'env>( let output_type = { roc_call_result_type.ptr_type(AddressSpace::Generic) }; argument_types.push(output_type.into()); + // STEP 1: build function header + + // e.g. `roc__main_1_Fx_caller` + let function_name = format!( + "roc__{}_{}_caller", + def_name, + alias_symbol.as_str(&env.interns) + ); + let function_type = context.void_type().fn_type(&argument_types, false); let function_value = add_func( @@ -3672,9 +3695,15 @@ pub fn build_closure_caller<'a, 'ctx, 'env>( let mut parameters = function_value.get_params(); let output = parameters.pop().unwrap().into_pointer_value(); - let closure_data_ptr = parameters.pop().unwrap().into_pointer_value(); - let closure_data = builder.build_load(closure_data_ptr, "load_closure_data"); + let closure_data = if let Some(closure_data_ptr) = parameters.pop() { + let closure_data = + builder.build_load(closure_data_ptr.into_pointer_value(), "load_closure_data"); + + env.arena.alloc([closure_data]) as &[_] + } else { + &[] + }; let mut parameters = parameters; @@ -3688,7 +3717,7 @@ pub fn build_closure_caller<'a, 'ctx, 'env>( function_value, evaluator, evaluator.get_call_conventions(), - &[closure_data], + closure_data, result_type, ); @@ -3706,8 +3735,7 @@ pub fn build_closure_caller<'a, 'ctx, 'env>( ); // STEP 4: build a {} -> u64 function that gives the size of the closure - let layout = lambda_set.runtime_representation(); - build_host_exposed_alias_size(env, def_name, alias_symbol, layout); + build_host_exposed_alias_size(env, def_name, alias_symbol, lambda_set_runtime_layout); } fn build_host_exposed_alias_size<'a, 'ctx, 'env>( @@ -3822,8 +3850,47 @@ pub fn build_proc<'a, 'ctx, 'env>( ) } - RawFunctionLayout::ZeroArgumentThunk(_) => { + RawFunctionLayout::ZeroArgumentThunk(result) => { // do nothing + /* + let bytes = roc_mono::alias_analysis::func_name_bytes_help( + symbol, + std::iter::empty(), + top_level.result, + ); + let func_name = FuncName(&bytes); + let func_solutions = mod_solutions.func_solutions(func_name).unwrap(); + + let mut it = func_solutions.specs(); + let func_spec = it.next().unwrap(); + debug_assert!( + it.next().is_none(), + "we expect only one specialization of this symbol" + ); + + let evaluator = function_value_by_func_spec( + env, + *func_spec, + symbol, + &[], + &top_level.result, + ); + + let ident_string = proc.name.as_str(&env.interns); + let fn_name: String = format!("{}_1", ident_string); + + let arena = env.arena; + + build_closure_caller_help( + env, + &fn_name, + evaluator, + name, + Vec::new_in(arena), + result, + &result, + ) + */ } } } diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index 8ff5bc26e7..4ba24effa3 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -2032,9 +2032,34 @@ fn specialize_external<'a>( aliases.insert(*symbol, (name, top_level, layout)); } - RawFunctionLayout::ZeroArgumentThunk(layout) => { - todo!("our layout is {:?}", layout); - // + RawFunctionLayout::ZeroArgumentThunk(return_layout) => { + panic!("should be unused"); + /* + let assigned = env.unique_symbol(); + + let hole = env.arena.alloc(Stmt::Ret(assigned)); + + let body = force_thunk(env, name, return_layout, assigned, hole); + + let proc = Proc { + name, + args: &[], + body, + closure_data_layout: None, + ret_layout: return_layout, + is_self_recursive: SelfRecursive::NotSelfRecursive, + must_own_arguments: false, + host_exposed_layouts: HostExposedLayouts::NotHostExposed, + }; + + let top_level = ProcLayout::new(env.arena, &[], return_layout); + + procs + .specialized + .insert((name, top_level), InProgressProc::Done(proc)); + + aliases.insert(*symbol, (name, top_level, layout)); + */ } } } diff --git a/compiler/mono/src/layout.rs b/compiler/mono/src/layout.rs index de42e2dc31..0b9e5afda0 100644 --- a/compiler/mono/src/layout.rs +++ b/compiler/mono/src/layout.rs @@ -115,25 +115,40 @@ impl<'a> RawFunctionLayout<'a> { let arena = env.arena; - if let Func(args, closure_var, ret_var) = flat_type { - let mut fn_args = Vec::with_capacity_in(args.len(), arena); + match flat_type { + Func(args, closure_var, ret_var) => { + let mut fn_args = Vec::with_capacity_in(args.len(), arena); - for index in args.into_iter() { - let arg_var = env.subs[index]; - fn_args.push(Layout::from_var(env, arg_var)?); + for index in args.into_iter() { + let arg_var = env.subs[index]; + fn_args.push(Layout::from_var(env, arg_var)?); + } + + let ret = Layout::from_var(env, ret_var)?; + + let fn_args = fn_args.into_bump_slice(); + let ret = arena.alloc(ret); + + let lambda_set = LambdaSet::from_var(env.arena, env.subs, closure_var)?; + + Ok(Self::Function(fn_args, lambda_set, ret)) } + TagUnion(tags, _) if tags.is_newtype_wrapper(env.subs) => { + let slice_index = tags.variables().into_iter().next().unwrap(); + let slice = env.subs[slice_index]; + let var_index = slice.into_iter().next().unwrap(); + let var = env.subs[var_index]; - let ret = Layout::from_var(env, ret_var)?; - - let fn_args = fn_args.into_bump_slice(); - let ret = arena.alloc(ret); - - let lambda_set = LambdaSet::from_var(env.arena, env.subs, closure_var)?; - - Ok(Self::Function(fn_args, lambda_set, ret)) - } else { - let layout = layout_from_flat_type(env, flat_type)?; - Ok(Self::ZeroArgumentThunk(layout)) + Self::from_var(env, var) + } + Record(fields, _) if fields.len() == 1 => { + // + todo!() + } + _ => { + let layout = layout_from_flat_type(env, flat_type)?; + Ok(Self::ZeroArgumentThunk(layout)) + } } }