1use crate::entity::SecondaryMap;
7use crate::ir::progpoint::ProgramPoint;
8use crate::ir::{Block, Inst};
9use crate::packed_option::PackedOption;
10use crate::{timing, trace};
11use core::cmp;
12
13#[derive(Debug, Clone, PartialEq, Hash)]
27pub struct Layout {
28 blocks: SecondaryMap<Block, BlockNode>,
31
32 insts: SecondaryMap<Inst, InstNode>,
35
36 first_block: Option<Block>,
38
39 last_block: Option<Block>,
41}
42
43impl Layout {
44 pub fn new() -> Self {
46 Self {
47 blocks: SecondaryMap::new(),
48 insts: SecondaryMap::new(),
49 first_block: None,
50 last_block: None,
51 }
52 }
53
54 pub fn clear(&mut self) {
56 self.blocks.clear();
57 self.insts.clear();
58 self.first_block = None;
59 self.last_block = None;
60 }
61
62 pub fn block_capacity(&self) -> usize {
64 self.blocks.capacity()
65 }
66}
67
68type SequenceNumber = u32;
78
79const MAJOR_STRIDE: SequenceNumber = 10;
81
82const MINOR_STRIDE: SequenceNumber = 2;
84
85const LOCAL_LIMIT: SequenceNumber = 100 * MINOR_STRIDE;
88
89fn midpoint(a: SequenceNumber, b: SequenceNumber) -> Option<SequenceNumber> {
92 debug_assert!(a < b);
93 let m = a + (b - a) / 2;
95 if m > a {
96 Some(m)
97 } else {
98 None
99 }
100}
101
102#[test]
103fn test_midpoint() {
104 assert_eq!(midpoint(0, 1), None);
105 assert_eq!(midpoint(0, 2), Some(1));
106 assert_eq!(midpoint(0, 3), Some(1));
107 assert_eq!(midpoint(0, 4), Some(2));
108 assert_eq!(midpoint(1, 4), Some(2));
109 assert_eq!(midpoint(2, 4), Some(3));
110 assert_eq!(midpoint(3, 4), None);
111 assert_eq!(midpoint(3, 4), None);
112}
113
114impl Layout {
115 pub fn pp_cmp<A, B>(&self, a: A, b: B) -> cmp::Ordering
123 where
124 A: Into<ProgramPoint>,
125 B: Into<ProgramPoint>,
126 {
127 let a = a.into();
128 let b = b.into();
129 debug_assert_eq!(self.pp_block(a), self.pp_block(b));
130 let a_seq = match a {
131 ProgramPoint::Block(_block) => 0,
132 ProgramPoint::Inst(inst) => self.insts[inst].seq,
133 };
134 let b_seq = match b {
135 ProgramPoint::Block(_block) => 0,
136 ProgramPoint::Inst(inst) => self.insts[inst].seq,
137 };
138 a_seq.cmp(&b_seq)
139 }
140}
141
142impl Layout {
144 fn assign_inst_seq(&mut self, inst: Inst) {
147 let prev_seq = match self.insts[inst].prev.expand() {
149 Some(prev_inst) => self.insts[prev_inst].seq,
150 None => 0,
151 };
152
153 let next_seq = if let Some(next_inst) = self.insts[inst].next.expand() {
155 self.insts[next_inst].seq
156 } else {
157 self.insts[inst].seq = prev_seq + MAJOR_STRIDE;
159 return;
160 };
161
162 if let Some(seq) = midpoint(prev_seq, next_seq) {
164 self.insts[inst].seq = seq;
165 } else {
166 self.renumber_insts(inst, prev_seq + MINOR_STRIDE, prev_seq + LOCAL_LIMIT);
168 }
169 }
170
171 fn renumber_insts(&mut self, inst: Inst, seq: SequenceNumber, limit: SequenceNumber) {
176 let mut inst = inst;
177 let mut seq = seq;
178
179 loop {
180 self.insts[inst].seq = seq;
181
182 inst = match self.insts[inst].next.expand() {
184 None => return,
185 Some(next) => next,
186 };
187
188 if seq < self.insts[inst].seq {
189 return;
191 }
192
193 if seq > limit {
194 self.full_block_renumber(
197 self.inst_block(inst)
198 .expect("inst must be inserted before assigning an seq"),
199 );
200 return;
201 }
202
203 seq += MINOR_STRIDE;
204 }
205 }
206
207 fn full_block_renumber(&mut self, block: Block) {
212 let _tt = timing::layout_renumber();
213 let mut seq = MAJOR_STRIDE;
215 let mut next_inst = self.blocks[block].first_inst.expand();
216 while let Some(inst) = next_inst {
217 self.insts[inst].seq = seq;
218 seq += MAJOR_STRIDE;
219 next_inst = self.insts[inst].next.expand();
220 }
221
222 trace!("Renumbered {} program points", seq / MAJOR_STRIDE);
223 }
224}
225
226impl Layout {
236 pub fn is_block_inserted(&self, block: Block) -> bool {
238 Some(block) == self.first_block || self.blocks[block].prev.is_some()
239 }
240
241 pub fn append_block(&mut self, block: Block) {
243 debug_assert!(
244 !self.is_block_inserted(block),
245 "Cannot append block that is already in the layout"
246 );
247 {
248 let node = &mut self.blocks[block];
249 debug_assert!(node.first_inst.is_none() && node.last_inst.is_none());
250 node.prev = self.last_block.into();
251 node.next = None.into();
252 }
253 if let Some(last) = self.last_block {
254 self.blocks[last].next = block.into();
255 } else {
256 self.first_block = Some(block);
257 }
258 self.last_block = Some(block);
259 }
260
261 pub fn insert_block(&mut self, block: Block, before: Block) {
263 debug_assert!(
264 !self.is_block_inserted(block),
265 "Cannot insert block that is already in the layout"
266 );
267 debug_assert!(
268 self.is_block_inserted(before),
269 "block Insertion point not in the layout"
270 );
271 let after = self.blocks[before].prev;
272 {
273 let node = &mut self.blocks[block];
274 node.next = before.into();
275 node.prev = after;
276 }
277 self.blocks[before].prev = block.into();
278 match after.expand() {
279 None => self.first_block = Some(block),
280 Some(a) => self.blocks[a].next = block.into(),
281 }
282 }
283
284 pub fn insert_block_after(&mut self, block: Block, after: Block) {
286 debug_assert!(
287 !self.is_block_inserted(block),
288 "Cannot insert block that is already in the layout"
289 );
290 debug_assert!(
291 self.is_block_inserted(after),
292 "block Insertion point not in the layout"
293 );
294 let before = self.blocks[after].next;
295 {
296 let node = &mut self.blocks[block];
297 node.next = before;
298 node.prev = after.into();
299 }
300 self.blocks[after].next = block.into();
301 match before.expand() {
302 None => self.last_block = Some(block),
303 Some(b) => self.blocks[b].prev = block.into(),
304 }
305 }
306
307 pub fn remove_block(&mut self, block: Block) {
309 debug_assert!(self.is_block_inserted(block), "block not in the layout");
310 debug_assert!(self.first_inst(block).is_none(), "block must be empty.");
311
312 let prev;
314 let next;
315 {
316 let n = &mut self.blocks[block];
317 prev = n.prev;
318 next = n.next;
319 n.prev = None.into();
320 n.next = None.into();
321 }
322 match prev.expand() {
324 None => self.first_block = next.expand(),
325 Some(p) => self.blocks[p].next = next,
326 }
327 match next.expand() {
328 None => self.last_block = prev.expand(),
329 Some(n) => self.blocks[n].prev = prev,
330 }
331 }
332
333 pub fn blocks(&self) -> Blocks {
335 Blocks {
336 layout: self,
337 next: self.first_block,
338 }
339 }
340
341 pub fn entry_block(&self) -> Option<Block> {
344 self.first_block
345 }
346
347 pub fn last_block(&self) -> Option<Block> {
349 self.last_block
350 }
351
352 pub fn prev_block(&self, block: Block) -> Option<Block> {
354 self.blocks[block].prev.expand()
355 }
356
357 pub fn next_block(&self, block: Block) -> Option<Block> {
359 self.blocks[block].next.expand()
360 }
361
362 pub fn set_cold(&mut self, block: Block) {
367 self.blocks[block].cold = true;
368 }
369
370 pub fn is_cold(&self, block: Block) -> bool {
372 self.blocks[block].cold
373 }
374}
375
376#[derive(Clone, Debug, Default, PartialEq, Hash)]
379struct BlockNode {
380 prev: PackedOption<Block>,
381 next: PackedOption<Block>,
382 first_inst: PackedOption<Inst>,
383 last_inst: PackedOption<Inst>,
384 cold: bool,
385}
386
387pub struct Blocks<'f> {
389 layout: &'f Layout,
390 next: Option<Block>,
391}
392
393impl<'f> Iterator for Blocks<'f> {
394 type Item = Block;
395
396 fn next(&mut self) -> Option<Block> {
397 match self.next {
398 Some(block) => {
399 self.next = self.layout.next_block(block);
400 Some(block)
401 }
402 None => None,
403 }
404 }
405}
406
407impl<'f> IntoIterator for &'f Layout {
409 type Item = Block;
410 type IntoIter = Blocks<'f>;
411
412 fn into_iter(self) -> Blocks<'f> {
413 self.blocks()
414 }
415}
416
417impl Layout {
422 pub fn inst_block(&self, inst: Inst) -> Option<Block> {
424 self.insts[inst].block.into()
425 }
426
427 pub fn pp_block(&self, pp: ProgramPoint) -> Block {
429 match pp {
430 ProgramPoint::Block(block) => block,
431 ProgramPoint::Inst(inst) => self.inst_block(inst).expect("Program point not in layout"),
432 }
433 }
434
435 pub fn append_inst(&mut self, inst: Inst, block: Block) {
437 debug_assert_eq!(self.inst_block(inst), None);
438 debug_assert!(
439 self.is_block_inserted(block),
440 "Cannot append instructions to block not in layout"
441 );
442 {
443 let block_node = &mut self.blocks[block];
444 {
445 let inst_node = &mut self.insts[inst];
446 inst_node.block = block.into();
447 inst_node.prev = block_node.last_inst;
448 debug_assert!(inst_node.next.is_none());
449 }
450 if block_node.first_inst.is_none() {
451 block_node.first_inst = inst.into();
452 } else {
453 self.insts[block_node.last_inst.unwrap()].next = inst.into();
454 }
455 block_node.last_inst = inst.into();
456 }
457 self.assign_inst_seq(inst);
458 }
459
460 pub fn first_inst(&self, block: Block) -> Option<Inst> {
462 self.blocks[block].first_inst.into()
463 }
464
465 pub fn last_inst(&self, block: Block) -> Option<Inst> {
467 self.blocks[block].last_inst.into()
468 }
469
470 pub fn next_inst(&self, inst: Inst) -> Option<Inst> {
472 self.insts[inst].next.expand()
473 }
474
475 pub fn prev_inst(&self, inst: Inst) -> Option<Inst> {
477 self.insts[inst].prev.expand()
478 }
479
480 pub fn insert_inst(&mut self, inst: Inst, before: Inst) {
482 debug_assert_eq!(self.inst_block(inst), None);
483 let block = self
484 .inst_block(before)
485 .expect("Instruction before insertion point not in the layout");
486 let after = self.insts[before].prev;
487 {
488 let inst_node = &mut self.insts[inst];
489 inst_node.block = block.into();
490 inst_node.next = before.into();
491 inst_node.prev = after;
492 }
493 self.insts[before].prev = inst.into();
494 match after.expand() {
495 None => self.blocks[block].first_inst = inst.into(),
496 Some(a) => self.insts[a].next = inst.into(),
497 }
498 self.assign_inst_seq(inst);
499 }
500
501 pub fn remove_inst(&mut self, inst: Inst) {
503 let block = self.inst_block(inst).expect("Instruction already removed.");
504 let prev;
506 let next;
507 {
508 let n = &mut self.insts[inst];
509 prev = n.prev;
510 next = n.next;
511 n.block = None.into();
512 n.prev = None.into();
513 n.next = None.into();
514 }
515 match prev.expand() {
517 None => self.blocks[block].first_inst = next,
518 Some(p) => self.insts[p].next = next,
519 }
520 match next.expand() {
521 None => self.blocks[block].last_inst = prev,
522 Some(n) => self.insts[n].prev = prev,
523 }
524 }
525
526 pub fn block_insts(&self, block: Block) -> Insts {
528 Insts {
529 layout: self,
530 head: self.blocks[block].first_inst.into(),
531 tail: self.blocks[block].last_inst.into(),
532 }
533 }
534
535 pub fn split_block(&mut self, new_block: Block, before: Inst) {
558 let old_block = self
559 .inst_block(before)
560 .expect("The `before` instruction must be in the layout");
561 debug_assert!(!self.is_block_inserted(new_block));
562
563 let next_block = self.blocks[old_block].next;
565 let last_inst = self.blocks[old_block].last_inst;
566 {
567 let node = &mut self.blocks[new_block];
568 node.prev = old_block.into();
569 node.next = next_block;
570 node.first_inst = before.into();
571 node.last_inst = last_inst;
572 }
573 self.blocks[old_block].next = new_block.into();
574
575 if Some(old_block) == self.last_block {
577 self.last_block = Some(new_block);
578 } else {
579 self.blocks[next_block.unwrap()].prev = new_block.into();
580 }
581
582 let prev_inst = self.insts[before].prev;
584 self.insts[before].prev = None.into();
585 self.blocks[old_block].last_inst = prev_inst;
586 match prev_inst.expand() {
587 None => self.blocks[old_block].first_inst = None.into(),
588 Some(pi) => self.insts[pi].next = None.into(),
589 }
590
591 let mut opt_i = Some(before);
593 while let Some(i) = opt_i {
594 debug_assert_eq!(self.insts[i].block.expand(), Some(old_block));
595 self.insts[i].block = new_block.into();
596 opt_i = self.insts[i].next.into();
597 }
598 }
599}
600
601#[derive(Clone, Debug, Default)]
602struct InstNode {
603 block: PackedOption<Block>,
605 prev: PackedOption<Inst>,
606 next: PackedOption<Inst>,
607 seq: SequenceNumber,
608}
609
610impl PartialEq for InstNode {
611 fn eq(&self, other: &Self) -> bool {
612 self.block == other.block && self.prev == other.prev && self.next == other.next
615 }
616}
617
618impl core::hash::Hash for InstNode {
619 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
620 self.block.hash(state);
623 self.prev.hash(state);
624 self.next.hash(state);
625 }
626}
627
628pub struct Insts<'f> {
630 layout: &'f Layout,
631 head: Option<Inst>,
632 tail: Option<Inst>,
633}
634
635impl<'f> Iterator for Insts<'f> {
636 type Item = Inst;
637
638 fn next(&mut self) -> Option<Inst> {
639 let rval = self.head;
640 if let Some(inst) = rval {
641 if self.head == self.tail {
642 self.head = None;
643 self.tail = None;
644 } else {
645 self.head = self.layout.insts[inst].next.into();
646 }
647 }
648 rval
649 }
650}
651
652impl<'f> DoubleEndedIterator for Insts<'f> {
653 fn next_back(&mut self) -> Option<Inst> {
654 let rval = self.tail;
655 if let Some(inst) = rval {
656 if self.head == self.tail {
657 self.head = None;
658 self.tail = None;
659 } else {
660 self.tail = self.layout.insts[inst].prev.into();
661 }
662 }
663 rval
664 }
665}
666
667#[cfg(feature = "enable-serde")]
679mod serde {
680 use ::serde::de::{Deserializer, Error, SeqAccess, Visitor};
681 use ::serde::ser::{SerializeSeq, Serializer};
682 use ::serde::{Deserialize, Serialize};
683 use core::fmt;
684 use core::marker::PhantomData;
685
686 use super::*;
687
688 impl Serialize for Layout {
689 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
690 where
691 S: Serializer,
692 {
693 let size = self.blocks().count() * 3
694 + self
695 .blocks()
696 .map(|block| self.block_insts(block).count())
697 .sum::<usize>();
698 let mut seq = serializer.serialize_seq(Some(size))?;
699 for block in self.blocks() {
700 seq.serialize_element(&block)?;
701 seq.serialize_element(&self.blocks[block].cold)?;
702 seq.serialize_element(&u32::try_from(self.block_insts(block).count()).unwrap())?;
703 for inst in self.block_insts(block) {
704 seq.serialize_element(&inst)?;
705 }
706 }
707 seq.end()
708 }
709 }
710
711 impl<'de> Deserialize<'de> for Layout {
712 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
713 where
714 D: Deserializer<'de>,
715 {
716 deserializer.deserialize_seq(LayoutVisitor {
717 marker: PhantomData,
718 })
719 }
720 }
721
722 struct LayoutVisitor {
723 marker: PhantomData<fn() -> Layout>,
724 }
725
726 impl<'de> Visitor<'de> for LayoutVisitor {
727 type Value = Layout;
728
729 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
730 write!(formatter, "a `cranelift_codegen::ir::Layout`")
731 }
732
733 fn visit_seq<M>(self, mut access: M) -> Result<Self::Value, M::Error>
734 where
735 M: SeqAccess<'de>,
736 {
737 let mut layout = Layout::new();
738
739 while let Some(block) = access.next_element::<Block>()? {
740 layout.append_block(block);
741
742 let cold = access
743 .next_element::<bool>()?
744 .ok_or_else(|| Error::missing_field("cold"))?;
745 layout.blocks[block].cold = cold;
746
747 let count = access
748 .next_element::<u32>()?
749 .ok_or_else(|| Error::missing_field("count"))?;
750
751 for _ in 0..count {
752 let inst = access
753 .next_element::<Inst>()?
754 .ok_or_else(|| Error::missing_field("inst"))?;
755 layout.append_inst(inst, block);
756 }
757 }
758
759 Ok(layout)
760 }
761 }
762}
763
764#[cfg(test)]
765mod tests {
766 use super::Layout;
767 use crate::cursor::{Cursor, CursorPosition};
768 use crate::entity::EntityRef;
769 use crate::ir::{Block, Inst, SourceLoc};
770 use alloc::vec::Vec;
771 use core::cmp::Ordering;
772
773 struct LayoutCursor<'f> {
774 pub layout: &'f mut Layout,
776 pos: CursorPosition,
777 }
778
779 impl<'f> Cursor for LayoutCursor<'f> {
780 fn position(&self) -> CursorPosition {
781 self.pos
782 }
783
784 fn set_position(&mut self, pos: CursorPosition) {
785 self.pos = pos;
786 }
787
788 fn srcloc(&self) -> SourceLoc {
789 unimplemented!()
790 }
791
792 fn set_srcloc(&mut self, _srcloc: SourceLoc) {
793 unimplemented!()
794 }
795
796 fn layout(&self) -> &Layout {
797 self.layout
798 }
799
800 fn layout_mut(&mut self) -> &mut Layout {
801 self.layout
802 }
803 }
804
805 impl<'f> LayoutCursor<'f> {
806 pub fn new(layout: &'f mut Layout) -> Self {
809 Self {
810 layout,
811 pos: CursorPosition::Nowhere,
812 }
813 }
814 }
815
816 fn verify(layout: &mut Layout, blocks: &[(Block, &[Inst])]) {
817 {
821 let mut block_iter = layout.blocks();
822 for &(block, insts) in blocks {
823 assert!(layout.is_block_inserted(block));
824 assert_eq!(block_iter.next(), Some(block));
825
826 let mut seq = 0;
827 let mut inst_iter = layout.block_insts(block);
828 for &inst in insts {
829 assert_eq!(layout.inst_block(inst), Some(block));
830 assert_eq!(inst_iter.next(), Some(inst));
831 assert!(layout.insts[inst].seq > seq);
832 seq = layout.insts[inst].seq;
833 }
834 assert_eq!(inst_iter.next(), None);
835 }
836 assert_eq!(block_iter.next(), None);
837 }
838
839 let mut cur = LayoutCursor::new(layout);
841 for &(block, insts) in blocks.into_iter().rev() {
842 assert_eq!(cur.prev_block(), Some(block));
843 for &inst in insts.into_iter().rev() {
844 assert_eq!(cur.prev_inst(), Some(inst));
845 }
846 assert_eq!(cur.prev_inst(), None);
847 }
848 assert_eq!(cur.prev_block(), None);
849 }
850
851 #[test]
852 fn append_block() {
853 let mut layout = Layout::new();
854 let e0 = Block::new(0);
855 let e1 = Block::new(1);
856 let e2 = Block::new(2);
857
858 {
859 let imm = &layout;
860 assert!(!imm.is_block_inserted(e0));
861 assert!(!imm.is_block_inserted(e1));
862 }
863 verify(&mut layout, &[]);
864
865 layout.append_block(e1);
866 assert!(!layout.is_block_inserted(e0));
867 assert!(layout.is_block_inserted(e1));
868 assert!(!layout.is_block_inserted(e2));
869 let v: Vec<Block> = layout.blocks().collect();
870 assert_eq!(v, [e1]);
871
872 layout.append_block(e2);
873 assert!(!layout.is_block_inserted(e0));
874 assert!(layout.is_block_inserted(e1));
875 assert!(layout.is_block_inserted(e2));
876 let v: Vec<Block> = layout.blocks().collect();
877 assert_eq!(v, [e1, e2]);
878
879 layout.append_block(e0);
880 assert!(layout.is_block_inserted(e0));
881 assert!(layout.is_block_inserted(e1));
882 assert!(layout.is_block_inserted(e2));
883 let v: Vec<Block> = layout.blocks().collect();
884 assert_eq!(v, [e1, e2, e0]);
885
886 {
887 let imm = &layout;
888 let mut v = Vec::new();
889 for e in imm {
890 v.push(e);
891 }
892 assert_eq!(v, [e1, e2, e0]);
893 }
894
895 let mut cur = LayoutCursor::new(&mut layout);
897 assert_eq!(cur.position(), CursorPosition::Nowhere);
898 assert_eq!(cur.next_inst(), None);
899 assert_eq!(cur.position(), CursorPosition::Nowhere);
900 assert_eq!(cur.prev_inst(), None);
901 assert_eq!(cur.position(), CursorPosition::Nowhere);
902
903 assert_eq!(cur.next_block(), Some(e1));
904 assert_eq!(cur.position(), CursorPosition::Before(e1));
905 assert_eq!(cur.next_inst(), None);
906 assert_eq!(cur.position(), CursorPosition::After(e1));
907 assert_eq!(cur.next_inst(), None);
908 assert_eq!(cur.position(), CursorPosition::After(e1));
909 assert_eq!(cur.next_block(), Some(e2));
910 assert_eq!(cur.prev_inst(), None);
911 assert_eq!(cur.position(), CursorPosition::Before(e2));
912 assert_eq!(cur.next_block(), Some(e0));
913 assert_eq!(cur.next_block(), None);
914 assert_eq!(cur.position(), CursorPosition::Nowhere);
915
916 assert_eq!(cur.prev_block(), Some(e0));
918 assert_eq!(cur.position(), CursorPosition::After(e0));
919 assert_eq!(cur.prev_block(), Some(e2));
920 assert_eq!(cur.prev_block(), Some(e1));
921 assert_eq!(cur.prev_block(), None);
922 assert_eq!(cur.position(), CursorPosition::Nowhere);
923 }
924
925 #[test]
926 fn insert_block() {
927 let mut layout = Layout::new();
928 let e0 = Block::new(0);
929 let e1 = Block::new(1);
930 let e2 = Block::new(2);
931
932 {
933 let imm = &layout;
934 assert!(!imm.is_block_inserted(e0));
935 assert!(!imm.is_block_inserted(e1));
936
937 let v: Vec<Block> = layout.blocks().collect();
938 assert_eq!(v, []);
939 }
940
941 layout.append_block(e1);
942 assert!(!layout.is_block_inserted(e0));
943 assert!(layout.is_block_inserted(e1));
944 assert!(!layout.is_block_inserted(e2));
945 verify(&mut layout, &[(e1, &[])]);
946
947 layout.insert_block(e2, e1);
948 assert!(!layout.is_block_inserted(e0));
949 assert!(layout.is_block_inserted(e1));
950 assert!(layout.is_block_inserted(e2));
951 verify(&mut layout, &[(e2, &[]), (e1, &[])]);
952
953 layout.insert_block(e0, e1);
954 assert!(layout.is_block_inserted(e0));
955 assert!(layout.is_block_inserted(e1));
956 assert!(layout.is_block_inserted(e2));
957 verify(&mut layout, &[(e2, &[]), (e0, &[]), (e1, &[])]);
958 }
959
960 #[test]
961 fn insert_block_after() {
962 let mut layout = Layout::new();
963 let e0 = Block::new(0);
964 let e1 = Block::new(1);
965 let e2 = Block::new(2);
966
967 layout.append_block(e1);
968 layout.insert_block_after(e2, e1);
969 verify(&mut layout, &[(e1, &[]), (e2, &[])]);
970
971 layout.insert_block_after(e0, e1);
972 verify(&mut layout, &[(e1, &[]), (e0, &[]), (e2, &[])]);
973 }
974
975 #[test]
976 fn append_inst() {
977 let mut layout = Layout::new();
978 let e1 = Block::new(1);
979
980 layout.append_block(e1);
981 let v: Vec<Inst> = layout.block_insts(e1).collect();
982 assert_eq!(v, []);
983
984 let i0 = Inst::new(0);
985 let i1 = Inst::new(1);
986 let i2 = Inst::new(2);
987
988 assert_eq!(layout.inst_block(i0), None);
989 assert_eq!(layout.inst_block(i1), None);
990 assert_eq!(layout.inst_block(i2), None);
991
992 layout.append_inst(i1, e1);
993 assert_eq!(layout.inst_block(i0), None);
994 assert_eq!(layout.inst_block(i1), Some(e1));
995 assert_eq!(layout.inst_block(i2), None);
996 let v: Vec<Inst> = layout.block_insts(e1).collect();
997 assert_eq!(v, [i1]);
998
999 layout.append_inst(i2, e1);
1000 assert_eq!(layout.inst_block(i0), None);
1001 assert_eq!(layout.inst_block(i1), Some(e1));
1002 assert_eq!(layout.inst_block(i2), Some(e1));
1003 let v: Vec<Inst> = layout.block_insts(e1).collect();
1004 assert_eq!(v, [i1, i2]);
1005
1006 let v: Vec<Inst> = layout.block_insts(e1).rev().collect();
1008 assert_eq!(v, [i2, i1]);
1009
1010 layout.append_inst(i0, e1);
1011 verify(&mut layout, &[(e1, &[i1, i2, i0])]);
1012
1013 let mut cur = LayoutCursor::new(&mut layout).at_top(e1);
1015 assert_eq!(cur.position(), CursorPosition::Before(e1));
1016 assert_eq!(cur.prev_inst(), None);
1017 assert_eq!(cur.position(), CursorPosition::Before(e1));
1018 assert_eq!(cur.next_inst(), Some(i1));
1019 assert_eq!(cur.position(), CursorPosition::At(i1));
1020 assert_eq!(cur.next_inst(), Some(i2));
1021 assert_eq!(cur.next_inst(), Some(i0));
1022 assert_eq!(cur.prev_inst(), Some(i2));
1023 assert_eq!(cur.position(), CursorPosition::At(i2));
1024 assert_eq!(cur.next_inst(), Some(i0));
1025 assert_eq!(cur.position(), CursorPosition::At(i0));
1026 assert_eq!(cur.next_inst(), None);
1027 assert_eq!(cur.position(), CursorPosition::After(e1));
1028 assert_eq!(cur.next_inst(), None);
1029 assert_eq!(cur.position(), CursorPosition::After(e1));
1030 assert_eq!(cur.prev_inst(), Some(i0));
1031 assert_eq!(cur.prev_inst(), Some(i2));
1032 assert_eq!(cur.prev_inst(), Some(i1));
1033 assert_eq!(cur.prev_inst(), None);
1034 assert_eq!(cur.position(), CursorPosition::Before(e1));
1035
1036 cur.goto_inst(i2);
1038 assert_eq!(cur.remove_inst(), i2);
1039 verify(cur.layout, &[(e1, &[i1, i0])]);
1040 assert_eq!(cur.layout.inst_block(i2), None);
1041 assert_eq!(cur.remove_inst(), i0);
1042 verify(cur.layout, &[(e1, &[i1])]);
1043 assert_eq!(cur.layout.inst_block(i0), None);
1044 assert_eq!(cur.position(), CursorPosition::After(e1));
1045 cur.layout.remove_inst(i1);
1046 verify(cur.layout, &[(e1, &[])]);
1047 assert_eq!(cur.layout.inst_block(i1), None);
1048 }
1049
1050 #[test]
1051 fn insert_inst() {
1052 let mut layout = Layout::new();
1053 let e1 = Block::new(1);
1054
1055 layout.append_block(e1);
1056 let v: Vec<Inst> = layout.block_insts(e1).collect();
1057 assert_eq!(v, []);
1058
1059 let i0 = Inst::new(0);
1060 let i1 = Inst::new(1);
1061 let i2 = Inst::new(2);
1062
1063 assert_eq!(layout.inst_block(i0), None);
1064 assert_eq!(layout.inst_block(i1), None);
1065 assert_eq!(layout.inst_block(i2), None);
1066
1067 layout.append_inst(i1, e1);
1068 assert_eq!(layout.inst_block(i0), None);
1069 assert_eq!(layout.inst_block(i1), Some(e1));
1070 assert_eq!(layout.inst_block(i2), None);
1071 let v: Vec<Inst> = layout.block_insts(e1).collect();
1072 assert_eq!(v, [i1]);
1073
1074 layout.insert_inst(i2, i1);
1075 assert_eq!(layout.inst_block(i0), None);
1076 assert_eq!(layout.inst_block(i1), Some(e1));
1077 assert_eq!(layout.inst_block(i2), Some(e1));
1078 let v: Vec<Inst> = layout.block_insts(e1).collect();
1079 assert_eq!(v, [i2, i1]);
1080
1081 layout.insert_inst(i0, i1);
1082 verify(&mut layout, &[(e1, &[i2, i0, i1])]);
1083 }
1084
1085 #[test]
1086 fn multiple_blocks() {
1087 let mut layout = Layout::new();
1088
1089 let e0 = Block::new(0);
1090 let e1 = Block::new(1);
1091
1092 assert_eq!(layout.entry_block(), None);
1093 layout.append_block(e0);
1094 assert_eq!(layout.entry_block(), Some(e0));
1095 layout.append_block(e1);
1096 assert_eq!(layout.entry_block(), Some(e0));
1097
1098 let i0 = Inst::new(0);
1099 let i1 = Inst::new(1);
1100 let i2 = Inst::new(2);
1101 let i3 = Inst::new(3);
1102
1103 layout.append_inst(i0, e0);
1104 layout.append_inst(i1, e0);
1105 layout.append_inst(i2, e1);
1106 layout.append_inst(i3, e1);
1107
1108 let v0: Vec<Inst> = layout.block_insts(e0).collect();
1109 let v1: Vec<Inst> = layout.block_insts(e1).collect();
1110 assert_eq!(v0, [i0, i1]);
1111 assert_eq!(v1, [i2, i3]);
1112 }
1113
1114 #[test]
1115 fn split_block() {
1116 let mut layout = Layout::new();
1117
1118 let e0 = Block::new(0);
1119 let e1 = Block::new(1);
1120 let e2 = Block::new(2);
1121
1122 let i0 = Inst::new(0);
1123 let i1 = Inst::new(1);
1124 let i2 = Inst::new(2);
1125 let i3 = Inst::new(3);
1126
1127 layout.append_block(e0);
1128 layout.append_inst(i0, e0);
1129 assert_eq!(layout.inst_block(i0), Some(e0));
1130 layout.split_block(e1, i0);
1131 assert_eq!(layout.inst_block(i0), Some(e1));
1132
1133 {
1134 let mut cur = LayoutCursor::new(&mut layout);
1135 assert_eq!(cur.next_block(), Some(e0));
1136 assert_eq!(cur.next_inst(), None);
1137 assert_eq!(cur.next_block(), Some(e1));
1138 assert_eq!(cur.next_inst(), Some(i0));
1139 assert_eq!(cur.next_inst(), None);
1140 assert_eq!(cur.next_block(), None);
1141
1142 assert_eq!(cur.prev_block(), Some(e1));
1144 assert_eq!(cur.prev_inst(), Some(i0));
1145 assert_eq!(cur.prev_inst(), None);
1146 assert_eq!(cur.prev_block(), Some(e0));
1147 assert_eq!(cur.prev_inst(), None);
1148 assert_eq!(cur.prev_block(), None);
1149 }
1150
1151 layout.append_inst(i1, e0);
1152 layout.append_inst(i2, e0);
1153 layout.append_inst(i3, e0);
1154 layout.split_block(e2, i2);
1155
1156 assert_eq!(layout.inst_block(i0), Some(e1));
1157 assert_eq!(layout.inst_block(i1), Some(e0));
1158 assert_eq!(layout.inst_block(i2), Some(e2));
1159 assert_eq!(layout.inst_block(i3), Some(e2));
1160
1161 {
1162 let mut cur = LayoutCursor::new(&mut layout);
1163 assert_eq!(cur.next_block(), Some(e0));
1164 assert_eq!(cur.next_inst(), Some(i1));
1165 assert_eq!(cur.next_inst(), None);
1166 assert_eq!(cur.next_block(), Some(e2));
1167 assert_eq!(cur.next_inst(), Some(i2));
1168 assert_eq!(cur.next_inst(), Some(i3));
1169 assert_eq!(cur.next_inst(), None);
1170 assert_eq!(cur.next_block(), Some(e1));
1171 assert_eq!(cur.next_inst(), Some(i0));
1172 assert_eq!(cur.next_inst(), None);
1173 assert_eq!(cur.next_block(), None);
1174
1175 assert_eq!(cur.prev_block(), Some(e1));
1176 assert_eq!(cur.prev_inst(), Some(i0));
1177 assert_eq!(cur.prev_inst(), None);
1178 assert_eq!(cur.prev_block(), Some(e2));
1179 assert_eq!(cur.prev_inst(), Some(i3));
1180 assert_eq!(cur.prev_inst(), Some(i2));
1181 assert_eq!(cur.prev_inst(), None);
1182 assert_eq!(cur.prev_block(), Some(e0));
1183 assert_eq!(cur.prev_inst(), Some(i1));
1184 assert_eq!(cur.prev_inst(), None);
1185 assert_eq!(cur.prev_block(), None);
1186 }
1187
1188 assert_eq!(layout.pp_cmp(e2, e2), Ordering::Equal);
1190 assert_eq!(layout.pp_cmp(e2, i2), Ordering::Less);
1191 assert_eq!(layout.pp_cmp(i3, i2), Ordering::Greater)
1192 }
1193}