mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
llvm build working
This commit is contained in:
parent
c4ec9aa898
commit
123c963ff1
8 changed files with 237 additions and 162 deletions
|
@ -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::*;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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: ({:?})",
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<'_>]],
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue