use vectors instead of maps

This commit is contained in:
Folkert 2022-04-23 16:57:28 +02:00
parent 7b37727175
commit 5840693743
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C

View file

@ -11,7 +11,7 @@ use crate::reference_matrix::ReferenceMatrix;
use crate::reference_matrix::TopologicalSort;
use crate::scope::create_alias;
use crate::scope::Scope;
use roc_collections::{default_hasher, ImEntry, ImMap, ImSet, MutMap, MutSet, SendMap};
use roc_collections::{ImEntry, ImMap, ImSet, MutMap, MutSet, SendMap};
use roc_module::ident::Lowercase;
use roc_module::symbol::IdentId;
use roc_module::symbol::ModuleId;
@ -28,7 +28,6 @@ use roc_types::subs::{VarStore, Variable};
use roc_types::types::AliasKind;
use roc_types::types::LambdaSet;
use roc_types::types::{Alias, Type};
use std::collections::HashMap;
use std::fmt::Debug;
use ven_graph::topological_sort;
@ -50,10 +49,12 @@ pub struct Annotation {
}
#[derive(Debug)]
pub struct CanDefs {
pub refs_by_symbol: MutMap<Symbol, (Region, References)>,
pub can_defs_by_symbol: MutMap<Symbol, Def>,
pub aliases: SendMap<Symbol, Alias>,
pub(crate) struct CanDefs {
symbol_to_index: Vec<(IdentId, u32)>,
defs: Vec<Def>,
references: Vec<(References, Region)>,
aliases: SendMap<Symbol, Alias>,
}
/// A Def that has had patterns and type annnotations canonicalized,
@ -205,7 +206,7 @@ fn sort_type_defs_before_introduction(
}
#[inline(always)]
pub fn canonicalize_defs<'a>(
pub(crate) fn canonicalize_defs<'a>(
env: &mut Env<'a>,
mut output: Output,
var_store: &mut VarStore,
@ -234,7 +235,6 @@ pub fn canonicalize_defs<'a>(
// so we can diff them while detecting unused defs.
let mut scope = original_scope.clone();
let num_defs = loc_defs.len();
let mut refs_by_symbol = MutMap::default();
let mut type_defs = Vec::with_capacity(num_defs);
let mut value_defs = Vec::with_capacity(num_defs);
@ -489,7 +489,7 @@ pub fn canonicalize_defs<'a>(
}
}
let mut symbol_to_id: Vec<(IdentId, u32)> = Vec::with_capacity(pending_value_defs.len());
let mut symbol_to_index: Vec<(IdentId, u32)> = Vec::with_capacity(pending_value_defs.len());
for (def_index, pending_def) in pending_value_defs.iter().enumerate() {
for (s, _) in bindings_from_patterns(std::iter::once(pending_def.loc_pattern())) {
@ -499,23 +499,22 @@ pub fn canonicalize_defs<'a>(
}
debug_assert_eq!(env.home, s.module_id());
debug_assert!(!symbol_to_id.iter().any(|(id, _)| *id == s.ident_id()));
debug_assert!(!symbol_to_index.iter().any(|(id, _)| *id == s.ident_id()));
symbol_to_id.push((s.ident_id(), def_index as u32));
symbol_to_index.push((s.ident_id(), def_index as u32));
}
}
// let mut def_order = DefOrdering::from_symbol_to_id(env.home, symbol_to_id);
let mut can_defs_by_symbol = HashMap::with_capacity_and_hasher(num_defs, default_hasher());
// env.home.register_debug_idents(&env.ident_ids);
let mut defs = Vec::with_capacity(pending_value_defs.len());
let mut references = Vec::with_capacity(pending_value_defs.len());
for pending_def in pending_value_defs.into_iter() {
let region = pending_def.loc_pattern().region;
let bindings = bindings_from_patterns(std::iter::once(pending_def.loc_pattern()));
let temp_output = canonicalize_pending_value_def_new(
env,
pending_def,
@ -528,10 +527,8 @@ pub fn canonicalize_defs<'a>(
output = temp_output.output;
for (symbol, _) in bindings {
can_defs_by_symbol.insert(symbol, temp_output.def.clone());
refs_by_symbol.insert(symbol, (region, temp_output.references.clone()));
}
defs.push(temp_output.def);
references.push((temp_output.references, region));
}
// Determine which idents we introduced in the course of this process.
@ -555,8 +552,9 @@ pub fn canonicalize_defs<'a>(
// defs need to get moved later.
(
CanDefs {
refs_by_symbol,
can_defs_by_symbol,
symbol_to_index,
defs,
references,
// The result needs a thread-safe `SendMap`
aliases: aliases.into_iter().collect(),
},
@ -723,15 +721,15 @@ struct DefOrdering {
}
impl DefOrdering {
fn with_capacity(home: ModuleId, capacity: usize) -> Self {
Self {
home,
symbol_to_id: Vec::with_capacity(capacity),
references: ReferenceMatrix::new(capacity),
direct_references: ReferenceMatrix::new(capacity),
length: capacity as u32,
}
}
// fn with_capacity(home: ModuleId, capacity: usize) -> Self {
// Self {
// home,
// symbol_to_id: Vec::with_capacity(capacity),
// references: ReferenceMatrix::new(capacity),
// direct_references: ReferenceMatrix::new(capacity),
// length: capacity as u32,
// }
// }
// fn from_symbol_to_id(home: ModuleId, symbol_to_id: Vec<(IdentId, u32)>) -> Self {
// let capacity = symbol_to_id.len();
@ -747,37 +745,59 @@ impl DefOrdering {
fn from_defs_by_symbol(
env: &Env,
can_defs_by_symbol: &MutMap<Symbol, Def>,
refs_by_symbol: &MutMap<Symbol, (Region, References)>,
symbol_to_id: Vec<(IdentId, u32)>,
references: &[(References, Region)],
capacity: usize,
) -> Self {
let mut this = Self::with_capacity(env.home, can_defs_by_symbol.len());
// because of `Pair a b = someDef` patterns, we can have more symbols than defs
debug_assert!(symbol_to_id.len() >= capacity);
for (i, symbol) in can_defs_by_symbol.keys().enumerate() {
debug_assert_eq!(env.home, symbol.module_id());
let mut this = Self {
home: env.home,
symbol_to_id,
references: ReferenceMatrix::new(capacity),
direct_references: ReferenceMatrix::new(capacity),
length: capacity as u32,
};
this.symbol_to_id.push((symbol.ident_id(), i as u32));
}
for (symbol, (_, references)) in refs_by_symbol.iter() {
let def_id = this.get_id(*symbol).unwrap();
for (ident_id, def_id) in this.symbol_to_id.iter() {
let def_id = *def_id;
let references = &references[def_id as usize].0;
let symbol = Symbol::new(this.home, *ident_id);
for referenced in references.value_lookups() {
this.register_reference(def_id, *referenced);
this.register_direct_reference(def_id, *referenced);
if let Some(ref_id) = this.get_id(*referenced) {
this.references
.set_row_col(def_id as usize, ref_id as usize, true);
this.direct_references
.set_row_col(def_id as usize, ref_id as usize, true);
}
}
for referenced in references.calls() {
this.register_reference(def_id, *referenced);
this.register_direct_reference(def_id, *referenced);
if let Some(ref_id) = this.get_id(*referenced) {
this.references
.set_row_col(def_id as usize, ref_id as usize, true);
this.direct_references
.set_row_col(def_id as usize, ref_id as usize, true);
}
}
if let Some(references) = env.closures.get(symbol) {
if let Some(references) = env.closures.get(&symbol) {
for referenced in references.value_lookups() {
this.register_reference(def_id, *referenced);
if let Some(ref_id) = this.get_id(*referenced) {
this.references
.set_row_col(def_id as usize, ref_id as usize, true);
}
}
for referenced in references.calls() {
this.register_reference(def_id, *referenced);
if let Some(ref_id) = this.get_id(*referenced) {
this.references
.set_row_col(def_id as usize, ref_id as usize, true);
}
}
}
}
@ -785,6 +805,46 @@ impl DefOrdering {
this
}
// fn from_defs_by_symbol_old(
// env: &Env,
// can_defs_by_symbol: &MutMap<Symbol, Def>,
// refs_by_symbol: &MutMap<Symbol, (Region, References)>,
// ) -> Self {
// let mut this = Self::with_capacity(env.home, can_defs_by_symbol.len());
//
// for (i, symbol) in can_defs_by_symbol.keys().enumerate() {
// debug_assert_eq!(env.home, symbol.module_id());
//
// this.symbol_to_id.push((symbol.ident_id(), i as u32));
// }
//
// for (symbol, (_, references)) in refs_by_symbol.iter() {
// let def_id = this.get_id(*symbol).unwrap();
//
// for referenced in references.value_lookups() {
// this.register_reference(def_id, *referenced);
// this.register_direct_reference(def_id, *referenced);
// }
//
// for referenced in references.calls() {
// this.register_reference(def_id, *referenced);
// this.register_direct_reference(def_id, *referenced);
// }
//
// if let Some(references) = env.closures.get(symbol) {
// for referenced in references.value_lookups() {
// this.register_reference(def_id, *referenced);
// }
//
// for referenced in references.calls() {
// this.register_reference(def_id, *referenced);
// }
// }
// }
//
// this
// }
fn get_id(&self, symbol: Symbol) -> Option<u32> {
if symbol.module_id() != self.home {
return None;
@ -811,20 +871,6 @@ impl DefOrdering {
None
}
fn register_direct_reference(&mut self, id: u32, referenced: Symbol) {
if let Some(ref_id) = self.get_id(referenced) {
self.direct_references
.set_row_col(id as usize, ref_id as usize, true);
}
}
fn register_reference(&mut self, id: u32, referenced: Symbol) {
if let Some(ref_id) = self.get_id(referenced) {
self.references
.set_row_col(id as usize, ref_id as usize, true);
}
}
fn is_self_recursive(&self, id: u32) -> bool {
debug_assert!(id < self.length);
@ -848,20 +894,20 @@ impl DefOrdering {
}
#[inline(always)]
pub fn sort_can_defs(
pub(crate) fn sort_can_defs(
env: &mut Env<'_>,
defs: CanDefs,
mut output: Output,
) -> (Result<Vec<Declaration>, RuntimeError>, Output) {
let def_ids =
DefOrdering::from_defs_by_symbol(env, &defs.can_defs_by_symbol, &defs.refs_by_symbol);
let CanDefs {
refs_by_symbol,
mut can_defs_by_symbol,
symbol_to_index,
defs,
references,
aliases,
} = defs;
let def_ids = DefOrdering::from_defs_by_symbol(env, symbol_to_index, &references, defs.len());
for (symbol, alias) in aliases.into_iter() {
output.aliases.insert(symbol, alias);
}
@ -874,13 +920,7 @@ pub fn sort_can_defs(
// groups are in reversed order
for group in groups.into_iter().rev() {
group_to_declaration(
&def_ids,
&group,
&env.closures,
&mut can_defs_by_symbol,
&mut declarations,
);
group_to_declaration(&def_ids, &group, &env.closures, &defs, &mut declarations);
}
(Ok(declarations), output)
@ -931,14 +971,14 @@ pub fn sort_can_defs(
for def_id in &cycle {
let symbol = def_ids.get_symbol(*def_id).unwrap();
match refs_by_symbol.get(&symbol) {
match references.get(*def_id as usize) {
None => unreachable!(
r#"Symbol `{:?}` not found in refs_by_symbol! refs_by_symbol was: {:?}"#,
symbol, refs_by_symbol
r#"Symbol `{:?}` not found in references! references was: {:?}"#,
symbol, references
),
Some((region, _)) => {
Some((_, region)) => {
let expr_region =
can_defs_by_symbol.get(&symbol).unwrap().loc_expr.region;
defs.get(*def_id as usize).unwrap().loc_expr.region;
let entry = CycleEntry {
symbol,
@ -1016,7 +1056,7 @@ pub fn sort_can_defs(
&def_ids,
group,
&env.closures,
&mut can_defs_by_symbol,
&defs,
&mut declarations,
);
}
@ -1038,7 +1078,7 @@ fn group_to_declaration(
def_ids: &DefOrdering,
group: &[u32],
closures: &MutMap<Symbol, References>,
can_defs_by_symbol: &mut MutMap<Symbol, Def>,
defs: &[Def],
declarations: &mut Vec<Declaration>,
) {
use Declaration::*;
@ -1059,7 +1099,7 @@ fn group_to_declaration(
let def_id = cycle[0];
let symbol = def_ids.get_symbol(def_id).unwrap();
match can_defs_by_symbol.remove(&symbol) {
match defs.get(def_id as usize).cloned() {
Some(mut new_def) => {
// there is only one definition in this cycle, so we only have
// to check whether it recurses with itself; there is nobody else
@ -1094,7 +1134,7 @@ fn group_to_declaration(
// Topological sort gives us the reverse of the sorting we want!
for def_id in cycle.into_iter().rev() {
let symbol = def_ids.get_symbol(def_id).unwrap();
match can_defs_by_symbol.remove(&symbol) {
match defs.get(def_id as usize).cloned() {
Some(mut new_def) => {
// Determine recursivity of closures that are not tail-recursive
if let Closure(ClosureData {