llvm build working

This commit is contained in:
Folkert 2021-11-21 00:23:59 +01:00
parent c4ec9aa898
commit 123c963ff1
8 changed files with 237 additions and 162 deletions

View file

@ -78,19 +78,24 @@ impl FloatWidth {
#[repr(u8)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum IntWidth {
U8,
U16,
U32,
U64,
U128,
I8,
I16,
I32,
I64,
I128,
U8 = 0,
U16 = 1,
U32 = 2,
U64 = 3,
U128 = 4,
I8 = 5,
I16 = 6,
I32 = 7,
I64 = 8,
I128 = 9,
}
impl IntWidth {
pub const fn is_signed(&self) -> bool {
use IntWidth::*;
matches!(self, I8 | I16 | I32 | I64 | I128)
}
pub const fn stack_size(&self) -> u32 {
use IntWidth::*;

View file

@ -22,7 +22,7 @@ use crate::llvm::build_str::{
};
use crate::llvm::compare::{generic_eq, generic_neq};
use crate::llvm::convert::{
basic_type_from_builtin, basic_type_from_layout, basic_type_from_layout_1,
self, basic_type_from_builtin, basic_type_from_layout, basic_type_from_layout_1,
block_of_memory_slices, ptr_int,
};
use crate::llvm::refcounting::{
@ -703,32 +703,31 @@ fn promote_to_main_function<'a, 'ctx, 'env>(
(main_fn_name, main_fn)
}
pub fn int_with_precision<'a, 'ctx, 'env>(
fn int_with_precision<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
value: i128,
precision: &Builtin,
int_width: IntWidth,
) -> IntValue<'ctx> {
match precision {
Builtin::Usize => ptr_int(env.context, env.ptr_bytes).const_int(value as u64, false),
Builtin::Int128 => const_i128(env, value),
Builtin::Int64 => env.context.i64_type().const_int(value as u64, false),
Builtin::Int32 => env.context.i32_type().const_int(value as u64, false),
Builtin::Int16 => env.context.i16_type().const_int(value as u64, false),
Builtin::Int8 => env.context.i8_type().const_int(value as u64, false),
Builtin::Bool => env.context.bool_type().const_int(value as u64, false),
_ => panic!("Invalid layout for int literal = {:?}", precision),
use IntWidth::*;
match int_width {
U128 | I128 => const_i128(env, value),
U64 | I64 => env.context.i64_type().const_int(value as u64, false),
U32 | I32 => env.context.i32_type().const_int(value as u64, false),
U16 | I16 => env.context.i16_type().const_int(value as u64, false),
U8 | I8 => env.context.i8_type().const_int(value as u64, false),
}
}
pub fn float_with_precision<'a, 'ctx, 'env>(
fn float_with_precision<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
value: f64,
precision: &Builtin,
float_width: FloatWidth,
) -> BasicValueEnum<'ctx> {
match precision {
Builtin::Float64 => env.context.f64_type().const_float(value).into(),
Builtin::Float32 => env.context.f32_type().const_float(value).into(),
_ => panic!("Invalid layout for float literal = {:?}", precision),
match float_width {
FloatWidth::F64 => env.context.f64_type().const_float(value).into(),
FloatWidth::F32 => env.context.f32_type().const_float(value).into(),
FloatWidth::F128 => todo!("F128 is not implemented"),
}
}
@ -741,12 +740,22 @@ pub fn build_exp_literal<'a, 'ctx, 'env>(
match literal {
Int(int) => match layout {
Layout::Builtin(builtin) => int_with_precision(env, *int as i128, builtin).into(),
Layout::Builtin(Builtin::Bool) => {
env.context.bool_type().const_int(*int as u64, false).into()
}
Layout::Builtin(Builtin::Usize) => ptr_int(env.context, env.ptr_bytes)
.const_int(*int as u64, false)
.into(),
Layout::Builtin(Builtin::Int(int_width)) => {
int_with_precision(env, *int as i128, *int_width).into()
}
_ => panic!("Invalid layout for int literal = {:?}", layout),
},
Float(float) => match layout {
Layout::Builtin(builtin) => float_with_precision(env, *float, builtin),
Layout::Builtin(Builtin::Float(float_width)) => {
float_with_precision(env, *float, *float_width)
}
_ => panic!("Invalid layout for float literal = {:?}", layout),
},
@ -3044,20 +3053,18 @@ fn build_switch_ir<'a, 'ctx, 'env>(
// Build the condition
let cond = match cond_layout {
Layout::Builtin(Builtin::Float64) => {
Layout::Builtin(Builtin::Float(float_width)) => {
// float matches are done on the bit pattern
cond_layout = Layout::Builtin(Builtin::Int64);
cond_layout = Layout::float_width(float_width);
let int_type = match float_width {
FloatWidth::F32 => env.context.i32_type(),
FloatWidth::F64 => env.context.i64_type(),
FloatWidth::F128 => env.context.i128_type(),
};
builder
.build_bitcast(cond_value, env.context.i64_type(), "")
.into_int_value()
}
Layout::Builtin(Builtin::Float32) => {
// float matches are done on the bit pattern
cond_layout = Layout::Builtin(Builtin::Int32);
builder
.build_bitcast(cond_value, env.context.i32_type(), "")
.build_bitcast(cond_value, int_type, "")
.into_int_value()
}
Layout::Union(variant) => {
@ -3433,7 +3440,7 @@ fn expose_function_to_host_help_c_abi_gen_test<'a, 'ctx, 'env>(
call_roc_function(
env,
roc_wrapper_function,
&Layout::Struct(&[Layout::Builtin(Builtin::Int64), return_layout]),
&Layout::Struct(&[Layout::u64(), return_layout]),
arguments_for_call,
)
};
@ -3811,11 +3818,7 @@ fn make_exception_catcher<'a, 'ctx, 'env>(
}
fn roc_result_layout<'a>(arena: &'a Bump, return_layout: Layout<'a>) -> Layout<'a> {
let elements = [
Layout::Builtin(Builtin::Int64),
Layout::Builtin(Builtin::Usize),
return_layout,
];
let elements = [Layout::u64(), Layout::usize(), return_layout];
Layout::Struct(arena.alloc(elements))
}
@ -5553,17 +5556,13 @@ fn run_low_level<'a, 'ctx, 'env>(
use roc_mono::layout::Builtin::*;
match arg_builtin {
Usize | Int128 | Int64 | Int32 | Int16 | Int8 => {
build_int_unary_op(env, arg.into_int_value(), arg_builtin, op)
Usize | Int(_) => {
let int_width = intwidth_from_builtin(*arg_builtin, env.ptr_bytes);
let int_type = convert::int_type_from_int_width(env, int_width);
build_int_unary_op(env, arg.into_int_value(), int_type, op)
}
Float32 => {
build_float_unary_op(env, arg.into_float_value(), op, FloatWidth::F32)
}
Float64 => {
build_float_unary_op(env, arg.into_float_value(), op, FloatWidth::F64)
}
Float128 => {
build_float_unary_op(env, arg.into_float_value(), op, FloatWidth::F128)
Float(float_width) => {
build_float_unary_op(env, arg.into_float_value(), op, *float_width)
}
_ => {
unreachable!("Compiler bug: tried to run numeric operation {:?} on invalid builtin layout: ({:?})", op, arg_layout);
@ -5633,15 +5632,22 @@ fn run_low_level<'a, 'ctx, 'env>(
let tag_lt = env.context.i8_type().const_int(2_u64, false);
match lhs_builtin {
Usize | Int128 | Int64 | Int32 | Int16 | Int8 => {
Int(int_width) => {
let are_equal = env.builder.build_int_compare(
IntPredicate::EQ,
lhs_arg.into_int_value(),
rhs_arg.into_int_value(),
"int_eq",
);
let predicate = if int_width.is_signed() {
IntPredicate::SLT
} else {
IntPredicate::ULT
};
let is_less_than = env.builder.build_int_compare(
IntPredicate::SLT,
predicate,
lhs_arg.into_int_value(),
rhs_arg.into_int_value(),
"int_compare",
@ -5658,7 +5664,32 @@ fn run_low_level<'a, 'ctx, 'env>(
"lt_or_gt",
)
}
Float128 | Float64 | Float32 => {
Usize => {
let are_equal = env.builder.build_int_compare(
IntPredicate::EQ,
lhs_arg.into_int_value(),
rhs_arg.into_int_value(),
"int_eq",
);
let is_less_than = env.builder.build_int_compare(
IntPredicate::ULT,
lhs_arg.into_int_value(),
rhs_arg.into_int_value(),
"int_compare",
);
let step1 =
env.builder
.build_select(is_less_than, tag_lt, tag_gt, "lt_or_gt");
env.builder.build_select(
are_equal,
tag_eq,
step1.into_int_value(),
"lt_or_gt",
)
}
Float(_) => {
let are_equal = env.builder.build_float_compare(
FloatPredicate::OEQ,
lhs_arg.into_float_value(),
@ -5711,13 +5742,15 @@ fn run_low_level<'a, 'ctx, 'env>(
let (lhs_arg, lhs_layout) = load_symbol_and_layout(scope, &args[0]);
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);
build_int_binop(
env,
parent,
int_width,
lhs_arg.into_int_value(),
lhs_layout,
rhs_arg.into_int_value(),
rhs_layout,
op,
)
}
@ -5727,13 +5760,15 @@ fn run_low_level<'a, 'ctx, 'env>(
let (lhs_arg, lhs_layout) = load_symbol_and_layout(scope, &args[0]);
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);
build_int_binop(
env,
parent,
int_width,
lhs_arg.into_int_value(),
lhs_layout,
rhs_arg.into_int_value(),
rhs_layout,
op,
)
}
@ -6096,17 +6131,9 @@ fn to_cc_type_builtin<'a, 'ctx, 'env>(
builtin: &Builtin<'a>,
) -> BasicTypeEnum<'ctx> {
match builtin {
Builtin::Int128
| Builtin::Int64
| Builtin::Int32
| Builtin::Int16
| Builtin::Int8
| Builtin::Bool
| Builtin::Usize
| Builtin::Decimal
| Builtin::Float128
| Builtin::Float64
| Builtin::Float32 => basic_type_from_builtin(env, builtin),
Builtin::Int(_) | Builtin::Float(_) | Builtin::Bool | Builtin::Usize | Builtin::Decimal => {
basic_type_from_builtin(env, builtin)
}
Builtin::Str | Builtin::EmptyStr | Builtin::List(_) | Builtin::EmptyList => {
env.str_list_c_abi().into()
}
@ -6329,11 +6356,7 @@ pub fn intwidth_from_builtin(builtin: Builtin<'_>, ptr_bytes: u32) -> IntWidth {
use IntWidth::*;
match builtin {
Builtin::Int128 => I128,
Builtin::Int64 => I64,
Builtin::Int32 => I32,
Builtin::Int16 => I16,
Builtin::Int8 => I8,
Builtin::Int(int_width) => int_width,
Builtin::Usize => match ptr_bytes {
4 => I32,
8 => I64,
@ -6353,10 +6376,9 @@ fn intwidth_from_layout(layout: Layout<'_>, ptr_bytes: u32) -> IntWidth {
fn build_int_binop<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
parent: FunctionValue<'ctx>,
int_width: IntWidth,
lhs: IntValue<'ctx>,
lhs_layout: &Layout<'a>,
rhs: IntValue<'ctx>,
_rhs_layout: &Layout<'a>,
op: LowLevel,
) -> BasicValueEnum<'ctx> {
use inkwell::IntPredicate::*;
@ -6364,8 +6386,6 @@ fn build_int_binop<'a, 'ctx, 'env>(
let bd = env.builder;
let int_width = intwidth_from_layout(*lhs_layout, env.ptr_bytes);
match op {
NumAdd => {
let result = env
@ -6541,27 +6561,35 @@ pub fn build_num_binop<'a, 'ctx, 'env>(
build_float_binop(
env,
parent,
float_width,
lhs_arg.into_float_value(),
rhs_arg.into_float_value(),
float_width,
op,
)
};
match lhs_builtin {
Usize | Int128 | Int64 | Int32 | Int16 | Int8 => build_int_binop(
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,
*int_width,
lhs_arg.into_int_value(),
lhs_layout,
rhs_arg.into_int_value(),
rhs_layout,
op,
),
Float32 => float_binop(FloatWidth::F32),
Float64 => float_binop(FloatWidth::F64),
Float128 => float_binop(FloatWidth::F128),
Float(float_width) => float_binop(*float_width),
Decimal => {
build_dec_binop(env, parent, lhs_arg, lhs_layout, rhs_arg, rhs_layout, op)
@ -6580,9 +6608,9 @@ pub fn build_num_binop<'a, 'ctx, 'env>(
fn build_float_binop<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
parent: FunctionValue<'ctx>,
float_width: FloatWidth,
lhs: FloatValue<'ctx>,
rhs: FloatValue<'ctx>,
float_width: FloatWidth,
op: LowLevel,
) -> BasicValueEnum<'ctx> {
use inkwell::FloatPredicate::*;
@ -6843,20 +6871,10 @@ fn int_type_signed_min(int_type: IntType) -> IntValue {
}
}
fn builtin_to_int_type<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
builtin: &Builtin<'a>,
) -> IntType<'ctx> {
let result = basic_type_from_builtin(env, builtin);
debug_assert!(result.is_int_type());
result.into_int_type()
}
fn build_int_unary_op<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
arg: IntValue<'ctx>,
arg_layout: &Builtin<'a>,
int_type: IntType<'ctx>,
op: LowLevel,
) -> BasicValueEnum<'ctx> {
use roc_module::low_level::LowLevel::*;
@ -6866,11 +6884,11 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
match op {
NumNeg => {
// integer abs overflows when applied to the minimum value of a signed type
int_neg_raise_on_overflow(env, arg, arg_layout)
int_neg_raise_on_overflow(env, arg, int_type)
}
NumAbs => {
// integer abs overflows when applied to the minimum value of a signed type
int_abs_raise_on_overflow(env, arg, arg_layout)
int_abs_raise_on_overflow(env, arg, int_type)
}
NumToFloat => {
// TODO: Handle different sized numbers
@ -6891,11 +6909,11 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
fn int_neg_raise_on_overflow<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
arg: IntValue<'ctx>,
builtin: &Builtin<'a>,
int_type: IntType<'ctx>,
) -> BasicValueEnum<'ctx> {
let builder = env.builder;
let min_val = int_type_signed_min(builtin_to_int_type(env, builtin));
let min_val = int_type_signed_min(int_type);
let condition = builder.build_int_compare(IntPredicate::EQ, arg, min_val, "is_min_val");
let block = env.builder.get_insert_block().expect("to be in a function");
@ -6921,11 +6939,11 @@ fn int_neg_raise_on_overflow<'a, 'ctx, 'env>(
fn int_abs_raise_on_overflow<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
arg: IntValue<'ctx>,
builtin: &Builtin<'a>,
int_type: IntType<'ctx>,
) -> BasicValueEnum<'ctx> {
let builder = env.builder;
let min_val = int_type_signed_min(builtin_to_int_type(env, builtin));
let min_val = int_type_signed_min(int_type);
let condition = builder.build_int_compare(IntPredicate::EQ, arg, min_val, "is_min_val");
let block = env.builder.get_insert_block().expect("to be in a function");
@ -6945,13 +6963,13 @@ fn int_abs_raise_on_overflow<'a, 'ctx, 'env>(
builder.position_at_end(else_block);
int_abs_with_overflow(env, arg, builtin)
int_abs_with_overflow(env, arg, int_type)
}
fn int_abs_with_overflow<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
arg: IntValue<'ctx>,
arg_layout: &Builtin<'a>,
int_type: IntType<'ctx>,
) -> BasicValueEnum<'ctx> {
// This is how libc's abs() is implemented - it uses no branching!
//
@ -6964,10 +6982,10 @@ fn int_abs_with_overflow<'a, 'ctx, 'env>(
let ctx = env.context;
let shifted_name = "abs_shift_right";
let shifted_alloca = {
let bits_to_shift = ((arg_layout.stack_size(env.ptr_bytes) as u64) * 8) - 1;
let bits_to_shift = int_type.get_bit_width() as u64 - 1;
let shift_val = ctx.i64_type().const_int(bits_to_shift, false);
let shifted = bd.build_right_shift(arg, shift_val, true, shifted_name);
let alloca = bd.build_alloca(basic_type_from_builtin(env, arg_layout), "#int_abs_help");
let alloca = bd.build_alloca(int_type, "#int_abs_help");
// shifted = arg >>> 63
bd.build_store(alloca, shifted);

View file

@ -123,17 +123,7 @@ fn hash_builtin<'a, 'ctx, 'env>(
let ptr_bytes = env.ptr_bytes;
match builtin {
Builtin::Int128
| Builtin::Int64
| Builtin::Int32
| Builtin::Int16
| Builtin::Int8
| Builtin::Bool
| Builtin::Float64
| Builtin::Float32
| Builtin::Float128
| Builtin::Decimal
| Builtin::Usize => {
Builtin::Int(_) | Builtin::Float(_) | Builtin::Bool | Builtin::Decimal | Builtin::Usize => {
let hash_bytes = store_and_use_as_u8_ptr(env, val, layout);
hash_bitcode_fn(env, seed, hash_bytes, layout.stack_size(ptr_bytes))
}

View file

@ -183,7 +183,7 @@ pub fn list_reverse<'a, 'ctx, 'env>(
let element_layout = match *list_layout {
Layout::Builtin(Builtin::EmptyList) => {
// this pointer will never actually be dereferenced
Layout::Builtin(Builtin::Int64)
Layout::i64()
}
Layout::Builtin(Builtin::List(elem_layout)) => *elem_layout,

View file

@ -13,7 +13,7 @@ use roc_mono::layout::{Builtin, Layout};
use super::build::{intwidth_from_builtin, load_symbol, load_symbol_and_layout};
pub static CHAR_LAYOUT: Layout = Layout::Builtin(Builtin::Int8);
pub static CHAR_LAYOUT: Layout = Layout::u8();
/// Str.repeat : Str, Nat -> Str
pub fn str_repeat<'a, 'ctx, 'env>(
@ -289,15 +289,11 @@ pub fn str_from_int<'a, 'ctx, 'env>(
match int_layout {
Layout::Builtin(builtin) => match builtin {
Builtin::Usize
| Builtin::Int128
| Builtin::Int64
| Builtin::Int32
| Builtin::Int16
| Builtin::Int8 => {
Builtin::Usize | 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: ({:?})",

View file

@ -10,6 +10,7 @@ use inkwell::values::{
};
use inkwell::{AddressSpace, FloatPredicate, IntPredicate};
use roc_builtins::bitcode;
use roc_builtins::bitcode::{FloatWidth, IntWidth};
use roc_module::symbol::Symbol;
use roc_mono::layout::{Builtin, Layout, LayoutIds, UnionLayout};
@ -88,19 +89,40 @@ fn build_eq_builtin<'a, 'ctx, 'env>(
};
match builtin {
Builtin::Int128 => int_cmp(IntPredicate::EQ, "eq_i128"),
Builtin::Int64 => int_cmp(IntPredicate::EQ, "eq_i64"),
Builtin::Int32 => int_cmp(IntPredicate::EQ, "eq_i32"),
Builtin::Int16 => int_cmp(IntPredicate::EQ, "eq_i16"),
Builtin::Int8 => int_cmp(IntPredicate::EQ, "eq_i8"),
Builtin::Int(int_width) => {
use IntWidth::*;
let name = match int_width {
I128 => "eq_i128",
I64 => "eq_i64",
I32 => "eq_i32",
I16 => "eq_i16",
I8 => "eq_i8",
U128 => "eq_u128",
U64 => "eq_u64",
U32 => "eq_u32",
U16 => "eq_u16",
U8 => "eq_u8",
};
int_cmp(IntPredicate::EQ, name)
}
Builtin::Float(float_width) => {
use FloatWidth::*;
let name = match float_width {
F128 => "eq_f128",
F64 => "eq_f64",
F32 => "eq_f32",
};
float_cmp(FloatPredicate::OEQ, name)
}
Builtin::Bool => int_cmp(IntPredicate::EQ, "eq_i1"),
Builtin::Usize => int_cmp(IntPredicate::EQ, "eq_usize"),
Builtin::Decimal => call_bitcode_fn(env, &[lhs_val, rhs_val], bitcode::DEC_EQ),
Builtin::Float128 => float_cmp(FloatPredicate::OEQ, "eq_f128"),
Builtin::Float64 => float_cmp(FloatPredicate::OEQ, "eq_f64"),
Builtin::Float32 => float_cmp(FloatPredicate::OEQ, "eq_f32"),
Builtin::Str => str_equal(env, lhs_val, rhs_val),
Builtin::List(elem) => build_list_eq(
@ -231,19 +253,40 @@ fn build_neq_builtin<'a, 'ctx, 'env>(
};
match builtin {
Builtin::Int128 => int_cmp(IntPredicate::NE, "neq_i128"),
Builtin::Int64 => int_cmp(IntPredicate::NE, "neq_i64"),
Builtin::Int32 => int_cmp(IntPredicate::NE, "neq_i32"),
Builtin::Int16 => int_cmp(IntPredicate::NE, "neq_i16"),
Builtin::Int8 => int_cmp(IntPredicate::NE, "neq_i8"),
Builtin::Int(int_width) => {
use IntWidth::*;
let name = match int_width {
I128 => "neq_i128",
I64 => "neq_i64",
I32 => "neq_i32",
I16 => "neq_i16",
I8 => "neq_i8",
U128 => "neq_u128",
U64 => "neq_u64",
U32 => "neq_u32",
U16 => "neq_u16",
U8 => "neq_u8",
};
int_cmp(IntPredicate::NE, name)
}
Builtin::Float(float_width) => {
use FloatWidth::*;
let name = match float_width {
F128 => "neq_f128",
F64 => "neq_f64",
F32 => "neq_f32",
};
float_cmp(FloatPredicate::ONE, name)
}
Builtin::Bool => int_cmp(IntPredicate::NE, "neq_i1"),
Builtin::Usize => int_cmp(IntPredicate::NE, "neq_usize"),
Builtin::Decimal => call_bitcode_fn(env, &[lhs_val, rhs_val], bitcode::DEC_NEQ),
Builtin::Float128 => float_cmp(FloatPredicate::ONE, "neq_f128"),
Builtin::Float64 => float_cmp(FloatPredicate::ONE, "neq_f64"),
Builtin::Float32 => float_cmp(FloatPredicate::ONE, "neq_f32"),
Builtin::Str => {
let is_equal = str_equal(env, lhs_val, rhs_val).into_int_value();

View file

@ -1,7 +1,8 @@
use bumpalo::collections::Vec;
use inkwell::context::Context;
use inkwell::types::{BasicType, BasicTypeEnum, IntType, StructType};
use inkwell::types::{BasicType, BasicTypeEnum, FloatType, IntType, StructType};
use inkwell::AddressSpace;
use roc_builtins::bitcode::{FloatWidth, IntWidth};
use roc_mono::layout::{Builtin, Layout, UnionLayout};
fn basic_type_from_record<'a, 'ctx, 'env>(
@ -146,17 +147,11 @@ pub fn basic_type_from_builtin<'a, 'ctx, 'env>(
let ptr_bytes = env.ptr_bytes;
match builtin {
Int128 => context.i128_type().as_basic_type_enum(),
Int64 => context.i64_type().as_basic_type_enum(),
Int32 => context.i32_type().as_basic_type_enum(),
Int16 => context.i16_type().as_basic_type_enum(),
Int8 => context.i8_type().as_basic_type_enum(),
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(),
Float128 => context.f128_type().as_basic_type_enum(),
Float64 => context.f64_type().as_basic_type_enum(),
Float32 => context.f32_type().as_basic_type_enum(),
Dict(_, _) | EmptyDict => zig_dict_type(env).into(),
Set(_) | EmptySet => zig_dict_type(env).into(),
List(_) | EmptyList => zig_list_type(env).into(),
@ -164,6 +159,34 @@ pub fn basic_type_from_builtin<'a, 'ctx, 'env>(
}
}
pub fn int_type_from_int_width<'a, 'ctx, 'env>(
env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
int_width: IntWidth,
) -> IntType<'ctx> {
use IntWidth::*;
match int_width {
U128 | I128 => env.context.i128_type(),
U64 | I64 => env.context.i64_type(),
U32 | I32 => env.context.i32_type(),
U16 | I16 => env.context.i16_type(),
U8 | I8 => env.context.i8_type(),
}
}
pub fn float_type_from_float_width<'a, 'ctx, 'env>(
env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
float_width: FloatWidth,
) -> FloatType<'ctx> {
use FloatWidth::*;
match float_width {
F128 => todo!("F128 is not implemented"),
F64 => env.context.f64_type(),
F32 => env.context.f32_type(),
}
}
pub fn block_of_memory_slices<'ctx>(
context: &'ctx Context,
layouts: &[&[Layout<'_>]],

View file

@ -1167,7 +1167,7 @@ impl<'a> Layout<'a> {
Layout::Builtin(Builtin::Bool)
}
pub fn u8() -> Layout<'a> {
pub const fn u8() -> Layout<'a> {
Layout::Builtin(Builtin::Int(IntWidth::U8))
}