This commit is contained in:
Folkert 2021-11-21 14:11:18 +01:00
parent 96498d667e
commit dc44eaac97
10 changed files with 57 additions and 111 deletions

View file

@ -23,7 +23,7 @@ use crate::llvm::build_str::{
use crate::llvm::compare::{generic_eq, generic_neq};
use crate::llvm::convert::{
self, basic_type_from_builtin, basic_type_from_layout, basic_type_from_layout_1,
block_of_memory_slices, ptr_int,
block_of_memory_slices,
};
use crate::llvm::refcounting::{
build_reset, decrement_refcount_layout, increment_refcount_layout, PointerToRefcount,
@ -190,7 +190,18 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
/// on 64-bit systems, this is i64
/// on 32-bit systems, this is i32
pub fn ptr_int(&self) -> IntType<'ctx> {
ptr_int(self.context, self.ptr_bytes)
let ctx = self.context;
match self.ptr_bytes {
1 => ctx.i8_type(),
2 => ctx.i16_type(),
4 => ctx.i32_type(),
8 => ctx.i64_type(),
_ => panic!(
"Invalid target: Roc does't support compiling to {}-bit systems.",
self.ptr_bytes * 8
),
}
}
/// The integer type representing a RocList or RocStr when following the C ABI
@ -2137,7 +2148,6 @@ pub fn allocate_with_refcount_help<'a, 'ctx, 'env>(
initial_refcount: IntValue<'ctx>,
) -> PointerValue<'ctx> {
let builder = env.builder;
let ctx = env.context;
let len_type = env.ptr_int();
@ -2156,7 +2166,7 @@ pub fn allocate_with_refcount_help<'a, 'ctx, 'env>(
// We must return a pointer to the first element:
let data_ptr = {
let int_type = ptr_int(ctx, env.ptr_bytes);
let int_type = env.ptr_int();
let as_usize_ptr = builder
.build_bitcast(
ptr,
@ -5297,7 +5307,15 @@ fn run_low_level<'a, 'ctx, 'env>(
// Str.fromInt : Int -> Str
debug_assert_eq!(args.len(), 1);
str_from_int(env, scope, args[0])
let (int, int_layout) = load_symbol_and_layout(scope, &args[0]);
let int = int.into_int_value();
let int_width = match int_layout {
Layout::Builtin(Builtin::Int(int_width)) => *int_width,
_ => unreachable!(),
};
str_from_int(env, int, int_width)
}
StrFromFloat => {
// Str.fromFloat : Float * -> Str
@ -5439,12 +5457,12 @@ fn run_low_level<'a, 'ctx, 'env>(
let (low, low_layout) = load_symbol_and_layout(scope, &args[0]);
let high = load_symbol(scope, &args[1]);
let builtin = match low_layout {
Layout::Builtin(builtin) => builtin,
let int_width = match low_layout {
Layout::Builtin(Builtin::Int(int_width)) => *int_width,
_ => unreachable!(),
};
list_range(env, *builtin, low.into_int_value(), high.into_int_value())
list_range(env, int_width, low.into_int_value(), high.into_int_value())
}
ListAppend => {
// List.append : List elem, elem -> List elem
@ -5553,9 +5571,8 @@ fn run_low_level<'a, 'ctx, 'env>(
use roc_mono::layout::Builtin::*;
match arg_builtin {
Int(_) => {
let int_width = intwidth_from_builtin(*arg_builtin, env.ptr_bytes);
let int_type = convert::int_type_from_int_width(env, int_width);
Int(int_width) => {
let int_type = convert::int_type_from_int_width(env, *int_width);
build_int_unary_op(env, arg.into_int_value(), int_type, op)
}
Float(float_width) => {
@ -5715,7 +5732,7 @@ fn run_low_level<'a, 'ctx, 'env>(
let (rhs_arg, rhs_layout) = load_symbol_and_layout(scope, &args[1]);
debug_assert_eq!(lhs_layout, rhs_layout);
let int_width = intwidth_from_layout(*lhs_layout, env.ptr_bytes);
let int_width = intwidth_from_layout(*lhs_layout);
build_int_binop(
env,
@ -5733,7 +5750,7 @@ fn run_low_level<'a, 'ctx, 'env>(
let (rhs_arg, rhs_layout) = load_symbol_and_layout(scope, &args[1]);
debug_assert_eq!(lhs_layout, rhs_layout);
let int_width = intwidth_from_layout(*lhs_layout, env.ptr_bytes);
let int_width = intwidth_from_layout(*lhs_layout);
build_int_binop(
env,
@ -6324,23 +6341,10 @@ fn throw_on_overflow<'a, 'ctx, 'env>(
.unwrap()
}
pub fn intwidth_from_builtin(builtin: Builtin<'_>, ptr_bytes: u32) -> IntWidth {
use IntWidth::*;
match builtin {
Builtin::Int(int_width) => int_width,
Builtin::Usize => match ptr_bytes {
4 => I32,
8 => I64,
_ => unreachable!(),
},
_ => unreachable!(),
}
}
fn intwidth_from_layout(layout: Layout<'_>, ptr_bytes: u32) -> IntWidth {
fn intwidth_from_layout(layout: Layout<'_>) -> IntWidth {
match layout {
Layout::Builtin(builtin) => intwidth_from_builtin(builtin, ptr_bytes),
Layout::Builtin(Builtin::Int(int_width)) => int_width,
_ => unreachable!(),
}
}
@ -6541,17 +6545,6 @@ pub fn build_num_binop<'a, 'ctx, 'env>(
};
match lhs_builtin {
Usize => {
let int_width = intwidth_from_builtin(*lhs_builtin, env.ptr_bytes);
build_int_binop(
env,
parent,
int_width,
lhs_arg.into_int_value(),
rhs_arg.into_int_value(),
op,
)
}
Int(int_width) => build_int_binop(
env,
parent,

View file

@ -14,7 +14,7 @@ use inkwell::types::{BasicType, BasicTypeEnum, PointerType};
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue};
use inkwell::{AddressSpace, IntPredicate};
use morphic_lib::UpdateMode;
use roc_builtins::bitcode;
use roc_builtins::bitcode::{self, IntWidth};
use roc_mono::layout::{Builtin, Layout, LayoutIds};
use super::build::{load_roc_value, store_roc_value};
@ -514,7 +514,7 @@ pub fn list_walk_generic<'a, 'ctx, 'env>(
/// List.range : Int a, Int a -> List (Int a)
pub fn list_range<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
builtin: Builtin<'a>,
int_width: IntWidth,
low: IntValue<'ctx>,
high: IntValue<'ctx>,
) -> BasicValueEnum<'ctx> {
@ -529,10 +529,7 @@ pub fn list_range<'a, 'ctx, 'env>(
let int_width = env
.context
.i8_type()
.const_int(
crate::llvm::build::intwidth_from_builtin(builtin, env.ptr_bytes) as u64,
false,
)
.const_int(int_width as u64, false)
.into();
call_bitcode_fn(

View file

@ -7,11 +7,11 @@ use inkwell::builder::Builder;
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue};
use inkwell::AddressSpace;
use morphic_lib::UpdateMode;
use roc_builtins::bitcode;
use roc_builtins::bitcode::{self, IntWidth};
use roc_module::symbol::Symbol;
use roc_mono::layout::{Builtin, Layout};
use super::build::{intwidth_from_builtin, load_symbol, load_symbol_and_layout};
use super::build::load_symbol;
pub static CHAR_LAYOUT: Layout = Layout::u8();
@ -282,32 +282,10 @@ pub fn str_trim_right<'a, 'ctx, 'env>(
/// Str.fromInt : Int -> Str
pub fn str_from_int<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
scope: &Scope<'a, 'ctx>,
int_symbol: Symbol,
value: IntValue<'ctx>,
int_width: IntWidth,
) -> BasicValueEnum<'ctx> {
let (int, int_layout) = load_symbol_and_layout(scope, &int_symbol);
match int_layout {
Layout::Builtin(builtin) => match builtin {
Builtin::Int(_) => {
let intwidth = intwidth_from_builtin(*builtin, env.ptr_bytes);
call_bitcode_fn(env, &[int], &bitcode::STR_FROM_INT[intwidth])
}
_ => {
unreachable!(
"Compiler bug: tried to convert numeric on invalid builtin layout: ({:?})",
int_layout
);
}
},
_ => {
unreachable!(
"Compiler bug: tried to convert numeric on invalid layout: {:?}",
int_layout
);
}
}
call_bitcode_fn(env, &[value.into()], &bitcode::STR_FROM_INT[int_width])
}
/// Str.toUtf8 : Str -> List U8

View file

@ -144,13 +144,11 @@ pub fn basic_type_from_builtin<'a, 'ctx, 'env>(
use Builtin::*;
let context = env.context;
let ptr_bytes = env.ptr_bytes;
match builtin {
Int(int_width) => int_type_from_int_width(env, *int_width).as_basic_type_enum(),
Float(float_width) => float_type_from_float_width(env, *float_width).as_basic_type_enum(),
Bool => context.bool_type().as_basic_type_enum(),
Usize => ptr_int(context, ptr_bytes).as_basic_type_enum(),
Decimal => context.i128_type().as_basic_type_enum(),
Dict(_, _) | EmptyDict => zig_dict_type(env).into(),
Set(_) | EmptySet => zig_dict_type(env).into(),
@ -264,19 +262,6 @@ fn block_of_memory_help(context: &Context, union_size: u32) -> BasicTypeEnum<'_>
}
}
pub fn ptr_int(ctx: &Context, ptr_bytes: u32) -> IntType<'_> {
match ptr_bytes {
1 => ctx.i8_type(),
2 => ctx.i16_type(),
4 => ctx.i32_type(),
8 => ctx.i64_type(),
_ => panic!(
"Invalid target: Roc does't support compiling to {}-bit systems.",
ptr_bytes * 8
),
}
}
/// The int type that the C ABI turns our RocList/RocStr into
pub fn str_list_int(ctx: &Context, ptr_bytes: u32) -> IntType<'_> {
match ptr_bytes {

View file

@ -1,6 +1,5 @@
use crate::llvm::build::Env;
use crate::llvm::build::{add_func, C_CALL_CONV};
use crate::llvm::convert::ptr_int;
use inkwell::module::Linkage;
use inkwell::values::BasicValue;
use inkwell::AddressSpace;
@ -11,9 +10,8 @@ pub fn add_default_roc_externs(env: &Env<'_, '_, '_>) {
let ctx = env.context;
let module = env.module;
let builder = env.builder;
let ptr_bytes = env.ptr_bytes;
let usize_type = ptr_int(ctx, ptr_bytes);
let usize_type = env.ptr_int();
let i8_ptr_type = ctx.i8_type().ptr_type(AddressSpace::Generic);
// roc_alloc

View file

@ -5,7 +5,7 @@ use crate::llvm::build::{
FAST_CALL_CONV, TAG_DATA_INDEX, TAG_ID_INDEX,
};
use crate::llvm::build_list::{incrementing_elem_loop, list_len, load_list};
use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_1, ptr_int};
use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_1};
use bumpalo::collections::Vec;
use inkwell::basic_block::BasicBlock;
use inkwell::context::Context;
@ -46,7 +46,7 @@ impl<'ctx> PointerToRefcount<'ctx> {
/// alignment works out that way.
pub unsafe fn from_ptr<'a, 'env>(env: &Env<'a, 'ctx, 'env>, ptr: PointerValue<'ctx>) -> Self {
// must make sure it's a pointer to usize
let refcount_type = ptr_int(env.context, env.ptr_bytes);
let refcount_type = env.ptr_int();
let value = env
.builder
@ -66,7 +66,7 @@ impl<'ctx> PointerToRefcount<'ctx> {
) -> Self {
let builder = env.builder;
// pointer to usize
let refcount_type = ptr_int(env.context, env.ptr_bytes);
let refcount_type = env.ptr_int();
let refcount_ptr_type = refcount_type.ptr_type(AddressSpace::Generic);
let ptr_as_usize_ptr = builder
@ -127,7 +127,7 @@ impl<'ctx> PointerToRefcount<'ctx> {
fn increment<'a, 'env>(&self, amount: IntValue<'ctx>, env: &Env<'a, 'ctx, 'env>) {
let refcount = self.get_refcount(env);
let builder = env.builder;
let refcount_type = ptr_int(env.context, env.ptr_bytes);
let refcount_type = env.ptr_int();
let is_static_allocation = builder.build_int_compare(
IntPredicate::EQ,
@ -857,7 +857,7 @@ fn modify_refcount_str_help<'a, 'ctx, 'env>(
let is_big_and_non_empty = builder.build_int_compare(
IntPredicate::SGT,
len,
ptr_int(ctx, env.ptr_bytes).const_zero(),
env.ptr_int().const_zero(),
"is_big_str",
);
@ -979,7 +979,7 @@ fn modify_refcount_dict_help<'a, 'ctx, 'env>(
let is_non_empty = builder.build_int_compare(
IntPredicate::SGT,
len,
ptr_int(ctx, env.ptr_bytes).const_zero(),
env.ptr_int().const_zero(),
"is_non_empty",
);
@ -1027,7 +1027,7 @@ fn build_header<'a, 'ctx, 'env>(
env,
fn_name,
env.context.void_type().into(),
&[arg_type, ptr_int(env.context, env.ptr_bytes).into()],
&[arg_type, env.ptr_int().into()],
),
Mode::Dec => build_header_help(env, fn_name, env.context.void_type().into(), &[arg_type]),
}