mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 08:11:12 +00:00
cleanup
This commit is contained in:
parent
a1fd34feef
commit
79d5c82dfb
12 changed files with 186 additions and 70 deletions
|
@ -1,6 +1,8 @@
|
|||
/// Helpers for interacting with the zig that generates bitcode
|
||||
use crate::debug_info_init;
|
||||
use crate::llvm::build::{struct_from_fields, Env, C_CALL_CONV, FAST_CALL_CONV, TAG_DATA_INDEX};
|
||||
use crate::llvm::build::{
|
||||
load_roc_value, struct_from_fields, Env, C_CALL_CONV, FAST_CALL_CONV, TAG_DATA_INDEX,
|
||||
};
|
||||
use crate::llvm::convert::basic_type_from_layout;
|
||||
use crate::llvm::refcounting::{
|
||||
decrement_refcount_layout, increment_n_refcount_layout, increment_refcount_layout,
|
||||
|
@ -506,8 +508,9 @@ pub fn build_eq_wrapper<'a, 'ctx, 'env>(
|
|||
.build_bitcast(value_ptr2, value_type, "load_opaque")
|
||||
.into_pointer_value();
|
||||
|
||||
let value1 = env.builder.build_load(value_cast1, "load_opaque");
|
||||
let value2 = env.builder.build_load(value_cast2, "load_opaque");
|
||||
// load_roc_value(env, *element_layout, elem_ptr, "get_elem")
|
||||
let value1 = load_roc_value(env, *layout, value_cast1, "load_opaque");
|
||||
let value2 = load_roc_value(env, *layout, value_cast2, "load_opaque");
|
||||
|
||||
let result =
|
||||
crate::llvm::compare::generic_eq(env, layout_ids, value1, value2, layout, layout);
|
||||
|
|
|
@ -3,7 +3,8 @@ use crate::llvm::bitcode::{
|
|||
build_dec_wrapper, build_eq_wrapper, build_inc_wrapper, call_bitcode_fn, call_void_bitcode_fn,
|
||||
};
|
||||
use crate::llvm::build::{
|
||||
complex_bitcast, load_symbol, load_symbol_and_layout, Env, RocFunctionCall, Scope,
|
||||
complex_bitcast, load_roc_value, load_symbol, load_symbol_and_layout, Env, RocFunctionCall,
|
||||
Scope,
|
||||
};
|
||||
use crate::llvm::build_list::{layout_width, pass_as_opaque};
|
||||
use crate::llvm::convert::{basic_type_from_layout, zig_dict_type, zig_list_type};
|
||||
|
@ -810,7 +811,7 @@ fn build_hash_wrapper<'a, 'ctx, 'env>(
|
|||
.build_bitcast(value_ptr, value_type, "load_opaque")
|
||||
.into_pointer_value();
|
||||
|
||||
let val_arg = env.builder.build_load(value_cast, "load_opaque");
|
||||
let val_arg = load_roc_value(env, *layout, value_cast, "load_opaque");
|
||||
|
||||
let result =
|
||||
crate::llvm::build_hash::generic_hash(env, layout_ids, seed_arg, val_arg, layout);
|
||||
|
|
|
@ -327,7 +327,6 @@ fn build_hash_tag<'a, 'ctx, 'env>(
|
|||
let seed_type = env.context.i64_type();
|
||||
|
||||
let arg_type = basic_type_from_layout_1(env, layout);
|
||||
dbg!(layout, arg_type);
|
||||
|
||||
let function_value = crate::llvm::refcounting::build_header_help(
|
||||
env,
|
||||
|
@ -443,9 +442,15 @@ fn hash_tag<'a, 'ctx, 'env>(
|
|||
|
||||
env.builder.position_at_end(entry_block);
|
||||
|
||||
let default = cases.pop().unwrap().1;
|
||||
|
||||
env.builder.build_switch(current_tag_id, default, &cases);
|
||||
match cases.pop() {
|
||||
Some((_, default)) => {
|
||||
env.builder.build_switch(current_tag_id, default, &cases);
|
||||
}
|
||||
None => {
|
||||
// we're hashing empty tag unions; this code is effectively unreachable
|
||||
env.builder.build_unreachable();
|
||||
}
|
||||
}
|
||||
}
|
||||
Recursive(tags) => {
|
||||
let current_tag_id = get_tag_id(env, parent, union_layout, tag);
|
||||
|
|
|
@ -585,6 +585,14 @@ pub fn list_keep_if<'a, 'ctx, 'env>(
|
|||
)
|
||||
}
|
||||
|
||||
fn empty_list<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValueEnum<'ctx> {
|
||||
let struct_type = super::convert::zig_list_type(env);
|
||||
|
||||
// The pointer should be null (aka zero) and the length should be zero,
|
||||
// so the whole struct should be a const_zero
|
||||
BasicValueEnum::StructValue(struct_type.const_zero())
|
||||
}
|
||||
|
||||
/// List.keepOks : List before, (before -> Result after *) -> List after
|
||||
pub fn list_keep_oks<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
|
@ -607,6 +615,10 @@ pub fn list_keep_oks<'a, 'ctx, 'env>(
|
|||
|
||||
let has_tag_id = match result_layout {
|
||||
Layout::Union(union_layout) => build_has_tag_id(env, function, *union_layout),
|
||||
Layout::Builtin(Builtin::Bool) => {
|
||||
// a `Result [] whatever`, so there is nothing to keep
|
||||
return empty_list(env);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -651,6 +663,10 @@ pub fn list_keep_errs<'a, 'ctx, 'env>(
|
|||
|
||||
let has_tag_id = match result_layout {
|
||||
Layout::Union(union_layout) => build_has_tag_id(env, function, *union_layout),
|
||||
Layout::Builtin(Builtin::Bool) => {
|
||||
// a `Result whatever []`, so there is nothing to keep
|
||||
return empty_list(env);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ 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;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum WhenRecursive<'a> {
|
||||
Unreachable,
|
||||
|
@ -521,13 +523,13 @@ fn build_list_eq_help<'a, 'ctx, 'env>(
|
|||
let elem1 = {
|
||||
let elem_ptr =
|
||||
unsafe { builder.build_in_bounds_gep(ptr1, &[curr_index], "load_index") };
|
||||
builder.build_load(elem_ptr, "get_elem")
|
||||
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") };
|
||||
builder.build_load(elem_ptr, "get_elem")
|
||||
load_roc_value(env, *element_layout, elem_ptr, "get_elem")
|
||||
};
|
||||
|
||||
let are_equal = build_eq(
|
||||
|
@ -870,6 +872,10 @@ fn build_tag_eq_help<'a, 'ctx, 'env>(
|
|||
use UnionLayout::*;
|
||||
|
||||
match union_layout {
|
||||
NonRecursive(&[]) => {
|
||||
// we're comparing empty tag unions; this code is effectively unreachable
|
||||
env.builder.build_unreachable();
|
||||
}
|
||||
NonRecursive(tags) => {
|
||||
let ptr_equal = env.builder.build_int_compare(
|
||||
IntPredicate::EQ,
|
||||
|
@ -930,9 +936,15 @@ fn build_tag_eq_help<'a, 'ctx, 'env>(
|
|||
|
||||
env.builder.position_at_end(compare_tag_fields);
|
||||
|
||||
let default = cases.pop().unwrap().1;
|
||||
|
||||
env.builder.build_switch(id1, default, &cases);
|
||||
match cases.pop() {
|
||||
Some((_, default)) => {
|
||||
env.builder.build_switch(id1, default, &cases);
|
||||
}
|
||||
None => {
|
||||
// we're comparing empty tag unions; this code is effectively unreachable
|
||||
env.builder.build_unreachable();
|
||||
}
|
||||
}
|
||||
}
|
||||
Recursive(tags) => {
|
||||
let ptr_equal = env.builder.build_int_compare(
|
||||
|
|
|
@ -593,21 +593,31 @@ fn modify_refcount_layout_build_function<'a, 'ctx, 'env>(
|
|||
Union(variant) => {
|
||||
use UnionLayout::*;
|
||||
|
||||
if let NonRecursive(tags) = variant {
|
||||
let function = modify_refcount_union(env, layout_ids, mode, when_recursive, tags);
|
||||
match variant {
|
||||
NonRecursive(&[]) => {
|
||||
// void type, nothing to refcount here
|
||||
None
|
||||
}
|
||||
|
||||
return Some(function);
|
||||
NonRecursive(tags) => {
|
||||
let function =
|
||||
modify_refcount_union(env, layout_ids, mode, when_recursive, tags);
|
||||
|
||||
Some(function)
|
||||
}
|
||||
|
||||
_ => {
|
||||
let function = build_rec_union(
|
||||
env,
|
||||
layout_ids,
|
||||
mode,
|
||||
&WhenRecursive::Loop(*variant),
|
||||
*variant,
|
||||
);
|
||||
|
||||
Some(function)
|
||||
}
|
||||
}
|
||||
|
||||
let function = build_rec_union(
|
||||
env,
|
||||
layout_ids,
|
||||
mode,
|
||||
&WhenRecursive::Loop(*variant),
|
||||
*variant,
|
||||
);
|
||||
|
||||
Some(function)
|
||||
}
|
||||
|
||||
Struct(layouts) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue