mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 15:59:20 +03:00
Merge pull request #3015 from rtfeldman/matrix-more-bitvec
Matrix more bitvec
This commit is contained in:
commit
e8c2e96879
@ -192,17 +192,12 @@ fn sort_type_defs_before_introduction(
|
||||
}
|
||||
|
||||
// find the strongly connected components and their relations
|
||||
let nodes: Vec<_> = (0..capacity as u32).collect();
|
||||
|
||||
let mut output = Vec::with_capacity(capacity);
|
||||
|
||||
for group in matrix.strongly_connected_components(&nodes).groups() {
|
||||
for index in group.iter_ones() {
|
||||
output.push(symbols[index])
|
||||
}
|
||||
}
|
||||
|
||||
output
|
||||
matrix
|
||||
.strongly_connected_components_all()
|
||||
.groups()
|
||||
.flat_map(|group| group.iter_ones())
|
||||
.map(|index| symbols[index])
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@ -790,14 +785,10 @@ pub(crate) fn sort_can_defs(
|
||||
};
|
||||
}
|
||||
|
||||
let nodes: Vec<_> = (0..defs.len() as u32).collect();
|
||||
|
||||
// We first perform SCC based on any reference, both variable usage and calls
|
||||
// considering both value definitions and function bodies. This will spot any
|
||||
// recursive relations between any 2 definitions.
|
||||
let sccs = def_ordering
|
||||
.references
|
||||
.strongly_connected_components(&nodes);
|
||||
let sccs = def_ordering.references.strongly_connected_components_all();
|
||||
|
||||
let mut declarations = Vec::new();
|
||||
|
||||
@ -838,10 +829,9 @@ pub(crate) fn sort_can_defs(
|
||||
// boom = \{} -> boom {}
|
||||
//
|
||||
// In general we cannot spot faulty recursion (halting problem) so this is our best attempt
|
||||
let nodes: Vec<_> = group.iter_ones().map(|v| v as u32).collect();
|
||||
let direct_sccs = def_ordering
|
||||
.direct_references
|
||||
.strongly_connected_components(&nodes);
|
||||
.strongly_connected_components_subset(group);
|
||||
|
||||
let declaration = if direct_sccs.groups().count() == 1 {
|
||||
// all defs are part of the same direct cycle, that is invalid!
|
||||
@ -1571,8 +1561,7 @@ fn correct_mutual_recursive_type_alias<'a>(
|
||||
|
||||
let mut solved_aliases = bitvec::vec::BitVec::<usize>::repeat(false, capacity);
|
||||
|
||||
let group: Vec<_> = (0u32..capacity as u32).collect();
|
||||
let sccs = matrix.strongly_connected_components(&group);
|
||||
let sccs = matrix.strongly_connected_components_all();
|
||||
|
||||
// scratchpad to store aliases that are modified in the current iteration.
|
||||
// Only used when there is are more than one alias in a group. See below why
|
||||
|
@ -129,8 +129,14 @@ impl ReferenceMatrix {
|
||||
TopologicalSort::Groups { groups }
|
||||
}
|
||||
|
||||
/// Get the strongly-connected components of the set of input nodes.
|
||||
pub fn strongly_connected_components(&self, nodes: &[u32]) -> Sccs {
|
||||
/// Get the strongly-connected components all nodes in the matrix
|
||||
pub fn strongly_connected_components_all(&self) -> Sccs {
|
||||
let bitvec = BitVec::repeat(true, self.length);
|
||||
self.strongly_connected_components_subset(&bitvec)
|
||||
}
|
||||
|
||||
/// Get the strongly-connected components of a set of input nodes.
|
||||
pub fn strongly_connected_components_subset(&self, nodes: &BitSlice) -> Sccs {
|
||||
let mut params = Params::new(self.length, nodes);
|
||||
|
||||
'outer: loop {
|
||||
@ -176,15 +182,15 @@ struct Params {
|
||||
p: Vec<u32>,
|
||||
s: Vec<u32>,
|
||||
scc: Sccs,
|
||||
scca: Vec<u32>,
|
||||
scca: BitVec,
|
||||
}
|
||||
|
||||
impl Params {
|
||||
fn new(length: usize, group: &[u32]) -> Self {
|
||||
fn new(length: usize, group: &BitSlice) -> Self {
|
||||
let mut preorders = vec![Preorder::Removed; length];
|
||||
|
||||
for value in group {
|
||||
preorders[*value as usize] = Preorder::Empty;
|
||||
for index in group.iter_ones() {
|
||||
preorders[index] = Preorder::Empty;
|
||||
}
|
||||
|
||||
Self {
|
||||
@ -196,7 +202,7 @@ impl Params {
|
||||
matrix: ReferenceMatrix::new(length),
|
||||
components: 0,
|
||||
},
|
||||
scca: Vec::new(),
|
||||
scca: BitVec::repeat(false, length),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,7 +216,7 @@ fn recurse_onto(length: usize, bitvec: &BitVec, v: usize, params: &mut Params) {
|
||||
params.p.push(v as u32);
|
||||
|
||||
for w in bitvec[v * length..][..length].iter_ones() {
|
||||
if !params.scca.contains(&(w as u32)) {
|
||||
if !params.scca[w] {
|
||||
match params.preorders[w] {
|
||||
Preorder::Filled(pw) => loop {
|
||||
let index = *params.p.last().unwrap();
|
||||
@ -241,7 +247,7 @@ fn recurse_onto(length: usize, bitvec: &BitVec, v: usize, params: &mut Params) {
|
||||
.scc
|
||||
.matrix
|
||||
.set_row_col(params.scc.components, node as usize, true);
|
||||
params.scca.push(node);
|
||||
params.scca.set(node as usize, true);
|
||||
params.preorders[node as usize] = Preorder::Removed;
|
||||
if node as usize == v {
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user