Skip to content

Commit 9990a42

Browse files
committed
add dataflow algorithm
1 parent f1eb89f commit 9990a42

File tree

2 files changed

+79
-19
lines changed

2 files changed

+79
-19
lines changed

crates/ir/src/control.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use crate::{Expr, Prop, Time};
1+
use crate::{Direction, Expr, PortOwner, Prop, Time};
22

33
use super::{
44
Access, CompIdx, Component, Ctx, Event, ExprIdx, Fact, Foreign, InfoIdx,
5-
InstIdx, InvIdx, ParamIdx, PortIdx, PropIdx, Range, TimeIdx, TimeSub,
5+
InstIdx, InvIdx, ParamIdx, Port, PortIdx, PropIdx, Range, TimeIdx, TimeSub,
66
};
77

88
#[derive(Clone, PartialEq, Eq)]
@@ -171,6 +171,52 @@ impl InvIdx {
171171
let inst = self.inst(ctx);
172172
inst.comp(ctx)
173173
}
174+
175+
// Input ports to the iterator
176+
pub fn inputs<C>(self, ctx: &C) -> impl Iterator<Item = PortIdx> + '_
177+
where
178+
C: Ctx<Invoke> + Ctx<Port>,
179+
{
180+
let inv = ctx.get(self);
181+
inv.ports.iter().filter_map(|&port| {
182+
let Port {
183+
owner: PortOwner::Inv { dir, .. },
184+
..
185+
} = ctx.get(port)
186+
else {
187+
unreachable!("Port is not an invocation port")
188+
};
189+
190+
if *dir == Direction::In {
191+
Some(port)
192+
} else {
193+
None
194+
}
195+
})
196+
}
197+
198+
// Output ports to the iterator
199+
pub fn outputs<C>(self, ctx: &C) -> impl Iterator<Item = PortIdx> + '_
200+
where
201+
C: Ctx<Invoke> + Ctx<Port>,
202+
{
203+
let inv = ctx.get(self);
204+
inv.ports.iter().filter_map(|&port| {
205+
let Port {
206+
owner: PortOwner::Inv { dir, .. },
207+
..
208+
} = ctx.get(port)
209+
else {
210+
unreachable!("Port is not an invocation port")
211+
};
212+
213+
if *dir == Direction::Out {
214+
Some(port)
215+
} else {
216+
None
217+
}
218+
})
219+
}
174220
}
175221

176222
#[derive(Clone, PartialEq, Eq)]

crates/ir/src/utils/dataflow.rs

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,52 @@
1-
use std::collections::HashMap;
1+
use itertools::Itertools;
22

33
use super::DenseIndexInfo;
44
use crate::{self as ir, Ctx};
55

66
/// Dataflow graph of a component
77
#[derive(Clone)]
88
pub struct Dataflow {
9-
preds: HashMap<ir::Port, Vec<ir::Port>>,
10-
succs: HashMap<ir::Port, Vec<ir::Port>>,
9+
pub preds: DenseIndexInfo<ir::Port, Vec<ir::PortIdx>>,
10+
pub succs: DenseIndexInfo<ir::Port, Vec<ir::PortIdx>>,
1111
}
1212

1313
impl From<&ir::Component> for Dataflow {
1414
fn from(comp: &ir::Component) -> Self {
15-
let mut preds = DenseIndexInfo::with_default(comp.ports().len());
16-
let mut succs = DenseIndexInfo::with_default(comp.ports().len());
15+
let mut preds: DenseIndexInfo<ir::Port, Vec<_>> =
16+
DenseIndexInfo::with_default(comp.ports().len());
17+
let mut succs: DenseIndexInfo<ir::Port, Vec<_>> =
18+
DenseIndexInfo::with_default(comp.ports().len());
1719

1820
for cmd in &comp.cmds {
1921
match cmd {
2022
crate::Command::Invoke(idx) => {
21-
let inv = comp.get(*idx);
22-
for port in &inv.ports {
23-
for &pred in &port.pred {
24-
preds.insert(*port, pred);
23+
let inputs = idx.inputs(comp);
24+
let outputs = idx.outputs(comp).collect_vec();
25+
26+
for pred in inputs {
27+
for succ in &outputs {
28+
preds.get_mut(*succ).push(pred);
29+
succs.get_mut(pred).push(*succ);
2530
}
2631
}
2732
}
28-
crate::Command::Instance(idx) => todo!(),
29-
crate::Command::BundleDef(idx) => todo!(),
30-
crate::Command::Connect(connect) => todo!(),
31-
crate::Command::Let(_) => todo!(),
32-
crate::Command::ForLoop(_) => todo!(),
33-
crate::Command::If(_) => todo!(),
34-
crate::Command::Fact(fact) => todo!(),
35-
crate::Command::Exists(exists) => todo!(),
33+
crate::Command::Connect(ir::Connect { src, dst, .. }) => {
34+
assert!(src.is_port(comp) && dst.is_port(comp), "Bundles should be resolved before constructing dataflow");
35+
36+
preds.get_mut(dst.port).push(src.port);
37+
succs.get_mut(src.port).push(dst.port);
38+
}
39+
crate::Command::BundleDef(_)
40+
| crate::Command::ForLoop(_)
41+
| crate::Command::If(_) => {
42+
unreachable!(
43+
"Components should be monomorphic and bundle-free"
44+
)
45+
}
46+
crate::Command::Instance(_)
47+
| crate::Command::Let(_)
48+
| crate::Command::Fact(_)
49+
| crate::Command::Exists(_) => {}
3650
}
3751
}
3852

0 commit comments

Comments
 (0)