This commit is contained in:
Folkert 2022-07-23 14:25:38 +02:00
parent 6c0217c6f6
commit 954a4fbe32
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
8 changed files with 146 additions and 10 deletions

View file

@ -696,8 +696,8 @@ pub fn construct_optimization_passes<'a>(
mpm.add_always_inliner_pass();
// tail-call elimination is always on
fpm.add_instruction_combining_pass();
fpm.add_tail_call_elimination_pass();
//fpm.add_instruction_combining_pass();
//fpm.add_tail_call_elimination_pass();
let pmb = PassManagerBuilder::create();
match opt_level {

View file

@ -373,6 +373,29 @@ pub fn list_capacity<'ctx>(
.into_int_value()
}
pub fn destructure<'ctx>(
builder: &Builder<'ctx>,
wrapper_struct: StructValue<'ctx>,
) -> (PointerValue<'ctx>, IntValue<'ctx>, IntValue<'ctx>) {
let length = builder
.build_extract_value(wrapper_struct, Builtin::WRAPPER_LEN, "list_len")
.unwrap()
.into_int_value();
let capacity = builder
.build_extract_value(wrapper_struct, Builtin::WRAPPER_CAPACITY, "list_cap")
.unwrap()
.into_int_value();
// a `*mut u8` pointer
let generic_ptr = builder
.build_extract_value(wrapper_struct, Builtin::WRAPPER_PTR, "read_list_ptr")
.unwrap()
.into_pointer_value();
(generic_ptr, length, capacity)
}
/// List.sortWith : List a, (a, a -> Ordering) -> List a
pub fn list_sort_with<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
@ -646,6 +669,8 @@ where
{
let builder = env.builder;
dbg!(ptr);
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") };

View file

@ -1,9 +1,10 @@
use crate::llvm::bitcode::{call_bitcode_fn, call_str_bitcode_fn};
use crate::llvm::build::{get_tag_id, tag_pointer_clear_tag_id, Env, FAST_CALL_CONV};
use crate::llvm::build_list::{list_len, load_list_ptr};
use crate::llvm::build_list::{self, incrementing_elem_loop, list_len, load_list_ptr};
use crate::llvm::build_str::str_equal;
use crate::llvm::convert::basic_type_from_layout;
use bumpalo::collections::Vec;
use inkwell::builder::Builder;
use inkwell::types::BasicType;
use inkwell::values::{
BasicValue, BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue,
@ -20,6 +21,14 @@ use super::build::{
};
use super::convert::argument_type_from_union_layout;
fn pointer_at_offset<'ctx>(
bd: &Builder<'ctx>,
ptr: PointerValue<'ctx>,
offset: IntValue<'ctx>,
) -> PointerValue<'ctx> {
unsafe { bd.build_gep(ptr, &[offset], "offset_ptr") }
}
pub(crate) fn clone_to_shared_memory<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
scope: &Scope<'a, 'ctx>,
@ -124,7 +133,7 @@ pub(crate) fn clone_to_shared_memory<'a, 'ctx, 'env>(
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Copy)]
enum WhenRecursive<'a> {
Unreachable,
Loop(UnionLayout<'a>),
@ -132,7 +141,7 @@ enum WhenRecursive<'a> {
fn build_clone<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
_layout_ids: &mut LayoutIds<'a>,
layout_ids: &mut LayoutIds<'a>,
ptr: PointerValue<'ctx>,
offset: IntValue<'ctx>,
value: BasicValueEnum<'ctx>,
@ -141,7 +150,7 @@ fn build_clone<'a, 'ctx, 'env>(
) -> IntValue<'ctx> {
match layout {
Layout::Builtin(builtin) => {
build_clone_builtin(env, ptr, offset, value, builtin, when_recursive)
build_clone_builtin(env, layout_ids, ptr, offset, value, builtin, when_recursive)
}
Layout::Struct {
@ -235,6 +244,7 @@ fn build_copy<'a, 'ctx, 'env>(
fn build_clone_builtin<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
layout_ids: &mut LayoutIds<'a>,
ptr: PointerValue<'ctx>,
offset: IntValue<'ctx>,
value: BasicValueEnum<'ctx>,
@ -256,6 +266,74 @@ fn build_clone_builtin<'a, 'ctx, 'env>(
)
.into_int_value()
}
Builtin::List(elem) => todo!(),
Builtin::List(elem) => {
let bd = env.builder;
let list = value.into_struct_value();
let (elements, len, cap) = build_list::destructure(env.builder, list);
let list_width = env
.ptr_int()
.const_int(env.target_info.ptr_size() as u64 * 3, false);
let elements_offset = bd.build_int_add(offset, list_width, "new_offset");
let mut offset = offset;
offset = build_copy(env, ptr, offset, elements_offset.into());
offset = build_copy(env, ptr, offset, len.into());
offset = build_copy(env, ptr, offset, cap.into());
let (element_width, _element_align) = elem.stack_size_and_alignment(env.target_info);
let element_width = env.ptr_int().const_int(element_width as _, false);
let elements_width = bd.build_int_mul(element_width, cap, "elements_width");
if false && elem.safe_to_memcpy() {
// NOTE we are not actually sure the dest is properly aligned
let dest = pointer_at_offset(bd, ptr, offset);
let src = bd.build_pointer_cast(
elements,
env.context.i8_type().ptr_type(AddressSpace::Generic),
"to_bytes_pointer",
);
bd.build_memcpy(dest, 1, src, 1, elements_width).unwrap();
bd.build_int_add(offset, elements_width, "new_offset")
} else {
let elements_start_offset = offset;
let mut element_offset = elements_start_offset;
let body = |_index, element| {
element_offset = build_clone(
env,
layout_ids,
ptr,
element_offset,
element,
*elem,
when_recursive,
);
};
let parent = env
.builder
.get_insert_block()
.and_then(|b| b.get_parent())
.unwrap();
let element_type = basic_type_from_layout(env, elem);
let elements = bd.build_pointer_cast(
elements,
element_type.ptr_type(AddressSpace::Generic),
"elements",
);
dbg!(elements);
incrementing_elem_loop(env, parent, *elem, elements, len, "index", body);
element_offset
}
}
}
}