sim: add .dot output for Assignments graph for debugging
This commit is contained in:
		
							parent
							
								
									564ccb30bc
								
							
						
					
					
						commit
						6b31e6d515
					
				
					 2 changed files with 342 additions and 43 deletions
				
			
		|  | @ -42,8 +42,12 @@ use bitvec::{bits, order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView}; | ||||||
| use hashbrown::{HashMap, HashSet}; | use hashbrown::{HashMap, HashSet}; | ||||||
| use num_bigint::BigInt; | use num_bigint::BigInt; | ||||||
| use num_traits::{Signed, ToPrimitive, Zero}; | use num_traits::{Signed, ToPrimitive, Zero}; | ||||||
| use petgraph::visit::{ | use petgraph::{ | ||||||
|     GraphBase, IntoNeighbors, IntoNeighborsDirected, IntoNodeIdentifiers, VisitMap, Visitable, |     data::FromElements, | ||||||
|  |     visit::{ | ||||||
|  |         EdgeRef, GraphBase, IntoEdgeReferences, IntoNeighbors, IntoNeighborsDirected, | ||||||
|  |         IntoNodeIdentifiers, IntoNodeReferences, NodeRef, VisitMap, Visitable, | ||||||
|  |     }, | ||||||
| }; | }; | ||||||
| use std::{borrow::Cow, collections::BTreeSet, fmt, marker::PhantomData, mem, ops::IndexMut}; | use std::{borrow::Cow, collections::BTreeSet, fmt, marker::PhantomData, mem, ops::IndexMut}; | ||||||
| 
 | 
 | ||||||
|  | @ -384,8 +388,8 @@ impl CompiledExpr<Array> { | ||||||
| #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||||||
| enum AssignmentOrSlotIndex { | enum AssignmentOrSlotIndex { | ||||||
|     AssignmentIndex(usize), |     AssignmentIndex(usize), | ||||||
|     SmallSlots(StatePartIndex<StatePartKindSmallSlots>), |     SmallSlot(StatePartIndex<StatePartKindSmallSlots>), | ||||||
|     BigSlots(StatePartIndex<StatePartKindBigSlots>), |     BigSlot(StatePartIndex<StatePartKindBigSlots>), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||||||
|  | @ -408,6 +412,15 @@ enum AssignmentIO { | ||||||
|     }, |     }, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||||||
|  | enum AssignmentsEdge { | ||||||
|  |     IO(AssignmentIO), | ||||||
|  |     AssignmentImmediatePredecessor { | ||||||
|  |         predecessor_assignment_index: usize, | ||||||
|  |         assignment_index: usize, | ||||||
|  |     }, | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| enum Assignments { | enum Assignments { | ||||||
|     Accumulating { |     Accumulating { | ||||||
|  | @ -415,6 +428,7 @@ enum Assignments { | ||||||
|     }, |     }, | ||||||
|     Finalized { |     Finalized { | ||||||
|         assignments: Box<[Assignment]>, |         assignments: Box<[Assignment]>, | ||||||
|  |         slots_layout: TypeLayout<InsnsBuildingDone>, | ||||||
|         slot_readers: SlotToAssignmentIndexFullMap, |         slot_readers: SlotToAssignmentIndexFullMap, | ||||||
|         slot_writers: SlotToAssignmentIndexFullMap, |         slot_writers: SlotToAssignmentIndexFullMap, | ||||||
|         assignment_immediate_predecessors: Box<[Box<[usize]>]>, |         assignment_immediate_predecessors: Box<[Box<[usize]>]>, | ||||||
|  | @ -431,13 +445,13 @@ impl Default for Assignments { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Assignments { | impl Assignments { | ||||||
|     fn finalize(&mut self, slots_len: TypeLen) { |     fn finalize(&mut self, slots_layout: TypeLayout<InsnsBuildingDone>) { | ||||||
|         let Self::Accumulating { assignments } = self else { |         let Self::Accumulating { assignments } = self else { | ||||||
|             unreachable!("already finalized"); |             unreachable!("already finalized"); | ||||||
|         }; |         }; | ||||||
|         let assignments = mem::take(assignments).into_boxed_slice(); |         let assignments = mem::take(assignments).into_boxed_slice(); | ||||||
|         let mut slot_readers = SlotToAssignmentIndexFullMap::new(slots_len); |         let mut slot_readers = SlotToAssignmentIndexFullMap::new(slots_layout.len()); | ||||||
|         let mut slot_writers = SlotToAssignmentIndexFullMap::new(slots_len); |         let mut slot_writers = SlotToAssignmentIndexFullMap::new(slots_layout.len()); | ||||||
|         let mut assignment_immediate_predecessors = vec![BTreeSet::new(); assignments.len()]; |         let mut assignment_immediate_predecessors = vec![BTreeSet::new(); assignments.len()]; | ||||||
|         let mut assignment_immediate_successors = vec![BTreeSet::new(); assignments.len()]; |         let mut assignment_immediate_successors = vec![BTreeSet::new(); assignments.len()]; | ||||||
|         for (assignment_index, assignment) in assignments.iter().enumerate() { |         for (assignment_index, assignment) in assignments.iter().enumerate() { | ||||||
|  | @ -465,6 +479,7 @@ impl Assignments { | ||||||
|         } |         } | ||||||
|         *self = Self::Finalized { |         *self = Self::Finalized { | ||||||
|             assignments, |             assignments, | ||||||
|  |             slots_layout, | ||||||
|             slot_readers, |             slot_readers, | ||||||
|             slot_writers, |             slot_writers, | ||||||
|             assignment_immediate_predecessors: assignment_immediate_predecessors |             assignment_immediate_predecessors: assignment_immediate_predecessors | ||||||
|  | @ -489,6 +504,12 @@ impl Assignments { | ||||||
|         }; |         }; | ||||||
|         assignments |         assignments | ||||||
|     } |     } | ||||||
|  |     fn slots_layout(&self) -> TypeLayout<InsnsBuildingDone> { | ||||||
|  |         let Self::Finalized { slots_layout, .. } = self else { | ||||||
|  |             unreachable!("Assignments::finalize should have been called"); | ||||||
|  |         }; | ||||||
|  |         *slots_layout | ||||||
|  |     } | ||||||
|     fn slot_readers(&self) -> &SlotToAssignmentIndexFullMap { |     fn slot_readers(&self) -> &SlotToAssignmentIndexFullMap { | ||||||
|         let Self::Finalized { slot_readers, .. } = self else { |         let Self::Finalized { slot_readers, .. } = self else { | ||||||
|             unreachable!("Assignments::finalize should have been called"); |             unreachable!("Assignments::finalize should have been called"); | ||||||
|  | @ -521,46 +542,131 @@ impl Assignments { | ||||||
|         }; |         }; | ||||||
|         assignment_immediate_successors |         assignment_immediate_successors | ||||||
|     } |     } | ||||||
|  |     fn elements(&self) -> AssignmentsElements<'_> { | ||||||
|  |         let SlotToAssignmentIndexFullMap(TypeParts { | ||||||
|  |             small_slots, | ||||||
|  |             big_slots, | ||||||
|  |         }) = self.slot_readers(); | ||||||
|  |         AssignmentsElements { | ||||||
|  |             node_indexes: HashMap::with_capacity( | ||||||
|  |                 self.assignments().len() + small_slots.len() + big_slots.len(), | ||||||
|  |             ), | ||||||
|  |             nodes: self.node_references(), | ||||||
|  |             edges: self.edge_references(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl GraphBase for Assignments { | impl GraphBase for Assignments { | ||||||
|     type EdgeId = AssignmentIO; |     type EdgeId = AssignmentsEdge; | ||||||
|     type NodeId = AssignmentOrSlotIndex; |     type NodeId = AssignmentOrSlotIndex; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[derive(Debug, Clone, Copy)] | ||||||
|  | enum AssignmentsNodeRef<'a> { | ||||||
|  |     Assignment { | ||||||
|  |         index: usize, | ||||||
|  |         assignment: &'a Assignment, | ||||||
|  |     }, | ||||||
|  |     SmallSlot(StatePartIndex<StatePartKindSmallSlots>, SlotDebugData), | ||||||
|  |     BigSlot(StatePartIndex<StatePartKindBigSlots>, SlotDebugData), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'a> NodeRef for AssignmentsNodeRef<'a> { | ||||||
|  |     type NodeId = AssignmentOrSlotIndex; | ||||||
|  |     type Weight = AssignmentsNodeRef<'a>; | ||||||
|  | 
 | ||||||
|  |     fn id(&self) -> Self::NodeId { | ||||||
|  |         match *self { | ||||||
|  |             AssignmentsNodeRef::Assignment { | ||||||
|  |                 index, | ||||||
|  |                 assignment: _, | ||||||
|  |             } => AssignmentOrSlotIndex::AssignmentIndex(index), | ||||||
|  |             AssignmentsNodeRef::SmallSlot(slot, _) => AssignmentOrSlotIndex::SmallSlot(slot), | ||||||
|  |             AssignmentsNodeRef::BigSlot(slot, _) => AssignmentOrSlotIndex::BigSlot(slot), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn weight(&self) -> &Self::Weight { | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'a> petgraph::visit::Data for &'a Assignments { | ||||||
|  |     type NodeWeight = AssignmentsNodeRef<'a>; | ||||||
|  |     type EdgeWeight = AssignmentsEdge; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct AssignmentsElements<'a> { | ||||||
|  |     node_indexes: HashMap<AssignmentOrSlotIndex, usize>, | ||||||
|  |     nodes: AssignmentsNodes<'a>, | ||||||
|  |     edges: AssignmentsEdges<'a>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'a> Iterator for AssignmentsElements<'a> { | ||||||
|  |     type Item = petgraph::data::Element< | ||||||
|  |         <&'a Assignments as petgraph::visit::Data>::NodeWeight, | ||||||
|  |         <&'a Assignments as petgraph::visit::Data>::EdgeWeight, | ||||||
|  |     >; | ||||||
|  | 
 | ||||||
|  |     fn next(&mut self) -> Option<Self::Item> { | ||||||
|  |         let Self { | ||||||
|  |             node_indexes, | ||||||
|  |             nodes, | ||||||
|  |             edges, | ||||||
|  |         } = self; | ||||||
|  |         if let Some(node) = nodes.next() { | ||||||
|  |             node_indexes.insert(node.id(), node_indexes.len()); | ||||||
|  |             return Some(petgraph::data::Element::Node { weight: node }); | ||||||
|  |         } | ||||||
|  |         let edge = edges.next()?; | ||||||
|  |         Some(petgraph::data::Element::Edge { | ||||||
|  |             source: node_indexes[&edge.source()], | ||||||
|  |             target: node_indexes[&edge.target()], | ||||||
|  |             weight: *edge.weight(), | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Clone)] | ||||||
| struct AssignmentsNodeIdentifiers { | struct AssignmentsNodeIdentifiers { | ||||||
|     assignment_indexes: std::ops::Range<usize>, |     assignment_indexes: std::ops::Range<usize>, | ||||||
|     small_slots: std::ops::Range<u32>, |     small_slots: std::ops::Range<u32>, | ||||||
|     big_slots: std::ops::Range<u32>, |     big_slots: std::ops::Range<u32>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Iterator for AssignmentsNodeIdentifiers { | impl AssignmentsNodeIdentifiers { | ||||||
|     type Item = AssignmentOrSlotIndex; |     fn internal_iter<'a>(&'a mut self) -> impl Iterator<Item = AssignmentOrSlotIndex> + 'a { | ||||||
|     fn next(&mut self) -> Option<Self::Item> { |  | ||||||
|         let Self { |         let Self { | ||||||
|             assignment_indexes, |             assignment_indexes, | ||||||
|             small_slots, |             small_slots, | ||||||
|             big_slots, |             big_slots, | ||||||
|         } = self; |         } = self; | ||||||
|         assignment_indexes |         assignment_indexes | ||||||
|             .next() |  | ||||||
|             .map(AssignmentOrSlotIndex::AssignmentIndex) |             .map(AssignmentOrSlotIndex::AssignmentIndex) | ||||||
|             .or_else(|| { |             .chain(small_slots.map(|value| { | ||||||
|                 small_slots.next().map(|value| { |                 AssignmentOrSlotIndex::SmallSlot(StatePartIndex { | ||||||
|                     AssignmentOrSlotIndex::SmallSlots(StatePartIndex { |  | ||||||
|                     value, |                     value, | ||||||
|                     _phantom: PhantomData, |                     _phantom: PhantomData, | ||||||
|                 }) |                 }) | ||||||
|                 }) |             })) | ||||||
|             }) |             .chain(big_slots.map(|value| { | ||||||
|             .or_else(|| { |                 AssignmentOrSlotIndex::BigSlot(StatePartIndex { | ||||||
|                 big_slots.next().map(|value| { |  | ||||||
|                     AssignmentOrSlotIndex::BigSlots(StatePartIndex { |  | ||||||
|                     value, |                     value, | ||||||
|                     _phantom: PhantomData, |                     _phantom: PhantomData, | ||||||
|                 }) |                 }) | ||||||
|                 }) |             })) | ||||||
|             }) |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Iterator for AssignmentsNodeIdentifiers { | ||||||
|  |     type Item = AssignmentOrSlotIndex; | ||||||
|  |     fn next(&mut self) -> Option<Self::Item> { | ||||||
|  |         self.internal_iter().next() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn nth(&mut self, n: usize) -> Option<Self::Item> { | ||||||
|  |         self.internal_iter().nth(n) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -580,6 +686,44 @@ impl<'a> IntoNodeIdentifiers for &'a Assignments { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | struct AssignmentsNodes<'a> { | ||||||
|  |     assignments: &'a Assignments, | ||||||
|  |     nodes: AssignmentsNodeIdentifiers, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'a> Iterator for AssignmentsNodes<'a> { | ||||||
|  |     type Item = AssignmentsNodeRef<'a>; | ||||||
|  | 
 | ||||||
|  |     fn next(&mut self) -> Option<Self::Item> { | ||||||
|  |         self.nodes.next().map(|node| match node { | ||||||
|  |             AssignmentOrSlotIndex::AssignmentIndex(index) => AssignmentsNodeRef::Assignment { | ||||||
|  |                 index, | ||||||
|  |                 assignment: &self.assignments.assignments()[index], | ||||||
|  |             }, | ||||||
|  |             AssignmentOrSlotIndex::SmallSlot(slot) => AssignmentsNodeRef::SmallSlot( | ||||||
|  |                 slot, | ||||||
|  |                 *self.assignments.slots_layout().small_slots.debug_data(slot), | ||||||
|  |             ), | ||||||
|  |             AssignmentOrSlotIndex::BigSlot(slot) => AssignmentsNodeRef::BigSlot( | ||||||
|  |                 slot, | ||||||
|  |                 *self.assignments.slots_layout().big_slots.debug_data(slot), | ||||||
|  |             ), | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'a> IntoNodeReferences for &'a Assignments { | ||||||
|  |     type NodeRef = AssignmentsNodeRef<'a>; | ||||||
|  |     type NodeReferences = AssignmentsNodes<'a>; | ||||||
|  | 
 | ||||||
|  |     fn node_references(self) -> Self::NodeReferences { | ||||||
|  |         AssignmentsNodes { | ||||||
|  |             assignments: self, | ||||||
|  |             nodes: self.node_identifiers(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| struct AssignmentsNeighborsDirected<'a> { | struct AssignmentsNeighborsDirected<'a> { | ||||||
|     assignment_indexes: std::slice::Iter<'a, usize>, |     assignment_indexes: std::slice::Iter<'a, usize>, | ||||||
|     small_slots: std::collections::btree_set::Iter<'a, StatePartIndex<StatePartKindSmallSlots>>, |     small_slots: std::collections::btree_set::Iter<'a, StatePartIndex<StatePartKindSmallSlots>>, | ||||||
|  | @ -603,13 +747,13 @@ impl Iterator for AssignmentsNeighborsDirected<'_> { | ||||||
|         } else if let retval @ Some(_) = small_slots |         } else if let retval @ Some(_) = small_slots | ||||||
|             .next() |             .next() | ||||||
|             .copied() |             .copied() | ||||||
|             .map(AssignmentOrSlotIndex::SmallSlots) |             .map(AssignmentOrSlotIndex::SmallSlot) | ||||||
|         { |         { | ||||||
|             retval |             retval | ||||||
|         } else if let retval @ Some(_) = big_slots |         } else if let retval @ Some(_) = big_slots | ||||||
|             .next() |             .next() | ||||||
|             .copied() |             .copied() | ||||||
|             .map(AssignmentOrSlotIndex::BigSlots) |             .map(AssignmentOrSlotIndex::BigSlot) | ||||||
|         { |         { | ||||||
|             retval |             retval | ||||||
|         } else { |         } else { | ||||||
|  | @ -664,12 +808,12 @@ impl<'a> IntoNeighborsDirected for &'a Assignments { | ||||||
|                     big_slots: big_slots.iter(), |                     big_slots: big_slots.iter(), | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             AssignmentOrSlotIndex::SmallSlots(slot) => AssignmentsNeighborsDirected { |             AssignmentOrSlotIndex::SmallSlot(slot) => AssignmentsNeighborsDirected { | ||||||
|                 assignment_indexes: slot_map[slot].iter(), |                 assignment_indexes: slot_map[slot].iter(), | ||||||
|                 small_slots: Default::default(), |                 small_slots: Default::default(), | ||||||
|                 big_slots: Default::default(), |                 big_slots: Default::default(), | ||||||
|             }, |             }, | ||||||
|             AssignmentOrSlotIndex::BigSlots(slot) => AssignmentsNeighborsDirected { |             AssignmentOrSlotIndex::BigSlot(slot) => AssignmentsNeighborsDirected { | ||||||
|                 assignment_indexes: slot_map[slot].iter(), |                 assignment_indexes: slot_map[slot].iter(), | ||||||
|                 small_slots: Default::default(), |                 small_slots: Default::default(), | ||||||
|                 big_slots: Default::default(), |                 big_slots: Default::default(), | ||||||
|  | @ -678,6 +822,149 @@ impl<'a> IntoNeighborsDirected for &'a Assignments { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl EdgeRef for AssignmentsEdge { | ||||||
|  |     type NodeId = AssignmentOrSlotIndex; | ||||||
|  |     type EdgeId = AssignmentsEdge; | ||||||
|  |     type Weight = AssignmentsEdge; | ||||||
|  | 
 | ||||||
|  |     fn source(&self) -> Self::NodeId { | ||||||
|  |         match *self { | ||||||
|  |             AssignmentsEdge::IO(AssignmentIO::BigInput { | ||||||
|  |                 assignment_index: _, | ||||||
|  |                 slot, | ||||||
|  |             }) => AssignmentOrSlotIndex::BigSlot(slot), | ||||||
|  |             AssignmentsEdge::IO(AssignmentIO::SmallInput { | ||||||
|  |                 assignment_index: _, | ||||||
|  |                 slot, | ||||||
|  |             }) => AssignmentOrSlotIndex::SmallSlot(slot), | ||||||
|  |             AssignmentsEdge::IO(AssignmentIO::BigOutput { | ||||||
|  |                 assignment_index, | ||||||
|  |                 slot: _, | ||||||
|  |             }) => AssignmentOrSlotIndex::AssignmentIndex(assignment_index), | ||||||
|  |             AssignmentsEdge::IO(AssignmentIO::SmallOutput { | ||||||
|  |                 assignment_index, | ||||||
|  |                 slot: _, | ||||||
|  |             }) => AssignmentOrSlotIndex::AssignmentIndex(assignment_index), | ||||||
|  |             AssignmentsEdge::AssignmentImmediatePredecessor { | ||||||
|  |                 predecessor_assignment_index, | ||||||
|  |                 assignment_index: _, | ||||||
|  |             } => AssignmentOrSlotIndex::AssignmentIndex(predecessor_assignment_index), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn target(&self) -> Self::NodeId { | ||||||
|  |         match *self { | ||||||
|  |             AssignmentsEdge::IO(AssignmentIO::BigInput { | ||||||
|  |                 assignment_index, | ||||||
|  |                 slot: _, | ||||||
|  |             }) => AssignmentOrSlotIndex::AssignmentIndex(assignment_index), | ||||||
|  |             AssignmentsEdge::IO(AssignmentIO::SmallInput { | ||||||
|  |                 assignment_index, | ||||||
|  |                 slot: _, | ||||||
|  |             }) => AssignmentOrSlotIndex::AssignmentIndex(assignment_index), | ||||||
|  |             AssignmentsEdge::IO(AssignmentIO::BigOutput { | ||||||
|  |                 assignment_index: _, | ||||||
|  |                 slot, | ||||||
|  |             }) => AssignmentOrSlotIndex::BigSlot(slot), | ||||||
|  |             AssignmentsEdge::IO(AssignmentIO::SmallOutput { | ||||||
|  |                 assignment_index: _, | ||||||
|  |                 slot, | ||||||
|  |             }) => AssignmentOrSlotIndex::SmallSlot(slot), | ||||||
|  |             AssignmentsEdge::AssignmentImmediatePredecessor { | ||||||
|  |                 predecessor_assignment_index: _, | ||||||
|  |                 assignment_index, | ||||||
|  |             } => AssignmentOrSlotIndex::AssignmentIndex(assignment_index), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn weight(&self) -> &Self::Weight { | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn id(&self) -> Self::EdgeId { | ||||||
|  |         *self | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct AssignmentsEdges<'a> { | ||||||
|  |     assignments: &'a Assignments, | ||||||
|  |     nodes: AssignmentsNodeIdentifiers, | ||||||
|  |     outgoing_neighbors: Option<(AssignmentOrSlotIndex, AssignmentsNeighborsDirected<'a>)>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Iterator for AssignmentsEdges<'_> { | ||||||
|  |     type Item = AssignmentsEdge; | ||||||
|  | 
 | ||||||
|  |     fn next(&mut self) -> Option<Self::Item> { | ||||||
|  |         loop { | ||||||
|  |             if let Some((node, outgoing_neighbors)) = &mut self.outgoing_neighbors { | ||||||
|  |                 if let Some(outgoing_neighbor) = outgoing_neighbors.next() { | ||||||
|  |                     return Some(match (*node, outgoing_neighbor) { | ||||||
|  |                         ( | ||||||
|  |                             AssignmentOrSlotIndex::SmallSlot(_) | AssignmentOrSlotIndex::BigSlot(_), | ||||||
|  |                             AssignmentOrSlotIndex::SmallSlot(_) | AssignmentOrSlotIndex::BigSlot(_), | ||||||
|  |                         ) => unreachable!(), | ||||||
|  |                         ( | ||||||
|  |                             AssignmentOrSlotIndex::AssignmentIndex(predecessor_assignment_index), | ||||||
|  |                             AssignmentOrSlotIndex::AssignmentIndex(assignment_index), | ||||||
|  |                         ) => AssignmentsEdge::AssignmentImmediatePredecessor { | ||||||
|  |                             predecessor_assignment_index, | ||||||
|  |                             assignment_index, | ||||||
|  |                         }, | ||||||
|  |                         ( | ||||||
|  |                             AssignmentOrSlotIndex::AssignmentIndex(assignment_index), | ||||||
|  |                             AssignmentOrSlotIndex::SmallSlot(slot), | ||||||
|  |                         ) => AssignmentsEdge::IO(AssignmentIO::SmallOutput { | ||||||
|  |                             assignment_index, | ||||||
|  |                             slot, | ||||||
|  |                         }), | ||||||
|  |                         ( | ||||||
|  |                             AssignmentOrSlotIndex::AssignmentIndex(assignment_index), | ||||||
|  |                             AssignmentOrSlotIndex::BigSlot(slot), | ||||||
|  |                         ) => AssignmentsEdge::IO(AssignmentIO::BigOutput { | ||||||
|  |                             assignment_index, | ||||||
|  |                             slot, | ||||||
|  |                         }), | ||||||
|  |                         ( | ||||||
|  |                             AssignmentOrSlotIndex::SmallSlot(slot), | ||||||
|  |                             AssignmentOrSlotIndex::AssignmentIndex(assignment_index), | ||||||
|  |                         ) => AssignmentsEdge::IO(AssignmentIO::SmallInput { | ||||||
|  |                             assignment_index, | ||||||
|  |                             slot, | ||||||
|  |                         }), | ||||||
|  |                         ( | ||||||
|  |                             AssignmentOrSlotIndex::BigSlot(slot), | ||||||
|  |                             AssignmentOrSlotIndex::AssignmentIndex(assignment_index), | ||||||
|  |                         ) => AssignmentsEdge::IO(AssignmentIO::BigInput { | ||||||
|  |                             assignment_index, | ||||||
|  |                             slot, | ||||||
|  |                         }), | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             let node = self.nodes.next()?; | ||||||
|  |             self.outgoing_neighbors = Some(( | ||||||
|  |                 node, | ||||||
|  |                 self.assignments | ||||||
|  |                     .neighbors_directed(node, petgraph::Direction::Outgoing), | ||||||
|  |             )); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'a> IntoEdgeReferences for &'a Assignments { | ||||||
|  |     type EdgeRef = AssignmentsEdge; | ||||||
|  |     type EdgeReferences = AssignmentsEdges<'a>; | ||||||
|  | 
 | ||||||
|  |     fn edge_references(self) -> Self::EdgeReferences { | ||||||
|  |         AssignmentsEdges { | ||||||
|  |             assignments: self, | ||||||
|  |             nodes: self.node_identifiers(), | ||||||
|  |             outgoing_neighbors: None, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| struct AssignmentsVisitMap { | struct AssignmentsVisitMap { | ||||||
|     assignments: Vec<bool>, |     assignments: Vec<bool>, | ||||||
|     slots: DenseSlotSet, |     slots: DenseSlotSet, | ||||||
|  | @ -689,8 +976,8 @@ impl VisitMap<AssignmentOrSlotIndex> for AssignmentsVisitMap { | ||||||
|             AssignmentOrSlotIndex::AssignmentIndex(assignment_index) => { |             AssignmentOrSlotIndex::AssignmentIndex(assignment_index) => { | ||||||
|                 !mem::replace(&mut self.assignments[assignment_index], true) |                 !mem::replace(&mut self.assignments[assignment_index], true) | ||||||
|             } |             } | ||||||
|             AssignmentOrSlotIndex::SmallSlots(slot) => self.slots.insert(slot), |             AssignmentOrSlotIndex::SmallSlot(slot) => self.slots.insert(slot), | ||||||
|             AssignmentOrSlotIndex::BigSlots(slot) => self.slots.insert(slot), |             AssignmentOrSlotIndex::BigSlot(slot) => self.slots.insert(slot), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -699,8 +986,8 @@ impl VisitMap<AssignmentOrSlotIndex> for AssignmentsVisitMap { | ||||||
|             AssignmentOrSlotIndex::AssignmentIndex(assignment_index) => { |             AssignmentOrSlotIndex::AssignmentIndex(assignment_index) => { | ||||||
|                 self.assignments[assignment_index] |                 self.assignments[assignment_index] | ||||||
|             } |             } | ||||||
|             AssignmentOrSlotIndex::SmallSlots(slot) => self.slots.contains(slot), |             AssignmentOrSlotIndex::SmallSlot(slot) => self.slots.contains(slot), | ||||||
|             AssignmentOrSlotIndex::BigSlots(slot) => self.slots.contains(slot), |             AssignmentOrSlotIndex::BigSlot(slot) => self.slots.contains(slot), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -2725,12 +3012,15 @@ impl Compiler { | ||||||
|                 .compile_expr(instantiated_module, Expr::canonical(expr.base())) |                 .compile_expr(instantiated_module, Expr::canonical(expr.base())) | ||||||
|                 .map_ty(Bundle::from_canonical) |                 .map_ty(Bundle::from_canonical) | ||||||
|                 .field_by_index(expr.field_index()), |                 .field_by_index(expr.field_index()), | ||||||
|             ExprEnum::VariantAccess(variant_access) => self.compile_expr( |             ExprEnum::VariantAccess(variant_access) => { | ||||||
|  |                 let start = Expr::ty(variant_access.base()).discriminant_bit_width(); | ||||||
|  |                 let len = Expr::ty(expr).bit_width(); | ||||||
|  |                 self.compile_expr( | ||||||
|                     instantiated_module, |                     instantiated_module, | ||||||
|                 variant_access.base().cast_to_bits() |                     variant_access.base().cast_to_bits()[start..start + len] | ||||||
|                     [Expr::ty(variant_access.base()).discriminant_bit_width()..] |  | ||||||
|                         .cast_bits_to(Expr::ty(expr)), |                         .cast_bits_to(Expr::ty(expr)), | ||||||
|             ), |                 ) | ||||||
|  |             } | ||||||
|             ExprEnum::ArrayIndex(expr) => self |             ExprEnum::ArrayIndex(expr) => self | ||||||
|                 .compile_expr(instantiated_module, Expr::canonical(expr.base())) |                 .compile_expr(instantiated_module, Expr::canonical(expr.base())) | ||||||
|                 .map_ty(Array::from_canonical) |                 .map_ty(Array::from_canonical) | ||||||
|  | @ -4146,7 +4436,13 @@ impl Compiler { | ||||||
|     } |     } | ||||||
|     fn process_assignments(&mut self) { |     fn process_assignments(&mut self) { | ||||||
|         self.assignments |         self.assignments | ||||||
|             .finalize(self.insns.state_layout().len().ty); |             .finalize(self.insns.state_layout().ty.clone().into()); | ||||||
|  |         println!( | ||||||
|  |             "{:#?}", | ||||||
|  |             petgraph::dot::Dot::new(&petgraph::graph::DiGraph::<_, _, usize>::from_elements( | ||||||
|  |                 self.assignments.elements() | ||||||
|  |             )) | ||||||
|  |         ); | ||||||
|         let assignments_order: Vec<_> = match petgraph::algo::toposort(&self.assignments, None) { |         let assignments_order: Vec<_> = match petgraph::algo::toposort(&self.assignments, None) { | ||||||
|             Ok(nodes) => nodes |             Ok(nodes) => nodes | ||||||
|                 .into_iter() |                 .into_iter() | ||||||
|  | @ -4160,11 +4456,11 @@ impl Compiler { | ||||||
|                     "combinatorial logic cycle detected at: {}", |                     "combinatorial logic cycle detected at: {}", | ||||||
|                     self.assignments.assignments()[assignment_index].source_location, |                     self.assignments.assignments()[assignment_index].source_location, | ||||||
|                 ), |                 ), | ||||||
|                 AssignmentOrSlotIndex::SmallSlots(slot) => panic!( |                 AssignmentOrSlotIndex::SmallSlot(slot) => panic!( | ||||||
|                     "combinatorial logic cycle detected through: {}", |                     "combinatorial logic cycle detected through: {}", | ||||||
|                     self.insns.state_layout().ty.small_slots.debug_data[slot.as_usize()].name, |                     self.insns.state_layout().ty.small_slots.debug_data[slot.as_usize()].name, | ||||||
|                 ), |                 ), | ||||||
|                 AssignmentOrSlotIndex::BigSlots(slot) => panic!( |                 AssignmentOrSlotIndex::BigSlot(slot) => panic!( | ||||||
|                     "combinatorial logic cycle detected through: {}", |                     "combinatorial logic cycle detected through: {}", | ||||||
|                     self.insns.state_layout().ty.big_slots.debug_data[slot.as_usize()].name, |                     self.insns.state_layout().ty.big_slots.debug_data[slot.as_usize()].name, | ||||||
|                 ), |                 ), | ||||||
|  |  | ||||||
|  | @ -1652,6 +1652,9 @@ impl<K: StatePartKind, BK: InsnsBuildingKind> StatePartLayout<K, BK> { | ||||||
|             _phantom: PhantomData, |             _phantom: PhantomData, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |     pub(crate) fn debug_data(&self, index: StatePartIndex<K>) -> &K::DebugData { | ||||||
|  |         &self.debug_data[index.as_usize()] | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<K: StatePartKind> From<StatePartLayout<K, InsnsBuilding>> | impl<K: StatePartKind> From<StatePartLayout<K, InsnsBuilding>> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue