1 //! Function layout.
2 //!
3 //! The order of basic blocks in a function and the order of instructions in a block is
4 //! determined by the `Layout` data structure defined in this module.
5 
6 use crate::entity::SecondaryMap;
7 use crate::ir::dfg::DataFlowGraph;
8 use crate::ir::progpoint::{ExpandedProgramPoint, ProgramOrder};
9 use crate::ir::{Block, Inst};
10 use crate::packed_option::PackedOption;
11 use crate::{timing, trace};
12 use core::cmp;
13 use core::iter::{IntoIterator, Iterator};
14 
15 /// The `Layout` struct determines the layout of blocks and instructions in a function. It does not
16 /// contain definitions of instructions or blocks, but depends on `Inst` and `Block` entity references
17 /// being defined elsewhere.
18 ///
19 /// This data structure determines:
20 ///
21 /// - The order of blocks in the function.
22 /// - Which block contains a given instruction.
23 /// - The order of instructions with a block.
24 ///
25 /// While data dependencies are not recorded, instruction ordering does affect control
26 /// dependencies, so part of the semantics of the program are determined by the layout.
27 ///
28 #[derive(Clone)]
29 pub struct Layout {
30     /// Linked list nodes for the layout order of blocks Forms a doubly linked list, terminated in
31     /// both ends by `None`.
32     blocks: SecondaryMap<Block, BlockNode>,
33 
34     /// Linked list nodes for the layout order of instructions. Forms a double linked list per block,
35     /// terminated in both ends by `None`.
36     insts: SecondaryMap<Inst, InstNode>,
37 
38     /// First block in the layout order, or `None` when no blocks have been laid out.
39     first_block: Option<Block>,
40 
41     /// Last block in the layout order, or `None` when no blocks have been laid out.
42     last_block: Option<Block>,
43 }
44 
45 impl Layout {
46     /// Create a new empty `Layout`.
47     pub fn new() -> Self {
48         Self {
49             blocks: SecondaryMap::new(),
50             insts: SecondaryMap::new(),
51             first_block: None,
52             last_block: None,
53         }
54     }
55 
56     /// Clear the layout.
57     pub fn clear(&mut self) {
58         self.blocks.clear();
59         self.insts.clear();
60         self.first_block = None;
61         self.last_block = None;
62     }
63 
64     /// Returns the capacity of the `BlockData` map.
65     pub fn block_capacity(&self) -> usize {
66         self.blocks.capacity()
67     }
68 }
69 
70 /// Sequence numbers.
71 ///
72 /// All instructions and blocks are given a sequence number that can be used to quickly determine
73 /// their relative position in the layout. The sequence numbers are not contiguous, but are assigned
74 /// like line numbers in BASIC: 10, 20, 30, ...
75 ///
76 /// The block sequence numbers are strictly increasing, and so are the instruction sequence numbers
77 /// within a block. The instruction sequence numbers are all between the sequence number of their
78 /// containing block and the following block.
79 ///
80 /// The result is that sequence numbers work like BASIC line numbers for the textual form of the IR.
81 type SequenceNumber = u32;
82 
83 /// Initial stride assigned to new sequence numbers.
84 const MAJOR_STRIDE: SequenceNumber = 10;
85 
86 /// Secondary stride used when renumbering locally.
87 const MINOR_STRIDE: SequenceNumber = 2;
88 
89 /// Limit on the sequence number range we'll renumber locally. If this limit is exceeded, we'll
90 /// switch to a full function renumbering.
91 const LOCAL_LIMIT: SequenceNumber = 100 * MINOR_STRIDE;
92 
93 /// Compute the midpoint between `a` and `b`.
94 /// Return `None` if the midpoint would be equal to either.
95 fn midpoint(a: SequenceNumber, b: SequenceNumber) -> Option<SequenceNumber> {
96     debug_assert!(a < b);
97     // Avoid integer overflow.
98     let m = a + (b - a) / 2;
99     if m > a {
100         Some(m)
101     } else {
102         None
103     }
104 }
105 
106 #[test]
107 fn test_midpoint() {
108     assert_eq!(midpoint(0, 1), None);
109     assert_eq!(midpoint(0, 2), Some(1));
110     assert_eq!(midpoint(0, 3), Some(1));
111     assert_eq!(midpoint(0, 4), Some(2));
112     assert_eq!(midpoint(1, 4), Some(2));
113     assert_eq!(midpoint(2, 4), Some(3));
114     assert_eq!(midpoint(3, 4), None);
115     assert_eq!(midpoint(3, 4), None);
116 }
117 
118 impl ProgramOrder for Layout {
119     fn cmp<A, B>(&self, a: A, b: B) -> cmp::Ordering
120     where
121         A: Into<ExpandedProgramPoint>,
122         B: Into<ExpandedProgramPoint>,
123     {
124         let a_seq = self.seq(a);
125         let b_seq = self.seq(b);
126         a_seq.cmp(&b_seq)
127     }
128 
129     fn is_block_gap(&self, inst: Inst, block: Block) -> bool {
130         let i = &self.insts[inst];
131         let e = &self.blocks[block];
132 
133         i.next.is_none() && i.block == e.prev
134     }
135 }
136 
137 // Private methods for dealing with sequence numbers.
138 impl Layout {
139     /// Get the sequence number of a program point that must correspond to an entity in the layout.
140     fn seq<PP: Into<ExpandedProgramPoint>>(&self, pp: PP) -> SequenceNumber {
141         // When `PP = Inst` or `PP = Block`, we expect this dynamic type check to be optimized out.
142         match pp.into() {
143             ExpandedProgramPoint::Block(block) => self.blocks[block].seq,
144             ExpandedProgramPoint::Inst(inst) => self.insts[inst].seq,
145         }
146     }
147 
148     /// Get the last sequence number in `block`.
149     fn last_block_seq(&self, block: Block) -> SequenceNumber {
150         // Get the seq of the last instruction if it exists, otherwise use the block header seq.
151         self.blocks[block]
152             .last_inst
153             .map(|inst| self.insts[inst].seq)
154             .unwrap_or(self.blocks[block].seq)
155     }
156 
157     /// Assign a valid sequence number to `block` such that the numbers are still monotonic. This may
158     /// require renumbering.
159     fn assign_block_seq(&mut self, block: Block) {
160         debug_assert!(self.is_block_inserted(block));
161 
162         // Get the sequence number immediately before `block`, or 0.
163         let prev_seq = self.blocks[block]
164             .prev
165             .map(|prev_block| self.last_block_seq(prev_block))
166             .unwrap_or(0);
167 
168         // Get the sequence number immediately following `block`.
169         let next_seq = if let Some(inst) = self.blocks[block].first_inst.expand() {
170             self.insts[inst].seq
171         } else if let Some(next_block) = self.blocks[block].next.expand() {
172             self.blocks[next_block].seq
173         } else {
174             // There is nothing after `block`. We can just use a major stride.
175             self.blocks[block].seq = prev_seq + MAJOR_STRIDE;
176             return;
177         };
178 
179         // Check if there is room between these sequence numbers.
180         if let Some(seq) = midpoint(prev_seq, next_seq) {
181             self.blocks[block].seq = seq;
182         } else {
183             // No available integers between `prev_seq` and `next_seq`. We have to renumber.
184             self.renumber_from_block(block, prev_seq + MINOR_STRIDE, prev_seq + LOCAL_LIMIT);
185         }
186     }
187 
188     /// Assign a valid sequence number to `inst` such that the numbers are still monotonic. This may
189     /// require renumbering.
190     fn assign_inst_seq(&mut self, inst: Inst) {
191         let block = self
192             .inst_block(inst)
193             .expect("inst must be inserted before assigning an seq");
194 
195         // Get the sequence number immediately before `inst`.
196         let prev_seq = match self.insts[inst].prev.expand() {
197             Some(prev_inst) => self.insts[prev_inst].seq,
198             None => self.blocks[block].seq,
199         };
200 
201         // Get the sequence number immediately following `inst`.
202         let next_seq = if let Some(next_inst) = self.insts[inst].next.expand() {
203             self.insts[next_inst].seq
204         } else if let Some(next_block) = self.blocks[block].next.expand() {
205             self.blocks[next_block].seq
206         } else {
207             // There is nothing after `inst`. We can just use a major stride.
208             self.insts[inst].seq = prev_seq + MAJOR_STRIDE;
209             return;
210         };
211 
212         // Check if there is room between these sequence numbers.
213         if let Some(seq) = midpoint(prev_seq, next_seq) {
214             self.insts[inst].seq = seq;
215         } else {
216             // No available integers between `prev_seq` and `next_seq`. We have to renumber.
217             self.renumber_from_inst(inst, prev_seq + MINOR_STRIDE, prev_seq + LOCAL_LIMIT);
218         }
219     }
220 
221     /// Renumber instructions starting from `inst` until the end of the block or until numbers catch
222     /// up.
223     ///
224     /// Return `None` if renumbering has caught up and the sequence is monotonic again. Otherwise
225     /// return the last used sequence number.
226     ///
227     /// If sequence numbers exceed `limit`, switch to a full function renumbering and return `None`.
228     fn renumber_insts(
229         &mut self,
230         inst: Inst,
231         seq: SequenceNumber,
232         limit: SequenceNumber,
233     ) -> Option<SequenceNumber> {
234         let mut inst = inst;
235         let mut seq = seq;
236 
237         loop {
238             self.insts[inst].seq = seq;
239 
240             // Next instruction.
241             inst = match self.insts[inst].next.expand() {
242                 None => return Some(seq),
243                 Some(next) => next,
244             };
245 
246             if seq < self.insts[inst].seq {
247                 // Sequence caught up.
248                 return None;
249             }
250 
251             if seq > limit {
252                 // We're pushing too many instructions in front of us.
253                 // Switch to a full function renumbering to make some space.
254                 self.full_renumber();
255                 return None;
256             }
257 
258             seq += MINOR_STRIDE;
259         }
260     }
261 
262     /// Renumber starting from `block` to `seq` and continuing until the sequence numbers are
263     /// monotonic again.
264     fn renumber_from_block(
265         &mut self,
266         block: Block,
267         first_seq: SequenceNumber,
268         limit: SequenceNumber,
269     ) {
270         let mut block = block;
271         let mut seq = first_seq;
272 
273         loop {
274             self.blocks[block].seq = seq;
275 
276             // Renumber instructions in `block`. Stop when the numbers catch up.
277             if let Some(inst) = self.blocks[block].first_inst.expand() {
278                 seq = match self.renumber_insts(inst, seq + MINOR_STRIDE, limit) {
279                     Some(s) => s,
280                     None => return,
281                 }
282             }
283 
284             // Advance to the next block.
285             block = match self.blocks[block].next.expand() {
286                 Some(next) => next,
287                 None => return,
288             };
289 
290             // Stop renumbering once the numbers catch up.
291             if seq < self.blocks[block].seq {
292                 return;
293             }
294 
295             seq += MINOR_STRIDE;
296         }
297     }
298 
299     /// Renumber starting from `inst` to `seq` and continuing until the sequence numbers are
300     /// monotonic again.
301     fn renumber_from_inst(&mut self, inst: Inst, first_seq: SequenceNumber, limit: SequenceNumber) {
302         if let Some(seq) = self.renumber_insts(inst, first_seq, limit) {
303             // Renumbering spills over into next block.
304             if let Some(next_block) = self.blocks[self.inst_block(inst).unwrap()].next.expand() {
305                 self.renumber_from_block(next_block, seq + MINOR_STRIDE, limit);
306             }
307         }
308     }
309 
310     /// Renumber all blocks and instructions in the layout.
311     ///
312     /// This doesn't affect the position of anything, but it gives more room in the internal
313     /// sequence numbers for inserting instructions later.
314     fn full_renumber(&mut self) {
315         let _tt = timing::layout_renumber();
316         let mut seq = 0;
317         let mut next_block = self.first_block;
318         while let Some(block) = next_block {
319             self.blocks[block].seq = seq;
320             seq += MAJOR_STRIDE;
321             next_block = self.blocks[block].next.expand();
322 
323             let mut next_inst = self.blocks[block].first_inst.expand();
324             while let Some(inst) = next_inst {
325                 self.insts[inst].seq = seq;
326                 seq += MAJOR_STRIDE;
327                 next_inst = self.insts[inst].next.expand();
328             }
329         }
330         trace!("Renumbered {} program points", seq / MAJOR_STRIDE);
331     }
332 }
333 
334 /// Methods for laying out blocks.
335 ///
336 /// An unknown block starts out as *not inserted* in the block layout. The layout is a linear order of
337 /// inserted blocks. Once a block has been inserted in the layout, instructions can be added. A block
338 /// can only be removed from the layout when it is empty.
339 ///
340 /// Since every block must end with a terminator instruction which cannot fall through, the layout of
341 /// blocks do not affect the semantics of the program.
342 ///
343 impl Layout {
344     /// Is `block` currently part of the layout?
345     pub fn is_block_inserted(&self, block: Block) -> bool {
346         Some(block) == self.first_block || self.blocks[block].prev.is_some()
347     }
348 
349     /// Insert `block` as the last block in the layout.
350     pub fn append_block(&mut self, block: Block) {
351         debug_assert!(
352             !self.is_block_inserted(block),
353             "Cannot append block that is already in the layout"
354         );
355         {
356             let node = &mut self.blocks[block];
357             debug_assert!(node.first_inst.is_none() && node.last_inst.is_none());
358             node.prev = self.last_block.into();
359             node.next = None.into();
360         }
361         if let Some(last) = self.last_block {
362             self.blocks[last].next = block.into();
363         } else {
364             self.first_block = Some(block);
365         }
366         self.last_block = Some(block);
367         self.assign_block_seq(block);
368     }
369 
370     /// Insert `block` in the layout before the existing block `before`.
371     pub fn insert_block(&mut self, block: Block, before: Block) {
372         debug_assert!(
373             !self.is_block_inserted(block),
374             "Cannot insert block that is already in the layout"
375         );
376         debug_assert!(
377             self.is_block_inserted(before),
378             "block Insertion point not in the layout"
379         );
380         let after = self.blocks[before].prev;
381         {
382             let node = &mut self.blocks[block];
383             node.next = before.into();
384             node.prev = after;
385         }
386         self.blocks[before].prev = block.into();
387         match after.expand() {
388             None => self.first_block = Some(block),
389             Some(a) => self.blocks[a].next = block.into(),
390         }
391         self.assign_block_seq(block);
392     }
393 
394     /// Insert `block` in the layout *after* the existing block `after`.
395     pub fn insert_block_after(&mut self, block: Block, after: Block) {
396         debug_assert!(
397             !self.is_block_inserted(block),
398             "Cannot insert block that is already in the layout"
399         );
400         debug_assert!(
401             self.is_block_inserted(after),
402             "block Insertion point not in the layout"
403         );
404         let before = self.blocks[after].next;
405         {
406             let node = &mut self.blocks[block];
407             node.next = before;
408             node.prev = after.into();
409         }
410         self.blocks[after].next = block.into();
411         match before.expand() {
412             None => self.last_block = Some(block),
413             Some(b) => self.blocks[b].prev = block.into(),
414         }
415         self.assign_block_seq(block);
416     }
417 
418     /// Remove `block` from the layout.
419     pub fn remove_block(&mut self, block: Block) {
420         debug_assert!(self.is_block_inserted(block), "block not in the layout");
421         debug_assert!(self.first_inst(block).is_none(), "block must be empty.");
422 
423         // Clear the `block` node and extract links.
424         let prev;
425         let next;
426         {
427             let n = &mut self.blocks[block];
428             prev = n.prev;
429             next = n.next;
430             n.prev = None.into();
431             n.next = None.into();
432         }
433         // Fix up links to `block`.
434         match prev.expand() {
435             None => self.first_block = next.expand(),
436             Some(p) => self.blocks[p].next = next,
437         }
438         match next.expand() {
439             None => self.last_block = prev.expand(),
440             Some(n) => self.blocks[n].prev = prev,
441         }
442     }
443 
444     /// Return an iterator over all blocks in layout order.
445     pub fn blocks(&self) -> Blocks {
446         Blocks {
447             layout: self,
448             next: self.first_block,
449         }
450     }
451 
452     /// Get the function's entry block.
453     /// This is simply the first block in the layout order.
454     pub fn entry_block(&self) -> Option<Block> {
455         self.first_block
456     }
457 
458     /// Get the last block in the layout.
459     pub fn last_block(&self) -> Option<Block> {
460         self.last_block
461     }
462 
463     /// Get the block preceding `block` in the layout order.
464     pub fn prev_block(&self, block: Block) -> Option<Block> {
465         self.blocks[block].prev.expand()
466     }
467 
468     /// Get the block following `block` in the layout order.
469     pub fn next_block(&self, block: Block) -> Option<Block> {
470         self.blocks[block].next.expand()
471     }
472 
473     /// Mark a block as "cold".
474     ///
475     /// This will try to move it out of the ordinary path of execution
476     /// when lowered to machine code.
477     pub fn set_cold(&mut self, block: Block) {
478         self.blocks[block].cold = true;
479     }
480 
481     /// Is the given block cold?
482     pub fn is_cold(&self, block: Block) -> bool {
483         self.blocks[block].cold
484     }
485 }
486 
487 /// A single node in the linked-list of blocks.
488 // Whenever you add new fields here, don't forget to update the custom serializer for `Layout` too.
489 #[derive(Clone, Debug, Default)]
490 struct BlockNode {
491     prev: PackedOption<Block>,
492     next: PackedOption<Block>,
493     first_inst: PackedOption<Inst>,
494     last_inst: PackedOption<Inst>,
495     seq: SequenceNumber,
496     cold: bool,
497 }
498 
499 /// Iterate over blocks in layout order. See [crate::ir::layout::Layout::blocks].
500 pub struct Blocks<'f> {
501     layout: &'f Layout,
502     next: Option<Block>,
503 }
504 
505 impl<'f> Iterator for Blocks<'f> {
506     type Item = Block;
507 
508     fn next(&mut self) -> Option<Block> {
509         match self.next {
510             Some(block) => {
511                 self.next = self.layout.next_block(block);
512                 Some(block)
513             }
514             None => None,
515         }
516     }
517 }
518 
519 /// Use a layout reference in a for loop.
520 impl<'f> IntoIterator for &'f Layout {
521     type Item = Block;
522     type IntoIter = Blocks<'f>;
523 
524     fn into_iter(self) -> Blocks<'f> {
525         self.blocks()
526     }
527 }
528 
529 /// Methods for arranging instructions.
530 ///
531 /// An instruction starts out as *not inserted* in the layout. An instruction can be inserted into
532 /// a block at a given position.
533 impl Layout {
534     /// Get the block containing `inst`, or `None` if `inst` is not inserted in the layout.
535     pub fn inst_block(&self, inst: Inst) -> Option<Block> {
536         self.insts[inst].block.into()
537     }
538 
539     /// Get the block containing the program point `pp`. Panic if `pp` is not in the layout.
540     pub fn pp_block<PP>(&self, pp: PP) -> Block
541     where
542         PP: Into<ExpandedProgramPoint>,
543     {
544         match pp.into() {
545             ExpandedProgramPoint::Block(block) => block,
546             ExpandedProgramPoint::Inst(inst) => {
547                 self.inst_block(inst).expect("Program point not in layout")
548             }
549         }
550     }
551 
552     /// Append `inst` to the end of `block`.
553     pub fn append_inst(&mut self, inst: Inst, block: Block) {
554         debug_assert_eq!(self.inst_block(inst), None);
555         debug_assert!(
556             self.is_block_inserted(block),
557             "Cannot append instructions to block not in layout"
558         );
559         {
560             let block_node = &mut self.blocks[block];
561             {
562                 let inst_node = &mut self.insts[inst];
563                 inst_node.block = block.into();
564                 inst_node.prev = block_node.last_inst;
565                 debug_assert!(inst_node.next.is_none());
566             }
567             if block_node.first_inst.is_none() {
568                 block_node.first_inst = inst.into();
569             } else {
570                 self.insts[block_node.last_inst.unwrap()].next = inst.into();
571             }
572             block_node.last_inst = inst.into();
573         }
574         self.assign_inst_seq(inst);
575     }
576 
577     /// Fetch a block's first instruction.
578     pub fn first_inst(&self, block: Block) -> Option<Inst> {
579         self.blocks[block].first_inst.into()
580     }
581 
582     /// Fetch a block's last instruction.
583     pub fn last_inst(&self, block: Block) -> Option<Inst> {
584         self.blocks[block].last_inst.into()
585     }
586 
587     /// Fetch the instruction following `inst`.
588     pub fn next_inst(&self, inst: Inst) -> Option<Inst> {
589         self.insts[inst].next.expand()
590     }
591 
592     /// Fetch the instruction preceding `inst`.
593     pub fn prev_inst(&self, inst: Inst) -> Option<Inst> {
594         self.insts[inst].prev.expand()
595     }
596 
597     /// Fetch the first instruction in a block's terminal branch group.
598     pub fn canonical_branch_inst(&self, dfg: &DataFlowGraph, block: Block) -> Option<Inst> {
599         // Basic blocks permit at most two terminal branch instructions.
600         // If two, the former is conditional and the latter is unconditional.
601         let last = self.last_inst(block)?;
602         if let Some(prev) = self.prev_inst(last) {
603             if dfg[prev].opcode().is_branch() {
604                 return Some(prev);
605             }
606         }
607         Some(last)
608     }
609 
610     /// Insert `inst` before the instruction `before` in the same block.
611     pub fn insert_inst(&mut self, inst: Inst, before: Inst) {
612         debug_assert_eq!(self.inst_block(inst), None);
613         let block = self
614             .inst_block(before)
615             .expect("Instruction before insertion point not in the layout");
616         let after = self.insts[before].prev;
617         {
618             let inst_node = &mut self.insts[inst];
619             inst_node.block = block.into();
620             inst_node.next = before.into();
621             inst_node.prev = after;
622         }
623         self.insts[before].prev = inst.into();
624         match after.expand() {
625             None => self.blocks[block].first_inst = inst.into(),
626             Some(a) => self.insts[a].next = inst.into(),
627         }
628         self.assign_inst_seq(inst);
629     }
630 
631     /// Remove `inst` from the layout.
632     pub fn remove_inst(&mut self, inst: Inst) {
633         let block = self.inst_block(inst).expect("Instruction already removed.");
634         // Clear the `inst` node and extract links.
635         let prev;
636         let next;
637         {
638             let n = &mut self.insts[inst];
639             prev = n.prev;
640             next = n.next;
641             n.block = None.into();
642             n.prev = None.into();
643             n.next = None.into();
644         }
645         // Fix up links to `inst`.
646         match prev.expand() {
647             None => self.blocks[block].first_inst = next,
648             Some(p) => self.insts[p].next = next,
649         }
650         match next.expand() {
651             None => self.blocks[block].last_inst = prev,
652             Some(n) => self.insts[n].prev = prev,
653         }
654     }
655 
656     /// Iterate over the instructions in `block` in layout order.
657     pub fn block_insts(&self, block: Block) -> Insts {
658         Insts {
659             layout: self,
660             head: self.blocks[block].first_inst.into(),
661             tail: self.blocks[block].last_inst.into(),
662         }
663     }
664 
665     /// Iterate over a limited set of instruction which are likely the branches of `block` in layout
666     /// order. Any instruction not visited by this iterator is not a branch, but an instruction visited by this may not be a branch.
667     pub fn block_likely_branches(&self, block: Block) -> Insts {
668         // Note: Checking whether an instruction is a branch or not while walking backward might add
669         // extra overhead. However, we know that the number of branches is limited to 2 at the end of
670         // each block, and therefore we can just iterate over the last 2 instructions.
671         let mut iter = self.block_insts(block);
672         let head = iter.head;
673         let tail = iter.tail;
674         iter.next_back();
675         let head = iter.next_back().or(head);
676         Insts {
677             layout: self,
678             head,
679             tail,
680         }
681     }
682 
683     /// Split the block containing `before` in two.
684     ///
685     /// Insert `new_block` after the old block and move `before` and the following instructions to
686     /// `new_block`:
687     ///
688     /// ```text
689     /// old_block:
690     ///     i1
691     ///     i2
692     ///     i3 << before
693     ///     i4
694     /// ```
695     /// becomes:
696     ///
697     /// ```text
698     /// old_block:
699     ///     i1
700     ///     i2
701     /// new_block:
702     ///     i3 << before
703     ///     i4
704     /// ```
705     pub fn split_block(&mut self, new_block: Block, before: Inst) {
706         let old_block = self
707             .inst_block(before)
708             .expect("The `before` instruction must be in the layout");
709         debug_assert!(!self.is_block_inserted(new_block));
710 
711         // Insert new_block after old_block.
712         let next_block = self.blocks[old_block].next;
713         let last_inst = self.blocks[old_block].last_inst;
714         {
715             let node = &mut self.blocks[new_block];
716             node.prev = old_block.into();
717             node.next = next_block;
718             node.first_inst = before.into();
719             node.last_inst = last_inst;
720         }
721         self.blocks[old_block].next = new_block.into();
722 
723         // Fix backwards link.
724         if Some(old_block) == self.last_block {
725             self.last_block = Some(new_block);
726         } else {
727             self.blocks[next_block.unwrap()].prev = new_block.into();
728         }
729 
730         // Disconnect the instruction links.
731         let prev_inst = self.insts[before].prev;
732         self.insts[before].prev = None.into();
733         self.blocks[old_block].last_inst = prev_inst;
734         match prev_inst.expand() {
735             None => self.blocks[old_block].first_inst = None.into(),
736             Some(pi) => self.insts[pi].next = None.into(),
737         }
738 
739         // Fix the instruction -> block pointers.
740         let mut opt_i = Some(before);
741         while let Some(i) = opt_i {
742             debug_assert_eq!(self.insts[i].block.expand(), Some(old_block));
743             self.insts[i].block = new_block.into();
744             opt_i = self.insts[i].next.into();
745         }
746 
747         self.assign_block_seq(new_block);
748     }
749 }
750 
751 #[derive(Clone, Debug, Default)]
752 struct InstNode {
753     /// The Block containing this instruction, or `None` if the instruction is not yet inserted.
754     block: PackedOption<Block>,
755     prev: PackedOption<Inst>,
756     next: PackedOption<Inst>,
757     seq: SequenceNumber,
758 }
759 
760 /// Iterate over instructions in a block in layout order. See `Layout::block_insts()`.
761 pub struct Insts<'f> {
762     layout: &'f Layout,
763     head: Option<Inst>,
764     tail: Option<Inst>,
765 }
766 
767 impl<'f> Iterator for Insts<'f> {
768     type Item = Inst;
769 
770     fn next(&mut self) -> Option<Inst> {
771         let rval = self.head;
772         if let Some(inst) = rval {
773             if self.head == self.tail {
774                 self.head = None;
775                 self.tail = None;
776             } else {
777                 self.head = self.layout.insts[inst].next.into();
778             }
779         }
780         rval
781     }
782 }
783 
784 impl<'f> DoubleEndedIterator for Insts<'f> {
785     fn next_back(&mut self) -> Option<Inst> {
786         let rval = self.tail;
787         if let Some(inst) = rval {
788             if self.head == self.tail {
789                 self.head = None;
790                 self.tail = None;
791             } else {
792                 self.tail = self.layout.insts[inst].prev.into();
793             }
794         }
795         rval
796     }
797 }
798 
799 /// A custom serialize and deserialize implementation for [`Layout`].
800 ///
801 /// This doesn't use a derived implementation as [`Layout`] is a manual implementation of a linked
802 /// list. Storing it directly as a regular list saves a lot of space.
803 ///
804 /// The following format is used. (notated in EBNF form)
805 ///
806 /// ```plain
807 /// data = block_data * ;
808 /// block_data = "block_id" , "cold" , "inst_count" , ( "inst_id" * ) ;
809 /// ```
810 #[cfg(feature = "enable-serde")]
811 mod serde {
812     use ::serde::de::{Deserializer, Error, SeqAccess, Visitor};
813     use ::serde::ser::{SerializeSeq, Serializer};
814     use ::serde::{Deserialize, Serialize};
815     use core::convert::TryFrom;
816     use core::fmt;
817     use core::marker::PhantomData;
818 
819     use super::*;
820 
821     impl Serialize for Layout {
822         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
823         where
824             S: Serializer,
825         {
826             let size = self.blocks().count() * 3
827                 + self
828                     .blocks()
829                     .map(|block| self.block_insts(block).count())
830                     .sum::<usize>();
831             let mut seq = serializer.serialize_seq(Some(size))?;
832             for block in self.blocks() {
833                 seq.serialize_element(&block)?;
834                 seq.serialize_element(&self.blocks[block].cold)?;
835                 seq.serialize_element(&u32::try_from(self.block_insts(block).count()).unwrap())?;
836                 for inst in self.block_insts(block) {
837                     seq.serialize_element(&inst)?;
838                 }
839             }
840             seq.end()
841         }
842     }
843 
844     impl<'de> Deserialize<'de> for Layout {
845         fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
846         where
847             D: Deserializer<'de>,
848         {
849             deserializer.deserialize_seq(LayoutVisitor {
850                 marker: PhantomData,
851             })
852         }
853     }
854 
855     struct LayoutVisitor {
856         marker: PhantomData<fn() -> Layout>,
857     }
858 
859     impl<'de> Visitor<'de> for LayoutVisitor {
860         type Value = Layout;
861 
862         fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
863             write!(formatter, "a `cranelift_codegen::ir::Layout`")
864         }
865 
866         fn visit_seq<M>(self, mut access: M) -> Result<Self::Value, M::Error>
867         where
868             M: SeqAccess<'de>,
869         {
870             let mut layout = Layout::new();
871 
872             while let Some(block) = access.next_element::<Block>()? {
873                 layout.append_block(block);
874 
875                 let cold = access
876                     .next_element::<bool>()?
877                     .ok_or_else(|| Error::missing_field("cold"))?;
878                 layout.blocks[block].cold = cold;
879 
880                 let count = access
881                     .next_element::<u32>()?
882                     .ok_or_else(|| Error::missing_field("count"))?;
883 
884                 for _ in 0..count {
885                     let inst = access
886                         .next_element::<Inst>()?
887                         .ok_or_else(|| Error::missing_field("inst"))?;
888                     layout.append_inst(inst, block);
889                 }
890             }
891 
892             Ok(layout)
893         }
894     }
895 }
896 
897 #[cfg(test)]
898 mod tests {
899     use super::Layout;
900     use crate::cursor::{Cursor, CursorPosition};
901     use crate::entity::EntityRef;
902     use crate::ir::{Block, Inst, ProgramOrder, SourceLoc};
903     use alloc::vec::Vec;
904     use core::cmp::Ordering;
905 
906     struct LayoutCursor<'f> {
907         /// Borrowed function layout. Public so it can be re-borrowed from this cursor.
908         pub layout: &'f mut Layout,
909         pos: CursorPosition,
910     }
911 
912     impl<'f> Cursor for LayoutCursor<'f> {
913         fn position(&self) -> CursorPosition {
914             self.pos
915         }
916 
917         fn set_position(&mut self, pos: CursorPosition) {
918             self.pos = pos;
919         }
920 
921         fn srcloc(&self) -> SourceLoc {
922             unimplemented!()
923         }
924 
925         fn set_srcloc(&mut self, _srcloc: SourceLoc) {
926             unimplemented!()
927         }
928 
929         fn layout(&self) -> &Layout {
930             self.layout
931         }
932 
933         fn layout_mut(&mut self) -> &mut Layout {
934             self.layout
935         }
936     }
937 
938     impl<'f> LayoutCursor<'f> {
939         /// Create a new `LayoutCursor` for `layout`.
940         /// The cursor holds a mutable reference to `layout` for its entire lifetime.
941         pub fn new(layout: &'f mut Layout) -> Self {
942             Self {
943                 layout,
944                 pos: CursorPosition::Nowhere,
945             }
946         }
947     }
948 
949     fn verify(layout: &mut Layout, blocks: &[(Block, &[Inst])]) {
950         // Check that blocks are inserted and instructions belong the right places.
951         // Check forward linkage with iterators.
952         // Check that layout sequence numbers are strictly monotonic.
953         {
954             let mut seq = 0;
955             let mut block_iter = layout.blocks();
956             for &(block, insts) in blocks {
957                 assert!(layout.is_block_inserted(block));
958                 assert_eq!(block_iter.next(), Some(block));
959                 assert!(layout.blocks[block].seq > seq);
960                 seq = layout.blocks[block].seq;
961 
962                 let mut inst_iter = layout.block_insts(block);
963                 for &inst in insts {
964                     assert_eq!(layout.inst_block(inst), Some(block));
965                     assert_eq!(inst_iter.next(), Some(inst));
966                     assert!(layout.insts[inst].seq > seq);
967                     seq = layout.insts[inst].seq;
968                 }
969                 assert_eq!(inst_iter.next(), None);
970             }
971             assert_eq!(block_iter.next(), None);
972         }
973 
974         // Check backwards linkage with a cursor.
975         let mut cur = LayoutCursor::new(layout);
976         for &(block, insts) in blocks.into_iter().rev() {
977             assert_eq!(cur.prev_block(), Some(block));
978             for &inst in insts.into_iter().rev() {
979                 assert_eq!(cur.prev_inst(), Some(inst));
980             }
981             assert_eq!(cur.prev_inst(), None);
982         }
983         assert_eq!(cur.prev_block(), None);
984     }
985 
986     #[test]
987     fn append_block() {
988         let mut layout = Layout::new();
989         let e0 = Block::new(0);
990         let e1 = Block::new(1);
991         let e2 = Block::new(2);
992 
993         {
994             let imm = &layout;
995             assert!(!imm.is_block_inserted(e0));
996             assert!(!imm.is_block_inserted(e1));
997         }
998         verify(&mut layout, &[]);
999 
1000         layout.append_block(e1);
1001         assert!(!layout.is_block_inserted(e0));
1002         assert!(layout.is_block_inserted(e1));
1003         assert!(!layout.is_block_inserted(e2));
1004         let v: Vec<Block> = layout.blocks().collect();
1005         assert_eq!(v, [e1]);
1006 
1007         layout.append_block(e2);
1008         assert!(!layout.is_block_inserted(e0));
1009         assert!(layout.is_block_inserted(e1));
1010         assert!(layout.is_block_inserted(e2));
1011         let v: Vec<Block> = layout.blocks().collect();
1012         assert_eq!(v, [e1, e2]);
1013 
1014         layout.append_block(e0);
1015         assert!(layout.is_block_inserted(e0));
1016         assert!(layout.is_block_inserted(e1));
1017         assert!(layout.is_block_inserted(e2));
1018         let v: Vec<Block> = layout.blocks().collect();
1019         assert_eq!(v, [e1, e2, e0]);
1020 
1021         {
1022             let imm = &layout;
1023             let mut v = Vec::new();
1024             for e in imm {
1025                 v.push(e);
1026             }
1027             assert_eq!(v, [e1, e2, e0]);
1028         }
1029 
1030         // Test cursor positioning.
1031         let mut cur = LayoutCursor::new(&mut layout);
1032         assert_eq!(cur.position(), CursorPosition::Nowhere);
1033         assert_eq!(cur.next_inst(), None);
1034         assert_eq!(cur.position(), CursorPosition::Nowhere);
1035         assert_eq!(cur.prev_inst(), None);
1036         assert_eq!(cur.position(), CursorPosition::Nowhere);
1037 
1038         assert_eq!(cur.next_block(), Some(e1));
1039         assert_eq!(cur.position(), CursorPosition::Before(e1));
1040         assert_eq!(cur.next_inst(), None);
1041         assert_eq!(cur.position(), CursorPosition::After(e1));
1042         assert_eq!(cur.next_inst(), None);
1043         assert_eq!(cur.position(), CursorPosition::After(e1));
1044         assert_eq!(cur.next_block(), Some(e2));
1045         assert_eq!(cur.prev_inst(), None);
1046         assert_eq!(cur.position(), CursorPosition::Before(e2));
1047         assert_eq!(cur.next_block(), Some(e0));
1048         assert_eq!(cur.next_block(), None);
1049         assert_eq!(cur.position(), CursorPosition::Nowhere);
1050 
1051         // Backwards through the blocks.
1052         assert_eq!(cur.prev_block(), Some(e0));
1053         assert_eq!(cur.position(), CursorPosition::After(e0));
1054         assert_eq!(cur.prev_block(), Some(e2));
1055         assert_eq!(cur.prev_block(), Some(e1));
1056         assert_eq!(cur.prev_block(), None);
1057         assert_eq!(cur.position(), CursorPosition::Nowhere);
1058     }
1059 
1060     #[test]
1061     fn insert_block() {
1062         let mut layout = Layout::new();
1063         let e0 = Block::new(0);
1064         let e1 = Block::new(1);
1065         let e2 = Block::new(2);
1066 
1067         {
1068             let imm = &layout;
1069             assert!(!imm.is_block_inserted(e0));
1070             assert!(!imm.is_block_inserted(e1));
1071 
1072             let v: Vec<Block> = layout.blocks().collect();
1073             assert_eq!(v, []);
1074         }
1075 
1076         layout.append_block(e1);
1077         assert!(!layout.is_block_inserted(e0));
1078         assert!(layout.is_block_inserted(e1));
1079         assert!(!layout.is_block_inserted(e2));
1080         verify(&mut layout, &[(e1, &[])]);
1081 
1082         layout.insert_block(e2, e1);
1083         assert!(!layout.is_block_inserted(e0));
1084         assert!(layout.is_block_inserted(e1));
1085         assert!(layout.is_block_inserted(e2));
1086         verify(&mut layout, &[(e2, &[]), (e1, &[])]);
1087 
1088         layout.insert_block(e0, e1);
1089         assert!(layout.is_block_inserted(e0));
1090         assert!(layout.is_block_inserted(e1));
1091         assert!(layout.is_block_inserted(e2));
1092         verify(&mut layout, &[(e2, &[]), (e0, &[]), (e1, &[])]);
1093     }
1094 
1095     #[test]
1096     fn insert_block_after() {
1097         let mut layout = Layout::new();
1098         let e0 = Block::new(0);
1099         let e1 = Block::new(1);
1100         let e2 = Block::new(2);
1101 
1102         layout.append_block(e1);
1103         layout.insert_block_after(e2, e1);
1104         verify(&mut layout, &[(e1, &[]), (e2, &[])]);
1105 
1106         layout.insert_block_after(e0, e1);
1107         verify(&mut layout, &[(e1, &[]), (e0, &[]), (e2, &[])]);
1108     }
1109 
1110     #[test]
1111     fn append_inst() {
1112         let mut layout = Layout::new();
1113         let e1 = Block::new(1);
1114 
1115         layout.append_block(e1);
1116         let v: Vec<Inst> = layout.block_insts(e1).collect();
1117         assert_eq!(v, []);
1118 
1119         let i0 = Inst::new(0);
1120         let i1 = Inst::new(1);
1121         let i2 = Inst::new(2);
1122 
1123         assert_eq!(layout.inst_block(i0), None);
1124         assert_eq!(layout.inst_block(i1), None);
1125         assert_eq!(layout.inst_block(i2), None);
1126 
1127         layout.append_inst(i1, e1);
1128         assert_eq!(layout.inst_block(i0), None);
1129         assert_eq!(layout.inst_block(i1), Some(e1));
1130         assert_eq!(layout.inst_block(i2), None);
1131         let v: Vec<Inst> = layout.block_insts(e1).collect();
1132         assert_eq!(v, [i1]);
1133 
1134         layout.append_inst(i2, e1);
1135         assert_eq!(layout.inst_block(i0), None);
1136         assert_eq!(layout.inst_block(i1), Some(e1));
1137         assert_eq!(layout.inst_block(i2), Some(e1));
1138         let v: Vec<Inst> = layout.block_insts(e1).collect();
1139         assert_eq!(v, [i1, i2]);
1140 
1141         // Test double-ended instruction iterator.
1142         let v: Vec<Inst> = layout.block_insts(e1).rev().collect();
1143         assert_eq!(v, [i2, i1]);
1144 
1145         layout.append_inst(i0, e1);
1146         verify(&mut layout, &[(e1, &[i1, i2, i0])]);
1147 
1148         // Test cursor positioning.
1149         let mut cur = LayoutCursor::new(&mut layout).at_top(e1);
1150         assert_eq!(cur.position(), CursorPosition::Before(e1));
1151         assert_eq!(cur.prev_inst(), None);
1152         assert_eq!(cur.position(), CursorPosition::Before(e1));
1153         assert_eq!(cur.next_inst(), Some(i1));
1154         assert_eq!(cur.position(), CursorPosition::At(i1));
1155         assert_eq!(cur.next_inst(), Some(i2));
1156         assert_eq!(cur.next_inst(), Some(i0));
1157         assert_eq!(cur.prev_inst(), Some(i2));
1158         assert_eq!(cur.position(), CursorPosition::At(i2));
1159         assert_eq!(cur.next_inst(), Some(i0));
1160         assert_eq!(cur.position(), CursorPosition::At(i0));
1161         assert_eq!(cur.next_inst(), None);
1162         assert_eq!(cur.position(), CursorPosition::After(e1));
1163         assert_eq!(cur.next_inst(), None);
1164         assert_eq!(cur.position(), CursorPosition::After(e1));
1165         assert_eq!(cur.prev_inst(), Some(i0));
1166         assert_eq!(cur.prev_inst(), Some(i2));
1167         assert_eq!(cur.prev_inst(), Some(i1));
1168         assert_eq!(cur.prev_inst(), None);
1169         assert_eq!(cur.position(), CursorPosition::Before(e1));
1170 
1171         // Test remove_inst.
1172         cur.goto_inst(i2);
1173         assert_eq!(cur.remove_inst(), i2);
1174         verify(cur.layout, &[(e1, &[i1, i0])]);
1175         assert_eq!(cur.layout.inst_block(i2), None);
1176         assert_eq!(cur.remove_inst(), i0);
1177         verify(cur.layout, &[(e1, &[i1])]);
1178         assert_eq!(cur.layout.inst_block(i0), None);
1179         assert_eq!(cur.position(), CursorPosition::After(e1));
1180         cur.layout.remove_inst(i1);
1181         verify(cur.layout, &[(e1, &[])]);
1182         assert_eq!(cur.layout.inst_block(i1), None);
1183     }
1184 
1185     #[test]
1186     fn insert_inst() {
1187         let mut layout = Layout::new();
1188         let e1 = Block::new(1);
1189 
1190         layout.append_block(e1);
1191         let v: Vec<Inst> = layout.block_insts(e1).collect();
1192         assert_eq!(v, []);
1193 
1194         let i0 = Inst::new(0);
1195         let i1 = Inst::new(1);
1196         let i2 = Inst::new(2);
1197 
1198         assert_eq!(layout.inst_block(i0), None);
1199         assert_eq!(layout.inst_block(i1), None);
1200         assert_eq!(layout.inst_block(i2), None);
1201 
1202         layout.append_inst(i1, e1);
1203         assert_eq!(layout.inst_block(i0), None);
1204         assert_eq!(layout.inst_block(i1), Some(e1));
1205         assert_eq!(layout.inst_block(i2), None);
1206         let v: Vec<Inst> = layout.block_insts(e1).collect();
1207         assert_eq!(v, [i1]);
1208 
1209         layout.insert_inst(i2, i1);
1210         assert_eq!(layout.inst_block(i0), None);
1211         assert_eq!(layout.inst_block(i1), Some(e1));
1212         assert_eq!(layout.inst_block(i2), Some(e1));
1213         let v: Vec<Inst> = layout.block_insts(e1).collect();
1214         assert_eq!(v, [i2, i1]);
1215 
1216         layout.insert_inst(i0, i1);
1217         verify(&mut layout, &[(e1, &[i2, i0, i1])]);
1218     }
1219 
1220     #[test]
1221     fn multiple_blocks() {
1222         let mut layout = Layout::new();
1223 
1224         let e0 = Block::new(0);
1225         let e1 = Block::new(1);
1226 
1227         assert_eq!(layout.entry_block(), None);
1228         layout.append_block(e0);
1229         assert_eq!(layout.entry_block(), Some(e0));
1230         layout.append_block(e1);
1231         assert_eq!(layout.entry_block(), Some(e0));
1232 
1233         let i0 = Inst::new(0);
1234         let i1 = Inst::new(1);
1235         let i2 = Inst::new(2);
1236         let i3 = Inst::new(3);
1237 
1238         layout.append_inst(i0, e0);
1239         layout.append_inst(i1, e0);
1240         layout.append_inst(i2, e1);
1241         layout.append_inst(i3, e1);
1242 
1243         let v0: Vec<Inst> = layout.block_insts(e0).collect();
1244         let v1: Vec<Inst> = layout.block_insts(e1).collect();
1245         assert_eq!(v0, [i0, i1]);
1246         assert_eq!(v1, [i2, i3]);
1247     }
1248 
1249     #[test]
1250     fn split_block() {
1251         let mut layout = Layout::new();
1252 
1253         let e0 = Block::new(0);
1254         let e1 = Block::new(1);
1255         let e2 = Block::new(2);
1256 
1257         let i0 = Inst::new(0);
1258         let i1 = Inst::new(1);
1259         let i2 = Inst::new(2);
1260         let i3 = Inst::new(3);
1261 
1262         layout.append_block(e0);
1263         layout.append_inst(i0, e0);
1264         assert_eq!(layout.inst_block(i0), Some(e0));
1265         layout.split_block(e1, i0);
1266         assert_eq!(layout.inst_block(i0), Some(e1));
1267 
1268         {
1269             let mut cur = LayoutCursor::new(&mut layout);
1270             assert_eq!(cur.next_block(), Some(e0));
1271             assert_eq!(cur.next_inst(), None);
1272             assert_eq!(cur.next_block(), Some(e1));
1273             assert_eq!(cur.next_inst(), Some(i0));
1274             assert_eq!(cur.next_inst(), None);
1275             assert_eq!(cur.next_block(), None);
1276 
1277             // Check backwards links.
1278             assert_eq!(cur.prev_block(), Some(e1));
1279             assert_eq!(cur.prev_inst(), Some(i0));
1280             assert_eq!(cur.prev_inst(), None);
1281             assert_eq!(cur.prev_block(), Some(e0));
1282             assert_eq!(cur.prev_inst(), None);
1283             assert_eq!(cur.prev_block(), None);
1284         }
1285 
1286         layout.append_inst(i1, e0);
1287         layout.append_inst(i2, e0);
1288         layout.append_inst(i3, e0);
1289         layout.split_block(e2, i2);
1290 
1291         assert_eq!(layout.inst_block(i0), Some(e1));
1292         assert_eq!(layout.inst_block(i1), Some(e0));
1293         assert_eq!(layout.inst_block(i2), Some(e2));
1294         assert_eq!(layout.inst_block(i3), Some(e2));
1295 
1296         {
1297             let mut cur = LayoutCursor::new(&mut layout);
1298             assert_eq!(cur.next_block(), Some(e0));
1299             assert_eq!(cur.next_inst(), Some(i1));
1300             assert_eq!(cur.next_inst(), None);
1301             assert_eq!(cur.next_block(), Some(e2));
1302             assert_eq!(cur.next_inst(), Some(i2));
1303             assert_eq!(cur.next_inst(), Some(i3));
1304             assert_eq!(cur.next_inst(), None);
1305             assert_eq!(cur.next_block(), Some(e1));
1306             assert_eq!(cur.next_inst(), Some(i0));
1307             assert_eq!(cur.next_inst(), None);
1308             assert_eq!(cur.next_block(), None);
1309 
1310             assert_eq!(cur.prev_block(), Some(e1));
1311             assert_eq!(cur.prev_inst(), Some(i0));
1312             assert_eq!(cur.prev_inst(), None);
1313             assert_eq!(cur.prev_block(), Some(e2));
1314             assert_eq!(cur.prev_inst(), Some(i3));
1315             assert_eq!(cur.prev_inst(), Some(i2));
1316             assert_eq!(cur.prev_inst(), None);
1317             assert_eq!(cur.prev_block(), Some(e0));
1318             assert_eq!(cur.prev_inst(), Some(i1));
1319             assert_eq!(cur.prev_inst(), None);
1320             assert_eq!(cur.prev_block(), None);
1321         }
1322 
1323         // Check `ProgramOrder`.
1324         assert_eq!(layout.cmp(e2, e2), Ordering::Equal);
1325         assert_eq!(layout.cmp(e2, i2), Ordering::Less);
1326         assert_eq!(layout.cmp(i3, i2), Ordering::Greater);
1327 
1328         assert_eq!(layout.is_block_gap(i1, e2), true);
1329         assert_eq!(layout.is_block_gap(i3, e1), true);
1330         assert_eq!(layout.is_block_gap(i1, e1), false);
1331         assert_eq!(layout.is_block_gap(i2, e1), false);
1332     }
1333 }
1334