update rust code to llvm-16 and fix build

also update:
 - llvm frame address
 - erased function type
 - dec passing to zig
 - gen dev storage size
This commit is contained in:
Brendan Hansknecht 2023-09-21 13:12:48 -07:00
parent 2e2e609547
commit 398bf2f96c
No known key found for this signature in database
GPG key ID: 0EA784685083E75B
20 changed files with 1830 additions and 1432 deletions

View file

@ -14,9 +14,7 @@ use bumpalo::collections::Vec;
use inkwell::basic_block::BasicBlock;
use inkwell::module::Linkage;
use inkwell::types::{AnyTypeEnum, BasicMetadataTypeEnum, BasicType, BasicTypeEnum};
use inkwell::values::{
BasicValueEnum, CallableValue, FunctionValue, InstructionValue, IntValue, PointerValue,
};
use inkwell::values::{BasicValueEnum, FunctionValue, InstructionValue, IntValue, PointerValue};
use inkwell::{AddressSpace, IntPredicate};
use roc_module::symbol::Interns;
use roc_module::symbol::Symbol;
@ -43,7 +41,7 @@ impl<'ctx> PointerToRefcount<'ctx> {
// must make sure it's a pointer to usize
let refcount_type = env.ptr_int();
let value = env.builder.build_pointer_cast(
let value = env.builder.new_build_pointer_cast(
ptr,
refcount_type.ptr_type(AddressSpace::default()),
"to_refcount_ptr",
@ -62,7 +60,7 @@ impl<'ctx> PointerToRefcount<'ctx> {
let refcount_ptr_type = refcount_type.ptr_type(AddressSpace::default());
let ptr_as_usize_ptr =
builder.build_pointer_cast(data_ptr, refcount_ptr_type, "as_usize_ptr");
builder.new_build_pointer_cast(data_ptr, refcount_ptr_type, "as_usize_ptr");
// get a pointer to index -1
let index_intvalue = refcount_type.const_int(-1_i64 as u64, false);
@ -92,7 +90,7 @@ impl<'ctx> PointerToRefcount<'ctx> {
};
env.builder
.build_int_compare(IntPredicate::EQ, current, one, "is_one")
.new_build_int_compare(IntPredicate::EQ, current, one, "is_one")
}
fn get_refcount<'a, 'env>(&self, env: &Env<'a, 'ctx, 'env>) -> IntValue<'ctx> {
@ -102,7 +100,7 @@ impl<'ctx> PointerToRefcount<'ctx> {
}
pub fn set_refcount<'a, 'env>(&self, env: &Env<'a, 'ctx, 'env>, refcount: IntValue<'ctx>) {
env.builder.build_store(self.value, refcount);
env.builder.new_build_store(self.value, refcount);
}
fn modify<'a, 'env>(
@ -171,7 +169,7 @@ impl<'ctx> PointerToRefcount<'ctx> {
let call = env
.builder
.build_call(function, &[refcount_ptr.into()], fn_name);
.new_build_call(function, &[refcount_ptr.into()], fn_name);
call.set_call_convention(FAST_CALL_CONV);
}
@ -195,7 +193,7 @@ impl<'ctx> PointerToRefcount<'ctx> {
alignment,
);
builder.build_return(None);
builder.new_build_return(None);
}
pub fn deallocate<'a, 'env>(
@ -216,7 +214,7 @@ fn incref_pointer<'ctx>(
env,
&[
env.builder
.build_pointer_cast(
.new_build_pointer_cast(
pointer,
env.ptr_int().ptr_type(AddressSpace::default()),
"to_isize_ptr",
@ -238,7 +236,7 @@ fn free_pointer<'ctx>(
env,
&[
env.builder
.build_pointer_cast(
.new_build_pointer_cast(
pointer,
env.ptr_int().ptr_type(AddressSpace::default()),
"to_isize_ptr",
@ -256,7 +254,7 @@ fn decref_pointer<'ctx>(env: &Env<'_, 'ctx, '_>, pointer: PointerValue<'ctx>, al
env,
&[
env.builder
.build_pointer_cast(
.new_build_pointer_cast(
pointer,
env.ptr_int().ptr_type(AddressSpace::default()),
"to_isize_ptr",
@ -279,7 +277,7 @@ pub fn decref_pointer_check_null<'ctx>(
env,
&[
env.builder
.build_pointer_cast(
.new_build_pointer_cast(
pointer,
env.context.i8_type().ptr_type(AddressSpace::default()),
"to_i8_ptr",
@ -389,7 +387,7 @@ fn modify_refcount_struct_help<'a, 'ctx>(
}
}
// this function returns void
builder.build_return(None);
builder.new_build_return(None);
}
fn modify_refcount_erased<'a, 'ctx>(
@ -450,33 +448,34 @@ fn modify_refcount_erased_help<'ctx>(
arg_val.set_name(arg_symbol.as_str(&env.interns));
let refcounter = erased::load_refcounter(env, arg_val, mode);
let refcounter_is_null = env.builder.build_is_null(refcounter, "refcounter_unset");
let refcounter_is_null = env
.builder
.new_build_is_null(refcounter, "refcounter_unset");
let call_refcounter_block = ctx.append_basic_block(fn_val, "call_refcounter");
let noop_block = ctx.append_basic_block(fn_val, "noop");
builder.build_conditional_branch(refcounter_is_null, noop_block, call_refcounter_block);
builder.new_build_conditional_branch(refcounter_is_null, noop_block, call_refcounter_block);
{
builder.position_at_end(call_refcounter_block);
let value = erased::load(
env,
arg_val,
ErasedField::Value,
erased::opaque_ptr_type(env),
);
let opaque_ptr_type = erased::opaque_ptr_type(env);
let value = erased::load(env, arg_val, ErasedField::Value, opaque_ptr_type);
builder.build_call(
CallableValue::try_from(refcounter).unwrap(),
builder.new_build_indirect_call(
env.context
.void_type()
.fn_type(&[opaque_ptr_type.into()], false),
refcounter,
&[value.into()],
"call_refcounter",
);
builder.build_return(None);
builder.new_build_return(None);
}
{
builder.position_at_end(noop_block);
builder.build_return(None);
builder.new_build_return(None);
}
}
@ -598,7 +597,7 @@ fn modify_refcount_layout_help<'a, 'ctx>(
let bt = basic_type_from_layout(env, layout_interner, layout_interner.get_repr(layout));
// cast the i64 pointer to a pointer to block of memory
let field_cast = env.builder.build_pointer_cast(
let field_cast = env.builder.new_build_pointer_cast(
value.into_pointer_value(),
bt.into_pointer_type(),
"i64_to_opaque",
@ -627,11 +626,11 @@ fn call_help<'ctx>(
let call = match call_mode {
CallMode::Inc(inc_amount) => {
env.builder
.build_call(function, &[value.into(), inc_amount.into()], "increment")
.new_build_call(function, &[value.into(), inc_amount.into()], "increment")
}
CallMode::Dec => env
.builder
.build_call(function, &[value.into()], "decrement"),
.new_build_call(function, &[value.into()], "decrement"),
};
call.set_call_convention(FAST_CALL_CONV);
@ -816,7 +815,7 @@ fn modify_refcount_list_help<'a, 'ctx>(
// We use the raw capacity to ensure we always decrement the refcount of seamless slices.
let capacity = list_capacity_or_ref_ptr(builder, original_wrapper);
let is_non_empty = builder.build_int_compare(
let is_non_empty = builder.new_build_int_compare(
IntPredicate::UGT,
capacity,
env.ptr_int().const_zero(),
@ -827,7 +826,7 @@ fn modify_refcount_list_help<'a, 'ctx>(
let modification_list_block = ctx.append_basic_block(parent, "modification_list_block");
let cont_block = ctx.append_basic_block(parent, "modify_rc_list_cont");
builder.build_conditional_branch(is_non_empty, modification_list_block, cont_block);
builder.new_build_conditional_branch(is_non_empty, modification_list_block, cont_block);
builder.position_at_end(modification_list_block);
@ -869,12 +868,12 @@ fn modify_refcount_list_help<'a, 'ctx>(
let call_mode = mode_to_call_mode(fn_val, mode);
refcount_ptr.modify(call_mode, layout, env, layout_interner);
builder.build_unconditional_branch(cont_block);
builder.new_build_unconditional_branch(cont_block);
builder.position_at_end(cont_block);
// this function returns void
builder.build_return(None);
builder.new_build_return(None);
}
fn modify_refcount_str<'a, 'ctx>(
@ -958,7 +957,7 @@ fn modify_refcount_str_help<'a, 'ctx>(
// Small strings have 1 as the first bit of capacity, making them negative.
// Thus, to check for big and non empty, just needs a signed len > 0.
let is_big_and_non_empty = builder.build_int_compare(
let is_big_and_non_empty = builder.new_build_int_compare(
IntPredicate::SGT,
capacity,
env.ptr_int().const_zero(),
@ -969,7 +968,7 @@ fn modify_refcount_str_help<'a, 'ctx>(
let cont_block = ctx.append_basic_block(parent, "modify_rc_str_cont");
let modification_block = ctx.append_basic_block(parent, "modify_rc");
builder.build_conditional_branch(is_big_and_non_empty, modification_block, cont_block);
builder.new_build_conditional_branch(is_big_and_non_empty, modification_block, cont_block);
builder.position_at_end(modification_block);
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, str_refcount_ptr(env, arg_val));
@ -981,12 +980,12 @@ fn modify_refcount_str_help<'a, 'ctx>(
layout_interner,
);
builder.build_unconditional_branch(cont_block);
builder.new_build_unconditional_branch(cont_block);
builder.position_at_end(cont_block);
// this function returns void
builder.build_return(None);
builder.new_build_return(None);
}
/// Build an increment or decrement function for a specific layout
@ -1169,19 +1168,20 @@ fn build_rec_union_help<'a, 'ctx>(
let ctx = env.context;
if union_layout.is_nullable() {
let is_null = env.builder.build_is_null(value_ptr, "is_null");
let is_null = env.builder.new_build_is_null(value_ptr, "is_null");
let then_block = ctx.append_basic_block(parent, "then");
env.builder
.build_conditional_branch(is_null, then_block, should_recurse_block);
.new_build_conditional_branch(is_null, then_block, should_recurse_block);
{
env.builder.position_at_end(then_block);
env.builder.build_return(None);
env.builder.new_build_return(None);
}
} else {
env.builder.build_unconditional_branch(should_recurse_block);
env.builder
.new_build_unconditional_branch(should_recurse_block);
}
env.builder.position_at_end(should_recurse_block);
@ -1196,14 +1196,14 @@ fn build_rec_union_help<'a, 'ctx>(
Mode::Inc => {
// inc is cheap; we never recurse
refcount_ptr.modify(call_mode, layout, env, layout_interner);
env.builder.build_return(None);
env.builder.new_build_return(None);
}
Mode::Dec => {
let do_recurse_block = env.context.append_basic_block(parent, "do_recurse");
let no_recurse_block = env.context.append_basic_block(parent, "no_recurse");
builder.build_conditional_branch(
builder.new_build_conditional_branch(
refcount_ptr.is_1(env),
do_recurse_block,
no_recurse_block,
@ -1213,7 +1213,7 @@ fn build_rec_union_help<'a, 'ctx>(
env.builder.position_at_end(no_recurse_block);
refcount_ptr.modify(call_mode, layout, env, layout_interner);
env.builder.build_return(None);
env.builder.new_build_return(None);
}
{
@ -1304,7 +1304,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
let wrapper_type = basic_type_from_layout(env, layout_interner, fields_struct);
// cast the opaque pointer to a pointer of the correct shape
let struct_ptr = env.builder.build_pointer_cast(
let struct_ptr = env.builder.new_build_pointer_cast(
value_ptr,
wrapper_type.ptr_type(AddressSpace::default()),
"opaque_to_correct_recursive_decrement",
@ -1318,15 +1318,12 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
for (i, field_layout) in field_layouts.iter().enumerate() {
if let LayoutRepr::RecursivePointer(_) = layout_interner.get_repr(*field_layout) {
// this field has type `*i64`, but is really a pointer to the data we want
let elem_pointer = env
.builder
.new_build_struct_gep(
wrapper_type.into_struct_type(),
struct_ptr,
i as u32,
"gep_recursive_pointer",
)
.unwrap();
let elem_pointer = env.builder.new_build_struct_gep(
wrapper_type.into_struct_type(),
struct_ptr,
i as u32,
"gep_recursive_pointer",
);
let ptr_as_i64_ptr = env.builder.new_build_load(
env.context.i64_type().ptr_type(AddressSpace::default()),
@ -1343,15 +1340,12 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
deferred_rec.push(recursive_field_ptr);
} else if layout_interner.contains_refcounted(*field_layout) {
let elem_pointer = env
.builder
.new_build_struct_gep(
wrapper_type.into_struct_type(),
struct_ptr,
i as u32,
"gep_recursive_pointer",
)
.unwrap();
let elem_pointer = env.builder.new_build_struct_gep(
wrapper_type.into_struct_type(),
struct_ptr,
i as u32,
"gep_recursive_pointer",
);
let field = load_roc_value(
env,
@ -1398,7 +1392,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
}
// this function returns void
builder.build_return(None);
builder.new_build_return(None);
cases.push((tag_id_int_type.const_int(tag_id as u64, false), block));
}
@ -1415,18 +1409,18 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
if cases.is_empty() {
// The only other layout doesn't need refcounting. Pass through.
builder.build_return(None);
builder.new_build_return(None);
} else {
// in this case, don't switch, because the `else` branch below would try to read the (nonexistent) tag id
let (_, only_branch) = cases.pop().unwrap();
env.builder.build_unconditional_branch(only_branch);
env.builder.new_build_unconditional_branch(only_branch);
}
} else {
let default_block = env.context.append_basic_block(parent, "switch_default");
// switch on it
env.builder
.build_switch(current_tag_id, default_block, &cases);
.new_build_switch(current_tag_id, default_block, &cases);
{
env.builder.position_at_end(default_block);
@ -1439,7 +1433,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
}
// this function returns void
builder.build_return(None);
builder.new_build_return(None);
}
}
@ -1572,19 +1566,20 @@ fn build_reuse_rec_union_help<'a, 'ctx>(
let ctx = env.context;
if union_layout.is_nullable() {
let is_null = env.builder.build_is_null(value_ptr, "is_null");
let is_null = env.builder.new_build_is_null(value_ptr, "is_null");
let then_block = ctx.append_basic_block(parent, "then");
env.builder
.build_conditional_branch(is_null, then_block, should_recurse_block);
.new_build_conditional_branch(is_null, then_block, should_recurse_block);
{
env.builder.position_at_end(then_block);
env.builder.build_return(None);
env.builder.new_build_return(None);
}
} else {
env.builder.build_unconditional_branch(should_recurse_block);
env.builder
.new_build_unconditional_branch(should_recurse_block);
}
env.builder.position_at_end(should_recurse_block);
@ -1594,13 +1589,17 @@ fn build_reuse_rec_union_help<'a, 'ctx>(
let do_recurse_block = env.context.append_basic_block(parent, "do_recurse");
let no_recurse_block = env.context.append_basic_block(parent, "no_recurse");
builder.build_conditional_branch(refcount_ptr.is_1(env), do_recurse_block, no_recurse_block);
builder.new_build_conditional_branch(
refcount_ptr.is_1(env),
do_recurse_block,
no_recurse_block,
);
{
env.builder.position_at_end(no_recurse_block);
refcount_ptr.modify(call_mode, layout, env, layout_interner);
env.builder.build_return(None);
env.builder.new_build_return(None);
}
{
@ -1725,15 +1724,12 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
let union_struct_type = basic_type_from_layout(env, layout_interner, layout).into_struct_type();
// read the tag_id
let tag_id_ptr = env
.builder
.new_build_struct_gep(
union_struct_type,
arg_ptr,
RocUnion::TAG_ID_INDEX,
"tag_id_ptr",
)
.unwrap();
let tag_id_ptr = env.builder.new_build_struct_gep(
union_struct_type,
arg_ptr,
RocUnion::TAG_ID_INDEX,
"tag_id_ptr",
);
let tag_id = env
.builder
@ -1750,7 +1746,7 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
let tag_id_u8 =
env.builder
.build_int_cast_sign_flag(tag_id, env.context.i8_type(), false, "tag_id_u8");
.new_build_int_cast_sign_flag(tag_id, env.context.i8_type(), false, "tag_id_u8");
// next, make a jump table for all possible values of the tag_id
let mut cases = Vec::with_capacity_in(tags.len(), env.arena);
@ -1776,17 +1772,14 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
debug_assert!(data_struct_type.is_struct_type());
let data_struct_type = data_struct_type.into_struct_type();
let opaque_tag_data_ptr = env
.builder
.new_build_struct_gep(
union_struct_type,
arg_ptr,
RocUnion::TAG_DATA_INDEX,
"field_ptr",
)
.unwrap();
let opaque_tag_data_ptr = env.builder.new_build_struct_gep(
union_struct_type,
arg_ptr,
RocUnion::TAG_DATA_INDEX,
"field_ptr",
);
let cast_tag_data_pointer = env.builder.build_pointer_cast(
let cast_tag_data_pointer = env.builder.new_build_pointer_cast(
opaque_tag_data_ptr,
data_struct_type.ptr_type(AddressSpace::default()),
"cast_to_concrete_tag",
@ -1797,15 +1790,12 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
layout_interner.get_repr(*field_layout)
{
// This field is a pointer to the recursive pointer.
let field_ptr = env
.builder
.new_build_struct_gep(
data_struct_type,
cast_tag_data_pointer,
i as u32,
"modify_tag_field",
)
.unwrap();
let field_ptr = env.builder.new_build_struct_gep(
data_struct_type,
cast_tag_data_pointer,
i as u32,
"modify_tag_field",
);
// This is the actual pointer to the recursive data.
let field_value = env.builder.new_build_load(
@ -1834,15 +1824,12 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
*field_layout,
)
} else if layout_interner.contains_refcounted(*field_layout) {
let field_ptr = env
.builder
.new_build_struct_gep(
data_struct_type,
cast_tag_data_pointer,
i as u32,
"modify_tag_field",
)
.unwrap();
let field_ptr = env.builder.new_build_struct_gep(
data_struct_type,
cast_tag_data_pointer,
i as u32,
"modify_tag_field",
);
let field_value = if layout_interner.is_passed_by_reference(*field_layout) {
field_ptr.into()
@ -1869,17 +1856,17 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
}
}
env.builder.build_unconditional_branch(merge_block);
env.builder.new_build_unconditional_branch(merge_block);
cases.push((env.context.i8_type().const_int(tag_id as u64, false), block));
}
env.builder.position_at_end(before_block);
env.builder.build_switch(tag_id_u8, merge_block, &cases);
env.builder.new_build_switch(tag_id_u8, merge_block, &cases);
env.builder.position_at_end(merge_block);
// this function returns void
builder.build_return(None);
builder.new_build_return(None);
}