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 num_bigint::BigInt; | ||||
| use num_traits::{Signed, ToPrimitive, Zero}; | ||||
| use petgraph::visit::{ | ||||
|     GraphBase, IntoNeighbors, IntoNeighborsDirected, IntoNodeIdentifiers, VisitMap, Visitable, | ||||
| use petgraph::{ | ||||
|     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}; | ||||
| 
 | ||||
|  | @ -384,8 +388,8 @@ impl CompiledExpr<Array> { | |||
| #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||||
| enum AssignmentOrSlotIndex { | ||||
|     AssignmentIndex(usize), | ||||
|     SmallSlots(StatePartIndex<StatePartKindSmallSlots>), | ||||
|     BigSlots(StatePartIndex<StatePartKindBigSlots>), | ||||
|     SmallSlot(StatePartIndex<StatePartKindSmallSlots>), | ||||
|     BigSlot(StatePartIndex<StatePartKindBigSlots>), | ||||
| } | ||||
| 
 | ||||
| #[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)] | ||||
| enum Assignments { | ||||
|     Accumulating { | ||||
|  | @ -415,6 +428,7 @@ enum Assignments { | |||
|     }, | ||||
|     Finalized { | ||||
|         assignments: Box<[Assignment]>, | ||||
|         slots_layout: TypeLayout<InsnsBuildingDone>, | ||||
|         slot_readers: SlotToAssignmentIndexFullMap, | ||||
|         slot_writers: SlotToAssignmentIndexFullMap, | ||||
|         assignment_immediate_predecessors: Box<[Box<[usize]>]>, | ||||
|  | @ -431,13 +445,13 @@ impl Default for Assignments { | |||
| } | ||||
| 
 | ||||
| impl Assignments { | ||||
|     fn finalize(&mut self, slots_len: TypeLen) { | ||||
|     fn finalize(&mut self, slots_layout: TypeLayout<InsnsBuildingDone>) { | ||||
|         let Self::Accumulating { assignments } = self else { | ||||
|             unreachable!("already finalized"); | ||||
|         }; | ||||
|         let assignments = mem::take(assignments).into_boxed_slice(); | ||||
|         let mut slot_readers = SlotToAssignmentIndexFullMap::new(slots_len); | ||||
|         let mut slot_writers = SlotToAssignmentIndexFullMap::new(slots_len); | ||||
|         let mut slot_readers = SlotToAssignmentIndexFullMap::new(slots_layout.len()); | ||||
|         let mut slot_writers = SlotToAssignmentIndexFullMap::new(slots_layout.len()); | ||||
|         let mut assignment_immediate_predecessors = vec![BTreeSet::new(); assignments.len()]; | ||||
|         let mut assignment_immediate_successors = vec![BTreeSet::new(); assignments.len()]; | ||||
|         for (assignment_index, assignment) in assignments.iter().enumerate() { | ||||
|  | @ -465,6 +479,7 @@ impl Assignments { | |||
|         } | ||||
|         *self = Self::Finalized { | ||||
|             assignments, | ||||
|             slots_layout, | ||||
|             slot_readers, | ||||
|             slot_writers, | ||||
|             assignment_immediate_predecessors: assignment_immediate_predecessors | ||||
|  | @ -489,6 +504,12 @@ impl 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 { | ||||
|         let Self::Finalized { slot_readers, .. } = self else { | ||||
|             unreachable!("Assignments::finalize should have been called"); | ||||
|  | @ -521,46 +542,131 @@ impl Assignments { | |||
|         }; | ||||
|         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 { | ||||
|     type EdgeId = AssignmentIO; | ||||
|     type EdgeId = AssignmentsEdge; | ||||
|     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 { | ||||
|     assignment_indexes: std::ops::Range<usize>, | ||||
|     small_slots: std::ops::Range<u32>, | ||||
|     big_slots: std::ops::Range<u32>, | ||||
| } | ||||
| 
 | ||||
| impl Iterator for AssignmentsNodeIdentifiers { | ||||
|     type Item = AssignmentOrSlotIndex; | ||||
|     fn next(&mut self) -> Option<Self::Item> { | ||||
| impl AssignmentsNodeIdentifiers { | ||||
|     fn internal_iter<'a>(&'a mut self) -> impl Iterator<Item = AssignmentOrSlotIndex> + 'a { | ||||
|         let Self { | ||||
|             assignment_indexes, | ||||
|             small_slots, | ||||
|             big_slots, | ||||
|         } = self; | ||||
|         assignment_indexes | ||||
|             .next() | ||||
|             .map(AssignmentOrSlotIndex::AssignmentIndex) | ||||
|             .or_else(|| { | ||||
|                 small_slots.next().map(|value| { | ||||
|                     AssignmentOrSlotIndex::SmallSlots(StatePartIndex { | ||||
|             .chain(small_slots.map(|value| { | ||||
|                 AssignmentOrSlotIndex::SmallSlot(StatePartIndex { | ||||
|                     value, | ||||
|                     _phantom: PhantomData, | ||||
|                 }) | ||||
|                 }) | ||||
|             }) | ||||
|             .or_else(|| { | ||||
|                 big_slots.next().map(|value| { | ||||
|                     AssignmentOrSlotIndex::BigSlots(StatePartIndex { | ||||
|             })) | ||||
|             .chain(big_slots.map(|value| { | ||||
|                 AssignmentOrSlotIndex::BigSlot(StatePartIndex { | ||||
|                     value, | ||||
|                     _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> { | ||||
|     assignment_indexes: std::slice::Iter<'a, usize>, | ||||
|     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 | ||||
|             .next() | ||||
|             .copied() | ||||
|             .map(AssignmentOrSlotIndex::SmallSlots) | ||||
|             .map(AssignmentOrSlotIndex::SmallSlot) | ||||
|         { | ||||
|             retval | ||||
|         } else if let retval @ Some(_) = big_slots | ||||
|             .next() | ||||
|             .copied() | ||||
|             .map(AssignmentOrSlotIndex::BigSlots) | ||||
|             .map(AssignmentOrSlotIndex::BigSlot) | ||||
|         { | ||||
|             retval | ||||
|         } else { | ||||
|  | @ -664,12 +808,12 @@ impl<'a> IntoNeighborsDirected for &'a Assignments { | |||
|                     big_slots: big_slots.iter(), | ||||
|                 } | ||||
|             } | ||||
|             AssignmentOrSlotIndex::SmallSlots(slot) => AssignmentsNeighborsDirected { | ||||
|             AssignmentOrSlotIndex::SmallSlot(slot) => AssignmentsNeighborsDirected { | ||||
|                 assignment_indexes: slot_map[slot].iter(), | ||||
|                 small_slots: Default::default(), | ||||
|                 big_slots: Default::default(), | ||||
|             }, | ||||
|             AssignmentOrSlotIndex::BigSlots(slot) => AssignmentsNeighborsDirected { | ||||
|             AssignmentOrSlotIndex::BigSlot(slot) => AssignmentsNeighborsDirected { | ||||
|                 assignment_indexes: slot_map[slot].iter(), | ||||
|                 small_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 { | ||||
|     assignments: Vec<bool>, | ||||
|     slots: DenseSlotSet, | ||||
|  | @ -689,8 +976,8 @@ impl VisitMap<AssignmentOrSlotIndex> for AssignmentsVisitMap { | |||
|             AssignmentOrSlotIndex::AssignmentIndex(assignment_index) => { | ||||
|                 !mem::replace(&mut self.assignments[assignment_index], true) | ||||
|             } | ||||
|             AssignmentOrSlotIndex::SmallSlots(slot) => self.slots.insert(slot), | ||||
|             AssignmentOrSlotIndex::BigSlots(slot) => self.slots.insert(slot), | ||||
|             AssignmentOrSlotIndex::SmallSlot(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) => { | ||||
|                 self.assignments[assignment_index] | ||||
|             } | ||||
|             AssignmentOrSlotIndex::SmallSlots(slot) => self.slots.contains(slot), | ||||
|             AssignmentOrSlotIndex::BigSlots(slot) => self.slots.contains(slot), | ||||
|             AssignmentOrSlotIndex::SmallSlot(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())) | ||||
|                 .map_ty(Bundle::from_canonical) | ||||
|                 .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, | ||||
|                 variant_access.base().cast_to_bits() | ||||
|                     [Expr::ty(variant_access.base()).discriminant_bit_width()..] | ||||
|                     variant_access.base().cast_to_bits()[start..start + len] | ||||
|                         .cast_bits_to(Expr::ty(expr)), | ||||
|             ), | ||||
|                 ) | ||||
|             } | ||||
|             ExprEnum::ArrayIndex(expr) => self | ||||
|                 .compile_expr(instantiated_module, Expr::canonical(expr.base())) | ||||
|                 .map_ty(Array::from_canonical) | ||||
|  | @ -4146,7 +4436,13 @@ impl Compiler { | |||
|     } | ||||
|     fn process_assignments(&mut self) { | ||||
|         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) { | ||||
|             Ok(nodes) => nodes | ||||
|                 .into_iter() | ||||
|  | @ -4160,11 +4456,11 @@ impl Compiler { | |||
|                     "combinatorial logic cycle detected at: {}", | ||||
|                     self.assignments.assignments()[assignment_index].source_location, | ||||
|                 ), | ||||
|                 AssignmentOrSlotIndex::SmallSlots(slot) => panic!( | ||||
|                 AssignmentOrSlotIndex::SmallSlot(slot) => panic!( | ||||
|                     "combinatorial logic cycle detected through: {}", | ||||
|                     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: {}", | ||||
|                     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, | ||||
|         } | ||||
|     } | ||||
|     pub(crate) fn debug_data(&self, index: StatePartIndex<K>) -> &K::DebugData { | ||||
|         &self.debug_data[index.as_usize()] | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<K: StatePartKind> From<StatePartLayout<K, InsnsBuilding>> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue