chandeliers_san/causality/
mod.rs1use chandeliers_err::EAccum;
10
11use crate::ast;
12use crate::sp::Sp;
13
14pub mod depends;
15pub mod graph;
16
17use depends::Reference;
18use graph::Graph;
19
20pub trait Causality: Sized {
23 fn causality(self, eaccum: &mut EAccum) -> Option<Self>;
27}
28
29impl Causality for ast::decl::Prog {
30 fn causality(self, eaccum: &mut EAccum) -> Option<Self> {
32 let Self { decls } = self;
33 let mut g = Graph::default();
34 for decl in decls {
35 g.insert(decl.causality(eaccum)?);
36 }
37 let decls = g.scheduling(eaccum)?;
38 Some(Self { decls })
39 }
40}
41
42impl<T: Causality> Causality for Sp<T> {
43 fn causality(self, eaccum: &mut EAccum) -> Option<Self> {
45 self.map(|_, t| t.causality(eaccum)).transpose()
46 }
47}
48
49impl Causality for ast::decl::Decl {
50 fn causality(self, eaccum: &mut EAccum) -> Option<Self> {
52 Some(match self {
53 Self::Node(n) => Self::Node(n.causality(eaccum)?),
54 _ => self,
55 })
56 }
57}
58
59impl Causality for ast::decl::Node {
60 fn causality(self, eaccum: &mut EAccum) -> Option<Self> {
65 let Self {
66 name,
67 options,
68 inputs,
69 outputs,
70 locals,
71 blocks,
72 deptys,
73 stmts,
74 registers,
75 flips,
76 } = self;
77 let mut g = Graph::default();
78 for i in inputs.t.iter() {
79 g.already_provided(&Reference::LocalVarName(
80 i.t.name.as_ref().map(|_, t| t.repr.t.clone()),
81 ));
82 }
83 for stmt in stmts {
84 g.insert(stmt);
85 }
86 for l in locals.t.iter() {
88 let unit = Reference::LocalVarName(l.t.name.as_ref().map(|_, t| t.repr.t.clone()));
89 g.must_provide(eaccum, &unit)?;
90 }
91 for o in outputs.t.iter() {
92 let unit = Reference::LocalVarName(o.t.name.as_ref().map(|_, t| t.repr.t.clone()));
93 g.must_provide(eaccum, &unit)?;
94 }
95 let stmts = g.scheduling(eaccum)?;
97 Some(Self {
98 name,
99 options,
100 inputs,
101 outputs,
102 locals,
103 blocks,
104 deptys,
105 stmts,
106 registers,
107 flips,
108 })
109 }
110}