mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-11 16:51:53 +03:00
simplify monomorphization first steps
This commit is contained in:
parent
0529d6dbc6
commit
eaaf3eb940
@ -3981,6 +3981,30 @@ fn make_specializations<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct ProcsBase<'a> {
|
||||||
|
partial_procs: BumpMap<Symbol, PartialProc<'a>>,
|
||||||
|
module_thunks: bumpalo::collections::Vec<'a, Symbol>,
|
||||||
|
pending_specializations: BumpMap<Symbol, MutMap<ProcLayout<'a>, PendingSpecialization<'a>>>,
|
||||||
|
runtime_errors: BumpMap<Symbol, &'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ProcsBase<'a> {
|
||||||
|
fn add_pending(
|
||||||
|
&mut self,
|
||||||
|
symbol: Symbol,
|
||||||
|
layout: ProcLayout<'a>,
|
||||||
|
pending: PendingSpecialization<'a>,
|
||||||
|
) {
|
||||||
|
let all_pending = self
|
||||||
|
.pending_specializations
|
||||||
|
.entry(symbol)
|
||||||
|
.or_insert_with(|| HashMap::with_capacity_and_hasher(1, default_hasher()));
|
||||||
|
|
||||||
|
all_pending.insert(layout, pending);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn build_pending_specializations<'a>(
|
fn build_pending_specializations<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
@ -3996,10 +4020,12 @@ fn build_pending_specializations<'a>(
|
|||||||
exposed_to_host: MutMap<Symbol, Variable>,
|
exposed_to_host: MutMap<Symbol, Variable>,
|
||||||
) -> Msg<'a> {
|
) -> Msg<'a> {
|
||||||
let find_specializations_start = SystemTime::now();
|
let find_specializations_start = SystemTime::now();
|
||||||
let mut procs = Procs::new_in(arena);
|
let mut procs_base = ProcsBase {
|
||||||
|
partial_procs: BumpMap::default(),
|
||||||
debug_assert!(procs.imported_module_thunks.is_empty());
|
module_thunks: bumpalo::collections::Vec::new_in(arena),
|
||||||
procs.imported_module_thunks = imported_module_thunks;
|
pending_specializations: BumpMap::default(),
|
||||||
|
runtime_errors: BumpMap::default(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut mono_problems = std::vec::Vec::new();
|
let mut mono_problems = std::vec::Vec::new();
|
||||||
let mut subs = solved_subs.into_inner();
|
let mut subs = solved_subs.into_inner();
|
||||||
@ -4022,7 +4048,7 @@ fn build_pending_specializations<'a>(
|
|||||||
match decl {
|
match decl {
|
||||||
Declare(def) | Builtin(def) => add_def_to_module(
|
Declare(def) | Builtin(def) => add_def_to_module(
|
||||||
&mut layout_cache,
|
&mut layout_cache,
|
||||||
&mut procs,
|
&mut procs_base,
|
||||||
&mut mono_env,
|
&mut mono_env,
|
||||||
def,
|
def,
|
||||||
&exposed_to_host,
|
&exposed_to_host,
|
||||||
@ -4032,7 +4058,7 @@ fn build_pending_specializations<'a>(
|
|||||||
for def in defs {
|
for def in defs {
|
||||||
add_def_to_module(
|
add_def_to_module(
|
||||||
&mut layout_cache,
|
&mut layout_cache,
|
||||||
&mut procs,
|
&mut procs_base,
|
||||||
&mut mono_env,
|
&mut mono_env,
|
||||||
def,
|
def,
|
||||||
&exposed_to_host,
|
&exposed_to_host,
|
||||||
@ -4054,6 +4080,16 @@ fn build_pending_specializations<'a>(
|
|||||||
.duration_since(find_specializations_start)
|
.duration_since(find_specializations_start)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let mut procs = Procs::new_in(arena);
|
||||||
|
|
||||||
|
debug_assert!(procs.imported_module_thunks.is_empty());
|
||||||
|
procs.imported_module_thunks = imported_module_thunks;
|
||||||
|
|
||||||
|
procs.partial_procs = procs_base.partial_procs;
|
||||||
|
procs.module_thunks.extend(procs_base.module_thunks);
|
||||||
|
procs.pending_specializations = Some(procs_base.pending_specializations);
|
||||||
|
procs.runtime_errors = procs_base.runtime_errors;
|
||||||
|
|
||||||
Msg::FoundSpecializations {
|
Msg::FoundSpecializations {
|
||||||
module_id: home,
|
module_id: home,
|
||||||
solved_subs: roc_types::solved_types::Solved(subs),
|
solved_subs: roc_types::solved_types::Solved(subs),
|
||||||
@ -4067,7 +4103,7 @@ fn build_pending_specializations<'a>(
|
|||||||
|
|
||||||
fn add_def_to_module<'a>(
|
fn add_def_to_module<'a>(
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
procs: &mut Procs<'a>,
|
procs: &mut ProcsBase<'a>,
|
||||||
mono_env: &mut roc_mono::ir::Env<'a, '_>,
|
mono_env: &mut roc_mono::ir::Env<'a, '_>,
|
||||||
def: roc_can::def::Def,
|
def: roc_can::def::Def,
|
||||||
exposed_to_host: &MutMap<Symbol, Variable>,
|
exposed_to_host: &MutMap<Symbol, Variable>,
|
||||||
@ -4129,14 +4165,18 @@ fn add_def_to_module<'a>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
procs.insert_exposed(
|
let pending = PendingSpecialization::from_exposed_function(
|
||||||
symbol,
|
|
||||||
ProcLayout::from_raw(mono_env.arena, layout),
|
|
||||||
mono_env.arena,
|
mono_env.arena,
|
||||||
mono_env.subs,
|
mono_env.subs,
|
||||||
def.annotation,
|
def.annotation,
|
||||||
annotation,
|
annotation,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
procs.add_pending(
|
||||||
|
symbol,
|
||||||
|
ProcLayout::from_raw(mono_env.arena, layout),
|
||||||
|
pending,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let partial_proc = PartialProc::from_named_function(
|
let partial_proc = PartialProc::from_named_function(
|
||||||
@ -4154,7 +4194,7 @@ fn add_def_to_module<'a>(
|
|||||||
}
|
}
|
||||||
body => {
|
body => {
|
||||||
// mark this symbols as a top-level thunk before any other work on the procs
|
// mark this symbols as a top-level thunk before any other work on the procs
|
||||||
procs.module_thunks.insert(symbol);
|
procs.module_thunks.push(symbol);
|
||||||
|
|
||||||
// If this is an exposed symbol, we need to
|
// If this is an exposed symbol, we need to
|
||||||
// register it as such. Otherwise, since it
|
// register it as such. Otherwise, since it
|
||||||
@ -4189,14 +4229,14 @@ fn add_def_to_module<'a>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
procs.insert_exposed(
|
let pending = PendingSpecialization::from_exposed_function(
|
||||||
symbol,
|
|
||||||
top_level,
|
|
||||||
mono_env.arena,
|
mono_env.arena,
|
||||||
mono_env.subs,
|
mono_env.subs,
|
||||||
def.annotation,
|
def.annotation,
|
||||||
annotation,
|
annotation,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
procs.add_pending(symbol, top_level, pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
let proc = PartialProc {
|
let proc = PartialProc {
|
||||||
|
@ -188,6 +188,24 @@ impl<'a> PendingSpecialization<'a> {
|
|||||||
_lifetime: std::marker::PhantomData,
|
_lifetime: std::marker::PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a named function that will be publicly exposed to the host
|
||||||
|
pub fn from_exposed_function(
|
||||||
|
arena: &'a Bump,
|
||||||
|
subs: &Subs,
|
||||||
|
opt_annotation: Option<roc_can::def::Annotation>,
|
||||||
|
fn_var: Variable,
|
||||||
|
) -> Self {
|
||||||
|
match opt_annotation {
|
||||||
|
None => PendingSpecialization::from_var(arena, subs, fn_var),
|
||||||
|
Some(annotation) => PendingSpecialization::from_var_host_exposed(
|
||||||
|
arena,
|
||||||
|
subs,
|
||||||
|
fn_var,
|
||||||
|
&annotation.introduced_variables.host_exposed_aliases,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
@ -586,50 +604,7 @@ impl<'a> Procs<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a named function that will be publicly exposed to the host
|
fn insert_passed_by_name(
|
||||||
pub fn insert_exposed(
|
|
||||||
&mut self,
|
|
||||||
name: Symbol,
|
|
||||||
layout: ProcLayout<'a>,
|
|
||||||
arena: &'a Bump,
|
|
||||||
subs: &Subs,
|
|
||||||
opt_annotation: Option<roc_can::def::Annotation>,
|
|
||||||
fn_var: Variable,
|
|
||||||
) {
|
|
||||||
let tuple = (name, layout);
|
|
||||||
|
|
||||||
// If we've already specialized this one, no further work is needed.
|
|
||||||
if self.specialized.contains_key(&tuple) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We're done with that tuple, so move layout back out to avoid cloning it.
|
|
||||||
let (name, layout) = tuple;
|
|
||||||
let pending = match opt_annotation {
|
|
||||||
None => PendingSpecialization::from_var(arena, subs, fn_var),
|
|
||||||
Some(annotation) => PendingSpecialization::from_var_host_exposed(
|
|
||||||
arena,
|
|
||||||
subs,
|
|
||||||
fn_var,
|
|
||||||
&annotation.introduced_variables.host_exposed_aliases,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
// This should only be called when pending_specializations is Some.
|
|
||||||
// Otherwise, it's being called in the wrong pass!
|
|
||||||
match &mut self.pending_specializations {
|
|
||||||
Some(pending_specializations) => {
|
|
||||||
// register the pending specialization, so this gets code genned later
|
|
||||||
add_pending(pending_specializations, name, layout, pending)
|
|
||||||
}
|
|
||||||
None => unreachable!(
|
|
||||||
r"insert_exposed was called after the pending specializations phase had already completed!"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// TODO
|
|
||||||
pub fn insert_passed_by_name(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
fn_var: Variable,
|
fn_var: Variable,
|
||||||
|
Loading…
Reference in New Issue
Block a user