Skip to content

Commit d0d0555

Browse files
committed
mono rewrite
1 parent e540ae6 commit d0d0555

File tree

5 files changed

+491
-86
lines changed

5 files changed

+491
-86
lines changed
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
use super::{Base, Underlying};
2+
use fil_ir as ir;
3+
use std::collections::HashMap;
4+
use std::hash::Hash;
5+
6+
/// Generic mapping with debug info and better error messages
7+
pub struct MonoMapping<K, V> {
8+
map: HashMap<K, V>,
9+
name: &'static str,
10+
debug_mode: bool,
11+
}
12+
13+
impl<K, V> MonoMapping<K, V>
14+
where
15+
K: Hash + Eq + Copy,
16+
V: Copy,
17+
{
18+
pub fn new(name: &'static str) -> Self {
19+
Self {
20+
map: HashMap::new(),
21+
name,
22+
debug_mode: std::env::var("FIL_MONO_DEBUG").is_ok(),
23+
}
24+
}
25+
26+
/// Insert a new mapping, warning if overwriting
27+
pub fn insert(&mut self, key: K, value: V) {
28+
if let Some(_old) = self.map.insert(key, value) {
29+
if self.debug_mode {
30+
eprintln!("{}: Overwrote existing mapping", self.name);
31+
}
32+
} else if self.debug_mode {
33+
eprintln!("{}: Added new mapping", self.name);
34+
}
35+
}
36+
37+
/// Get a mapping, panicking with detailed context if not found
38+
pub fn get(&self, key: K) -> V {
39+
*self.map.get(&key).unwrap_or_else(|| {
40+
panic!(
41+
"{}: Missing key. Available keys: {}",
42+
self.name,
43+
self.map.len()
44+
)
45+
})
46+
}
47+
48+
/// Try to get a mapping, returning None if not found
49+
pub fn find(&self, key: K) -> Option<V> {
50+
let result = self.map.get(&key).copied();
51+
if self.debug_mode && result.is_none() {
52+
eprintln!("{}: Key not found", self.name);
53+
}
54+
result
55+
}
56+
57+
/// Check if a key exists
58+
pub fn contains_key(&self, key: K) -> bool {
59+
self.map.contains_key(&key)
60+
}
61+
62+
/// Get the number of mappings
63+
pub fn len(&self) -> usize {
64+
self.map.len()
65+
}
66+
67+
/// Check if the mapping is empty
68+
pub fn is_empty(&self) -> bool {
69+
self.map.is_empty()
70+
}
71+
72+
/// Iterate over all mappings
73+
pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
74+
self.map.iter()
75+
}
76+
77+
/// Clear all mappings
78+
pub fn clear(&mut self) {
79+
if self.debug_mode && !self.map.is_empty() {
80+
eprintln!("{}: Clearing {} mappings", self.name, self.map.len());
81+
}
82+
self.map.clear();
83+
}
84+
}
85+
86+
impl<K, V> Default for MonoMapping<K, V>
87+
where
88+
K: Hash + Eq + Copy,
89+
V: Copy,
90+
{
91+
fn default() -> Self {
92+
Self::new("default")
93+
}
94+
}
95+
96+
/// Specialized port mapping that handles complex composite keys
97+
pub struct PortMapping {
98+
map: HashMap<
99+
(Option<Base<ir::Invoke>>, Underlying<ir::Port>),
100+
Base<ir::Port>,
101+
>,
102+
debug_mode: bool,
103+
}
104+
105+
impl PortMapping {
106+
pub fn new() -> Self {
107+
Self {
108+
map: HashMap::new(),
109+
debug_mode: std::env::var("FIL_MONO_DEBUG").is_ok(),
110+
}
111+
}
112+
113+
/// Insert a port mapping
114+
pub fn insert(
115+
&mut self,
116+
inv: Option<Base<ir::Invoke>>,
117+
old_port: Underlying<ir::Port>,
118+
new_port: Base<ir::Port>,
119+
) {
120+
let key = (inv, old_port);
121+
if let Some(_old) = self.map.insert(key, new_port) {
122+
if self.debug_mode {
123+
eprintln!("PortMapping: Overwrote existing port mapping");
124+
}
125+
} else if self.debug_mode {
126+
eprintln!("PortMapping: Added new port mapping");
127+
}
128+
}
129+
130+
/// Get a port mapping, returning None if not found
131+
pub fn get(
132+
&self,
133+
inv: Option<Base<ir::Invoke>>,
134+
old_port: Underlying<ir::Port>,
135+
) -> Option<Base<ir::Port>> {
136+
let key = (inv, old_port);
137+
let result = self.map.get(&key).copied();
138+
if self.debug_mode && result.is_none() {
139+
eprintln!("PortMapping: Port key not found");
140+
}
141+
result
142+
}
143+
144+
/// Get a port mapping, panicking if not found
145+
pub fn expect(
146+
&self,
147+
inv: Option<Base<ir::Invoke>>,
148+
old_port: Underlying<ir::Port>,
149+
) -> Base<ir::Port> {
150+
let key = (inv, old_port);
151+
*self.map.get(&key).unwrap_or_else(|| {
152+
panic!(
153+
"PortMapping: Missing port key. Available keys: {}",
154+
self.map.len()
155+
)
156+
})
157+
}
158+
159+
/// Check if a port mapping exists
160+
pub fn contains_key(
161+
&self,
162+
inv: Option<Base<ir::Invoke>>,
163+
old_port: Underlying<ir::Port>,
164+
) -> bool {
165+
self.map.contains_key(&(inv, old_port))
166+
}
167+
168+
/// Get the number of mappings
169+
pub fn len(&self) -> usize {
170+
self.map.len()
171+
}
172+
173+
/// Check if the mapping is empty
174+
pub fn is_empty(&self) -> bool {
175+
self.map.is_empty()
176+
}
177+
178+
/// Clear all mappings
179+
pub fn clear(&mut self) {
180+
if self.debug_mode && !self.map.is_empty() {
181+
eprintln!("PortMapping: Clearing {} mappings", self.map.len());
182+
}
183+
self.map.clear();
184+
}
185+
}
186+
187+
impl Default for PortMapping {
188+
fn default() -> Self {
189+
Self::new()
190+
}
191+
}
192+
193+
/// Type aliases for commonly used mappings
194+
pub type EventMapping = MonoMapping<Underlying<ir::Event>, Base<ir::Event>>;
195+
pub type ParamMapping = MonoMapping<Underlying<ir::Param>, Base<ir::Param>>;
196+
pub type InstanceMapping =
197+
MonoMapping<Underlying<ir::Instance>, Base<ir::Instance>>;
198+
pub type InvokeMapping = MonoMapping<Underlying<ir::Invoke>, Base<ir::Invoke>>;

