From c09b3b89f38bbfe794209dcad4f2be685e6439e3 Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 18 Aug 2021 13:46:09 +0200 Subject: [PATCH] test_gen works again --- compiler/gen_llvm/src/llvm/bitcode.rs | 44 +++++++++++++ compiler/gen_llvm/src/llvm/build.rs | 8 --- compiler/gen_llvm/src/llvm/build_hash.rs | 4 -- compiler/gen_llvm/src/llvm/compare.rs | 8 --- compiler/gen_llvm/src/llvm/convert.rs | 4 -- compiler/gen_llvm/src/llvm/refcounting.rs | 17 ----- compiler/mono/src/alias_analysis.rs | 11 ---- compiler/mono/src/borrow.rs | 1 - compiler/mono/src/expand_rc.rs | 16 ----- compiler/mono/src/ir.rs | 77 ++++++++++++++--------- compiler/mono/src/layout.rs | 29 ++------- 11 files changed, 95 insertions(+), 124 deletions(-) diff --git a/compiler/gen_llvm/src/llvm/bitcode.rs b/compiler/gen_llvm/src/llvm/bitcode.rs index 2905b0da86..2ee98c8c8c 100644 --- a/compiler/gen_llvm/src/llvm/bitcode.rs +++ b/compiler/gen_llvm/src/llvm/bitcode.rs @@ -270,6 +270,25 @@ fn build_transform_caller_help<'a, 'ctx, 'env>( arguments_cast.push(argument); } + match closure_data_layout { + Layout::Struct(&[]) => { + // do nothing + } + other => { + let closure_type = basic_type_from_layout(env, &other).ptr_type(AddressSpace::Generic); + + let closure_cast = env + .builder + .build_bitcast(closure_ptr, closure_type, "load_opaque") + .into_pointer_value(); + + let closure_data = env.builder.build_load(closure_cast, "load_opaque"); + + arguments_cast.push(closure_data); + } + } + + /* match closure_data_layout { Layout::Closure(_, lambda_set, _) => { if let Layout::Struct(&[]) = lambda_set.runtime_representation() { @@ -316,6 +335,7 @@ fn build_transform_caller_help<'a, 'ctx, 'env>( } other => unreachable!("layout is not valid for a closure: {:?}", other), } + */ let call = { env.builder @@ -624,6 +644,7 @@ pub fn build_compare_wrapper<'a, 'ctx, 'env>( let default = [value1, value2]; + /* let arguments_cast = match closure_data_layout { Layout::Closure(_, lambda_set, _) => { if let Layout::Struct(&[]) = lambda_set.runtime_representation() { @@ -646,6 +667,29 @@ pub fn build_compare_wrapper<'a, 'ctx, 'env>( Layout::Struct([]) => &default, other => unreachable!("layout is not valid for a closure: {:?}", other), }; + */ + + let arguments_cast = match closure_data_layout { + Layout::Struct(&[]) => { + // do nothing + &default + } + other => { + // + + let closure_type = + basic_type_from_layout(env, &other).ptr_type(AddressSpace::Generic); + + let closure_cast = env + .builder + .build_bitcast(closure_ptr, closure_type, "load_opaque") + .into_pointer_value(); + + let closure_data = env.builder.build_load(closure_cast, "load_opaque"); + + env.arena.alloc([value1, value2, closure_data]) as &[_] + } + }; let call = env.builder.build_call( roc_function, diff --git a/compiler/gen_llvm/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs index 400f42f63a..f04064cdcb 100644 --- a/compiler/gen_llvm/src/llvm/build.rs +++ b/compiler/gen_llvm/src/llvm/build.rs @@ -1082,14 +1082,6 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( ) .unwrap() } - (StructValue(argument), Layout::Closure(_, _, _)) => env - .builder - .build_extract_value( - argument, - *index as u32, - env.arena.alloc(format!("closure_field_access_{}_", index)), - ) - .unwrap(), ( PointerValue(argument), Layout::Union(UnionLayout::NonNullableUnwrapped(fields)), diff --git a/compiler/gen_llvm/src/llvm/build_hash.rs b/compiler/gen_llvm/src/llvm/build_hash.rs index 71b6131e2e..85e82e18e8 100644 --- a/compiler/gen_llvm/src/llvm/build_hash.rs +++ b/compiler/gen_llvm/src/llvm/build_hash.rs @@ -88,10 +88,6 @@ fn build_hash_layout<'a, 'ctx, 'env>( ) } }, - - Layout::Closure(_, _, _) => { - unreachable!("the type system will guarantee these are never hashed") - } } } diff --git a/compiler/gen_llvm/src/llvm/compare.rs b/compiler/gen_llvm/src/llvm/compare.rs index 28f91d91b2..10463094df 100644 --- a/compiler/gen_llvm/src/llvm/compare.rs +++ b/compiler/gen_llvm/src/llvm/compare.rs @@ -198,10 +198,6 @@ fn build_eq<'a, 'ctx, 'env>( ) } }, - - Layout::Closure(_, _, _) => { - unreachable!("the type system will guarantee these are never compared") - } } } @@ -340,10 +336,6 @@ fn build_neq<'a, 'ctx, 'env>( Layout::RecursivePointer => { unreachable!("recursion pointers should never be compared directly") } - - Layout::Closure(_, _, _) => { - unreachable!("the type system will guarantee these are never compared") - } } } diff --git a/compiler/gen_llvm/src/llvm/convert.rs b/compiler/gen_llvm/src/llvm/convert.rs index df4a074e68..1522c21e9e 100644 --- a/compiler/gen_llvm/src/llvm/convert.rs +++ b/compiler/gen_llvm/src/llvm/convert.rs @@ -26,10 +26,6 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>( use Layout::*; match layout { - Closure(_args, closure_layout, _ret_layout) => { - let closure_data_layout = closure_layout.runtime_representation(); - basic_type_from_layout(env, &closure_data_layout) - } Struct(sorted_fields) => basic_type_from_record(env, sorted_fields), Union(union_layout) => { use UnionLayout::*; diff --git a/compiler/gen_llvm/src/llvm/refcounting.rs b/compiler/gen_llvm/src/llvm/refcounting.rs index 6aa30320ab..a36fe213e7 100644 --- a/compiler/gen_llvm/src/llvm/refcounting.rs +++ b/compiler/gen_llvm/src/llvm/refcounting.rs @@ -659,23 +659,6 @@ fn modify_refcount_layout_build_function<'a, 'ctx, 'env>( Some(function) } - Closure(_, lambda_set, _) => { - if lambda_set.contains_refcounted() { - let function = modify_refcount_layout_build_function( - env, - parent, - layout_ids, - mode, - when_recursive, - &lambda_set.runtime_representation(), - )?; - - Some(function) - } else { - None - } - } - Struct(layouts) => { let function = modify_refcount_struct(env, layout_ids, layouts, mode, when_recursive); diff --git a/compiler/mono/src/alias_analysis.rs b/compiler/mono/src/alias_analysis.rs index 878cf7e3e2..9f84305705 100644 --- a/compiler/mono/src/alias_analysis.rs +++ b/compiler/mono/src/alias_analysis.rs @@ -65,9 +65,6 @@ where for layout in argument_layouts { match layout { - Layout::Closure(_, lambda_set, _) => { - lambda_set.runtime_representation().hash(&mut hasher); - } _ => { layout.hash(&mut hasher); } @@ -75,9 +72,6 @@ where } match return_layout { - Layout::Closure(_, lambda_set, _) => { - lambda_set.runtime_representation().hash(&mut hasher); - } _ => { return_layout.hash(&mut hasher); } @@ -1258,11 +1252,6 @@ fn layout_spec_help( } }, }, - Closure(_, lambda_set, _) => layout_spec_help( - builder, - &lambda_set.runtime_representation(), - when_recursive, - ), } } diff --git a/compiler/mono/src/borrow.rs b/compiler/mono/src/borrow.rs index b5b2584801..51624dbce8 100644 --- a/compiler/mono/src/borrow.rs +++ b/compiler/mono/src/borrow.rs @@ -11,7 +11,6 @@ pub const BORROWED: bool = true; fn should_borrow_layout(layout: &Layout) -> bool { match layout { - Layout::Closure(_, _, _) => false, _ => layout.is_refcounted(), } } diff --git a/compiler/mono/src/expand_rc.rs b/compiler/mono/src/expand_rc.rs index 820fcf5395..0bc8f2e45d 100644 --- a/compiler/mono/src/expand_rc.rs +++ b/compiler/mono/src/expand_rc.rs @@ -165,11 +165,6 @@ impl<'a, 'i> Env<'a, 'i> { self.constructor_map.insert(symbol, 0); self.layout_map.insert(symbol, Layout::Struct(fields)); } - Closure(_, lambda_set, _) => { - self.constructor_map.insert(symbol, 0); - self.layout_map - .insert(symbol, lambda_set.runtime_representation()); - } _ => {} } } @@ -244,10 +239,6 @@ fn layout_for_constructor<'a>( debug_assert_eq!(constructor, 0); HasFields(fields) } - Closure(_arguments, _lambda_set, _result) => { - // HasFields(fields) - ConstructorLayout::Unknown - } other => unreachable!("weird layout {:?}", other), } } @@ -374,13 +365,6 @@ pub fn expand_and_cancel_proc<'a>( introduced.push(*symbol); } - Layout::Closure(_arguments, _lambda_set, _result) => { - // TODO can this be improved again? - // let fpointer = Layout::FunctionPointer(arguments, result); - // let fields = env.arena.alloc([fpointer, *closure_layout.layout]); - // env.insert_struct_info(*symbol, fields); - // introduced.push(*symbol); - } _ => {} } } diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index 58561e5fb5..8ff5bc26e7 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -546,11 +546,11 @@ impl<'a> Procs<'a> { // anonymous functions cannot reference themselves, therefore cannot be tail-recursive let is_self_recursive = false; - let layout = layout_cache - .from_var(env.arena, annotation, env.subs) + let raw_layout = layout_cache + .raw_from_var(env.arena, annotation, env.subs) .unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err)); - let top_level = ProcLayout::from_layout(env.arena, layout); + let top_level = ProcLayout::from_raw(env.arena, raw_layout); match patterns_to_when(env, layout_cache, loc_args, ret_var, loc_body) { Ok((_, pattern_symbols, body)) => { @@ -617,7 +617,11 @@ impl<'a> Procs<'a> { Ok((proc, layout)) => { let top_level = ProcLayout::from_raw(env.arena, layout); - debug_assert_eq!(outside_layout, top_level); + debug_assert_eq!( + outside_layout, top_level, + "different raw layouts for {:?}", + proc.name + ); if self.module_thunks.contains(&proc.name) { debug_assert!(top_level.arguments.is_empty()); @@ -2470,21 +2474,33 @@ fn specialize_solved_type<'a>( let fn_var = introduce_solved_type_to_subs(env, &solved_type); // for debugging only - let attempted_layout = layout_cache - .from_var(env.arena, fn_var, env.subs) + let raw = layout_cache + .raw_from_var(env.arena, fn_var, env.subs) .unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err)); - let raw = match attempted_layout { - Layout::Closure(a, lambda_set, c) => { - if procs.module_thunks.contains(&proc_name) { + let raw = if procs.module_thunks.contains(&proc_name) { + match raw { + RawFunctionLayout::Function(_, lambda_set, _) => { RawFunctionLayout::ZeroArgumentThunk(lambda_set.runtime_representation()) - } else { - RawFunctionLayout::Function(a, lambda_set, c) } + _ => raw, } - _ => RawFunctionLayout::ZeroArgumentThunk(attempted_layout), + } else { + raw }; + // TODO this module_thunks.contains check will be important + // let raw = match attempted_layout { + // Layout::Closure(a, lambda_set, c) => { + // if procs.module_thunks.contains(&proc_name) { + // RawFunctionLayout::ZeroArgumentThunk(lambda_set.runtime_representation()) + // } else { + // RawFunctionLayout::Function(a, lambda_set, c) + // } + // } + // _ => RawFunctionLayout::ZeroArgumentThunk(attempted_layout), + // }; + // make sure rigid variables in the annotation are converted to flex variables instantiate_rigids(env.subs, partial_proc.annotation); @@ -2509,12 +2525,12 @@ fn specialize_solved_type<'a>( match specialized { Ok(proc) => { // when successful, the layout after unification should be the layout before unification - debug_assert_eq!( - attempted_layout, - layout_cache - .from_var(env.arena, fn_var, env.subs) - .unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err)) - ); + // debug_assert_eq!( + // attempted_layout, + // layout_cache + // .from_var(env.arena, fn_var, env.subs) + // .unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err)) + // ); env.subs.rollback_to(snapshot); layout_cache.rollback_to(cache_snapshot); @@ -2545,16 +2561,11 @@ impl<'a> ProcLayout<'a> { for old in old_arguments { match old { - Layout::Closure(_, lambda_set, _) => { - let repr = lambda_set.runtime_representation(); - arguments.push(repr) - } other => arguments.push(*other), } } let new_result = match result { - Layout::Closure(_, lambda_set, _) => lambda_set.runtime_representation(), other => other, }; @@ -2563,12 +2574,10 @@ impl<'a> ProcLayout<'a> { result: new_result, } } + + // TODO remove!!!!! pub fn from_layout(arena: &'a Bump, layout: Layout<'a>) -> Self { match layout { - Layout::Closure(arguments, lambda_set, result) => { - let arguments = lambda_set.extend_argument_list(arena, arguments); - ProcLayout::new(arena, arguments, *result) - } _ => ProcLayout { arguments: &[], result: layout, @@ -6048,7 +6057,11 @@ fn reuse_function_symbol<'a>( ) } else if procs.module_thunks.contains(&original) { // this is a 0-argument thunk - let layout = Layout::Closure(argument_layouts, lambda_set, ret_layout); + + // TODO suspicious + // let layout = Layout::Closure(argument_layouts, lambda_set, ret_layout); + // panic!("suspicious"); + let layout = lambda_set.runtime_representation(); let top_level = ProcLayout::new(env.arena, &[], layout); procs.insert_passed_by_name( env, @@ -6654,8 +6667,12 @@ fn call_by_name_module_thunk<'a>( match specialize(env, procs, proc_name, layout_cache, pending, partial_proc) { - Ok((proc, layout)) => { - debug_assert!(layout.is_zero_argument_thunk()); + Ok((proc, raw_layout)) => { + debug_assert!( + raw_layout.is_zero_argument_thunk(), + "but actually {:?}", + raw_layout + ); let was_present = procs.specialized.remove(&(proc_name, top_level_layout)); diff --git a/compiler/mono/src/layout.rs b/compiler/mono/src/layout.rs index 22967824cc..de42e2dc31 100644 --- a/compiler/mono/src/layout.rs +++ b/compiler/mono/src/layout.rs @@ -160,9 +160,8 @@ pub enum Layout<'a> { Struct(&'a [Layout<'a>]), Union(UnionLayout<'a>), RecursivePointer, - - /// A function. The types of its arguments, then the type of its return value. - Closure(&'a [Layout<'a>], LambdaSet<'a>, &'a Layout<'a>), + // /// A function. The types of its arguments, then the type of its return value. + // Closure(&'a [Layout<'a>], LambdaSet<'a>, &'a Layout<'a>), } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -743,7 +742,6 @@ impl<'a> Layout<'a> { } } } - Closure(_, closure_layout, _) => closure_layout.safe_to_memcpy(), RecursivePointer => { // We cannot memcpy pointers, because then we would have the same pointer in multiple places! false @@ -808,7 +806,6 @@ impl<'a> Layout<'a> { | NonNullableUnwrapped(_) => pointer_size, } } - Closure(_, lambda_set, _) => lambda_set.stack_size(pointer_size), RecursivePointer => pointer_size, } } @@ -840,9 +837,6 @@ impl<'a> Layout<'a> { } Layout::Builtin(builtin) => builtin.alignment_bytes(pointer_size), Layout::RecursivePointer => pointer_size, - Layout::Closure(_, captured, _) => { - pointer_size.max(captured.alignment_bytes(pointer_size)) - } } } @@ -893,8 +887,6 @@ impl<'a> Layout<'a> { } } RecursivePointer => true, - - Closure(_, closure_layout, _) => closure_layout.contains_refcounted(), } } @@ -918,20 +910,6 @@ impl<'a> Layout<'a> { } Union(union_layout) => union_layout.to_doc(alloc, parens), RecursivePointer => alloc.text("*self"), - Closure(args, closure_layout, result) => { - let args_doc = args.iter().map(|x| x.to_doc(alloc, Parens::InFunction)); - - let bom = closure_layout - .representation - .to_doc(alloc, Parens::NotNeeded); - - alloc - .intersperse(args_doc, ", ") - .append(alloc.text(" {| ")) - .append(bom) - .append(" |} -> ") - .append(result.to_doc(alloc, Parens::InFunction)) - } } } } @@ -1257,7 +1235,8 @@ fn layout_from_flat_type<'a>( let lambda_set = LambdaSet::from_var(env.arena, env.subs, closure_var)?; - Ok(Layout::Closure(fn_args, lambda_set, ret)) + // Ok(Layout::Closure(fn_args, lambda_set, ret)) + Ok(lambda_set.runtime_representation()) } Record(fields, ext_var) => { // extract any values from the ext_var