mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 04:08:19 +00:00
Merge remote-tracking branch 'origin/main' into upgrade-llvm-zig
This commit is contained in:
commit
0a573ca557
818 changed files with 15185 additions and 4951 deletions
|
@ -12,8 +12,8 @@ use crate::llvm::refcounting::{
|
|||
use inkwell::attributes::{Attribute, AttributeLoc};
|
||||
use inkwell::types::{BasicType, BasicTypeEnum, StructType};
|
||||
use inkwell::values::{
|
||||
BasicValueEnum, CallSiteValue, FunctionValue, InstructionValue, IntValue, PointerValue,
|
||||
StructValue,
|
||||
BasicMetadataValueEnum, BasicValue, BasicValueEnum, CallSiteValue, FunctionValue,
|
||||
InstructionValue, IntValue, PointerValue, StructValue,
|
||||
};
|
||||
use inkwell::AddressSpace;
|
||||
use roc_error_macros::internal_error;
|
||||
|
@ -47,6 +47,28 @@ pub fn call_bitcode_fn<'ctx>(
|
|||
.build_bit_cast(ret, env.context.i128_type(), "return_i128")
|
||||
.unwrap();
|
||||
}
|
||||
} else if env.target == roc_target::Target::MacArm64 {
|
||||
// Essentially the same happens on macos arm64, but with array type [2xi64].
|
||||
let i64_type = env.context.i64_type();
|
||||
let arr_type = i64_type.array_type(2);
|
||||
if ret.get_type() == arr_type.into() {
|
||||
let alloca = env
|
||||
.builder
|
||||
.build_array_alloca(i64_type, i64_type.const_int(2, false), "dec_alloca")
|
||||
.unwrap_or_else(|err| internal_error!("failed to build array alloca: {err}"));
|
||||
let instruction = alloca.as_instruction_value().unwrap_or_else(|| {
|
||||
internal_error!("failed to convert pointer to instruction value ({alloca:?})");
|
||||
});
|
||||
instruction.set_alignment(16).unwrap_or_else(|err| {
|
||||
internal_error!(
|
||||
"failed to set 16-byte alignment on instruction ({instruction:?}): {err}"
|
||||
);
|
||||
});
|
||||
env.builder.new_build_store(alloca, ret);
|
||||
return env
|
||||
.builder
|
||||
.new_build_load(env.context.i128_type(), alloca, "return_i128");
|
||||
}
|
||||
}
|
||||
|
||||
ret
|
||||
|
@ -696,13 +718,18 @@ pub fn build_compare_wrapper<'a, 'ctx>(
|
|||
"load_opaque",
|
||||
);
|
||||
|
||||
let closure_data =
|
||||
env.builder
|
||||
.new_build_load(closure_type, closure_cast, "load_opaque");
|
||||
let closure_data: BasicMetadataValueEnum =
|
||||
if layout_interner.is_passed_by_reference(closure_data_repr) {
|
||||
closure_cast.into()
|
||||
} else {
|
||||
env.builder
|
||||
.new_build_load(closure_type, closure_cast, "load_opaque")
|
||||
.into()
|
||||
};
|
||||
|
||||
env.arena
|
||||
.alloc([value1.into(), value2.into(), closure_data.into()])
|
||||
as &[_]
|
||||
.alloc([value1.into(), value2.into(), closure_data])
|
||||
as &[BasicMetadataValueEnum]
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -685,7 +685,7 @@ macro_rules! debug_info_init {
|
|||
pub enum LlvmBackendMode {
|
||||
/// Assumes primitives (roc_alloc, roc_panic, etc) are provided by the host
|
||||
Binary,
|
||||
BinaryDev,
|
||||
BinaryWithExpect,
|
||||
/// Creates a test wrapper around the main roc function to catch and report panics.
|
||||
/// Provides a testing implementation of primitives (roc_alloc, roc_panic, etc)
|
||||
BinaryGlue,
|
||||
|
@ -698,7 +698,7 @@ impl LlvmBackendMode {
|
|||
pub(crate) fn has_host(self) -> bool {
|
||||
match self {
|
||||
LlvmBackendMode::Binary => true,
|
||||
LlvmBackendMode::BinaryDev => true,
|
||||
LlvmBackendMode::BinaryWithExpect => true,
|
||||
LlvmBackendMode::BinaryGlue => false,
|
||||
LlvmBackendMode::GenTest => false,
|
||||
LlvmBackendMode::WasmGenTest => true,
|
||||
|
@ -710,7 +710,7 @@ impl LlvmBackendMode {
|
|||
fn returns_roc_result(self) -> bool {
|
||||
match self {
|
||||
LlvmBackendMode::Binary => false,
|
||||
LlvmBackendMode::BinaryDev => false,
|
||||
LlvmBackendMode::BinaryWithExpect => false,
|
||||
LlvmBackendMode::BinaryGlue => true,
|
||||
LlvmBackendMode::GenTest => true,
|
||||
LlvmBackendMode::WasmGenTest => true,
|
||||
|
@ -721,7 +721,7 @@ impl LlvmBackendMode {
|
|||
pub(crate) fn runs_expects(self) -> bool {
|
||||
match self {
|
||||
LlvmBackendMode::Binary => false,
|
||||
LlvmBackendMode::BinaryDev => true,
|
||||
LlvmBackendMode::BinaryWithExpect => true,
|
||||
LlvmBackendMode::BinaryGlue => false,
|
||||
LlvmBackendMode::GenTest => false,
|
||||
LlvmBackendMode::WasmGenTest => false,
|
||||
|
@ -3470,12 +3470,10 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
|
|||
variable: _,
|
||||
remainder,
|
||||
} => {
|
||||
if env.mode.runs_expects() {
|
||||
let location = build_string_literal(env, source_location);
|
||||
let source = build_string_literal(env, source);
|
||||
let message = scope.load_symbol(symbol);
|
||||
env.call_dbg(env, location, source, message);
|
||||
}
|
||||
let location = build_string_literal(env, source_location);
|
||||
let source = build_string_literal(env, source);
|
||||
let message = scope.load_symbol(symbol);
|
||||
env.call_dbg(env, location, source, message);
|
||||
|
||||
build_exp_stmt(
|
||||
env,
|
||||
|
@ -3531,7 +3529,7 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
|
|||
variables,
|
||||
);
|
||||
|
||||
if let LlvmBackendMode::BinaryDev = env.mode {
|
||||
if let LlvmBackendMode::BinaryWithExpect = env.mode {
|
||||
crate::llvm::expect::notify_parent_expect(env, &shared_memory);
|
||||
}
|
||||
|
||||
|
@ -4809,7 +4807,9 @@ fn expose_function_to_host_help_c_abi<'a, 'ctx>(
|
|||
)
|
||||
}
|
||||
|
||||
LlvmBackendMode::Binary | LlvmBackendMode::BinaryDev | LlvmBackendMode::BinaryGlue => {}
|
||||
LlvmBackendMode::Binary
|
||||
| LlvmBackendMode::BinaryWithExpect
|
||||
| LlvmBackendMode::BinaryGlue => {}
|
||||
}
|
||||
|
||||
// a generic version that writes the result into a passed *u8 pointer
|
||||
|
@ -4862,13 +4862,13 @@ fn expose_function_to_host_help_c_abi<'a, 'ctx>(
|
|||
roc_call_result_type(env, roc_function.get_type().get_return_type().unwrap()).into()
|
||||
}
|
||||
|
||||
LlvmBackendMode::Binary | LlvmBackendMode::BinaryDev | LlvmBackendMode::BinaryGlue => {
|
||||
basic_type_from_layout(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_interner.get_repr(return_layout),
|
||||
)
|
||||
}
|
||||
LlvmBackendMode::Binary
|
||||
| LlvmBackendMode::BinaryWithExpect
|
||||
| LlvmBackendMode::BinaryGlue => basic_type_from_layout(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_interner.get_repr(return_layout),
|
||||
),
|
||||
};
|
||||
|
||||
let size: BasicValueEnum = return_type.size_of().unwrap().into();
|
||||
|
@ -5657,7 +5657,7 @@ fn build_procedures_help<'a>(
|
|||
use LlvmBackendMode::*;
|
||||
match env.mode {
|
||||
GenTest | WasmGenTest | CliTest => { /* no host, or exposing types is not supported */ }
|
||||
Binary | BinaryDev | BinaryGlue => {
|
||||
Binary | BinaryWithExpect | BinaryGlue => {
|
||||
for (proc_name, alias_name, hels) in host_exposed_lambda_sets.iter() {
|
||||
let ident_string = proc_name.name().as_unsuffixed_str(&env.interns);
|
||||
let fn_name: String = format!("{}_{}", ident_string, hels.id.0);
|
||||
|
|
|
@ -29,7 +29,7 @@ pub(crate) struct SharedMemoryPointer<'ctx>(PointerValue<'ctx>);
|
|||
|
||||
impl<'ctx> SharedMemoryPointer<'ctx> {
|
||||
pub(crate) fn get<'a, 'env>(env: &Env<'a, 'ctx, 'env>) -> Self {
|
||||
let start_function = if let LlvmBackendMode::BinaryDev = env.mode {
|
||||
let start_function = if let LlvmBackendMode::BinaryWithExpect = env.mode {
|
||||
bitcode::UTILS_EXPECT_FAILED_START_SHARED_FILE
|
||||
} else {
|
||||
bitcode::UTILS_EXPECT_FAILED_START_SHARED_BUFFER
|
||||
|
|
|
@ -1137,15 +1137,37 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
)
|
||||
}
|
||||
NumIntCast => {
|
||||
arguments!(arg);
|
||||
arguments_with_layouts!((arg, arg_layout));
|
||||
|
||||
let to = basic_type_from_layout(env, layout_interner, layout_interner.get_repr(layout))
|
||||
.into_int_type();
|
||||
let to_signed = intwidth_from_layout(layout).is_signed();
|
||||
let from_signed = intwidth_from_layout(arg_layout).is_signed();
|
||||
let extend = intwidth_from_layout(layout).stack_size()
|
||||
> intwidth_from_layout(arg_layout).stack_size();
|
||||
//Examples given with sizes of 32, 16, and 8
|
||||
let result = match (from_signed, to_signed, extend) {
|
||||
//I16 -> I32
|
||||
(true, true, true) => {
|
||||
env.builder
|
||||
.build_int_s_extend(arg.into_int_value(), to, "inc_cast")
|
||||
}
|
||||
//U16 -> X32
|
||||
(false, _, true) => {
|
||||
env.builder
|
||||
.build_int_z_extend(arg.into_int_value(), to, "inc_cast")
|
||||
},
|
||||
//I16 -> U32
|
||||
(true,false,true)
|
||||
//Any case where it is not an extension, also perhaps warn here?
|
||||
| (_, _, false) => {
|
||||
Ok(env.builder
|
||||
.new_build_int_cast_sign_flag(arg.into_int_value(), to, to_signed, "inc_cast"))
|
||||
}
|
||||
};
|
||||
|
||||
env.builder
|
||||
.new_build_int_cast_sign_flag(arg.into_int_value(), to, to_signed, "inc_cast")
|
||||
.into()
|
||||
let Ok(value) = result else { todo!() };
|
||||
value.into()
|
||||
}
|
||||
NumToFloatCast => {
|
||||
arguments_with_layouts!((arg, arg_layout));
|
||||
|
@ -1748,7 +1770,7 @@ fn build_float_binop<'ctx>(
|
|||
};
|
||||
|
||||
match op {
|
||||
NumAdd => bd.new_build_float_add(lhs, rhs, "add_float").into(),
|
||||
NumAdd | NumAddSaturated => bd.new_build_float_add(lhs, rhs, "add_float").into(),
|
||||
NumAddChecked => {
|
||||
let context = env.context;
|
||||
|
||||
|
@ -1775,7 +1797,7 @@ fn build_float_binop<'ctx>(
|
|||
struct_value.into()
|
||||
}
|
||||
NumAddWrap => unreachable!("wrapping addition is not defined on floats"),
|
||||
NumSub => bd.new_build_float_sub(lhs, rhs, "sub_float").into(),
|
||||
NumSub | NumSubSaturated => bd.new_build_float_sub(lhs, rhs, "sub_float").into(),
|
||||
NumSubChecked => {
|
||||
let context = env.context;
|
||||
|
||||
|
@ -1802,8 +1824,7 @@ fn build_float_binop<'ctx>(
|
|||
struct_value.into()
|
||||
}
|
||||
NumSubWrap => unreachable!("wrapping subtraction is not defined on floats"),
|
||||
NumMul => bd.new_build_float_mul(lhs, rhs, "mul_float").into(),
|
||||
NumMulSaturated => bd.new_build_float_mul(lhs, rhs, "mul_float").into(),
|
||||
NumMul | NumMulSaturated => bd.new_build_float_mul(lhs, rhs, "mul_float").into(),
|
||||
NumMulChecked => {
|
||||
let context = env.context;
|
||||
|
||||
|
@ -1845,7 +1866,7 @@ fn build_float_binop<'ctx>(
|
|||
&bitcode::NUM_POW[float_width],
|
||||
),
|
||||
_ => {
|
||||
unreachable!("Unrecognized int binary operation: {:?}", op);
|
||||
unreachable!("Unrecognized float binary operation: {:?}", op);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2276,6 +2297,9 @@ fn build_dec_binop<'a, 'ctx>(
|
|||
rhs,
|
||||
"Decimal multiplication overflowed",
|
||||
),
|
||||
NumAddSaturated => dec_binary_op(env, bitcode::DEC_ADD_SATURATED, lhs, rhs),
|
||||
NumSubSaturated => dec_binary_op(env, bitcode::DEC_SUB_SATURATED, lhs, rhs),
|
||||
NumMulSaturated => dec_binary_op(env, bitcode::DEC_MUL_SATURATED, lhs, rhs),
|
||||
NumDivFrac => dec_binop_with_unchecked(env, bitcode::DEC_DIV, lhs, rhs),
|
||||
|
||||
NumLt => call_bitcode_fn(env, &[lhs, rhs], &bitcode::NUM_LESS_THAN[IntWidth::I128]),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue