MCPcopy Create free account
hub / github.com/chc4/lineiform / create_virtual_registers

Method create_virtual_registers

tangle/src/region.rs:252–406  ·  view source on GitHub ↗

Create and populate virtual registers for all ports

(&mut self, virts: &mut VirtualRegisterMap, token: &mut NodeOwner)

Source from the content-addressed store, hash-verified

250
251 /// Create and populate virtual registers for all ports
252 pub fn create_virtual_registers(&mut self, virts: &mut VirtualRegisterMap, token: &mut NodeOwner) {
253 let mut reg = virts.len().try_into().unwrap();
254 let mut ports = self.ports.clone();
255 // Give all ports that have no incoming edges and no storage a new virtual register
256 ports.clone().externals(Direction::Incoming).filter(|e| {
257 let e = &ports[*e];
258 (match e.variant { EdgeVariant::Data => true, _ => false }) && e.storage.is_none()
259 }).map(|e| {
260 self.ports[e].set_storage(Storage::Virtual(reg));
261 println!("gave {:?} virtual register {}", e, reg);
262 virts.insert(reg.into(), VirtualRegister { ports: vec![], hints: HashSet::new(), backing: None, allocated: false });
263 reg += 1;
264 }).for_each(drop);
265
266 // Give all ports that have a physical storage a virtual register constrained to the
267 // physical
268 ports.node_indices().clone().filter(|e| if let Some(Storage::Physical(_)) = *ports[*e].storage { true } else { false } ).map(|e| {
269 let phys = if let Some(Storage::Physical(p)) = *self.ports[e].storage { p }
270 else { panic!() };
271 self.ports[e].set_storage(Storage::Virtual(reg));
272 println!("made physical {:?} into virtual {}", e, reg);
273 let mut set = HashSet::new();
274 set.insert(phys);
275 virts.insert(reg.into(), VirtualRegister { ports: vec![], hints: set, backing: Some(phys), allocated: false });
276 reg += 1;
277 }).for_each(drop);
278 ports = self.ports.clone();
279
280 // We have a set of all the ports and edges between them
281 let mut ports_edges: Vec<_> = ports.edge_references()
282 .filter(|e| self.ports[e.source()].variant == EdgeVariant::Data ).collect();
283 ports_edges.sort_by_key(|e| self.ports[e.target()].time);
284 ports_edges.reverse();
285 // And we repeatedly propogate any edges we can. If we do propogate, we
286 // can remove it from the working set for next iteration.
287 // This is pretty slow, but who cares for now tbh.
288 //
289 // This should just be a queue that we add all source.incoming() to when
290 // we process (backwards moving frontier)
291 while ports_edges.len() > 0 {
292 println!("propogating edges, {} left", ports_edges.len());
293 println!("{:?}", ports_edges);
294 ports_edges = ports_edges.drain(..).filter(|e| {
295 let mut source = &self.ports[e.target()];
296 let mut sink = &self.ports[e.source()];
297 println!("v{} <- v{}", sink.id, source.id);
298 println!("storages {} <- {}", sink.storage, source.storage);
299 if let (None, _) = (*sink.storage, *source.storage) {
300 // We don't have a target storage to progate upwards, so
301 // have to try against next time
302 println!("skip");
303 return true
304 }
305 let (sink_backing, source_backing) = (
306 sink.storage,
307 source.storage,
308 );
309 println!("storages {} <- {}", sink.storage, source.storage);

Callers 1

regallocMethod · 0.80

Calls 8

cloneMethod · 0.80
set_storageMethod · 0.80
add_nodeMethod · 0.80
connect_inputMethod · 0.80
connect_outputMethod · 0.80
sourcesMethod · 0.80
sinksMethod · 0.80
pushMethod · 0.80

Tested by

no test coverage detected