mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 20:28:02 +00:00
WIP
This commit is contained in:
parent
6c0217c6f6
commit
954a4fbe32
8 changed files with 146 additions and 10 deletions
|
@ -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 {
|
||||
|
|
|
@ -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") };
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,9 +111,11 @@ pub fn occurring_variables(stmt: &Stmt<'_>) -> (MutSet<Symbol>, MutSet<Symbol>)
|
|||
Expect {
|
||||
condition,
|
||||
remainder,
|
||||
lookups,
|
||||
..
|
||||
} => {
|
||||
result.insert(*condition);
|
||||
result.extend(lookups.iter().copied());
|
||||
stack.push(remainder);
|
||||
}
|
||||
|
||||
|
@ -1180,7 +1182,7 @@ impl<'a> Context<'a> {
|
|||
lookups,
|
||||
layouts,
|
||||
} => {
|
||||
let (b, b_live_vars) = self.visit_stmt(codegen, remainder);
|
||||
let (b, mut b_live_vars) = self.visit_stmt(codegen, remainder);
|
||||
|
||||
let expect = self.arena.alloc(Stmt::Expect {
|
||||
condition: *condition,
|
||||
|
@ -1190,6 +1192,10 @@ impl<'a> Context<'a> {
|
|||
remainder: b,
|
||||
});
|
||||
|
||||
let expect = self.add_inc_before_consume_all(lookups, expect, &b_live_vars);
|
||||
|
||||
b_live_vars.extend(lookups.iter().copied());
|
||||
|
||||
(expect, b_live_vars)
|
||||
}
|
||||
|
||||
|
@ -1299,9 +1305,11 @@ pub fn collect_stmt(
|
|||
Expect {
|
||||
condition,
|
||||
remainder,
|
||||
lookups,
|
||||
..
|
||||
} => {
|
||||
vars.insert(*condition);
|
||||
vars.extend(lookups.iter().copied());
|
||||
collect_stmt(remainder, jp_live_vars, vars)
|
||||
}
|
||||
|
||||
|
|
|
@ -292,6 +292,8 @@ pub fn expect_mono_module_to_dylib<'a>(
|
|||
);
|
||||
}
|
||||
|
||||
env.module.print_to_file("/tmp/test.ll").unwrap();
|
||||
|
||||
llvm_module_to_dylib(env.module, &target, opt_level).map(|lib| (lib, expects))
|
||||
}
|
||||
|
||||
|
|
|
@ -356,6 +356,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
|||
Ok(app.call_function_returns_roc_list(
|
||||
main_fn_name,
|
||||
|mem: &A::Memory, (addr, len, _cap)| {
|
||||
dbg!(addr, len);
|
||||
list_to_ast(env, mem, addr, len, elem_layout, raw_content)
|
||||
},
|
||||
))
|
||||
|
@ -548,6 +549,9 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
|||
(_, Layout::Builtin(Builtin::List(elem_layout))) => {
|
||||
let elem_addr = mem.deref_usize(addr);
|
||||
let len = mem.deref_usize(addr + env.target_info.ptr_width() as usize);
|
||||
let cap = mem.deref_usize(addr + 2 * env.target_info.ptr_width() as usize);
|
||||
|
||||
dbg!(elem_addr, len, cap);
|
||||
|
||||
list_to_ast(env, mem, elem_addr, len, elem_layout, raw_content)
|
||||
}
|
||||
|
|
|
@ -78,8 +78,9 @@ struct ExpectMemory {
|
|||
macro_rules! deref_number {
|
||||
($name: ident, $t: ty) => {
|
||||
fn $name(&self, addr: usize) -> $t {
|
||||
// dbg!(std::any::type_name::<$t>(), self.start, addr);
|
||||
let ptr = unsafe { self.start.add(addr) } as *const _;
|
||||
unsafe { *ptr }
|
||||
unsafe { std::ptr::read_unaligned(ptr) }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -165,7 +166,10 @@ impl<'a> ReplApp<'a> for ExpectReplApp<'a> {
|
|||
F: Fn(&'a Self::Memory, (usize, usize, usize)) -> Expr<'a>,
|
||||
Self::Memory: 'a,
|
||||
{
|
||||
self.call_function(main_fn_name, transform)
|
||||
let result = self.call_function(main_fn_name, transform);
|
||||
dbg!(self.offset);
|
||||
self.offset += 8;
|
||||
result
|
||||
}
|
||||
|
||||
fn call_function_returns_roc_str<T, F>(
|
||||
|
|
|
@ -3,4 +3,19 @@ app "rocLovesZig"
|
|||
imports []
|
||||
provides [main] to pf
|
||||
|
||||
# expect
|
||||
# a = "a string so long it cannot possibly be small"
|
||||
# b = "foo"
|
||||
# a == b
|
||||
#
|
||||
# expect
|
||||
# a = { x: 0, y: 2 }
|
||||
# b = { x: 1, y: 2 }
|
||||
# a == b
|
||||
|
||||
expect
|
||||
b = [456]
|
||||
a = [ 12345, 6789, 12, 13, 14 ]
|
||||
a == b
|
||||
|
||||
main = "Roc <3 Zig!\n"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue