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 { Some(m) } else { None }
96}
97
98impl Layout {
99 pub fn pp_cmp<A, B>(&self, a: A, b: B) -> cmp::Ordering
107 where
108 A: Into<ProgramPoint>,
109 B: Into<ProgramPoint>,
110 {
111 let a = a.into();
112 let b = b.into();
113 debug_assert_eq!(self.pp_block(a), self.pp_block(b));
114 let a_seq = match a {
115 ProgramPoint::Block(_block) => 0,
116 ProgramPoint::Inst(inst) => self.insts[inst].seq,
117 };
118 let b_seq = match b {
119 ProgramPoint::Block(_block) => 0,
120 ProgramPoint::Inst(inst) => self.insts[inst].seq,
121 };
122 a_seq.cmp(&b_seq)
123 }
124}
125
126impl Layout {
128 fn assign_inst_seq(&mut self, inst: Inst) {
131 let prev_seq = match self.insts[inst].prev.expand() {
133 Some(prev_inst) => self.insts[prev_inst].seq,
134 None => 0,
135 };
136
137 let next_seq = if let Some(next_inst) = self.insts[inst].next.expand() {
139 self.insts[next_inst].seq
140 } else {
141 self.insts[inst].seq = prev_seq + MAJOR_STRIDE;
143 return;
144 };
145
146 if let Some(seq) = midpoint(prev_seq, next_seq) {
148 self.insts[inst].seq = seq;
149 } else {
150 self.renumber_insts(inst, prev_seq + MINOR_STRIDE, prev_seq + LOCAL_LIMIT);
152 }
153 }
154
155 fn renumber_insts(&mut self, inst: Inst, seq: SequenceNumber, limit: SequenceNumber) {
160 let mut inst = inst;
161 let mut seq = seq;
162
163 loop {
164 self.insts[inst].seq = seq;
165
166 inst = match self.insts[inst].next.expand() {
168 None => return,
169 Some(next) => next,
170 };
171
172 if seq < self.insts[inst].seq {
173 return;
175 }
176
177 if seq > limit {
178 self.full_block_renumber(
181 self.inst_block(inst)
182 .expect("inst must be inserted before assigning an seq"),
183 );
184 return;
185 }
186
187 seq += MINOR_STRIDE;
188 }
189 }
190
191 fn full_block_renumber(&mut self, block: Block) {
196 let _tt = timing::layout_renumber();
197 let mut seq = MAJOR_STRIDE;
199 let mut next_inst = self.blocks[block].first_inst.expand();
200 while let Some(inst) = next_inst {
201 self.insts[inst].seq = seq;
202 seq += MAJOR_STRIDE;
203 next_inst = self.insts[inst].next.expand();
204 }
205
206 trace!("Renumbered {} program points", seq / MAJOR_STRIDE);
207 }
208}
209
210impl Layout {
220 pub fn is_block_inserted(&self, block: Block) -> bool {
222 Some(block) == self.first_block || self.blocks[block].prev.is_some()
223 }
224
225 pub fn append_block(&mut self, block: Block) {
227 debug_assert!(
228 !self.is_block_inserted(block),
229 "Cannot append block that is already in the layout"
230 );
231 {
232 let node = &mut self.blocks[block];
233 debug_assert!(node.first_inst.is_none() && node.last_inst.is_none());
234 node.prev = self.last_block.into();
235 node.next = None.into();
236 }
237 if let Some(last) = self.last_block {
238 self.blocks[last].next = block.into();
239 } else {
240 self.first_block = Some(block);
241 }
242 self.last_block = Some(block);
243 }
244
245 pub fn insert_block(&mut self, block: Block, before: Block) {
247 debug_assert!(
248 !self.is_block_inserted(block),
249 "Cannot insert block that is already in the layout"
250 );
251 debug_assert!(
252 self.is_block_inserted(before),
253 "block Insertion point not in the layout"
254 );
255 let after = self.blocks[before].prev;
256 {
257 let node = &mut self.blocks[block];
258 node.next = before.into();
259 node.prev = after;
260 }
261 self.blocks[before].prev = block.into();
262 match after.expand() {
263 None => self.first_block = Some(block),
264 Some(a) => self.blocks[a].next = block.into(),
265 }
266 }
267
268 pub fn insert_block_after(&mut self, block: Block, after: Block) {
270 debug_assert!(
271 !self.is_block_inserted(block),
272 "Cannot insert block that is already in the layout"
273 );
274 debug_assert!(
275 self.is_block_inserted(after),
276 "block Insertion point not in the layout"
277 );
278 let before = self.blocks[after].next;
279 {
280 let node = &mut self.blocks[block];
281 node.next = before;
282 node.prev = after.into();
283 }
284 self.blocks[after].next = block.into();
285 match before.expand() {
286 None => self.last_block = Some(block),
287 Some(b) => self.blocks[b].prev = block.into(),
288 }
289 }
290
291 pub fn remove_block(&mut self, block: Block) {
293 debug_assert!(self.is_block_inserted(block), "block not in the layout");
294 debug_assert!(self.first_inst(block).is_none(), "block must be empty.");
295
296 let prev;
298 let next;
299 {
300 let n = &mut self.blocks[block];
301 prev = n.prev;
302 next = n.next;
303 n.prev = None.into();
304 n.next = None.into();
305 }
306 match prev.expand() {
308 None => self.first_block = next.expand(),
309 Some(p) => self.blocks[p].next = next,
310 }
311 match next.expand() {
312 None => self.last_block = prev.expand(),
313 Some(n) => self.blocks[n].prev = prev,
314 }
315 }
316
317 pub fn blocks(&self) -> Blocks<'_> {
319 Blocks {
320 layout: self,
321 next: self.first_block,
322 }
323 }
324
325 pub fn entry_block(&self) -> Option<Block> {
328 self.first_block
329 }
330
331 pub fn last_block(&self) -> Option<Block> {
333 self.last_block
334 }
335
336 pub fn prev_block(&self, block: Block) -> Option<Block> {
338 self.blocks[block].prev.expand()
339 }
340
341 pub fn next_block(&self, block: Block) -> Option<Block> {
343 self.blocks[block].next.expand()
344 }
345
346 pub fn set_cold(&mut self, block: Block) {
351 self.blocks[block].cold = true;
352 }
353
354 pub fn is_cold(&self, block: Block) -> bool {
356 self.blocks[block].cold
357 }
358}
359
360#[derive(Clone, Debug, Default, PartialEq, Hash)]
363struct BlockNode {
364 prev: PackedOption<Block>,
365 next: PackedOption<Block>,
366 first_inst: PackedOption<Inst>,
367 last_inst: PackedOption<Inst>,
368 cold: bool,
369}
370
371pub struct Blocks<'f> {
373 layout: &'f Layout,
374 next: Option<Block>,
375}
376
377impl<'f> Iterator for Blocks<'f> {
378 type Item = Block;
379
380 fn next(&mut self) -> Option<Block> {
381 match self.next {
382 Some(block) => {
383 self.next = self.layout.next_block(block);
384 Some(block)
385 }
386 None => None,
387 }
388 }
389}
390
391impl<'f> IntoIterator for &'f Layout {
393 type Item = Block;
394 type IntoIter = Blocks<'f>;
395
396 fn into_iter(self) -> Blocks<'f> {
397 self.blocks()
398 }
399}
400
401impl Layout {
406 pub fn inst_block(&self, inst: Inst) -> Option<Block> {
408 self.insts[inst].block.into()
409 }
410
411 pub fn pp_block(&self, pp: ProgramPoint) -> Block {
413 match pp {
414 ProgramPoint::Block(block) => block,
415 ProgramPoint::Inst(inst) => self.inst_block(inst).expect("Program point not in layout"),
416 }
417 }
418
419 pub fn append_inst(&mut self, inst: Inst, block: Block) {
421 debug_assert_eq!(self.inst_block(inst), None);
422 debug_assert!(
423 self.is_block_inserted(block),
424 "Cannot append instructions to block not in layout"
425 );
426 {
427 let block_node = &mut self.blocks[block];
428 {
429 let inst_node = &mut self.insts[inst];
430 inst_node.block = block.into();
431 inst_node.prev = block_node.last_inst;
432 debug_assert!(inst_node.next.is_none());
433 }
434 if block_node.first_inst.is_none() {
435 block_node.first_inst = inst.into();
436 } else {
437 self.insts[block_node.last_inst.unwrap()].next = inst.into();
438 }
439 block_node.last_inst = inst.into();
440 }
441 self.assign_inst_seq(inst);
442 }
443
444 pub fn first_inst(&self, block: Block) -> Option<Inst> {
446 self.blocks[block].first_inst.into()
447 }
448
449 pub fn last_inst(&self, block: Block) -> Option<Inst> {
451 self.blocks[block].last_inst.into()
452 }
453
454 pub fn next_inst(&self, inst: Inst) -> Option<Inst> {
456 self.insts[inst].next.expand()
457 }
458
459 pub fn prev_inst(&self, inst: Inst) -> Option<Inst> {
461 self.insts[inst].prev.expand()
462 }
463
464 pub fn insert_inst(&mut self, inst: Inst, before: Inst) {
466 debug_assert_eq!(self.inst_block(inst), None);
467 let block = self
468 .inst_block(before)
469 .expect("Instruction before insertion point not in the layout");
470 let after = self.insts[before].prev;
471 {
472 let inst_node = &mut self.insts[inst];
473 inst_node.block = block.into();
474 inst_node.next = before.into();
475 inst_node.prev = after;
476 }
477 self.insts[before].prev = inst.into();
478 match after.expand() {
479 None => self.blocks[block].first_inst = inst.into(),
480 Some(a) => self.insts[a].next = inst.into(),
481 }
482 self.assign_inst_seq(inst);
483 }
484
485 pub fn remove_inst(&mut self, inst: Inst) {
487 let block = self.inst_block(inst).expect("Instruction already removed.");
488 let prev;
490 let next;
491 {
492 let n = &mut self.insts[inst];
493 prev = n.prev;
494 next = n.next;
495 n.block = None.into();
496 n.prev = None.into();
497 n.next = None.into();
498 }
499 match prev.expand() {
501 None => self.blocks[block].first_inst = next,
502 Some(p) => self.insts[p].next = next,
503 }
504 match next.expand() {
505 None => self.blocks[block].last_inst = prev,
506 Some(n) => self.insts[n].prev = prev,
507 }
508 }
509
510 pub fn block_insts(&self, block: Block) -> Insts<'_> {
512 Insts {
513 layout: self,
514 head: self.blocks[block].first_inst.into(),
515 tail: self.blocks[block].last_inst.into(),
516 }
517 }
518
519 pub fn split_block(&mut self, new_block: Block, before: Inst) {
542 let old_block = self
543 .inst_block(before)
544 .expect("The `before` instruction must be in the layout");
545 debug_assert!(!self.is_block_inserted(new_block));
546
547 let next_block = self.blocks[old_block].next;
549 let last_inst = self.blocks[old_block].last_inst;
550 {
551 let node = &mut self.blocks[new_block];
552 node.prev = old_block.into();
553 node.next = next_block;
554 node.first_inst = before.into();
555 node.last_inst = last_inst;
556 }
557 self.blocks[old_block].next = new_block.into();
558
559 if Some(old_block) == self.last_block {
561 self.last_block = Some(new_block);
562 } else {
563 self.blocks[next_block.unwrap()].prev = new_block.into();
564 }
565
566 let prev_inst = self.insts[before].prev;
568 self.insts[before].prev = None.into();
569 self.blocks[old_block].last_inst = prev_inst;
570 match prev_inst.expand() {
571 None => self.blocks[old_block].first_inst = None.into(),
572 Some(pi) => self.insts[pi].next = None.into(),
573 }
574
575 let mut opt_i = Some(before);
577 while let Some(i) = opt_i {
578 debug_assert_eq!(self.insts[i].block.expand(), Some(old_block));
579 self.insts[i].block = new_block.into();
580 opt_i = self.insts[i].next.into();
581 }
582 }
583}
584
585#[derive(Clone, Debug, Default)]
586struct InstNode {
587 block: PackedOption<Block>,
589 prev: PackedOption<Inst>,
590 next: PackedOption<Inst>,
591 seq: SequenceNumber,
592}
593
594impl PartialEq for InstNode {
595 fn eq(&self, other: &Self) -> bool {
596 self.block == other.block && self.prev == other.prev && self.next == other.next
599 }
600}
601
602impl core::hash::Hash for InstNode {
603 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
604 self.block.hash(state);
607 self.prev.hash(state);
608 self.next.hash(state);
609 }
610}
611
612pub struct Insts<'f> {
614 layout: &'f Layout,
615 head: Option<Inst>,
616 tail: Option<Inst>,
617}
618
619impl<'f> Iterator for Insts<'f> {
620 type Item = Inst;
621
622 fn next(&mut self) -> Option<Inst> {
623 let rval = self.head;
624 if let Some(inst) = rval {
625 if self.head == self.tail {
626 self.head = None;
627 self.tail = None;
628 } else {
629 self.head = self.layout.insts[inst].next.into();
630 }
631 }
632 rval
633 }
634}
635
636impl<'f> DoubleEndedIterator for Insts<'f> {
637 fn next_back(&mut self) -> Option<Inst> {
638 let rval = self.tail;
639 if let Some(inst) = rval {
640 if self.head == self.tail {
641 self.head = None;
642 self.tail = None;
643 } else {
644 self.tail = self.layout.insts[inst].prev.into();
645 }
646 }
647 rval
648 }
649}
650
651#[cfg(feature = "enable-serde")]
663mod serde {
664 use ::serde::de::{Deserializer, Error, SeqAccess, Visitor};
665 use ::serde::ser::{SerializeSeq, Serializer};
666 use ::serde::{Deserialize, Serialize};
667 use core::fmt;
668 use core::marker::PhantomData;
669
670 use super::*;
671
672 impl Serialize for Layout {
673 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
674 where
675 S: Serializer,
676 {
677 let size = self.blocks().count() * 3
678 + self
679 .blocks()
680 .map(|block| self.block_insts(block).count())
681 .sum::<usize>();
682 let mut seq = serializer.serialize_seq(Some(size))?;
683 for block in self.blocks() {
684 seq.serialize_element(&block)?;
685 seq.serialize_element(&self.blocks[block].cold)?;
686 seq.serialize_element(&u32::try_from(self.block_insts(block).count()).unwrap())?;
687 for inst in self.block_insts(block) {
688 seq.serialize_element(&inst)?;
689 }
690 }
691 seq.end()
692 }
693 }
694
695 impl<'de> Deserialize<'de> for Layout {
696 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
697 where
698 D: Deserializer<'de>,
699 {
700 deserializer.deserialize_seq(LayoutVisitor {
701 marker: PhantomData,
702 })
703 }
704 }
705
706 struct LayoutVisitor {
707 marker: PhantomData<fn() -> Layout>,
708 }
709
710 impl<'de> Visitor<'de> for LayoutVisitor {
711 type Value = Layout;
712
713 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
714 write!(formatter, "a `cranelift_codegen::ir::Layout`")
715 }
716
717 fn visit_seq<M>(self, mut access: M) -> Result<Self::Value, M::Error>
718 where
719 M: SeqAccess<'de>,
720 {
721 let mut layout = Layout::new();
722
723 while let Some(block) = access.next_element::<Block>()? {
724 layout.append_block(block);
725
726 let cold = access
727 .next_element::<bool>()?
728 .ok_or_else(|| Error::missing_field("cold"))?;
729 layout.blocks[block].cold = cold;
730
731 let count = access
732 .next_element::<u32>()?
733 .ok_or_else(|| Error::missing_field("count"))?;
734
735 for _ in 0..count {
736 let inst = access
737 .next_element::<Inst>()?
738 .ok_or_else(|| Error::missing_field("inst"))?;
739 layout.append_inst(inst, block);
740 }
741 }
742
743 Ok(layout)
744 }
745 }
746}
747
748#[cfg(test)]
749mod tests {
750 use super::*;
751 use crate::cursor::{Cursor, CursorPosition};
752 use crate::entity::EntityRef;
753 use crate::ir::{Block, Inst, SourceLoc};
754 use alloc::vec::Vec;
755 use core::cmp::Ordering;
756
757 #[test]
758 fn test_midpoint() {
759 assert_eq!(midpoint(0, 1), None);
760 assert_eq!(midpoint(0, 2), Some(1));
761 assert_eq!(midpoint(0, 3), Some(1));
762 assert_eq!(midpoint(0, 4), Some(2));
763 assert_eq!(midpoint(1, 4), Some(2));
764 assert_eq!(midpoint(2, 4), Some(3));
765 assert_eq!(midpoint(3, 4), None);
766 assert_eq!(midpoint(3, 4), None);
767 }
768
769 struct LayoutCursor<'f> {
770 pub layout: &'f mut Layout,
772 pos: CursorPosition,
773 }
774
775 impl<'f> Cursor for LayoutCursor<'f> {
776 fn position(&self) -> CursorPosition {
777 self.pos
778 }
779
780 fn set_position(&mut self, pos: CursorPosition) {
781 self.pos = pos;
782 }
783
784 fn srcloc(&self) -> SourceLoc {
785 unimplemented!()
786 }
787
788 fn set_srcloc(&mut self, _srcloc: SourceLoc) {
789 unimplemented!()
790 }
791
792 fn layout(&self) -> &Layout {
793 self.layout
794 }
795
796 fn layout_mut(&mut self) -> &mut Layout {
797 self.layout
798 }
799 }
800
801 impl<'f> LayoutCursor<'f> {
802 pub fn new(layout: &'f mut Layout) -> Self {
805 Self {
806 layout,
807 pos: CursorPosition::Nowhere,
808 }
809 }
810 }
811
812 fn verify(layout: &mut Layout, blocks: &[(Block, &[Inst])]) {
813 {
817 let mut block_iter = layout.blocks();
818 for &(block, insts) in blocks {
819 assert!(layout.is_block_inserted(block));
820 assert_eq!(block_iter.next(), Some(block));
821
822 let mut seq = 0;
823 let mut inst_iter = layout.block_insts(block);
824 for &inst in insts {
825 assert_eq!(layout.inst_block(inst), Some(block));
826 assert_eq!(inst_iter.next(), Some(inst));
827 assert!(layout.insts[inst].seq > seq);
828 seq = layout.insts[inst].seq;
829 }
830 assert_eq!(inst_iter.next(), None);
831 }
832 assert_eq!(block_iter.next(), None);
833 }
834
835 let mut cur = LayoutCursor::new(layout);
837 for &(block, insts) in blocks.into_iter().rev() {
838 assert_eq!(cur.prev_block(), Some(block));
839 for &inst in insts.into_iter().rev() {
840 assert_eq!(cur.prev_inst(), Some(inst));
841 }
842 assert_eq!(cur.prev_inst(), None);
843 }
844 assert_eq!(cur.prev_block(), None);
845 }
846
847 #[test]
848 fn append_block() {
849 let mut layout = Layout::new();
850 let e0 = Block::new(0);
851 let e1 = Block::new(1);
852 let e2 = Block::new(2);
853
854 {
855 let imm = &layout;
856 assert!(!imm.is_block_inserted(e0));
857 assert!(!imm.is_block_inserted(e1));
858 }
859 verify(&mut layout, &[]);
860
861 layout.append_block(e1);
862 assert!(!layout.is_block_inserted(e0));
863 assert!(layout.is_block_inserted(e1));
864 assert!(!layout.is_block_inserted(e2));
865 let v: Vec<Block> = layout.blocks().collect();
866 assert_eq!(v, [e1]);
867
868 layout.append_block(e2);
869 assert!(!layout.is_block_inserted(e0));
870 assert!(layout.is_block_inserted(e1));
871 assert!(layout.is_block_inserted(e2));
872 let v: Vec<Block> = layout.blocks().collect();
873 assert_eq!(v, [e1, e2]);
874
875 layout.append_block(e0);
876 assert!(layout.is_block_inserted(e0));
877 assert!(layout.is_block_inserted(e1));
878 assert!(layout.is_block_inserted(e2));
879 let v: Vec<Block> = layout.blocks().collect();
880 assert_eq!(v, [e1, e2, e0]);
881
882 {
883 let imm = &layout;
884 let mut v = Vec::new();
885 for e in imm {
886 v.push(e);
887 }
888 assert_eq!(v, [e1, e2, e0]);
889 }
890
891 let mut cur = LayoutCursor::new(&mut layout);
893 assert_eq!(cur.position(), CursorPosition::Nowhere);
894 assert_eq!(cur.next_inst(), None);
895 assert_eq!(cur.position(), CursorPosition::Nowhere);
896 assert_eq!(cur.prev_inst(), None);
897 assert_eq!(cur.position(), CursorPosition::Nowhere);
898
899 assert_eq!(cur.next_block(), Some(e1));
900 assert_eq!(cur.position(), CursorPosition::Before(e1));
901 assert_eq!(cur.next_inst(), None);
902 assert_eq!(cur.position(), CursorPosition::After(e1));
903 assert_eq!(cur.next_inst(), None);
904 assert_eq!(cur.position(), CursorPosition::After(e1));
905 assert_eq!(cur.next_block(), Some(e2));
906 assert_eq!(cur.prev_inst(), None);
907 assert_eq!(cur.position(), CursorPosition::Before(e2));
908 assert_eq!(cur.next_block(), Some(e0));
909 assert_eq!(cur.next_block(), None);
910 assert_eq!(cur.position(), CursorPosition::Nowhere);
911
912 assert_eq!(cur.prev_block(), Some(e0));
914 assert_eq!(cur.position(), CursorPosition::After(e0));
915 assert_eq!(cur.prev_block(), Some(e2));
916 assert_eq!(cur.prev_block(), Some(e1));
917 assert_eq!(cur.prev_block(), None);
918 assert_eq!(cur.position(), CursorPosition::Nowhere);
919 }
920
921 #[test]
922 fn insert_block() {
923 let mut layout = Layout::new();
924 let e0 = Block::new(0);
925 let e1 = Block::new(1);
926 let e2 = Block::new(2);
927
928 {
929 let imm = &layout;
930 assert!(!imm.is_block_inserted(e0));
931 assert!(!imm.is_block_inserted(e1));
932
933 let v: Vec<Block> = layout.blocks().collect();
934 assert_eq!(v, []);
935 }
936
937 layout.append_block(e1);
938 assert!(!layout.is_block_inserted(e0));
939 assert!(layout.is_block_inserted(e1));
940 assert!(!layout.is_block_inserted(e2));
941 verify(&mut layout, &[(e1, &[])]);
942
943 layout.insert_block(e2, 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, &[(e2, &[]), (e1, &[])]);
948
949 layout.insert_block(e0, 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, &[]), (e0, &[]), (e1, &[])]);
954 }
955
956 #[test]
957 fn insert_block_after() {
958 let mut layout = Layout::new();
959 let e0 = Block::new(0);
960 let e1 = Block::new(1);
961 let e2 = Block::new(2);
962
963 layout.append_block(e1);
964 layout.insert_block_after(e2, e1);
965 verify(&mut layout, &[(e1, &[]), (e2, &[])]);
966
967 layout.insert_block_after(e0, e1);
968 verify(&mut layout, &[(e1, &[]), (e0, &[]), (e2, &[])]);
969 }
970
971 #[test]
972 fn append_inst() {
973 let mut layout = Layout::new();
974 let e1 = Block::new(1);
975
976 layout.append_block(e1);
977 let v: Vec<Inst> = layout.block_insts(e1).collect();
978 assert_eq!(v, []);
979
980 let i0 = Inst::new(0);
981 let i1 = Inst::new(1);
982 let i2 = Inst::new(2);
983
984 assert_eq!(layout.inst_block(i0), None);
985 assert_eq!(layout.inst_block(i1), None);
986 assert_eq!(layout.inst_block(i2), None);
987
988 layout.append_inst(i1, e1);
989 assert_eq!(layout.inst_block(i0), None);
990 assert_eq!(layout.inst_block(i1), Some(e1));
991 assert_eq!(layout.inst_block(i2), None);
992 let v: Vec<Inst> = layout.block_insts(e1).collect();
993 assert_eq!(v, [i1]);
994
995 layout.append_inst(i2, e1);
996 assert_eq!(layout.inst_block(i0), None);
997 assert_eq!(layout.inst_block(i1), Some(e1));
998 assert_eq!(layout.inst_block(i2), Some(e1));
999 let v: Vec<Inst> = layout.block_insts(e1).collect();
1000 assert_eq!(v, [i1, i2]);
1001
1002 let v: Vec<Inst> = layout.block_insts(e1).rev().collect();
1004 assert_eq!(v, [i2, i1]);
1005
1006 layout.append_inst(i0, e1);
1007 verify(&mut layout, &[(e1, &[i1, i2, i0])]);
1008
1009 let mut cur = LayoutCursor::new(&mut layout).at_top(e1);
1011 assert_eq!(cur.position(), CursorPosition::Before(e1));
1012 assert_eq!(cur.prev_inst(), None);
1013 assert_eq!(cur.position(), CursorPosition::Before(e1));
1014 assert_eq!(cur.next_inst(), Some(i1));
1015 assert_eq!(cur.position(), CursorPosition::At(i1));
1016 assert_eq!(cur.next_inst(), Some(i2));
1017 assert_eq!(cur.next_inst(), Some(i0));
1018 assert_eq!(cur.prev_inst(), Some(i2));
1019 assert_eq!(cur.position(), CursorPosition::At(i2));
1020 assert_eq!(cur.next_inst(), Some(i0));
1021 assert_eq!(cur.position(), CursorPosition::At(i0));
1022 assert_eq!(cur.next_inst(), None);
1023 assert_eq!(cur.position(), CursorPosition::After(e1));
1024 assert_eq!(cur.next_inst(), None);
1025 assert_eq!(cur.position(), CursorPosition::After(e1));
1026 assert_eq!(cur.prev_inst(), Some(i0));
1027 assert_eq!(cur.prev_inst(), Some(i2));
1028 assert_eq!(cur.prev_inst(), Some(i1));
1029 assert_eq!(cur.prev_inst(), None);
1030 assert_eq!(cur.position(), CursorPosition::Before(e1));
1031
1032 cur.goto_inst(i2);
1034 assert_eq!(cur.remove_inst(), i2);
1035 verify(cur.layout, &[(e1, &[i1, i0])]);
1036 assert_eq!(cur.layout.inst_block(i2), None);
1037 assert_eq!(cur.remove_inst(), i0);
1038 verify(cur.layout, &[(e1, &[i1])]);
1039 assert_eq!(cur.layout.inst_block(i0), None);
1040 assert_eq!(cur.position(), CursorPosition::After(e1));
1041 cur.layout.remove_inst(i1);
1042 verify(cur.layout, &[(e1, &[])]);
1043 assert_eq!(cur.layout.inst_block(i1), None);
1044 }
1045
1046 #[test]
1047 fn insert_inst() {
1048 let mut layout = Layout::new();
1049 let e1 = Block::new(1);
1050
1051 layout.append_block(e1);
1052 let v: Vec<Inst> = layout.block_insts(e1).collect();
1053 assert_eq!(v, []);
1054
1055 let i0 = Inst::new(0);
1056 let i1 = Inst::new(1);
1057 let i2 = Inst::new(2);
1058
1059 assert_eq!(layout.inst_block(i0), None);
1060 assert_eq!(layout.inst_block(i1), None);
1061 assert_eq!(layout.inst_block(i2), None);
1062
1063 layout.append_inst(i1, e1);
1064 assert_eq!(layout.inst_block(i0), None);
1065 assert_eq!(layout.inst_block(i1), Some(e1));
1066 assert_eq!(layout.inst_block(i2), None);
1067 let v: Vec<Inst> = layout.block_insts(e1).collect();
1068 assert_eq!(v, [i1]);
1069
1070 layout.insert_inst(i2, i1);
1071 assert_eq!(layout.inst_block(i0), None);
1072 assert_eq!(layout.inst_block(i1), Some(e1));
1073 assert_eq!(layout.inst_block(i2), Some(e1));
1074 let v: Vec<Inst> = layout.block_insts(e1).collect();
1075 assert_eq!(v, [i2, i1]);
1076
1077 layout.insert_inst(i0, i1);
1078 verify(&mut layout, &[(e1, &[i2, i0, i1])]);
1079 }
1080
1081 #[test]
1082 fn multiple_blocks() {
1083 let mut layout = Layout::new();
1084
1085 let e0 = Block::new(0);
1086 let e1 = Block::new(1);
1087
1088 assert_eq!(layout.entry_block(), None);
1089 layout.append_block(e0);
1090 assert_eq!(layout.entry_block(), Some(e0));
1091 layout.append_block(e1);
1092 assert_eq!(layout.entry_block(), Some(e0));
1093
1094 let i0 = Inst::new(0);
1095 let i1 = Inst::new(1);
1096 let i2 = Inst::new(2);
1097 let i3 = Inst::new(3);
1098
1099 layout.append_inst(i0, e0);
1100 layout.append_inst(i1, e0);
1101 layout.append_inst(i2, e1);
1102 layout.append_inst(i3, e1);
1103
1104 let v0: Vec<Inst> = layout.block_insts(e0).collect();
1105 let v1: Vec<Inst> = layout.block_insts(e1).collect();
1106 assert_eq!(v0, [i0, i1]);
1107 assert_eq!(v1, [i2, i3]);
1108 }
1109
1110 #[test]
1111 fn split_block() {
1112 let mut layout = Layout::new();
1113
1114 let e0 = Block::new(0);
1115 let e1 = Block::new(1);
1116 let e2 = Block::new(2);
1117
1118 let i0 = Inst::new(0);
1119 let i1 = Inst::new(1);
1120 let i2 = Inst::new(2);
1121 let i3 = Inst::new(3);
1122
1123 layout.append_block(e0);
1124 layout.append_inst(i0, e0);
1125 assert_eq!(layout.inst_block(i0), Some(e0));
1126 layout.split_block(e1, i0);
1127 assert_eq!(layout.inst_block(i0), Some(e1));
1128
1129 {
1130 let mut cur = LayoutCursor::new(&mut layout);
1131 assert_eq!(cur.next_block(), Some(e0));
1132 assert_eq!(cur.next_inst(), None);
1133 assert_eq!(cur.next_block(), Some(e1));
1134 assert_eq!(cur.next_inst(), Some(i0));
1135 assert_eq!(cur.next_inst(), None);
1136 assert_eq!(cur.next_block(), None);
1137
1138 assert_eq!(cur.prev_block(), Some(e1));
1140 assert_eq!(cur.prev_inst(), Some(i0));
1141 assert_eq!(cur.prev_inst(), None);
1142 assert_eq!(cur.prev_block(), Some(e0));
1143 assert_eq!(cur.prev_inst(), None);
1144 assert_eq!(cur.prev_block(), None);
1145 }
1146
1147 layout.append_inst(i1, e0);
1148 layout.append_inst(i2, e0);
1149 layout.append_inst(i3, e0);
1150 layout.split_block(e2, i2);
1151
1152 assert_eq!(layout.inst_block(i0), Some(e1));
1153 assert_eq!(layout.inst_block(i1), Some(e0));
1154 assert_eq!(layout.inst_block(i2), Some(e2));
1155 assert_eq!(layout.inst_block(i3), Some(e2));
1156
1157 {
1158 let mut cur = LayoutCursor::new(&mut layout);
1159 assert_eq!(cur.next_block(), Some(e0));
1160 assert_eq!(cur.next_inst(), Some(i1));
1161 assert_eq!(cur.next_inst(), None);
1162 assert_eq!(cur.next_block(), Some(e2));
1163 assert_eq!(cur.next_inst(), Some(i2));
1164 assert_eq!(cur.next_inst(), Some(i3));
1165 assert_eq!(cur.next_inst(), None);
1166 assert_eq!(cur.next_block(), Some(e1));
1167 assert_eq!(cur.next_inst(), Some(i0));
1168 assert_eq!(cur.next_inst(), None);
1169 assert_eq!(cur.next_block(), None);
1170
1171 assert_eq!(cur.prev_block(), Some(e1));
1172 assert_eq!(cur.prev_inst(), Some(i0));
1173 assert_eq!(cur.prev_inst(), None);
1174 assert_eq!(cur.prev_block(), Some(e2));
1175 assert_eq!(cur.prev_inst(), Some(i3));
1176 assert_eq!(cur.prev_inst(), Some(i2));
1177 assert_eq!(cur.prev_inst(), None);
1178 assert_eq!(cur.prev_block(), Some(e0));
1179 assert_eq!(cur.prev_inst(), Some(i1));
1180 assert_eq!(cur.prev_inst(), None);
1181 assert_eq!(cur.prev_block(), None);
1182 }
1183
1184 assert_eq!(layout.pp_cmp(e2, e2), Ordering::Equal);
1186 assert_eq!(layout.pp_cmp(e2, i2), Ordering::Less);
1187 assert_eq!(layout.pp_cmp(i3, i2), Ordering::Greater)
1188 }
1189}