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_and_insts(&mut self, block: Block) {
294 while let Some(inst) = self.first_inst(block) {
295 self.remove_inst(inst);
296 }
297 self.remove_block(block);
298 }
299
300 pub fn remove_block(&mut self, block: Block) {
302 debug_assert!(self.is_block_inserted(block), "block not in the layout");
303 debug_assert!(self.first_inst(block).is_none(), "block must be empty.");
304
305 let prev;
307 let next;
308 {
309 let n = &mut self.blocks[block];
310 prev = n.prev;
311 next = n.next;
312 n.prev = None.into();
313 n.next = None.into();
314 }
315 match prev.expand() {
317 None => self.first_block = next.expand(),
318 Some(p) => self.blocks[p].next = next,
319 }
320 match next.expand() {
321 None => self.last_block = prev.expand(),
322 Some(n) => self.blocks[n].prev = prev,
323 }
324 }
325
326 pub fn blocks(&self) -> Blocks<'_> {
328 Blocks {
329 layout: self,
330 next: self.first_block,
331 }
332 }
333
334 pub fn entry_block(&self) -> Option<Block> {
337 self.first_block
338 }
339
340 pub fn last_block(&self) -> Option<Block> {
342 self.last_block
343 }
344
345 pub fn prev_block(&self, block: Block) -> Option<Block> {
347 self.blocks[block].prev.expand()
348 }
349
350 pub fn next_block(&self, block: Block) -> Option<Block> {
352 self.blocks[block].next.expand()
353 }
354
355 pub fn set_cold(&mut self, block: Block) {
360 self.blocks[block].cold = true;
361 }
362
363 pub fn is_cold(&self, block: Block) -> bool {
365 self.blocks[block].cold
366 }
367}
368
369#[derive(Clone, Debug, Default, PartialEq, Hash)]
372struct BlockNode {
373 prev: PackedOption<Block>,
374 next: PackedOption<Block>,
375 first_inst: PackedOption<Inst>,
376 last_inst: PackedOption<Inst>,
377 cold: bool,
378}
379
380pub struct Blocks<'f> {
382 layout: &'f Layout,
383 next: Option<Block>,
384}
385
386impl<'f> Iterator for Blocks<'f> {
387 type Item = Block;
388
389 fn next(&mut self) -> Option<Block> {
390 match self.next {
391 Some(block) => {
392 self.next = self.layout.next_block(block);
393 Some(block)
394 }
395 None => None,
396 }
397 }
398}
399
400impl<'f> IntoIterator for &'f Layout {
402 type Item = Block;
403 type IntoIter = Blocks<'f>;
404
405 fn into_iter(self) -> Blocks<'f> {
406 self.blocks()
407 }
408}
409
410impl Layout {
415 pub fn inst_block(&self, inst: Inst) -> Option<Block> {
417 self.insts[inst].block.into()
418 }
419
420 pub fn pp_block(&self, pp: ProgramPoint) -> Block {
422 match pp {
423 ProgramPoint::Block(block) => block,
424 ProgramPoint::Inst(inst) => self.inst_block(inst).expect("Program point not in layout"),
425 }
426 }
427
428 pub fn append_inst(&mut self, inst: Inst, block: Block) {
430 debug_assert_eq!(self.inst_block(inst), None);
431 debug_assert!(
432 self.is_block_inserted(block),
433 "Cannot append instructions to block not in layout"
434 );
435 {
436 let block_node = &mut self.blocks[block];
437 {
438 let inst_node = &mut self.insts[inst];
439 inst_node.block = block.into();
440 inst_node.prev = block_node.last_inst;
441 debug_assert!(inst_node.next.is_none());
442 }
443 if block_node.first_inst.is_none() {
444 block_node.first_inst = inst.into();
445 } else {
446 self.insts[block_node.last_inst.unwrap()].next = inst.into();
447 }
448 block_node.last_inst = inst.into();
449 }
450 self.assign_inst_seq(inst);
451 }
452
453 pub fn first_inst(&self, block: Block) -> Option<Inst> {
455 self.blocks[block].first_inst.into()
456 }
457
458 pub fn last_inst(&self, block: Block) -> Option<Inst> {
460 self.blocks[block].last_inst.into()
461 }
462
463 pub fn next_inst(&self, inst: Inst) -> Option<Inst> {
465 self.insts[inst].next.expand()
466 }
467
468 pub fn prev_inst(&self, inst: Inst) -> Option<Inst> {
470 self.insts[inst].prev.expand()
471 }
472
473 pub fn insert_inst(&mut self, inst: Inst, before: Inst) {
475 debug_assert_eq!(self.inst_block(inst), None);
476 let block = self
477 .inst_block(before)
478 .expect("Instruction before insertion point not in the layout");
479 let after = self.insts[before].prev;
480 {
481 let inst_node = &mut self.insts[inst];
482 inst_node.block = block.into();
483 inst_node.next = before.into();
484 inst_node.prev = after;
485 }
486 self.insts[before].prev = inst.into();
487 match after.expand() {
488 None => self.blocks[block].first_inst = inst.into(),
489 Some(a) => self.insts[a].next = inst.into(),
490 }
491 self.assign_inst_seq(inst);
492 }
493
494 pub fn remove_inst(&mut self, inst: Inst) {
496 let block = self.inst_block(inst).expect("Instruction already removed.");
497 let prev;
499 let next;
500 {
501 let n = &mut self.insts[inst];
502 prev = n.prev;
503 next = n.next;
504 n.block = None.into();
505 n.prev = None.into();
506 n.next = None.into();
507 }
508 match prev.expand() {
510 None => self.blocks[block].first_inst = next,
511 Some(p) => self.insts[p].next = next,
512 }
513 match next.expand() {
514 None => self.blocks[block].last_inst = prev,
515 Some(n) => self.insts[n].prev = prev,
516 }
517 }
518
519 pub fn block_insts(&self, block: Block) -> Insts<'_> {
521 Insts {
522 layout: self,
523 head: self.blocks[block].first_inst.into(),
524 tail: self.blocks[block].last_inst.into(),
525 }
526 }
527
528 pub fn block_contains_exactly_one_inst(&self, block: Block) -> bool {
530 let block = &self.blocks[block];
531 block.first_inst.is_some() && block.first_inst == block.last_inst
532 }
533
534 pub fn split_block(&mut self, new_block: Block, before: Inst) {
557 let old_block = self
558 .inst_block(before)
559 .expect("The `before` instruction must be in the layout");
560 debug_assert!(!self.is_block_inserted(new_block));
561
562 let next_block = self.blocks[old_block].next;
564 let last_inst = self.blocks[old_block].last_inst;
565 {
566 let node = &mut self.blocks[new_block];
567 node.prev = old_block.into();
568 node.next = next_block;
569 node.first_inst = before.into();
570 node.last_inst = last_inst;
571 }
572 self.blocks[old_block].next = new_block.into();
573
574 if Some(old_block) == self.last_block {
576 self.last_block = Some(new_block);
577 } else {
578 self.blocks[next_block.unwrap()].prev = new_block.into();
579 }
580
581 let prev_inst = self.insts[before].prev;
583 self.insts[before].prev = None.into();
584 self.blocks[old_block].last_inst = prev_inst;
585 match prev_inst.expand() {
586 None => self.blocks[old_block].first_inst = None.into(),
587 Some(pi) => self.insts[pi].next = None.into(),
588 }
589
590 let mut opt_i = Some(before);
592 while let Some(i) = opt_i {
593 debug_assert_eq!(self.insts[i].block.expand(), Some(old_block));
594 self.insts[i].block = new_block.into();
595 opt_i = self.insts[i].next.into();
596 }
597 }
598}
599
600#[derive(Clone, Debug, Default)]
601struct InstNode {
602 block: PackedOption<Block>,
604 prev: PackedOption<Inst>,
605 next: PackedOption<Inst>,
606 seq: SequenceNumber,
607}
608
609impl PartialEq for InstNode {
610 fn eq(&self, other: &Self) -> bool {
611 self.block == other.block && self.prev == other.prev && self.next == other.next
614 }
615}
616
617impl core::hash::Hash for InstNode {
618 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
619 self.block.hash(state);
622 self.prev.hash(state);
623 self.next.hash(state);
624 }
625}
626
627pub struct Insts<'f> {
629 layout: &'f Layout,
630 head: Option<Inst>,
631 tail: Option<Inst>,
632}
633
634impl<'f> Iterator for Insts<'f> {
635 type Item = Inst;
636
637 fn next(&mut self) -> Option<Inst> {
638 let rval = self.head;
639 if let Some(inst) = rval {
640 if self.head == self.tail {
641 self.head = None;
642 self.tail = None;
643 } else {
644 self.head = self.layout.insts[inst].next.into();
645 }
646 }
647 rval
648 }
649}
650
651impl<'f> DoubleEndedIterator for Insts<'f> {
652 fn next_back(&mut self) -> Option<Inst> {
653 let rval = self.tail;
654 if let Some(inst) = rval {
655 if self.head == self.tail {
656 self.head = None;
657 self.tail = None;
658 } else {
659 self.tail = self.layout.insts[inst].prev.into();
660 }
661 }
662 rval
663 }
664}
665
666#[cfg(feature = "enable-serde")]
678mod serde {
679 use ::serde::de::{Deserializer, Error, SeqAccess, Visitor};
680 use ::serde::ser::{SerializeSeq, Serializer};
681 use ::serde::{Deserialize, Serialize};
682 use core::fmt;
683 use core::marker::PhantomData;
684
685 use super::*;
686
687 impl Serialize for Layout {
688 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
689 where
690 S: Serializer,
691 {
692 let size = self.blocks().count() * 3
693 + self
694 .blocks()
695 .map(|block| self.block_insts(block).count())
696 .sum::<usize>();
697 let mut seq = serializer.serialize_seq(Some(size))?;
698 for block in self.blocks() {
699 seq.serialize_element(&block)?;
700 seq.serialize_element(&self.blocks[block].cold)?;
701 seq.serialize_element(&u32::try_from(self.block_insts(block).count()).unwrap())?;
702 for inst in self.block_insts(block) {
703 seq.serialize_element(&inst)?;
704 }
705 }
706 seq.end()
707 }
708 }
709
710 impl<'de> Deserialize<'de> for Layout {
711 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
712 where
713 D: Deserializer<'de>,
714 {
715 deserializer.deserialize_seq(LayoutVisitor {
716 marker: PhantomData,
717 })
718 }
719 }
720
721 struct LayoutVisitor {
722 marker: PhantomData<fn() -> Layout>,
723 }
724
725 impl<'de> Visitor<'de> for LayoutVisitor {
726 type Value = Layout;
727
728 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
729 write!(formatter, "a `cranelift_codegen::ir::Layout`")
730 }
731
732 fn visit_seq<M>(self, mut access: M) -> Result<Self::Value, M::Error>
733 where
734 M: SeqAccess<'de>,
735 {
736 let mut layout = Layout::new();
737
738 while let Some(block) = access.next_element::<Block>()? {
739 layout.append_block(block);
740
741 let cold = access
742 .next_element::<bool>()?
743 .ok_or_else(|| Error::missing_field("cold"))?;
744 layout.blocks[block].cold = cold;
745
746 let count = access
747 .next_element::<u32>()?
748 .ok_or_else(|| Error::missing_field("count"))?;
749
750 for _ in 0..count {
751 let inst = access
752 .next_element::<Inst>()?
753 .ok_or_else(|| Error::missing_field("inst"))?;
754 layout.append_inst(inst, block);
755 }
756 }
757
758 Ok(layout)
759 }
760 }
761}
762
763#[cfg(test)]
764mod tests {
765 use super::*;
766 use crate::cursor::{Cursor, CursorPosition};
767 use crate::entity::EntityRef;
768 use crate::ir::{Block, Inst, SourceLoc};
769 use alloc::vec::Vec;
770 use core::cmp::Ordering;
771
772 #[test]
773 fn test_midpoint() {
774 assert_eq!(midpoint(0, 1), None);
775 assert_eq!(midpoint(0, 2), Some(1));
776 assert_eq!(midpoint(0, 3), Some(1));
777 assert_eq!(midpoint(0, 4), Some(2));
778 assert_eq!(midpoint(1, 4), Some(2));
779 assert_eq!(midpoint(2, 4), Some(3));
780 assert_eq!(midpoint(3, 4), None);
781 assert_eq!(midpoint(3, 4), None);
782 }
783
784 struct LayoutCursor<'f> {
785 pub layout: &'f mut Layout,
787 pos: CursorPosition,
788 }
789
790 impl<'f> Cursor for LayoutCursor<'f> {
791 fn position(&self) -> CursorPosition {
792 self.pos
793 }
794
795 fn set_position(&mut self, pos: CursorPosition) {
796 self.pos = pos;
797 }
798
799 fn srcloc(&self) -> SourceLoc {
800 unimplemented!()
801 }
802
803 fn set_srcloc(&mut self, _srcloc: SourceLoc) {
804 unimplemented!()
805 }
806
807 fn layout(&self) -> &Layout {
808 self.layout
809 }
810
811 fn layout_mut(&mut self) -> &mut Layout {
812 self.layout
813 }
814 }
815
816 impl<'f> LayoutCursor<'f> {
817 pub fn new(layout: &'f mut Layout) -> Self {
820 Self {
821 layout,
822 pos: CursorPosition::Nowhere,
823 }
824 }
825 }
826
827 fn verify(layout: &mut Layout, blocks: &[(Block, &[Inst])]) {
828 {
832 let mut block_iter = layout.blocks();
833 for &(block, insts) in blocks {
834 assert!(layout.is_block_inserted(block));
835 assert_eq!(block_iter.next(), Some(block));
836
837 let mut seq = 0;
838 let mut inst_iter = layout.block_insts(block);
839 for &inst in insts {
840 assert_eq!(layout.inst_block(inst), Some(block));
841 assert_eq!(inst_iter.next(), Some(inst));
842 assert!(layout.insts[inst].seq > seq);
843 seq = layout.insts[inst].seq;
844 }
845 assert_eq!(inst_iter.next(), None);
846 }
847 assert_eq!(block_iter.next(), None);
848 }
849
850 let mut cur = LayoutCursor::new(layout);
852 for &(block, insts) in blocks.into_iter().rev() {
853 assert_eq!(cur.prev_block(), Some(block));
854 for &inst in insts.into_iter().rev() {
855 assert_eq!(cur.prev_inst(), Some(inst));
856 }
857 assert_eq!(cur.prev_inst(), None);
858 }
859 assert_eq!(cur.prev_block(), None);
860 }
861
862 #[test]
863 fn append_block() {
864 let mut layout = Layout::new();
865 let e0 = Block::new(0);
866 let e1 = Block::new(1);
867 let e2 = Block::new(2);
868
869 {
870 let imm = &layout;
871 assert!(!imm.is_block_inserted(e0));
872 assert!(!imm.is_block_inserted(e1));
873 }
874 verify(&mut layout, &[]);
875
876 layout.append_block(e1);
877 assert!(!layout.is_block_inserted(e0));
878 assert!(layout.is_block_inserted(e1));
879 assert!(!layout.is_block_inserted(e2));
880 let v: Vec<Block> = layout.blocks().collect();
881 assert_eq!(v, [e1]);
882
883 layout.append_block(e2);
884 assert!(!layout.is_block_inserted(e0));
885 assert!(layout.is_block_inserted(e1));
886 assert!(layout.is_block_inserted(e2));
887 let v: Vec<Block> = layout.blocks().collect();
888 assert_eq!(v, [e1, e2]);
889
890 layout.append_block(e0);
891 assert!(layout.is_block_inserted(e0));
892 assert!(layout.is_block_inserted(e1));
893 assert!(layout.is_block_inserted(e2));
894 let v: Vec<Block> = layout.blocks().collect();
895 assert_eq!(v, [e1, e2, e0]);
896
897 {
898 let imm = &layout;
899 let mut v = Vec::new();
900 for e in imm {
901 v.push(e);
902 }
903 assert_eq!(v, [e1, e2, e0]);
904 }
905
906 let mut cur = LayoutCursor::new(&mut layout);
908 assert_eq!(cur.position(), CursorPosition::Nowhere);
909 assert_eq!(cur.next_inst(), None);
910 assert_eq!(cur.position(), CursorPosition::Nowhere);
911 assert_eq!(cur.prev_inst(), None);
912 assert_eq!(cur.position(), CursorPosition::Nowhere);
913
914 assert_eq!(cur.next_block(), Some(e1));
915 assert_eq!(cur.position(), CursorPosition::Before(e1));
916 assert_eq!(cur.next_inst(), None);
917 assert_eq!(cur.position(), CursorPosition::After(e1));
918 assert_eq!(cur.next_inst(), None);
919 assert_eq!(cur.position(), CursorPosition::After(e1));
920 assert_eq!(cur.next_block(), Some(e2));
921 assert_eq!(cur.prev_inst(), None);
922 assert_eq!(cur.position(), CursorPosition::Before(e2));
923 assert_eq!(cur.next_block(), Some(e0));
924 assert_eq!(cur.next_block(), None);
925 assert_eq!(cur.position(), CursorPosition::Nowhere);
926
927 assert_eq!(cur.prev_block(), Some(e0));
929 assert_eq!(cur.position(), CursorPosition::After(e0));
930 assert_eq!(cur.prev_block(), Some(e2));
931 assert_eq!(cur.prev_block(), Some(e1));
932 assert_eq!(cur.prev_block(), None);
933 assert_eq!(cur.position(), CursorPosition::Nowhere);
934 }
935
936 #[test]
937 fn insert_block() {
938 let mut layout = Layout::new();
939 let e0 = Block::new(0);
940 let e1 = Block::new(1);
941 let e2 = Block::new(2);
942
943 {
944 let imm = &layout;
945 assert!(!imm.is_block_inserted(e0));
946 assert!(!imm.is_block_inserted(e1));
947
948 let v: Vec<Block> = layout.blocks().collect();
949 assert_eq!(v, []);
950 }
951
952 layout.append_block(e1);
953 assert!(!layout.is_block_inserted(e0));
954 assert!(layout.is_block_inserted(e1));
955 assert!(!layout.is_block_inserted(e2));
956 verify(&mut layout, &[(e1, &[])]);
957
958 layout.insert_block(e2, e1);
959 assert!(!layout.is_block_inserted(e0));
960 assert!(layout.is_block_inserted(e1));
961 assert!(layout.is_block_inserted(e2));
962 verify(&mut layout, &[(e2, &[]), (e1, &[])]);
963
964 layout.insert_block(e0, e1);
965 assert!(layout.is_block_inserted(e0));
966 assert!(layout.is_block_inserted(e1));
967 assert!(layout.is_block_inserted(e2));
968 verify(&mut layout, &[(e2, &[]), (e0, &[]), (e1, &[])]);
969 }
970
971 #[test]
972 fn insert_block_after() {
973 let mut layout = Layout::new();
974 let e0 = Block::new(0);
975 let e1 = Block::new(1);
976 let e2 = Block::new(2);
977
978 layout.append_block(e1);
979 layout.insert_block_after(e2, e1);
980 verify(&mut layout, &[(e1, &[]), (e2, &[])]);
981
982 layout.insert_block_after(e0, e1);
983 verify(&mut layout, &[(e1, &[]), (e0, &[]), (e2, &[])]);
984 }
985
986 #[test]
987 fn append_inst() {
988 let mut layout = Layout::new();
989 let e1 = Block::new(1);
990
991 layout.append_block(e1);
992 let v: Vec<Inst> = layout.block_insts(e1).collect();
993 assert_eq!(v, []);
994
995 let i0 = Inst::new(0);
996 let i1 = Inst::new(1);
997 let i2 = Inst::new(2);
998
999 assert_eq!(layout.inst_block(i0), None);
1000 assert_eq!(layout.inst_block(i1), None);
1001 assert_eq!(layout.inst_block(i2), None);
1002
1003 layout.append_inst(i1, e1);
1004 assert_eq!(layout.inst_block(i0), None);
1005 assert_eq!(layout.inst_block(i1), Some(e1));
1006 assert_eq!(layout.inst_block(i2), None);
1007 let v: Vec<Inst> = layout.block_insts(e1).collect();
1008 assert_eq!(v, [i1]);
1009
1010 layout.append_inst(i2, e1);
1011 assert_eq!(layout.inst_block(i0), None);
1012 assert_eq!(layout.inst_block(i1), Some(e1));
1013 assert_eq!(layout.inst_block(i2), Some(e1));
1014 let v: Vec<Inst> = layout.block_insts(e1).collect();
1015 assert_eq!(v, [i1, i2]);
1016
1017 let v: Vec<Inst> = layout.block_insts(e1).rev().collect();
1019 assert_eq!(v, [i2, i1]);
1020
1021 layout.append_inst(i0, e1);
1022 verify(&mut layout, &[(e1, &[i1, i2, i0])]);
1023
1024 let mut cur = LayoutCursor::new(&mut layout).at_top(e1);
1026 assert_eq!(cur.position(), CursorPosition::Before(e1));
1027 assert_eq!(cur.prev_inst(), None);
1028 assert_eq!(cur.position(), CursorPosition::Before(e1));
1029 assert_eq!(cur.next_inst(), Some(i1));
1030 assert_eq!(cur.position(), CursorPosition::At(i1));
1031 assert_eq!(cur.next_inst(), Some(i2));
1032 assert_eq!(cur.next_inst(), Some(i0));
1033 assert_eq!(cur.prev_inst(), Some(i2));
1034 assert_eq!(cur.position(), CursorPosition::At(i2));
1035 assert_eq!(cur.next_inst(), Some(i0));
1036 assert_eq!(cur.position(), CursorPosition::At(i0));
1037 assert_eq!(cur.next_inst(), None);
1038 assert_eq!(cur.position(), CursorPosition::After(e1));
1039 assert_eq!(cur.next_inst(), None);
1040 assert_eq!(cur.position(), CursorPosition::After(e1));
1041 assert_eq!(cur.prev_inst(), Some(i0));
1042 assert_eq!(cur.prev_inst(), Some(i2));
1043 assert_eq!(cur.prev_inst(), Some(i1));
1044 assert_eq!(cur.prev_inst(), None);
1045 assert_eq!(cur.position(), CursorPosition::Before(e1));
1046
1047 cur.goto_inst(i2);
1049 assert_eq!(cur.remove_inst(), i2);
1050 verify(cur.layout, &[(e1, &[i1, i0])]);
1051 assert_eq!(cur.layout.inst_block(i2), None);
1052 assert_eq!(cur.remove_inst(), i0);
1053 verify(cur.layout, &[(e1, &[i1])]);
1054 assert_eq!(cur.layout.inst_block(i0), None);
1055 assert_eq!(cur.position(), CursorPosition::After(e1));
1056 cur.layout.remove_inst(i1);
1057 verify(cur.layout, &[(e1, &[])]);
1058 assert_eq!(cur.layout.inst_block(i1), None);
1059 }
1060
1061 #[test]
1062 fn insert_inst() {
1063 let mut layout = Layout::new();
1064 let e1 = Block::new(1);
1065
1066 layout.append_block(e1);
1067 let v: Vec<Inst> = layout.block_insts(e1).collect();
1068 assert_eq!(v, []);
1069
1070 let i0 = Inst::new(0);
1071 let i1 = Inst::new(1);
1072 let i2 = Inst::new(2);
1073
1074 assert_eq!(layout.inst_block(i0), None);
1075 assert_eq!(layout.inst_block(i1), None);
1076 assert_eq!(layout.inst_block(i2), None);
1077
1078 layout.append_inst(i1, e1);
1079 assert_eq!(layout.inst_block(i0), None);
1080 assert_eq!(layout.inst_block(i1), Some(e1));
1081 assert_eq!(layout.inst_block(i2), None);
1082 let v: Vec<Inst> = layout.block_insts(e1).collect();
1083 assert_eq!(v, [i1]);
1084
1085 layout.insert_inst(i2, i1);
1086 assert_eq!(layout.inst_block(i0), None);
1087 assert_eq!(layout.inst_block(i1), Some(e1));
1088 assert_eq!(layout.inst_block(i2), Some(e1));
1089 let v: Vec<Inst> = layout.block_insts(e1).collect();
1090 assert_eq!(v, [i2, i1]);
1091
1092 layout.insert_inst(i0, i1);
1093 verify(&mut layout, &[(e1, &[i2, i0, i1])]);
1094 }
1095
1096 #[test]
1097 fn multiple_blocks() {
1098 let mut layout = Layout::new();
1099
1100 let e0 = Block::new(0);
1101 let e1 = Block::new(1);
1102
1103 assert_eq!(layout.entry_block(), None);
1104 layout.append_block(e0);
1105 assert_eq!(layout.entry_block(), Some(e0));
1106 layout.append_block(e1);
1107 assert_eq!(layout.entry_block(), Some(e0));
1108
1109 let i0 = Inst::new(0);
1110 let i1 = Inst::new(1);
1111 let i2 = Inst::new(2);
1112 let i3 = Inst::new(3);
1113
1114 layout.append_inst(i0, e0);
1115 layout.append_inst(i1, e0);
1116 layout.append_inst(i2, e1);
1117 layout.append_inst(i3, e1);
1118
1119 let v0: Vec<Inst> = layout.block_insts(e0).collect();
1120 let v1: Vec<Inst> = layout.block_insts(e1).collect();
1121 assert_eq!(v0, [i0, i1]);
1122 assert_eq!(v1, [i2, i3]);
1123 }
1124
1125 #[test]
1126 fn split_block() {
1127 let mut layout = Layout::new();
1128
1129 let e0 = Block::new(0);
1130 let e1 = Block::new(1);
1131 let e2 = Block::new(2);
1132
1133 let i0 = Inst::new(0);
1134 let i1 = Inst::new(1);
1135 let i2 = Inst::new(2);
1136 let i3 = Inst::new(3);
1137
1138 layout.append_block(e0);
1139 layout.append_inst(i0, e0);
1140 assert_eq!(layout.inst_block(i0), Some(e0));
1141 layout.split_block(e1, i0);
1142 assert_eq!(layout.inst_block(i0), Some(e1));
1143
1144 {
1145 let mut cur = LayoutCursor::new(&mut layout);
1146 assert_eq!(cur.next_block(), Some(e0));
1147 assert_eq!(cur.next_inst(), None);
1148 assert_eq!(cur.next_block(), Some(e1));
1149 assert_eq!(cur.next_inst(), Some(i0));
1150 assert_eq!(cur.next_inst(), None);
1151 assert_eq!(cur.next_block(), None);
1152
1153 assert_eq!(cur.prev_block(), Some(e1));
1155 assert_eq!(cur.prev_inst(), Some(i0));
1156 assert_eq!(cur.prev_inst(), None);
1157 assert_eq!(cur.prev_block(), Some(e0));
1158 assert_eq!(cur.prev_inst(), None);
1159 assert_eq!(cur.prev_block(), None);
1160 }
1161
1162 layout.append_inst(i1, e0);
1163 layout.append_inst(i2, e0);
1164 layout.append_inst(i3, e0);
1165 layout.split_block(e2, i2);
1166
1167 assert_eq!(layout.inst_block(i0), Some(e1));
1168 assert_eq!(layout.inst_block(i1), Some(e0));
1169 assert_eq!(layout.inst_block(i2), Some(e2));
1170 assert_eq!(layout.inst_block(i3), Some(e2));
1171
1172 {
1173 let mut cur = LayoutCursor::new(&mut layout);
1174 assert_eq!(cur.next_block(), Some(e0));
1175 assert_eq!(cur.next_inst(), Some(i1));
1176 assert_eq!(cur.next_inst(), None);
1177 assert_eq!(cur.next_block(), Some(e2));
1178 assert_eq!(cur.next_inst(), Some(i2));
1179 assert_eq!(cur.next_inst(), Some(i3));
1180 assert_eq!(cur.next_inst(), None);
1181 assert_eq!(cur.next_block(), Some(e1));
1182 assert_eq!(cur.next_inst(), Some(i0));
1183 assert_eq!(cur.next_inst(), None);
1184 assert_eq!(cur.next_block(), None);
1185
1186 assert_eq!(cur.prev_block(), Some(e1));
1187 assert_eq!(cur.prev_inst(), Some(i0));
1188 assert_eq!(cur.prev_inst(), None);
1189 assert_eq!(cur.prev_block(), Some(e2));
1190 assert_eq!(cur.prev_inst(), Some(i3));
1191 assert_eq!(cur.prev_inst(), Some(i2));
1192 assert_eq!(cur.prev_inst(), None);
1193 assert_eq!(cur.prev_block(), Some(e0));
1194 assert_eq!(cur.prev_inst(), Some(i1));
1195 assert_eq!(cur.prev_inst(), None);
1196 assert_eq!(cur.prev_block(), None);
1197 }
1198
1199 assert_eq!(layout.pp_cmp(e2, e2), Ordering::Equal);
1201 assert_eq!(layout.pp_cmp(e2, i2), Ordering::Less);
1202 assert_eq!(layout.pp_cmp(i3, i2), Ordering::Greater)
1203 }
1204}