From ffb6ced18f8b71055124256cf2d11779cea3a4b2 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Tue, 25 May 2021 18:11:55 -0400 Subject: [PATCH] Move InPlace from llvm to mono --- compiler/gen/src/llvm/build.rs | 70 ++++++++--------------------- compiler/gen/src/llvm/build_list.rs | 4 +- compiler/gen/src/llvm/build_str.rs | 4 +- compiler/mono/src/layout.rs | 23 ++++++++++ 4 files changed, 45 insertions(+), 56 deletions(-) diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index e5eaf9229c..c1a0006844 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -49,7 +49,7 @@ use roc_module::ident::TagName; use roc_module::low_level::LowLevel; use roc_module::symbol::{Interns, ModuleId, Symbol}; use roc_mono::ir::{BranchInfo, CallType, JoinPointId, ModifyRc, TopLevelFunctionLayout, Wrapped}; -use roc_mono::layout::{Builtin, LambdaSet, Layout, LayoutIds, MemoryMode, UnionLayout}; +use roc_mono::layout::{Builtin, InPlace, LambdaSet, Layout, LayoutIds, UnionLayout}; use target_lexicon::CallingConvention; /// This is for Inkwell's FunctionValue::verify - we want to know the verification @@ -612,20 +612,6 @@ pub fn promote_to_main_function<'a, 'ctx, 'env>( (main_fn_name, main_fn) } -fn get_inplace_from_layout(layout: &Layout<'_>) -> InPlace { - match layout { - Layout::Builtin(Builtin::EmptyList) => InPlace::InPlace, - Layout::Builtin(Builtin::List(memory_mode, _)) => match memory_mode { - MemoryMode::Unique => InPlace::InPlace, - MemoryMode::Refcounted => InPlace::Clone, - }, - Layout::Builtin(Builtin::EmptyStr) => InPlace::InPlace, - Layout::Builtin(Builtin::Str) => InPlace::Clone, - Layout::Builtin(Builtin::Int1) => InPlace::Clone, - _ => unreachable!("Layout {:?} does not have an inplace", layout), - } -} - pub fn int_with_precision<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, value: i128, @@ -1615,9 +1601,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( } EmptyArray => empty_polymorphic_list(env), Array { elem_layout, elems } => { - let inplace = get_inplace_from_layout(layout); - - list_literal(env, inplace, scope, elem_layout, elems) + list_literal(env, layout.in_place(), scope, elem_layout, elems) } RuntimeErrorFunction(_) => todo!(), } @@ -3492,13 +3476,6 @@ fn call_with_args<'a, 'ctx, 'env>( .unwrap_or_else(|| panic!("LLVM error: Invalid call by name for name {:?}", symbol)) } -#[derive(Copy, Clone)] -#[repr(u8)] -pub enum InPlace { - InPlace, - Clone, -} - /// Translates a target_lexicon::Triple to a LLVM calling convention u32 /// as described in https://llvm.org/doxygen/namespacellvm_1_1CallingConv.html pub fn get_call_conventions(cc: CallingConvention) -> u32 { @@ -4030,17 +4007,13 @@ fn run_low_level<'a, 'ctx, 'env>( // Str.concat : Str, Str -> Str debug_assert_eq!(args.len(), 2); - let inplace = get_inplace_from_layout(layout); - - str_concat(env, inplace, scope, args[0], args[1]) + str_concat(env, layout.in_place(), scope, args[0], args[1]) } StrJoinWith => { // Str.joinWith : List Str, Str -> Str debug_assert_eq!(args.len(), 2); - let inplace = get_inplace_from_layout(layout); - - str_join_with(env, inplace, scope, args[0], args[1]) + str_join_with(env, layout.in_place(), scope, args[0], args[1]) } StrStartsWith => { // Str.startsWith : Str, Str -> Bool @@ -4094,9 +4067,7 @@ fn run_low_level<'a, 'ctx, 'env>( // Str.split : Str, Str -> List Str debug_assert_eq!(args.len(), 2); - let inplace = get_inplace_from_layout(layout); - - str_split(env, scope, inplace, args[0], args[1]) + str_split(env, scope, layout.in_place(), args[0], args[1]) } StrIsEmpty => { // Str.isEmpty : Str -> Str @@ -4131,9 +4102,7 @@ fn run_low_level<'a, 'ctx, 'env>( let (arg, arg_layout) = load_symbol_and_layout(scope, &args[0]); - let inplace = get_inplace_from_layout(layout); - - list_single(env, inplace, arg, arg_layout) + list_single(env, layout.in_place(), arg, arg_layout) } ListRepeat => { // List.repeat : Int, elem -> List elem @@ -4150,9 +4119,7 @@ fn run_low_level<'a, 'ctx, 'env>( let (list, list_layout) = load_symbol_and_layout(scope, &args[0]); - let inplace = get_inplace_from_layout(layout); - - list_reverse(env, inplace, list, list_layout) + list_reverse(env, layout.in_place(), list, list_layout) } ListConcat => { debug_assert_eq!(args.len(), 2); @@ -4161,9 +4128,14 @@ fn run_low_level<'a, 'ctx, 'env>( let second_list = load_symbol(scope, &args[1]); - let inplace = get_inplace_from_layout(layout); - - list_concat(env, inplace, parent, first_list, second_list, list_layout) + list_concat( + env, + layout.in_place(), + parent, + first_list, + second_list, + list_layout, + ) } ListContains => { // List.contains : List elem, elem -> Bool @@ -4196,9 +4168,7 @@ fn run_low_level<'a, 'ctx, 'env>( let original_wrapper = load_symbol(scope, &args[0]).into_struct_value(); let (elem, elem_layout) = load_symbol_and_layout(scope, &args[1]); - let inplace = get_inplace_from_layout(layout); - - list_append(env, inplace, original_wrapper, elem, elem_layout) + list_append(env, layout.in_place(), original_wrapper, elem, elem_layout) } ListDrop => { // List.drop : List elem, Nat -> List elem @@ -4228,9 +4198,7 @@ fn run_low_level<'a, 'ctx, 'env>( let original_wrapper = load_symbol(scope, &args[0]).into_struct_value(); let (elem, elem_layout) = load_symbol_and_layout(scope, &args[1]); - let inplace = get_inplace_from_layout(layout); - - list_prepend(env, inplace, original_wrapper, elem, elem_layout) + list_prepend(env, layout.in_place(), original_wrapper, elem, elem_layout) } ListJoin => { // List.join : List (List elem) -> List elem @@ -4238,9 +4206,7 @@ fn run_low_level<'a, 'ctx, 'env>( let (list, outer_list_layout) = load_symbol_and_layout(scope, &args[0]); - let inplace = get_inplace_from_layout(layout); - - list_join(env, inplace, parent, list, outer_list_layout) + list_join(env, layout.in_place(), parent, list, outer_list_layout) } NumAbs | NumNeg | NumRound | NumSqrtUnchecked | NumLogUnchecked | NumSin | NumCos | NumCeiling | NumFloor | NumToFloat | NumIsFinite | NumAtan | NumAcos | NumAsin => { diff --git a/compiler/gen/src/llvm/build_list.rs b/compiler/gen/src/llvm/build_list.rs index 33d7664df4..f71e4a507a 100644 --- a/compiler/gen/src/llvm/build_list.rs +++ b/compiler/gen/src/llvm/build_list.rs @@ -4,7 +4,7 @@ use crate::llvm::bitcode::{ build_transform_caller, call_bitcode_fn, call_void_bitcode_fn, }; use crate::llvm::build::{ - allocate_with_refcount_help, cast_basic_basic, complex_bitcast, Env, InPlace, RocFunctionCall, + allocate_with_refcount_help, cast_basic_basic, complex_bitcast, Env, RocFunctionCall, }; use crate::llvm::convert::{basic_type_from_layout, get_ptr_type}; use crate::llvm::refcounting::increment_refcount_layout; @@ -14,7 +14,7 @@ use inkwell::types::{BasicTypeEnum, PointerType}; use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue}; use inkwell::{AddressSpace, IntPredicate}; use roc_builtins::bitcode; -use roc_mono::layout::{Builtin, Layout, LayoutIds, MemoryMode}; +use roc_mono::layout::{Builtin, InPlace, Layout, LayoutIds, MemoryMode}; fn list_returned_from_zig<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, diff --git a/compiler/gen/src/llvm/build_str.rs b/compiler/gen/src/llvm/build_str.rs index 0907e213a2..4692f5eaa8 100644 --- a/compiler/gen/src/llvm/build_str.rs +++ b/compiler/gen/src/llvm/build_str.rs @@ -1,12 +1,12 @@ use crate::llvm::bitcode::{call_bitcode_fn, call_void_bitcode_fn}; -use crate::llvm::build::{complex_bitcast, Env, InPlace, Scope}; +use crate::llvm::build::{complex_bitcast, Env, Scope}; use crate::llvm::build_list::{allocate_list, call_bitcode_fn_returns_list, store_list}; use inkwell::builder::Builder; use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue}; use inkwell::AddressSpace; use roc_builtins::bitcode; use roc_module::symbol::Symbol; -use roc_mono::layout::{Builtin, Layout}; +use roc_mono::layout::{Builtin, InPlace, Layout}; use super::build::load_symbol; diff --git a/compiler/mono/src/layout.rs b/compiler/mono/src/layout.rs index d21ff72f0d..37f8669418 100644 --- a/compiler/mono/src/layout.rs +++ b/compiler/mono/src/layout.rs @@ -16,6 +16,13 @@ const GENERATE_NULLABLE: bool = true; const DEFAULT_NUM_BUILTIN: Builtin<'_> = Builtin::Int64; pub const TAG_SIZE: Builtin<'_> = Builtin::Int64; +#[derive(Copy, Clone)] +#[repr(u8)] +pub enum InPlace { + InPlace, + Clone, +} + #[derive(Debug, Clone)] pub enum LayoutProblem { UnresolvedTypeVar(Variable), @@ -39,6 +46,22 @@ pub enum Layout<'a> { Pointer(&'a Layout<'a>), } +impl<'a> Layout<'a> { + pub fn in_place(&self) -> InPlace { + match self { + Layout::Builtin(Builtin::EmptyList) => InPlace::InPlace, + Layout::Builtin(Builtin::List(memory_mode, _)) => match memory_mode { + MemoryMode::Unique => InPlace::InPlace, + MemoryMode::Refcounted => InPlace::Clone, + }, + Layout::Builtin(Builtin::EmptyStr) => InPlace::InPlace, + Layout::Builtin(Builtin::Str) => InPlace::Clone, + Layout::Builtin(Builtin::Int1) => InPlace::Clone, + _ => unreachable!("Layout {:?} does not have an inplace", self), + } + } +} + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum UnionLayout<'a> { /// A non-recursive tag union