feat(ir): use petgraph
This commit is contained in:
37
src/ir/graph.rs
Normal file
37
src/ir/graph.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
use hashbrown::HashMap;
|
||||
use petgraph::graph::{DiGraph, NodeIndex};
|
||||
use petgraph::algo::{condensation, toposort};
|
||||
|
||||
use super::*;
|
||||
|
||||
struct GraphBuilder<'ctx> {
|
||||
ctx: &'ctx DowngradeContext,
|
||||
graph: DiGraph<usize, ()>,
|
||||
nodes: HashMap<usize, NodeIndex>
|
||||
}
|
||||
|
||||
impl GraphBuilder<'_> {
|
||||
fn connect(&mut self, idx: usize) {
|
||||
let node = self.graph.add_node(idx);
|
||||
self.nodes.insert(idx, node);
|
||||
let deps = self.ctx.thunk_deps.get(idx).unwrap();
|
||||
for (&refee, _) in deps {
|
||||
if !self.nodes.contains_key(&refee) {
|
||||
self.connect(refee);
|
||||
}
|
||||
self.graph.add_edge(node, *self.nodes.get(&refee).unwrap(), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sort_dependencies(ctx: &DowngradeContext) -> Vec<Vec<usize>> {
|
||||
let mut builder = GraphBuilder {
|
||||
ctx,
|
||||
graph: DiGraph::new(),
|
||||
nodes: HashMap::new(),
|
||||
};
|
||||
builder.connect(ctx.thunks.len() - 1);
|
||||
let mut graph = condensation(builder.graph, false);
|
||||
let sorted = toposort(&graph, None).unwrap();
|
||||
sorted.into_iter().map(|idx| graph.remove_node(idx).unwrap()).collect_vec()
|
||||
}
|
||||
Reference in New Issue
Block a user