This commit is contained in:
Folkert 2021-06-04 22:26:45 +02:00
parent d061363243
commit 40792187fe
4 changed files with 82 additions and 64 deletions

1
Cargo.lock generated
View file

@ -3171,6 +3171,7 @@ dependencies = [
"inlinable_string", "inlinable_string",
"libc", "libc",
"maplit", "maplit",
"morphic_lib",
"pretty_assertions 0.5.1", "pretty_assertions 0.5.1",
"quickcheck 0.8.5", "quickcheck 0.8.5",
"quickcheck_macros 0.8.0", "quickcheck_macros 0.8.0",

View file

@ -15,6 +15,7 @@ roc_builtins = { path = "../builtins" }
roc_unify = { path = "../unify" } roc_unify = { path = "../unify" }
roc_solve = { path = "../solve" } roc_solve = { path = "../solve" }
roc_mono = { path = "../mono" } roc_mono = { path = "../mono" }
morphic_lib = { path = "../../vendor/morphic_lib" }
im = "14" # im and im-rc should always have the same version! im = "14" # im and im-rc should always have the same version!
im-rc = "14" # im and im-rc should always have the same version! im-rc = "14" # im and im-rc should always have the same version!
bumpalo = { version = "3.6.1", features = ["collections"] } bumpalo = { version = "3.6.1", features = ["collections"] }

View file

@ -43,6 +43,7 @@ use inkwell::values::{
}; };
use inkwell::OptimizationLevel; use inkwell::OptimizationLevel;
use inkwell::{AddressSpace, IntPredicate}; use inkwell::{AddressSpace, IntPredicate};
use morphic_lib::FuncName;
use roc_builtins::bitcode; use roc_builtins::bitcode;
use roc_collections::all::{ImMap, MutMap, MutSet}; use roc_collections::all::{ImMap, MutMap, MutSet};
use roc_module::ident::TagName; use roc_module::ident::TagName;
@ -795,21 +796,32 @@ pub fn build_exp_call<'a, 'ctx, 'env>(
match call_type { match call_type {
CallType::ByName { CallType::ByName {
name, full_layout, .. name,
full_layout,
arg_layouts,
ret_layout,
..
} => { } => {
let mut arg_tuples: Vec<BasicValueEnum> = let mut arg_tuples: Vec<BasicValueEnum> =
Vec::with_capacity_in(arguments.len(), env.arena); Vec::with_capacity_in(arguments.len(), env.arena);
let name_bytes = roc_mono::alias_analysis::func_name_bytes_help(
*name,
arg_layouts.iter().copied(),
*ret_layout,
);
let func_name = FuncName(&name_bytes);
for symbol in arguments.iter() { for symbol in arguments.iter() {
arg_tuples.push(load_symbol(scope, symbol)); arg_tuples.push(load_symbol(scope, symbol));
} }
call_with_args( roc_call_with_args(
env, env,
layout_ids, layout_ids,
&full_layout, &full_layout,
*name, *name,
parent, func_name,
arg_tuples.into_bump_slice(), arg_tuples.into_bump_slice(),
) )
} }
@ -3035,18 +3047,6 @@ pub fn build_procedures_return_main<'a, 'ctx, 'env>(
.unwrap() .unwrap()
} }
// Coming soon
// pub enum AliasAnalysisSolutions {
// NotAvailable,
// Available(morphic_lib::Solutions),
// }
//
// impl std::fmt::Debug for AliasAnalysisSolutions {
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// write!(f, "AliasAnalysisSolutions {{}}")
// }
// }
fn build_procedures_help<'a, 'ctx, 'env>( fn build_procedures_help<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,
opt_level: OptLevel, opt_level: OptLevel,
@ -3056,19 +3056,16 @@ fn build_procedures_help<'a, 'ctx, 'env>(
let mut layout_ids = roc_mono::layout::LayoutIds::default(); let mut layout_ids = roc_mono::layout::LayoutIds::default();
let mut scope = Scope::default(); let mut scope = Scope::default();
// Coming Soon let it = procedures.iter().map(|x| x.1);
//
// if false { let solutions = match roc_mono::alias_analysis::spec_program(it) {
// let it = state.procedures.iter().map(|x| x.1); Err(e) => panic!("Error in alias analysis: {:?}", e),
// Ok(solutions) => solutions,
// match roc_mono::alias_analysis::spec_program(it) { };
// Err(e) => panic!("Error in alias analysis: {:?}", e),
// Ok(solutions) => { let mod_solutions = solutions
// state.alias_analysis_solutions = .mod_solutions(roc_mono::alias_analysis::MOD_APP)
// AliasAnalysisSolutions::Available(solutions) .unwrap();
// }
// }
// }
// Add all the Proc headers to the module. // Add all the Proc headers to the module.
// We have to do this in a separate pass first, // We have to do this in a separate pass first,
@ -3080,6 +3077,9 @@ fn build_procedures_help<'a, 'ctx, 'env>(
for (proc, fn_val) in headers { for (proc, fn_val) in headers {
let mut current_scope = scope.clone(); let mut current_scope = scope.clone();
let name_bytes = roc_mono::alias_analysis::func_name_bytes(&proc);
let func_name = FuncName(&name_bytes);
// only have top-level thunks for this proc's module in scope // only have top-level thunks for this proc's module in scope
// this retain is not needed for correctness, but will cause less confusion when debugging // this retain is not needed for correctness, but will cause less confusion when debugging
let home = proc.name.module_id(); let home = proc.name.module_id();
@ -3569,12 +3569,12 @@ fn function_value_by_name_help<'a, 'ctx, 'env>(
// #[allow(clippy::cognitive_complexity)] // #[allow(clippy::cognitive_complexity)]
#[inline(always)] #[inline(always)]
fn call_with_args<'a, 'ctx, 'env>( fn roc_call_with_args<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,
layout_ids: &mut LayoutIds<'a>, layout_ids: &mut LayoutIds<'a>,
layout: &Layout<'a>, layout: &Layout<'a>,
symbol: Symbol, symbol: Symbol,
_parent: FunctionValue<'ctx>, _func_name: FuncName<'_>,
args: &[BasicValueEnum<'ctx>], args: &[BasicValueEnum<'ctx>],
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
let fn_val = function_value_by_name(env, layout_ids, *layout, symbol); let fn_val = function_value_by_name(env, layout_ids, *layout, symbol);

View file

@ -17,6 +17,50 @@ pub const MOD_APP: ModName = ModName(b"UserApp");
pub const STATIC_STR_NAME: ConstName = ConstName(&Symbol::STR_ALIAS_ANALYSIS_STATIC.to_ne_bytes()); pub const STATIC_STR_NAME: ConstName = ConstName(&Symbol::STR_ALIAS_ANALYSIS_STATIC.to_ne_bytes());
pub fn func_name_bytes(proc: &Proc) -> [u8; 16] {
func_name_bytes_help(proc.name, proc.args.iter().map(|x| x.0), proc.ret_layout)
}
pub fn func_name_bytes_help<'a, I>(
symbol: Symbol,
argument_layouts: I,
return_layout: Layout<'a>,
) -> [u8; 16]
where
I: Iterator<Item = Layout<'a>>,
{
let mut name_bytes = [0u8; 16];
use std::collections::hash_map::DefaultHasher;
use std::hash::Hash;
use std::hash::Hasher;
let layout_hash = {
let mut hasher = DefaultHasher::new();
for layout in argument_layouts {
layout.hash(&mut hasher);
}
return_layout.hash(&mut hasher);
hasher.finish()
};
let sbytes = symbol.to_ne_bytes();
let lbytes = layout_hash.to_ne_bytes();
let it = sbytes
.iter()
.chain(lbytes.iter())
.zip(name_bytes.iter_mut());
for (source, target) in it {
*target = *source;
}
return name_bytes;
}
pub fn spec_program<'a, I>(procs: I) -> Result<morphic_lib::Solutions> pub fn spec_program<'a, I>(procs: I) -> Result<morphic_lib::Solutions>
where where
I: Iterator<Item = &'a Proc<'a>>, I: Iterator<Item = &'a Proc<'a>>,
@ -40,36 +84,7 @@ where
for proc in procs { for proc in procs {
let spec = proc_spec(proc)?; let spec = proc_spec(proc)?;
let mut name_bytes = [0u8; 16]; m.add_func(FuncName(&func_name_bytes(proc)), spec)?;
use std::collections::hash_map::DefaultHasher;
use std::hash::Hash;
use std::hash::Hasher;
let layout_hash = {
let mut hasher = DefaultHasher::new();
for (layout, _) in proc.args.iter() {
layout.hash(&mut hasher);
}
proc.ret_layout.hash(&mut hasher);
hasher.finish()
};
let sbytes = proc.name.to_ne_bytes();
let lbytes = layout_hash.to_ne_bytes();
let it = sbytes
.iter()
.chain(lbytes.iter())
.zip(name_bytes.iter_mut());
for (source, target) in it {
*target = *source;
}
m.add_func(FuncName(&name_bytes), spec)?;
if format!("{:?}", proc.name).contains("mainForHost") { if format!("{:?}", proc.name).contains("mainForHost") {
main_function = Some(proc.name); main_function = Some(proc.name);
@ -345,16 +360,17 @@ fn call_spec(
ByName { ByName {
name: symbol, name: symbol,
full_layout: _, full_layout: _,
ret_layout: _, ret_layout,
arg_layouts: _, arg_layouts,
specialization_id, specialization_id,
} => { } => {
let array = specialization_id.to_bytes(); let array = specialization_id.to_bytes();
let spec_var = CalleeSpecVar(&array); let spec_var = CalleeSpecVar(&array);
let arg_value_id = build_tuple_value(builder, env, block, call.arguments)?; let arg_value_id = build_tuple_value(builder, env, block, call.arguments)?;
let slice = &symbol.to_ne_bytes(); let it = arg_layouts.iter().copied();
let name = FuncName(slice); let bytes = func_name_bytes_help(*symbol, it, *ret_layout);
let name = FuncName(&bytes);
let module = MOD_APP; let module = MOD_APP;
builder.add_call(block, spec_var, module, name, arg_value_id) builder.add_call(block, spec_var, module, name, arg_value_id)
} }