mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Use is_zero_sized to remove lots of ptr_bytes
This commit is contained in:
parent
7869311c7b
commit
c8e647ccfc
7 changed files with 56 additions and 112 deletions
|
@ -223,7 +223,7 @@ pub fn gen(src: &[u8], target: Triple, opt_level: OptLevel) -> Result<(String, S
|
||||||
let expr_type_str = content_to_string(content.clone(), &subs, home, &interns);
|
let expr_type_str = content_to_string(content.clone(), &subs, home, &interns);
|
||||||
|
|
||||||
// Compute main_fn_type before moving subs to Env
|
// Compute main_fn_type before moving subs to Env
|
||||||
let layout = Layout::new(&arena, content, &subs, ptr_bytes).unwrap_or_else(|err| {
|
let layout = Layout::new(&arena, content, &subs).unwrap_or_else(|err| {
|
||||||
panic!(
|
panic!(
|
||||||
"Code gen error in test: could not convert to layout. Err was {:?}",
|
"Code gen error in test: could not convert to layout. Err was {:?}",
|
||||||
err
|
err
|
||||||
|
@ -258,7 +258,6 @@ pub fn gen(src: &[u8], target: Triple, opt_level: OptLevel) -> Result<(String, S
|
||||||
problems: &mut mono_problems,
|
problems: &mut mono_problems,
|
||||||
home,
|
home,
|
||||||
ident_ids: &mut ident_ids,
|
ident_ids: &mut ident_ids,
|
||||||
pointer_size: ptr_bytes,
|
|
||||||
jump_counter: arena.alloc(0),
|
jump_counter: arena.alloc(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -137,14 +137,14 @@ pub fn gen(
|
||||||
fpm.initialize();
|
fpm.initialize();
|
||||||
|
|
||||||
// Compute main_fn_type before moving subs to Env
|
// Compute main_fn_type before moving subs to Env
|
||||||
let ptr_bytes = target.pointer_width().unwrap().bytes() as u32;
|
let layout = Layout::new(&arena, content, &subs).unwrap_or_else(|err| {
|
||||||
let layout = Layout::new(&arena, content, &subs, ptr_bytes).unwrap_or_else(|err| {
|
|
||||||
panic!(
|
panic!(
|
||||||
"Code gen error in Program: could not convert to layout. Err was {:?}",
|
"Code gen error in Program: could not convert to layout. Err was {:?}",
|
||||||
err
|
err
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let ptr_bytes = target.pointer_width().unwrap().bytes() as u32;
|
||||||
let main_fn_type =
|
let main_fn_type =
|
||||||
basic_type_from_layout(&arena, &context, &layout, ptr_bytes).fn_type(&[], false);
|
basic_type_from_layout(&arena, &context, &layout, ptr_bytes).fn_type(&[], false);
|
||||||
let main_fn_name = "$main";
|
let main_fn_name = "$main";
|
||||||
|
@ -169,7 +169,6 @@ pub fn gen(
|
||||||
problems: &mut mono_problems,
|
problems: &mut mono_problems,
|
||||||
home,
|
home,
|
||||||
ident_ids: &mut ident_ids,
|
ident_ids: &mut ident_ids,
|
||||||
pointer_size: ptr_bytes,
|
|
||||||
jump_counter: arena.alloc(0),
|
jump_counter: arena.alloc(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ macro_rules! assert_llvm_evals_to {
|
||||||
fpm.initialize();
|
fpm.initialize();
|
||||||
|
|
||||||
// Compute main_fn_type before moving subs to Env
|
// Compute main_fn_type before moving subs to Env
|
||||||
let layout = Layout::new(&arena, content, &subs, ptr_bytes)
|
let layout = Layout::new(&arena, content, &subs)
|
||||||
.unwrap_or_else(|err| panic!("Code gen error in NON-OPTIMIZED test: could not convert to layout. Err was {:?}", err));
|
.unwrap_or_else(|err| panic!("Code gen error in NON-OPTIMIZED test: could not convert to layout. Err was {:?}", err));
|
||||||
let execution_engine =
|
let execution_engine =
|
||||||
module
|
module
|
||||||
|
@ -70,7 +70,6 @@ macro_rules! assert_llvm_evals_to {
|
||||||
problems: &mut mono_problems,
|
problems: &mut mono_problems,
|
||||||
home,
|
home,
|
||||||
ident_ids: &mut ident_ids,
|
ident_ids: &mut ident_ids,
|
||||||
pointer_size: ptr_bytes,
|
|
||||||
jump_counter: arena.alloc(0),
|
jump_counter: arena.alloc(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -223,7 +222,7 @@ macro_rules! assert_opt_evals_to {
|
||||||
fpm.initialize();
|
fpm.initialize();
|
||||||
|
|
||||||
// Compute main_fn_type before moving subs to Env
|
// Compute main_fn_type before moving subs to Env
|
||||||
let layout = Layout::new(&arena, content, &subs, ptr_bytes)
|
let layout = Layout::new(&arena, content, &subs)
|
||||||
.unwrap_or_else(|err| panic!("Code gen error in OPTIMIZED test: could not convert to layout. Err was {:?}", err));
|
.unwrap_or_else(|err| panic!("Code gen error in OPTIMIZED test: could not convert to layout. Err was {:?}", err));
|
||||||
|
|
||||||
let execution_engine =
|
let execution_engine =
|
||||||
|
@ -256,7 +255,6 @@ macro_rules! assert_opt_evals_to {
|
||||||
problems: &mut mono_problems,
|
problems: &mut mono_problems,
|
||||||
home,
|
home,
|
||||||
ident_ids: &mut ident_ids,
|
ident_ids: &mut ident_ids,
|
||||||
pointer_size: ptr_bytes,
|
|
||||||
jump_counter: arena.alloc(0),
|
jump_counter: arena.alloc(0),
|
||||||
};
|
};
|
||||||
let main_body = Expr::new(&mut mono_env, loc_expr.value, &mut procs);
|
let main_body = Expr::new(&mut mono_env, loc_expr.value, &mut procs);
|
||||||
|
|
|
@ -114,7 +114,7 @@ impl<'a> Procs<'a> {
|
||||||
// by the surrounding context, so we can add pending specializations
|
// by the surrounding context, so we can add pending specializations
|
||||||
// for them immediately.
|
// for them immediately.
|
||||||
let layout = layout_cache
|
let layout = layout_cache
|
||||||
.from_var(env.arena, annotation, env.subs, env.pointer_size)
|
.from_var(env.arena, annotation, env.subs)
|
||||||
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
// if we've already specialized this one, no further work is needed.
|
// if we've already specialized this one, no further work is needed.
|
||||||
|
@ -252,7 +252,6 @@ pub struct Env<'a, 'i> {
|
||||||
pub problems: &'i mut std::vec::Vec<MonoProblem>,
|
pub problems: &'i mut std::vec::Vec<MonoProblem>,
|
||||||
pub home: ModuleId,
|
pub home: ModuleId,
|
||||||
pub ident_ids: &'i mut IdentIds,
|
pub ident_ids: &'i mut IdentIds,
|
||||||
pub pointer_size: u32,
|
|
||||||
pub jump_counter: &'a mut u64,
|
pub jump_counter: &'a mut u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,7 +626,7 @@ fn from_can<'a>(
|
||||||
for (arg_var, arg_expr) in args {
|
for (arg_var, arg_expr) in args {
|
||||||
let arg = from_can(env, arg_expr, procs, layout_cache);
|
let arg = from_can(env, arg_expr, procs, layout_cache);
|
||||||
let layout = layout_cache
|
let layout = layout_cache
|
||||||
.from_var(env.arena, arg_var, env.subs, env.pointer_size)
|
.from_var(env.arena, arg_var, env.subs)
|
||||||
.unwrap_or_else(|err| todo!("TODO turn fn_var into a RuntimeError {:?}", err));
|
.unwrap_or_else(|err| todo!("TODO turn fn_var into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
mono_args.push((arg, layout));
|
mono_args.push((arg, layout));
|
||||||
|
@ -672,7 +671,7 @@ fn from_can<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let layout = layout_cache
|
let layout = layout_cache
|
||||||
.from_var(env.arena, fn_var, env.subs, env.pointer_size)
|
.from_var(env.arena, fn_var, env.subs)
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
panic!("TODO turn fn_var into a RuntimeError {:?}", err)
|
panic!("TODO turn fn_var into a RuntimeError {:?}", err)
|
||||||
});
|
});
|
||||||
|
@ -708,10 +707,10 @@ fn from_can<'a>(
|
||||||
let arena = env.arena;
|
let arena = env.arena;
|
||||||
|
|
||||||
let ret_layout = layout_cache
|
let ret_layout = layout_cache
|
||||||
.from_var(env.arena, branch_var, env.subs, env.pointer_size)
|
.from_var(env.arena, branch_var, env.subs)
|
||||||
.expect("invalid ret_layout");
|
.expect("invalid ret_layout");
|
||||||
let cond_layout = layout_cache
|
let cond_layout = layout_cache
|
||||||
.from_var(env.arena, cond_var, env.subs, env.pointer_size)
|
.from_var(env.arena, cond_var, env.subs)
|
||||||
.expect("invalid cond_layout");
|
.expect("invalid cond_layout");
|
||||||
|
|
||||||
for (loc_cond, loc_then) in branches.into_iter().rev() {
|
for (loc_cond, loc_then) in branches.into_iter().rev() {
|
||||||
|
@ -746,12 +745,7 @@ fn from_can<'a>(
|
||||||
} => {
|
} => {
|
||||||
let arena = env.arena;
|
let arena = env.arena;
|
||||||
|
|
||||||
let sorted_fields = crate::layout::sort_record_fields(
|
let sorted_fields = crate::layout::sort_record_fields(env.arena, record_var, env.subs);
|
||||||
env.arena,
|
|
||||||
record_var,
|
|
||||||
env.subs,
|
|
||||||
env.pointer_size,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut field_tuples = Vec::with_capacity_in(sorted_fields.len(), arena);
|
let mut field_tuples = Vec::with_capacity_in(sorted_fields.len(), arena);
|
||||||
|
|
||||||
|
@ -776,12 +770,7 @@ fn from_can<'a>(
|
||||||
use crate::layout::UnionVariant::*;
|
use crate::layout::UnionVariant::*;
|
||||||
let arena = env.arena;
|
let arena = env.arena;
|
||||||
|
|
||||||
let variant = crate::layout::union_sorted_tags(
|
let variant = crate::layout::union_sorted_tags(env.arena, variant_var, env.subs);
|
||||||
env.arena,
|
|
||||||
variant_var,
|
|
||||||
env.subs,
|
|
||||||
env.pointer_size,
|
|
||||||
);
|
|
||||||
|
|
||||||
match variant {
|
match variant {
|
||||||
Never => unreachable!("The `[]` type has no constructors"),
|
Never => unreachable!("The `[]` type has no constructors"),
|
||||||
|
@ -855,12 +844,7 @@ fn from_can<'a>(
|
||||||
} => {
|
} => {
|
||||||
let arena = env.arena;
|
let arena = env.arena;
|
||||||
|
|
||||||
let sorted_fields = crate::layout::sort_record_fields(
|
let sorted_fields = crate::layout::sort_record_fields(env.arena, record_var, env.subs);
|
||||||
env.arena,
|
|
||||||
record_var,
|
|
||||||
env.subs,
|
|
||||||
env.pointer_size,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut index = None;
|
let mut index = None;
|
||||||
let mut field_layouts = Vec::with_capacity_in(sorted_fields.len(), env.arena);
|
let mut field_layouts = Vec::with_capacity_in(sorted_fields.len(), env.arena);
|
||||||
|
@ -890,7 +874,7 @@ fn from_can<'a>(
|
||||||
let arena = env.arena;
|
let arena = env.arena;
|
||||||
let subs = &env.subs;
|
let subs = &env.subs;
|
||||||
|
|
||||||
match list_layout_from_elem(arena, subs, elem_var, env.pointer_size) {
|
match list_layout_from_elem(arena, subs, elem_var) {
|
||||||
Ok(Layout::Builtin(Builtin::EmptyList)) => Expr::EmptyArray,
|
Ok(Layout::Builtin(Builtin::EmptyList)) => Expr::EmptyArray,
|
||||||
Ok(Layout::Builtin(Builtin::List(elem_layout))) => {
|
Ok(Layout::Builtin(Builtin::List(elem_layout))) => {
|
||||||
let mut elems = Vec::with_capacity_in(loc_elems.len(), arena);
|
let mut elems = Vec::with_capacity_in(loc_elems.len(), arena);
|
||||||
|
@ -1125,7 +1109,7 @@ fn from_can_defs<'a>(
|
||||||
let mono_pattern = from_can_pattern(env, procs, layout_cache, &loc_pattern.value);
|
let mono_pattern = from_can_pattern(env, procs, layout_cache, &loc_pattern.value);
|
||||||
|
|
||||||
let layout = layout_cache
|
let layout = layout_cache
|
||||||
.from_var(env.arena, def.expr_var, env.subs, env.pointer_size)
|
.from_var(env.arena, def.expr_var, env.subs)
|
||||||
.expect("invalid layout");
|
.expect("invalid layout");
|
||||||
|
|
||||||
match &mono_pattern {
|
match &mono_pattern {
|
||||||
|
@ -1239,7 +1223,7 @@ fn from_can_when<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let cond_layout = layout_cache
|
let cond_layout = layout_cache
|
||||||
.from_var(env.arena, cond_var, env.subs, env.pointer_size)
|
.from_var(env.arena, cond_var, env.subs)
|
||||||
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
||||||
let cond_symbol = env.unique_symbol();
|
let cond_symbol = env.unique_symbol();
|
||||||
let cond = from_can(env, loc_cond.value, procs, layout_cache);
|
let cond = from_can(env, loc_cond.value, procs, layout_cache);
|
||||||
|
@ -1255,7 +1239,7 @@ fn from_can_when<'a>(
|
||||||
Expr::Store(stored.into_bump_slice(), arena.alloc(ret))
|
Expr::Store(stored.into_bump_slice(), arena.alloc(ret))
|
||||||
} else {
|
} else {
|
||||||
let cond_layout = layout_cache
|
let cond_layout = layout_cache
|
||||||
.from_var(env.arena, cond_var, env.subs, env.pointer_size)
|
.from_var(env.arena, cond_var, env.subs)
|
||||||
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
let cond = from_can(env, loc_cond.value, procs, layout_cache);
|
let cond = from_can(env, loc_cond.value, procs, layout_cache);
|
||||||
|
@ -1379,7 +1363,7 @@ fn from_can_when<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret_layout = layout_cache
|
let ret_layout = layout_cache
|
||||||
.from_var(env.arena, expr_var, env.subs, env.pointer_size)
|
.from_var(env.arena, expr_var, env.subs)
|
||||||
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
let branching = crate::decision_tree::optimize_when(
|
let branching = crate::decision_tree::optimize_when(
|
||||||
|
@ -1406,7 +1390,7 @@ fn call_by_name<'a>(
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
) -> Expr<'a> {
|
) -> Expr<'a> {
|
||||||
// Register a pending_specialization for this function
|
// Register a pending_specialization for this function
|
||||||
match layout_cache.from_var(env.arena, fn_var, env.subs, env.pointer_size) {
|
match layout_cache.from_var(env.arena, fn_var, env.subs) {
|
||||||
Ok(layout) => {
|
Ok(layout) => {
|
||||||
// Build the CallByName node
|
// Build the CallByName node
|
||||||
let arena = env.arena;
|
let arena = env.arena;
|
||||||
|
@ -1414,7 +1398,7 @@ fn call_by_name<'a>(
|
||||||
let mut pattern_vars = Vec::with_capacity_in(loc_args.len(), arena);
|
let mut pattern_vars = Vec::with_capacity_in(loc_args.len(), arena);
|
||||||
|
|
||||||
for (var, loc_arg) in loc_args {
|
for (var, loc_arg) in loc_args {
|
||||||
match layout_cache.from_var(&env.arena, var, &env.subs, env.pointer_size) {
|
match layout_cache.from_var(&env.arena, var, &env.subs) {
|
||||||
Ok(layout) => {
|
Ok(layout) => {
|
||||||
pattern_vars.push(var);
|
pattern_vars.push(var);
|
||||||
args.push((from_can(env, loc_arg.value, procs, layout_cache), layout));
|
args.push((from_can(env, loc_arg.value, procs, layout_cache), layout));
|
||||||
|
@ -1625,13 +1609,13 @@ fn specialize<'a>(
|
||||||
);
|
);
|
||||||
|
|
||||||
for (arg_var, arg_name) in pattern_vars.iter().zip(pattern_symbols.iter()) {
|
for (arg_var, arg_name) in pattern_vars.iter().zip(pattern_symbols.iter()) {
|
||||||
let layout = layout_cache.from_var(&env.arena, *arg_var, env.subs, env.pointer_size)?;
|
let layout = layout_cache.from_var(&env.arena, *arg_var, env.subs)?;
|
||||||
|
|
||||||
proc_args.push((layout, *arg_name));
|
proc_args.push((layout, *arg_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret_layout = layout_cache
|
let ret_layout = layout_cache
|
||||||
.from_var(&env.arena, ret_var, env.subs, env.pointer_size)
|
.from_var(&env.arena, ret_var, env.subs)
|
||||||
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err));
|
||||||
|
|
||||||
let proc = Proc {
|
let proc = Proc {
|
||||||
|
@ -1736,8 +1720,7 @@ fn from_can_pattern<'a>(
|
||||||
use crate::layout::UnionVariant::*;
|
use crate::layout::UnionVariant::*;
|
||||||
use crate::pattern::Union;
|
use crate::pattern::Union;
|
||||||
|
|
||||||
let variant =
|
let variant = crate::layout::union_sorted_tags(env.arena, *whole_var, env.subs);
|
||||||
crate::layout::union_sorted_tags(env.arena, *whole_var, env.subs, env.pointer_size);
|
|
||||||
|
|
||||||
match variant {
|
match variant {
|
||||||
Never => unreachable!("there is no pattern of type `[]`"),
|
Never => unreachable!("there is no pattern of type `[]`"),
|
||||||
|
@ -1890,12 +1873,7 @@ fn from_can_pattern<'a>(
|
||||||
let mut it = destructs.iter();
|
let mut it = destructs.iter();
|
||||||
let mut opt_destruct = it.next();
|
let mut opt_destruct = it.next();
|
||||||
|
|
||||||
let sorted_fields = crate::layout::sort_record_fields(
|
let sorted_fields = crate::layout::sort_record_fields(env.arena, *whole_var, env.subs);
|
||||||
env.arena,
|
|
||||||
*whole_var,
|
|
||||||
env.subs,
|
|
||||||
env.pointer_size,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut field_layouts = Vec::with_capacity_in(sorted_fields.len(), env.arena);
|
let mut field_layouts = Vec::with_capacity_in(sorted_fields.len(), env.arena);
|
||||||
|
|
||||||
|
|
|
@ -50,17 +50,12 @@ pub enum Builtin<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Layout<'a> {
|
impl<'a> Layout<'a> {
|
||||||
pub fn new(
|
pub fn new(arena: &'a Bump, content: Content, subs: &Subs) -> Result<Self, LayoutProblem> {
|
||||||
arena: &'a Bump,
|
|
||||||
content: Content,
|
|
||||||
subs: &Subs,
|
|
||||||
pointer_size: u32,
|
|
||||||
) -> Result<Self, LayoutProblem> {
|
|
||||||
use roc_types::subs::Content::*;
|
use roc_types::subs::Content::*;
|
||||||
|
|
||||||
match content {
|
match content {
|
||||||
FlexVar(_) | RigidVar(_) => Err(LayoutProblem::UnresolvedTypeVar),
|
FlexVar(_) | RigidVar(_) => Err(LayoutProblem::UnresolvedTypeVar),
|
||||||
Structure(flat_type) => layout_from_flat_type(arena, flat_type, subs, pointer_size),
|
Structure(flat_type) => layout_from_flat_type(arena, flat_type, subs),
|
||||||
|
|
||||||
Alias(Symbol::NUM_INT, args, _) => {
|
Alias(Symbol::NUM_INT, args, _) => {
|
||||||
debug_assert!(args.is_empty());
|
debug_assert!(args.is_empty());
|
||||||
|
@ -70,12 +65,7 @@ impl<'a> Layout<'a> {
|
||||||
debug_assert!(args.is_empty());
|
debug_assert!(args.is_empty());
|
||||||
Ok(Layout::Builtin(Builtin::Float64))
|
Ok(Layout::Builtin(Builtin::Float64))
|
||||||
}
|
}
|
||||||
Alias(_, _, var) => Self::new(
|
Alias(_, _, var) => Self::new(arena, subs.get_without_compacting(var).content, subs),
|
||||||
arena,
|
|
||||||
subs.get_without_compacting(var).content,
|
|
||||||
subs,
|
|
||||||
pointer_size,
|
|
||||||
),
|
|
||||||
Error => Err(LayoutProblem::Erroneous),
|
Error => Err(LayoutProblem::Erroneous),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,15 +73,10 @@ impl<'a> Layout<'a> {
|
||||||
/// Returns Err(()) if given an error, or Ok(Layout) if given a non-erroneous Structure.
|
/// Returns Err(()) if given an error, or Ok(Layout) if given a non-erroneous Structure.
|
||||||
/// Panics if given a FlexVar or RigidVar, since those should have been
|
/// Panics if given a FlexVar or RigidVar, since those should have been
|
||||||
/// monomorphized away already!
|
/// monomorphized away already!
|
||||||
fn from_var(
|
fn from_var(arena: &'a Bump, var: Variable, subs: &Subs) -> Result<Self, LayoutProblem> {
|
||||||
arena: &'a Bump,
|
|
||||||
var: Variable,
|
|
||||||
subs: &Subs,
|
|
||||||
pointer_size: u32,
|
|
||||||
) -> Result<Self, LayoutProblem> {
|
|
||||||
let content = subs.get_without_compacting(var).content;
|
let content = subs.get_without_compacting(var).content;
|
||||||
|
|
||||||
Self::new(arena, content, subs, pointer_size)
|
Self::new(arena, content, subs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn safe_to_memcpy(&self) -> bool {
|
pub fn safe_to_memcpy(&self) -> bool {
|
||||||
|
@ -116,6 +101,13 @@ impl<'a> Layout<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_zero_sized(&self) -> bool {
|
||||||
|
// For this calculation, we don't need an accurate
|
||||||
|
// stack size, we just need to know whether it's zero,
|
||||||
|
// so it's fine to use a pointer size of 1.
|
||||||
|
self.stack_size(1) == 0
|
||||||
|
}
|
||||||
|
|
||||||
pub fn stack_size(&self, pointer_size: u32) -> u32 {
|
pub fn stack_size(&self, pointer_size: u32) -> u32 {
|
||||||
use Layout::*;
|
use Layout::*;
|
||||||
|
|
||||||
|
@ -161,7 +153,6 @@ impl<'a> LayoutCache<'a> {
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
var: Variable,
|
var: Variable,
|
||||||
subs: &Subs,
|
subs: &Subs,
|
||||||
pointer_size: u32,
|
|
||||||
) -> Result<Layout<'a>, LayoutProblem> {
|
) -> Result<Layout<'a>, LayoutProblem> {
|
||||||
// Store things according to the root Variable, to avoid duplicate work.
|
// Store things according to the root Variable, to avoid duplicate work.
|
||||||
let var = subs.get_root_key_without_compacting(var);
|
let var = subs.get_root_key_without_compacting(var);
|
||||||
|
@ -171,7 +162,7 @@ impl<'a> LayoutCache<'a> {
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
let content = subs.get_without_compacting(var).content;
|
let content = subs.get_without_compacting(var).content;
|
||||||
|
|
||||||
Layout::new(arena, content, subs, pointer_size)
|
Layout::new(arena, content, subs)
|
||||||
})
|
})
|
||||||
.clone()
|
.clone()
|
||||||
}
|
}
|
||||||
|
@ -238,7 +229,6 @@ fn layout_from_flat_type<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
flat_type: FlatType,
|
flat_type: FlatType,
|
||||||
subs: &Subs,
|
subs: &Subs,
|
||||||
pointer_size: u32,
|
|
||||||
) -> Result<Layout<'a>, LayoutProblem> {
|
) -> Result<Layout<'a>, LayoutProblem> {
|
||||||
use roc_types::subs::FlatType::*;
|
use roc_types::subs::FlatType::*;
|
||||||
|
|
||||||
|
@ -263,7 +253,7 @@ fn layout_from_flat_type<'a>(
|
||||||
layout_from_num_content(content)
|
layout_from_num_content(content)
|
||||||
}
|
}
|
||||||
Symbol::STR_STR => Ok(Layout::Builtin(Builtin::Str)),
|
Symbol::STR_STR => Ok(Layout::Builtin(Builtin::Str)),
|
||||||
Symbol::LIST_LIST => list_layout_from_elem(arena, subs, args[0], pointer_size),
|
Symbol::LIST_LIST => list_layout_from_elem(arena, subs, args[0]),
|
||||||
Symbol::ATTR_ATTR => {
|
Symbol::ATTR_ATTR => {
|
||||||
debug_assert_eq!(args.len(), 2);
|
debug_assert_eq!(args.len(), 2);
|
||||||
|
|
||||||
|
@ -274,7 +264,7 @@ fn layout_from_flat_type<'a>(
|
||||||
// For now, layout is unaffected by uniqueness.
|
// For now, layout is unaffected by uniqueness.
|
||||||
// (Incorporating refcounting may change this.)
|
// (Incorporating refcounting may change this.)
|
||||||
// Unwrap and continue
|
// Unwrap and continue
|
||||||
Layout::from_var(arena, wrapped_var, subs, pointer_size)
|
Layout::from_var(arena, wrapped_var, subs)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!("TODO layout_from_flat_type for {:?}", Apply(symbol, args));
|
panic!("TODO layout_from_flat_type for {:?}", Apply(symbol, args));
|
||||||
|
@ -287,11 +277,11 @@ fn layout_from_flat_type<'a>(
|
||||||
for arg_var in args {
|
for arg_var in args {
|
||||||
let arg_content = subs.get_without_compacting(arg_var).content;
|
let arg_content = subs.get_without_compacting(arg_var).content;
|
||||||
|
|
||||||
fn_args.push(Layout::new(arena, arg_content, subs, pointer_size)?);
|
fn_args.push(Layout::new(arena, arg_content, subs)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret_content = subs.get_without_compacting(ret_var).content;
|
let ret_content = subs.get_without_compacting(ret_var).content;
|
||||||
let ret = Layout::new(arena, ret_content, subs, pointer_size)?;
|
let ret = Layout::new(arena, ret_content, subs)?;
|
||||||
|
|
||||||
Ok(Layout::FunctionPointer(
|
Ok(Layout::FunctionPointer(
|
||||||
fn_args.into_bump_slice(),
|
fn_args.into_bump_slice(),
|
||||||
|
@ -319,10 +309,10 @@ fn layout_from_flat_type<'a>(
|
||||||
let field_var = field.into_inner();
|
let field_var = field.into_inner();
|
||||||
let field_content = subs.get_without_compacting(field_var).content;
|
let field_content = subs.get_without_compacting(field_var).content;
|
||||||
|
|
||||||
match Layout::new(arena, field_content, subs, pointer_size) {
|
match Layout::new(arena, field_content, subs) {
|
||||||
Ok(layout) => {
|
Ok(layout) => {
|
||||||
// Drop any zero-sized fields like {}
|
// Drop any zero-sized fields like {}.
|
||||||
if layout.stack_size(pointer_size) != 0 {
|
if !layout.is_zero_sized() {
|
||||||
layouts.push(layout);
|
layouts.push(layout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,7 +334,7 @@ fn layout_from_flat_type<'a>(
|
||||||
TagUnion(tags, ext_var) => {
|
TagUnion(tags, ext_var) => {
|
||||||
debug_assert!(ext_var_is_empty_tag_union(subs, ext_var));
|
debug_assert!(ext_var_is_empty_tag_union(subs, ext_var));
|
||||||
|
|
||||||
Ok(layout_from_tag_union(arena, tags, subs, pointer_size))
|
Ok(layout_from_tag_union(arena, tags, subs))
|
||||||
}
|
}
|
||||||
RecursiveTagUnion(_, _, _) => {
|
RecursiveTagUnion(_, _, _) => {
|
||||||
panic!("TODO make Layout for non-empty Tag Union");
|
panic!("TODO make Layout for non-empty Tag Union");
|
||||||
|
@ -364,7 +354,6 @@ pub fn sort_record_fields<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
var: Variable,
|
var: Variable,
|
||||||
subs: &Subs,
|
subs: &Subs,
|
||||||
pointer_size: u32,
|
|
||||||
) -> Vec<'a, (Lowercase, Layout<'a>)> {
|
) -> Vec<'a, (Lowercase, Layout<'a>)> {
|
||||||
let mut fields_map = MutMap::default();
|
let mut fields_map = MutMap::default();
|
||||||
|
|
||||||
|
@ -375,11 +364,10 @@ pub fn sort_record_fields<'a>(
|
||||||
|
|
||||||
for (label, field) in fields_map {
|
for (label, field) in fields_map {
|
||||||
let var = field.into_inner();
|
let var = field.into_inner();
|
||||||
let layout = Layout::from_var(arena, var, subs, pointer_size)
|
let layout = Layout::from_var(arena, var, subs).expect("invalid layout from var");
|
||||||
.expect("invalid layout from var");
|
|
||||||
|
|
||||||
// Drop any zero-sized fields like {}
|
// Drop any zero-sized fields like {}
|
||||||
if layout.stack_size(pointer_size) != 0 {
|
if !layout.is_zero_sized() {
|
||||||
sorted_fields.push((label, layout));
|
sorted_fields.push((label, layout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,17 +390,10 @@ pub enum UnionVariant<'a> {
|
||||||
Wrapped(Vec<'a, (TagName, &'a [Layout<'a>])>),
|
Wrapped(Vec<'a, (TagName, &'a [Layout<'a>])>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn union_sorted_tags<'a>(
|
pub fn union_sorted_tags<'a>(arena: &'a Bump, var: Variable, subs: &Subs) -> UnionVariant<'a> {
|
||||||
arena: &'a Bump,
|
|
||||||
var: Variable,
|
|
||||||
subs: &Subs,
|
|
||||||
pointer_size: u32,
|
|
||||||
) -> UnionVariant<'a> {
|
|
||||||
let mut tags_vec = std::vec::Vec::new();
|
let mut tags_vec = std::vec::Vec::new();
|
||||||
match roc_types::pretty_print::chase_ext_tag_union(subs, var, &mut tags_vec) {
|
match roc_types::pretty_print::chase_ext_tag_union(subs, var, &mut tags_vec) {
|
||||||
Ok(()) | Err((_, Content::FlexVar(_))) => {
|
Ok(()) | Err((_, Content::FlexVar(_))) => union_sorted_tags_help(arena, tags_vec, subs),
|
||||||
union_sorted_tags_help(arena, tags_vec, subs, pointer_size)
|
|
||||||
}
|
|
||||||
Err(other) => panic!("invalid content in tag union variable: {:?}", other),
|
Err(other) => panic!("invalid content in tag union variable: {:?}", other),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,7 +402,6 @@ fn union_sorted_tags_help<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
mut tags_vec: std::vec::Vec<(TagName, std::vec::Vec<Variable>)>,
|
mut tags_vec: std::vec::Vec<(TagName, std::vec::Vec<Variable>)>,
|
||||||
subs: &Subs,
|
subs: &Subs,
|
||||||
pointer_size: u32,
|
|
||||||
) -> UnionVariant<'a> {
|
) -> UnionVariant<'a> {
|
||||||
// sort up front; make sure the ordering stays intact!
|
// sort up front; make sure the ordering stays intact!
|
||||||
tags_vec.sort();
|
tags_vec.sort();
|
||||||
|
@ -444,10 +424,10 @@ fn union_sorted_tags_help<'a>(
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
for var in arguments {
|
for var in arguments {
|
||||||
match Layout::from_var(arena, var, subs, pointer_size) {
|
match Layout::from_var(arena, var, subs) {
|
||||||
Ok(layout) => {
|
Ok(layout) => {
|
||||||
// Drop any zero-sized arguments like {}
|
// Drop any zero-sized arguments like {}
|
||||||
if layout.stack_size(pointer_size) != 0 {
|
if !layout.is_zero_sized() {
|
||||||
layouts.push(layout);
|
layouts.push(layout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -483,10 +463,10 @@ fn union_sorted_tags_help<'a>(
|
||||||
arg_layouts.push(Layout::Builtin(Builtin::Int64));
|
arg_layouts.push(Layout::Builtin(Builtin::Int64));
|
||||||
|
|
||||||
for var in arguments {
|
for var in arguments {
|
||||||
match Layout::from_var(arena, var, subs, pointer_size) {
|
match Layout::from_var(arena, var, subs) {
|
||||||
Ok(layout) => {
|
Ok(layout) => {
|
||||||
// Drop any zero-sized arguments like {}
|
// Drop any zero-sized arguments like {}
|
||||||
if layout.stack_size(pointer_size) != 0 {
|
if !layout.is_zero_sized() {
|
||||||
has_any_arguments = true;
|
has_any_arguments = true;
|
||||||
|
|
||||||
arg_layouts.push(layout);
|
arg_layouts.push(layout);
|
||||||
|
@ -537,14 +517,13 @@ pub fn layout_from_tag_union<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
tags: MutMap<TagName, std::vec::Vec<Variable>>,
|
tags: MutMap<TagName, std::vec::Vec<Variable>>,
|
||||||
subs: &Subs,
|
subs: &Subs,
|
||||||
pointer_size: u32,
|
|
||||||
) -> Layout<'a> {
|
) -> Layout<'a> {
|
||||||
use UnionVariant::*;
|
use UnionVariant::*;
|
||||||
|
|
||||||
let tags_vec: std::vec::Vec<_> = tags.into_iter().collect();
|
let tags_vec: std::vec::Vec<_> = tags.into_iter().collect();
|
||||||
|
|
||||||
if tags_vec[0].0 != TagName::Private(Symbol::NUM_AT_NUM) {
|
if tags_vec[0].0 != TagName::Private(Symbol::NUM_AT_NUM) {
|
||||||
let variant = union_sorted_tags_help(arena, tags_vec, subs, pointer_size);
|
let variant = union_sorted_tags_help(arena, tags_vec, subs);
|
||||||
|
|
||||||
match variant {
|
match variant {
|
||||||
Never => panic!("TODO gracefully handle trying to instantiate Never"),
|
Never => panic!("TODO gracefully handle trying to instantiate Never"),
|
||||||
|
@ -678,7 +657,6 @@ pub fn list_layout_from_elem<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
subs: &Subs,
|
subs: &Subs,
|
||||||
var: Variable,
|
var: Variable,
|
||||||
pointer_size: u32,
|
|
||||||
) -> Result<Layout<'a>, LayoutProblem> {
|
) -> Result<Layout<'a>, LayoutProblem> {
|
||||||
match subs.get_without_compacting(var).content {
|
match subs.get_without_compacting(var).content {
|
||||||
Content::Structure(FlatType::Apply(Symbol::ATTR_ATTR, args)) => {
|
Content::Structure(FlatType::Apply(Symbol::ATTR_ATTR, args)) => {
|
||||||
|
@ -686,14 +664,14 @@ pub fn list_layout_from_elem<'a>(
|
||||||
|
|
||||||
let arg_var = args.get(1).unwrap();
|
let arg_var = args.get(1).unwrap();
|
||||||
|
|
||||||
list_layout_from_elem(arena, subs, *arg_var, pointer_size)
|
list_layout_from_elem(arena, subs, *arg_var)
|
||||||
}
|
}
|
||||||
Content::FlexVar(_) | Content::RigidVar(_) => {
|
Content::FlexVar(_) | Content::RigidVar(_) => {
|
||||||
// If this was still a (List *) then it must have been an empty list
|
// If this was still a (List *) then it must have been an empty list
|
||||||
Ok(Layout::Builtin(Builtin::EmptyList))
|
Ok(Layout::Builtin(Builtin::EmptyList))
|
||||||
}
|
}
|
||||||
content => {
|
content => {
|
||||||
let elem_layout = Layout::new(arena, content, subs, pointer_size)?;
|
let elem_layout = Layout::new(arena, content, subs)?;
|
||||||
|
|
||||||
// This is a normal list.
|
// This is a normal list.
|
||||||
Ok(Layout::Builtin(Builtin::List(arena.alloc(elem_layout))))
|
Ok(Layout::Builtin(Builtin::List(arena.alloc(elem_layout))))
|
||||||
|
|
|
@ -50,9 +50,6 @@ mod test_mono {
|
||||||
let mut procs = Procs::default();
|
let mut procs = Procs::default();
|
||||||
let mut ident_ids = interns.all_ident_ids.remove(&home).unwrap();
|
let mut ident_ids = interns.all_ident_ids.remove(&home).unwrap();
|
||||||
|
|
||||||
// assume 64-bit pointers
|
|
||||||
let pointer_size = std::mem::size_of::<u64>() as u32;
|
|
||||||
|
|
||||||
// Populate Procs and Subs, and get the low-level Expr from the canonical Expr
|
// Populate Procs and Subs, and get the low-level Expr from the canonical Expr
|
||||||
let mut mono_problems = Vec::new();
|
let mut mono_problems = Vec::new();
|
||||||
let mut mono_env = roc_mono::expr::Env {
|
let mut mono_env = roc_mono::expr::Env {
|
||||||
|
@ -61,7 +58,6 @@ mod test_mono {
|
||||||
problems: &mut mono_problems,
|
problems: &mut mono_problems,
|
||||||
home,
|
home,
|
||||||
ident_ids: &mut ident_ids,
|
ident_ids: &mut ident_ids,
|
||||||
pointer_size,
|
|
||||||
jump_counter: arena.alloc(0),
|
jump_counter: arena.alloc(0),
|
||||||
};
|
};
|
||||||
let mono_expr = Expr::new(&mut mono_env, loc_expr.value, &mut procs);
|
let mono_expr = Expr::new(&mut mono_env, loc_expr.value, &mut procs);
|
||||||
|
|
|
@ -86,9 +86,6 @@ mod test_reporting {
|
||||||
let mut procs = Procs::default();
|
let mut procs = Procs::default();
|
||||||
let mut ident_ids = interns.all_ident_ids.remove(&home).unwrap();
|
let mut ident_ids = interns.all_ident_ids.remove(&home).unwrap();
|
||||||
|
|
||||||
// assume 64-bit pointers
|
|
||||||
let pointer_size = std::mem::size_of::<u64>() as u32;
|
|
||||||
|
|
||||||
// Populate Procs and Subs, and get the low-level Expr from the canonical Expr
|
// Populate Procs and Subs, and get the low-level Expr from the canonical Expr
|
||||||
let mut mono_env = roc_mono::expr::Env {
|
let mut mono_env = roc_mono::expr::Env {
|
||||||
arena: &arena,
|
arena: &arena,
|
||||||
|
@ -96,7 +93,6 @@ mod test_reporting {
|
||||||
problems: &mut mono_problems,
|
problems: &mut mono_problems,
|
||||||
home,
|
home,
|
||||||
ident_ids: &mut ident_ids,
|
ident_ids: &mut ident_ids,
|
||||||
pointer_size,
|
|
||||||
jump_counter: arena.alloc(0),
|
jump_counter: arena.alloc(0),
|
||||||
};
|
};
|
||||||
let _mono_expr = Expr::new(&mut mono_env, loc_expr.value, &mut procs);
|
let _mono_expr = Expr::new(&mut mono_env, loc_expr.value, &mut procs);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue