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