From d561f2661d2348cf8bb12cc6c8df14e5e1b761ba Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 27 Oct 2021 00:01:21 +0200 Subject: [PATCH] speedups --- cli/tests/cli_run.rs | 1 + compiler/gen_llvm/src/llvm/build.rs | 2 +- compiler/mono/src/alias_analysis.rs | 9 ++- compiler/mono/src/ir.rs | 87 ++++++++++++++--------------- 4 files changed, 52 insertions(+), 47 deletions(-) diff --git a/cli/tests/cli_run.rs b/cli/tests/cli_run.rs index b74fa66094..3885603954 100644 --- a/cli/tests/cli_run.rs +++ b/cli/tests/cli_run.rs @@ -205,6 +205,7 @@ mod cli_run { example.use_valgrind, ); + #[cfg(not(debug_assertions))] check_output_with_stdin( &file_name, example.stdin, diff --git a/compiler/gen_llvm/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs index bacda91a69..34461198d8 100644 --- a/compiler/gen_llvm/src/llvm/build.rs +++ b/compiler/gen_llvm/src/llvm/build.rs @@ -3852,7 +3852,7 @@ fn build_procedures_help<'a, 'ctx, 'env>( let it = procedures.iter().map(|x| x.1); - let solutions = match roc_mono::alias_analysis::spec_program(entry_point, it) { + let solutions = match roc_mono::alias_analysis::spec_program(opt_level, entry_point, it) { Err(e) => panic!("Error in alias analysis: {}", e), Ok(solutions) => solutions, }; diff --git a/compiler/mono/src/alias_analysis.rs b/compiler/mono/src/alias_analysis.rs index 13485868d1..f029388086 100644 --- a/compiler/mono/src/alias_analysis.rs +++ b/compiler/mono/src/alias_analysis.rs @@ -10,7 +10,8 @@ use roc_module::symbol::Symbol; use std::convert::TryFrom; use crate::ir::{ - Call, CallType, Expr, HostExposedLayouts, ListLiteralElement, Literal, ModifyRc, Proc, Stmt, + Call, CallType, Expr, HostExposedLayouts, ListLiteralElement, Literal, ModifyRc, OptLevel, + Proc, Stmt, }; use crate::layout::{Builtin, Layout, ListLayout, RawFunctionLayout, UnionLayout}; @@ -109,6 +110,7 @@ fn bytes_as_ascii(bytes: &[u8]) -> String { } pub fn spec_program<'a, I>( + opt_level: OptLevel, entry_point: crate::ir::EntryPoint<'a>, procs: I, ) -> Result @@ -239,7 +241,10 @@ where eprintln!("{}", program.to_source_string()); } - morphic_lib::solve(program) + match opt_level { + OptLevel::Development | OptLevel::Normal => morphic_lib::solve_trivial(program), + OptLevel::Optimize => morphic_lib::solve(program), + } } /// if you want an "escape hatch" which allows you construct "best-case scenario" values diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index 5338fd08bc..6bb52e0a59 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -1767,13 +1767,9 @@ fn specialize_all_help<'a>( externals_others_need: ExternalSpecializations<'a>, layout_cache: &mut LayoutCache<'a>, ) { - let mut symbol_solved_type = Vec::new_in(env.arena); - for (symbol, solved_types) in externals_others_need.specs.iter() { // for some unclear reason, the MutSet does not deduplicate according to the hash // instance. So we do it manually here - let mut as_vec: std::vec::Vec<_> = solved_types.iter().collect(); - use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; @@ -1783,50 +1779,53 @@ fn specialize_all_help<'a>( hasher.finish() }; - as_vec.sort_by_key(|x| hash_the_thing(x)); - as_vec.dedup_by_key(|x| hash_the_thing(x)); + let mut as_vec = Vec::from_iter_in( + solved_types.iter().map(|x| (hash_the_thing(x), x)), + env.arena, + ); - for s in as_vec { - symbol_solved_type.push((*symbol, s.clone())); - } - } + as_vec.sort_by_key(|(k, _)| *k); + as_vec.dedup_by_key(|(k, _)| *k); - for (name, solved_type) in symbol_solved_type.into_iter() { - let partial_proc = match procs.partial_procs.get(&name) { - Some(v) => v.clone(), - None => { - panic!("Cannot find a partial proc for {:?}", name); - } - }; + for (_, solved_type) in as_vec { + let name = *symbol; - // TODO I believe this sis also duplicated - match specialize_solved_type( - env, - procs, - name, - layout_cache, - solved_type, - BumpMap::new_in(env.arena), - partial_proc, - ) { - Ok((proc, layout)) => { - let top_level = ProcLayout::from_raw(env.arena, layout); - - if procs.is_module_thunk(name) { - debug_assert!(top_level.arguments.is_empty()); + let partial_proc = match procs.partial_procs.get(&name) { + Some(v) => v.clone(), + None => { + panic!("Cannot find a partial proc for {:?}", name); } + }; - procs.specialized.insert((name, top_level), Done(proc)); - } - Err(SpecializeFailure { - problem: _, - attempted_layout, - }) => { - let proc = generate_runtime_error_function(env, name, attempted_layout); + // TODO I believe this sis also duplicated + match specialize_solved_type( + env, + procs, + name, + layout_cache, + solved_type, + BumpMap::new_in(env.arena), + partial_proc, + ) { + Ok((proc, layout)) => { + let top_level = ProcLayout::from_raw(env.arena, layout); - let top_level = ProcLayout::from_raw(env.arena, attempted_layout); + if procs.is_module_thunk(name) { + debug_assert!(top_level.arguments.is_empty()); + } - procs.specialized.insert((name, top_level), Done(proc)); + procs.specialized.insert((name, top_level), Done(proc)); + } + Err(SpecializeFailure { + problem: _, + attempted_layout, + }) => { + let proc = generate_runtime_error_function(env, name, attempted_layout); + + let top_level = ProcLayout::from_raw(env.arena, attempted_layout); + + procs.specialized.insert((name, top_level), Done(proc)); + } } } } @@ -2421,7 +2420,7 @@ fn specialize<'a>( procs, proc_name, layout_cache, - solved_type, + &solved_type, host_exposed_aliases, partial_proc, ) @@ -2451,7 +2450,7 @@ fn specialize_solved_type<'a>( procs: &mut Procs<'a>, proc_name: Symbol, layout_cache: &mut LayoutCache<'a>, - solved_type: SolvedType, + solved_type: &SolvedType, host_exposed_aliases: BumpMap, partial_proc: PartialProc<'a>, ) -> Result, SpecializeFailure<'a>> { @@ -2460,7 +2459,7 @@ fn specialize_solved_type<'a>( procs, proc_name, layout_cache, - |env| introduce_solved_type_to_subs(env, &solved_type), + |env| introduce_solved_type_to_subs(env, solved_type), host_exposed_aliases, partial_proc, )