crates/filament/src/ir_passes/mono/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
mod global;
2+
mod mappings;
23
mod monodeferred;
34
mod monomorphize;
45
mod monosig;
6+
mod param_resolver;
57
mod utils;
68

79
pub(super) use global::{CompKey, InstanceInfo};
10+
pub(super) use mappings::{
11+
EventMapping, InstanceMapping, InvokeMapping, ParamMapping, PortMapping,
12+
};
813
pub(super) use monodeferred::MonoDeferred;
914
pub(super) use monosig::MonoSig;
15+
pub(super) use param_resolver::ParamResolver;
1016
pub(super) use utils::{
1117
Base, BaseComp, IntoBase, IntoUdl, Underlying, UnderlyingComp,
1218
};

crates/filament/src/ir_passes/mono/monodeferred.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl MonoDeferred<'_, '_> {
4545

4646
/// The [CompKey] associated with the underlying component being monomorphized.
4747
fn comp_key(&self) -> CompKey {
48-
let binding = self.monosig.binding.inner();
48+
let binding = self.monosig.resolver.inner();
4949
let conc_params = if self.underlying.is_ext() {
5050
vec![]
5151
} else {
@@ -73,7 +73,7 @@ impl MonoDeferred<'_, '_> {
7373
// Add events without monomorphizing their data. The data is updated after the body is monomorphized
7474
// because it can mention existential parameters.
7575
let new_idx = monosig.base.add(event.clone());
76-
monosig.event_map.insert(idx.ul(), new_idx);
76+
monosig.events.insert(idx.ul(), new_idx);
7777
pass.inst_info_mut(comp_k.clone())
7878
.add_event(idx.ul(), new_idx);
7979
}
@@ -129,14 +129,19 @@ impl MonoDeferred<'_, '_> {
129129
for (idx, _) in
130130
self.underlying.ports().iter().filter(|(_, p)| p.is_sig())
131131
{
132-
let port_key = (None, idx.ul());
133-
let base = self.monosig.port_map[&port_key];
132+
let base = self.monosig.ports.expect(None, idx.ul());
134133
self.monosig
135134
.port_data(&self.underlying, self.pass, idx.ul(), base);
136135
}
137136

138137
// Handle event delays after monomorphization because delays might mention existential parameters.
139-
for (old, &new) in self.monosig.event_map.clone().iter() {
138+
let events: Vec<_> = self
139+
.monosig
140+
.events
141+
.iter()
142+
.map(|(&old, &new)| (old, new))
143+
.collect();
144+
for (old, new) in events {
140145
self.monosig
141146
.event_delay(&self.underlying, self.pass, old, new);
142147
}
@@ -147,7 +152,7 @@ impl MonoDeferred<'_, '_> {
147152

148153
/// Add to the parameter binding
149154
pub fn push_binding(&mut self, p: Underlying<ir::Param>, v: u64) {
150-
self.monosig.binding.push(p, v);
155+
self.monosig.resolver.push(p, v);
151156
}
152157

153158
/// Monomorphize a component definition
@@ -173,7 +178,7 @@ impl MonoDeferred<'_, '_> {
173178
self.underlying.display(param)
174179
)
175180
};
176-
self.monosig.binding.push(param, v);
181+
self.monosig.resolver.push(param, v);
177182
}
178183

179184
// Monomorphize the rest of the signature
@@ -241,16 +246,16 @@ impl MonoDeferred<'_, '_> {
241246

242247
while i < bound {
243248
let index = index.ul();
244-
let orig_l = self.monosig.binding.len();
245-
self.monosig.binding.push(index, i);
249+
let orig_l = self.monosig.resolver.len();
250+
self.monosig.resolver.push(index, i);
246251
for cmd in body.iter() {
247252
let cmd = self.command(cmd);
248253
self.monosig.base.extend_cmds(cmd);
249254
}
250255
// Remove all the bindings added in this scope including the index
251256
self.monosig
252-
.binding
253-
.pop_n(self.monosig.binding.len() - orig_l);
257+
.resolver
258+
.pop_n(self.monosig.resolver.len() - orig_l);
254259
i += 1;
255260
}
256261
}
@@ -295,7 +300,7 @@ impl MonoDeferred<'_, '_> {
295300

296301
if !params
297302
.into_iter()
298-
.all(|idx| self.monosig.binding.get(&idx).is_some())
303+
.all(|idx| self.monosig.resolver.get(&idx).is_some())
299304
{
300305
// Discards the assertion if it references parameters that can't be resolved (bundle parameters, etc)
301306
// TODO(edmund): Find a better solution to this - we should resolve bundle assertions when bundles are unrolled.
@@ -357,7 +362,7 @@ impl MonoDeferred<'_, '_> {
357362
self.monosig.base.comp().display(e)
358363
)
359364
};
360-
self.monosig.binding.push(p, v);
365+
self.monosig.resolver.push(p, v);
361366
None
362367
}
363368
ir::Command::Connect(con) => Some(self.connect(con).into()),

0 commit comments

Comments
 (0)