upgrade build_in_bounds_gep

This commit is contained in:
Folkert 2022-12-19 20:16:55 +01:00
parent bc9c813fec
commit f2d0953e0a
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
5 changed files with 122 additions and 39 deletions

View file

@ -75,6 +75,14 @@ pub(crate) trait BuilderExt<'ctx> {
ptr: PointerValue<'ctx>,
name: &str,
) -> BasicValueEnum<'ctx>;
unsafe fn new_build_in_bounds_gep(
&self,
element_type: impl BasicType<'ctx>,
ptr: PointerValue<'ctx>,
ordered_indexes: &[IntValue<'ctx>],
name: &str,
) -> PointerValue<'ctx>;
}
impl<'ctx> BuilderExt<'ctx> for Builder<'ctx> {
@ -104,6 +112,21 @@ impl<'ctx> BuilderExt<'ctx> for Builder<'ctx> {
);
self.build_load(ptr, name)
}
unsafe fn new_build_in_bounds_gep(
&self,
element_type: impl BasicType<'ctx>,
ptr: PointerValue<'ctx>,
ordered_indexes: &[IntValue<'ctx>],
name: &str,
) -> PointerValue<'ctx> {
assert_eq!(
ptr.get_type().get_element_type(),
element_type.as_any_type_enum()
);
self.build_in_bounds_gep(ptr, ordered_indexes, name)
}
}
#[inline(always)]
@ -2168,8 +2191,12 @@ fn list_literal<'a, 'ctx, 'env>(
let offset = env.ptr_int().const_int(zero_elements as _, false);
let ptr = unsafe {
env.builder
.build_in_bounds_gep(global, &[zero, offset], "first_element_pointer")
env.builder.new_build_in_bounds_gep(
element_type,
global,
&[zero, offset],
"first_element_pointer",
)
};
super::build_list::store_list(env, ptr, list_length_intval).into()
@ -2191,7 +2218,9 @@ fn list_literal<'a, 'ctx, 'env>(
// then replace the `undef`s with the values that we evaluate at runtime
for (index, val) in runtime_evaluated_elements {
let index_val = ctx.i64_type().const_int(index as u64, false);
let elem_ptr = unsafe { builder.build_in_bounds_gep(ptr, &[index_val], "index") };
let elem_ptr = unsafe {
builder.new_build_in_bounds_gep(element_type, ptr, &[index_val], "index")
};
builder.build_store(elem_ptr, val);
}
@ -2210,7 +2239,9 @@ fn list_literal<'a, 'ctx, 'env>(
ListLiteralElement::Symbol(symbol) => load_symbol(scope, symbol),
};
let index_val = ctx.i64_type().const_int(index as u64, false);
let elem_ptr = unsafe { builder.build_in_bounds_gep(ptr, &[index_val], "index") };
let elem_ptr = unsafe {
builder.new_build_in_bounds_gep(element_type, ptr, &[index_val], "index")
};
store_roc_value(env, *element_layout, elem_ptr, val);
}
@ -3901,13 +3932,15 @@ pub fn build_setjmp_call<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValu
// Anywhere else, use the LLVM intrinsic.
// https://llvm.org/docs/ExceptionHandling.html#llvm-eh-sjlj-setjmp
let buf_type = env
.context
.i8_type()
.ptr_type(AddressSpace::Generic)
.array_type(5);
let jmp_buf_i8p_arr = env.builder.build_pointer_cast(
jmp_buf,
env.context
.i8_type()
.ptr_type(AddressSpace::Generic)
.array_type(5)
.ptr_type(AddressSpace::Generic),
buf_type.ptr_type(AddressSpace::Generic),
"jmp_buf [5 x i8*]",
);
@ -3920,7 +3953,8 @@ pub fn build_setjmp_call<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValu
let zero = env.context.i32_type().const_zero();
let fa_index = env.context.i32_type().const_zero();
let fa = unsafe {
env.builder.build_in_bounds_gep(
env.builder.new_build_in_bounds_gep(
buf_type,
jmp_buf_i8p_arr,
&[zero, fa_index],
"frame address index",
@ -3933,8 +3967,12 @@ pub fn build_setjmp_call<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValu
// usage. But for whatever reason, on x86, it appears we need a stacksave in those words.
let ss_index = env.context.i32_type().const_int(2, false);
let ss = unsafe {
env.builder
.build_in_bounds_gep(jmp_buf_i8p_arr, &[zero, ss_index], "name")
env.builder.new_build_in_bounds_gep(
buf_type,
jmp_buf_i8p_arr,
&[zero, ss_index],
"name",
)
};
let stack_save = env.call_intrinsic(LLVM_STACK_SAVE, &[]);
env.builder.build_store(ss, stack_save);
@ -5550,7 +5588,8 @@ fn define_global_str_literal_ptr<'a, 'ctx, 'env>(
// a pointer to the first actual data (skipping over the refcount)
let ptr = unsafe {
env.builder.build_in_bounds_gep(
env.builder.new_build_in_bounds_gep(
env.context.i8_type(),
ptr,
&[env
.ptr_int()

View file

@ -17,6 +17,7 @@ use roc_mono::layout::{Builtin, Layout, LayoutIds};
use super::bitcode::{call_list_bitcode_fn, BitcodeReturns};
use super::build::{
create_entry_block_alloca, load_roc_value, load_symbol, store_roc_value, struct_from_fields,
BuilderExt,
};
use super::convert::zig_list_type;
@ -138,8 +139,14 @@ pub(crate) fn list_get_unsafe<'a, 'ctx, 'env>(
// Assume the bounds have already been checked earlier
// (e.g. by List.get or List.first, which wrap List.#getUnsafe)
let elem_ptr =
unsafe { builder.build_in_bounds_gep(array_data_ptr, &[elem_index], "list_get_element") };
let elem_ptr = unsafe {
builder.new_build_in_bounds_gep(
elem_type,
array_data_ptr,
&[elem_index],
"list_get_element",
)
};
let result = load_roc_value(env, *element_layout, elem_ptr, "list_get_load_element");
@ -608,9 +615,12 @@ where
{
let builder = env.builder;
let element_type = basic_type_from_layout(env, &element_layout);
incrementing_index_loop(env, parent, len, index_name, |index| {
// The pointer to the element in the list
let element_ptr = unsafe { builder.build_in_bounds_gep(ptr, &[index], "load_index") };
let element_ptr =
unsafe { builder.new_build_in_bounds_gep(element_type, ptr, &[index], "load_index") };
let elem = load_roc_value(
env,

View file

@ -15,7 +15,7 @@ use roc_builtins::bitcode::{FloatWidth, IntWidth};
use roc_module::symbol::Symbol;
use roc_mono::layout::{Builtin, Layout, LayoutIds, UnionLayout};
use super::build::{load_roc_value, use_roc_value};
use super::build::{load_roc_value, use_roc_value, BuilderExt};
use super::convert::argument_type_from_union_layout;
use super::lowlevel::dec_binop_with_unchecked;
@ -542,14 +542,16 @@ fn build_list_eq_help<'a, 'ctx, 'env>(
builder.position_at_end(body_bb);
let elem1 = {
let elem_ptr =
unsafe { builder.build_in_bounds_gep(ptr1, &[curr_index], "load_index") };
let elem_ptr = unsafe {
builder.new_build_in_bounds_gep(element_type, ptr1, &[curr_index], "load_index")
};
load_roc_value(env, *element_layout, elem_ptr, "get_elem")
};
let elem2 = {
let elem_ptr =
unsafe { builder.build_in_bounds_gep(ptr2, &[curr_index], "load_index") };
let elem_ptr = unsafe {
builder.new_build_in_bounds_gep(element_type, ptr2, &[curr_index], "load_index")
};
load_roc_value(env, *element_layout, elem_ptr, "get_elem")
};

View file

@ -19,6 +19,7 @@ use super::build::{
add_func, load_roc_value, load_symbol_and_layout, use_roc_value, FunctionSpec, LlvmBackendMode,
Scope, WhenRecursive,
};
use super::convert::struct_type_from_union_layout;
pub(crate) struct SharedMemoryPointer<'ctx>(PointerValue<'ctx>);
@ -54,10 +55,11 @@ struct Cursors<'ctx> {
fn pointer_at_offset<'ctx>(
bd: &Builder<'ctx>,
element_type: impl BasicType<'ctx>,
ptr: PointerValue<'ctx>,
offset: IntValue<'ctx>,
) -> PointerValue<'ctx> {
unsafe { bd.build_gep(ptr, &[offset], "offset_ptr") }
unsafe { bd.new_build_in_bounds_gep(element_type, ptr, &[offset], "offset_ptr") }
}
/// Writes the module and region into the buffer
@ -98,7 +100,7 @@ fn read_state<'a, 'ctx, 'env>(
let ptr = env.builder.build_pointer_cast(ptr, ptr_type, "");
let one = env.ptr_int().const_int(1, false);
let offset_ptr = pointer_at_offset(env.builder, ptr, one);
let offset_ptr = pointer_at_offset(env.builder, env.ptr_int(), ptr, one);
let count = env.builder.build_load(ptr, "load_count");
let offset = env.builder.build_load(offset_ptr, "load_offset");
@ -116,7 +118,7 @@ fn write_state<'a, 'ctx, 'env>(
let ptr = env.builder.build_pointer_cast(ptr, ptr_type, "");
let one = env.ptr_int().const_int(1, false);
let offset_ptr = pointer_at_offset(env.builder, ptr, one);
let offset_ptr = pointer_at_offset(env.builder, env.ptr_int(), ptr, one);
env.builder.build_store(ptr, count);
env.builder.build_store(offset_ptr, offset);
@ -238,8 +240,12 @@ pub(crate) fn clone_to_shared_memory<'a, 'ctx, 'env>(
// Store the specialized variable of the value
{
let ptr = unsafe {
env.builder
.build_in_bounds_gep(original_ptr, &[offset], "at_current_offset")
env.builder.new_build_in_bounds_gep(
env.context.i8_type(),
original_ptr,
&[offset],
"at_current_offset",
)
};
let u32_ptr = env.context.i32_type().ptr_type(AddressSpace::Generic);
@ -306,8 +312,12 @@ fn build_clone<'a, 'ctx, 'env>(
Layout::Union(union_layout) => {
if layout.safe_to_memcpy(env.layout_interner) {
let ptr = unsafe {
env.builder
.build_in_bounds_gep(ptr, &[cursors.offset], "at_current_offset")
env.builder.new_build_in_bounds_gep(
env.context.i8_type(),
ptr,
&[cursors.offset],
"at_current_offset",
)
};
let ptr_type = value.get_type().ptr_type(AddressSpace::Generic);
@ -525,13 +535,16 @@ fn build_clone_tag<'a, 'ctx, 'env>(
fn load_tag_data<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
union_layout: UnionLayout<'a>,
tag_value: PointerValue<'ctx>,
tag_type: BasicTypeEnum<'ctx>,
) -> BasicValueEnum<'ctx> {
let union_struct_type = struct_type_from_union_layout(env, &union_layout);
let raw_data_ptr = env
.builder
.new_build_struct_gep(
tag_type.into_struct_type(),
union_struct_type,
tag_value,
RocUnion::TAG_DATA_INDEX,
"tag_data",
@ -544,7 +557,7 @@ fn load_tag_data<'a, 'ctx, 'env>(
"data_ptr",
);
env.builder.build_load(data_ptr, "load_data")
env.builder.new_build_load(tag_type, data_ptr, "load_data")
}
#[allow(clippy::too_many_arguments)]
@ -612,7 +625,12 @@ fn build_clone_tag_help<'a, 'ctx, 'env>(
);
let basic_type = basic_type_from_layout(env, &layout);
let data = load_tag_data(env, tag_value.into_pointer_value(), basic_type);
let data = load_tag_data(
env,
union_layout,
tag_value.into_pointer_value(),
basic_type,
);
let answer =
build_clone(env, layout_ids, ptr, cursors, data, layout, when_recursive);
@ -661,7 +679,7 @@ fn build_clone_tag_help<'a, 'ctx, 'env>(
};
let basic_type = basic_type_from_layout(env, &layout);
let data = load_tag_data(env, tag_value, basic_type);
let data = load_tag_data(env, union_layout, tag_value, basic_type);
let (width, _) =
union_layout.data_size_and_alignment(env.layout_interner, env.target_info);
@ -716,7 +734,7 @@ fn build_clone_tag_help<'a, 'ctx, 'env>(
),
};
let data = load_tag_data(env, tag_value, basic_type);
let data = load_tag_data(env, union_layout, tag_value, basic_type);
let when_recursive = WhenRecursive::Loop(union_layout);
let answer = build_clone(env, layout_ids, ptr, cursors, data, layout, when_recursive);
@ -775,7 +793,7 @@ fn build_clone_tag_help<'a, 'ctx, 'env>(
};
let tag_value = tag_pointer_clear_tag_id(env, tag_value.into_pointer_value());
let data = load_tag_data(env, tag_value, basic_type);
let data = load_tag_data(env, union_layout, tag_value, basic_type);
let when_recursive = WhenRecursive::Loop(union_layout);
let answer =
@ -849,7 +867,12 @@ fn build_clone_tag_help<'a, 'ctx, 'env>(
),
};
let data = load_tag_data(env, tag_value.into_pointer_value(), basic_type);
let data = load_tag_data(
env,
union_layout,
tag_value.into_pointer_value(),
basic_type,
);
let when_recursive = WhenRecursive::Loop(union_layout);
let answer =
@ -896,8 +919,12 @@ fn build_copy<'a, 'ctx, 'env>(
value: BasicValueEnum<'ctx>,
) -> IntValue<'ctx> {
let ptr = unsafe {
env.builder
.build_in_bounds_gep(ptr, &[offset], "at_current_offset")
env.builder.new_build_in_bounds_gep(
env.context.i8_type(),
ptr,
&[offset],
"at_current_offset",
)
};
let ptr_type = value.get_type().ptr_type(AddressSpace::Generic);
@ -967,7 +994,7 @@ fn build_clone_builtin<'a, 'ctx, 'env>(
if elem.safe_to_memcpy(env.layout_interner) {
// NOTE we are not actually sure the dest is properly aligned
let dest = pointer_at_offset(bd, ptr, offset);
let dest = pointer_at_offset(bd, env.context.i8_type(), ptr, offset);
let src = bd.build_pointer_cast(
elements,
env.context.i8_type().ptr_type(AddressSpace::Generic),

View file

@ -60,7 +60,12 @@ impl<'ctx> PointerToRefcount<'ctx> {
// get a pointer to index -1
let index_intvalue = refcount_type.const_int(-1_i64 as u64, false);
let refcount_ptr = unsafe {
builder.build_in_bounds_gep(ptr_as_usize_ptr, &[index_intvalue], "get_rc_ptr")
builder.new_build_in_bounds_gep(
env.ptr_int(),
ptr_as_usize_ptr,
&[index_intvalue],
"get_rc_ptr",
)
};
Self {