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;
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         log::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 #[derive(Clone, Debug, Default)]
488 struct BlockNode {
489     prev: PackedOption<Block>,
490     next: PackedOption<Block>,
491     first_inst: PackedOption<Inst>,
492     last_inst: PackedOption<Inst>,
493     seq: SequenceNumber,
494     cold: bool,
495 }
496 
497 /// Iterate over blocks in layout order. See [crate::ir::layout::Layout::blocks].
498 pub struct Blocks<'f> {
499     layout: &'f Layout,
500     next: Option<Block>,
501 }
502 
503 impl<'f> Iterator for Blocks<'f> {
504     type Item = Block;
505 
506     fn next(&mut self) -> Option<Block> {
507         match self.next {
508             Some(block) => {
509                 self.next = self.layout.next_block(block);
510                 Some(block)
511             }
512             None => None,
513         }
514     }
515 }
516 
517 /// Use a layout reference in a for loop.
518 impl<'f> IntoIterator for &'f Layout {
519     type Item = Block;
520     type IntoIter = Blocks<'f>;
521 
522     fn into_iter(self) -> Blocks<'f> {
523         self.blocks()
524     }
525 }
526 
527 /// Methods for arranging instructions.
528 ///
529 /// An instruction starts out as *not inserted* in the layout. An instruction can be inserted into
530 /// a block at a given position.
531 impl Layout {
532     /// Get the block containing `inst`, or `None` if `inst` is not inserted in the layout.
533     pub fn inst_block(&self, inst: Inst) -> Option<Block> {
534         self.insts[inst].block.into()
535     }
536 
537     /// Get the block containing the program point `pp`. Panic if `pp` is not in the layout.
538     pub fn pp_block<PP>(&self, pp: PP) -> Block
539     where
540         PP: Into<ExpandedProgramPoint>,
541     {
542         match pp.into() {
543             ExpandedProgramPoint::Block(block) => block,
544             ExpandedProgramPoint::Inst(inst) => {
545                 self.inst_block(inst).expect("Program point not in layout")
546             }
547         }
548     }
549 
550     /// Append `inst` to the end of `block`.
551     pub fn append_inst(&mut self, inst: Inst, block: Block) {
552         debug_assert_eq!(self.inst_block(inst), None);
553         debug_assert!(
554             self.is_block_inserted(block),
555             "Cannot append instructions to block not in layout"
556         );
557         {
558             let block_node = &mut self.blocks[block];
559             {
560                 let inst_node = &mut self.insts[inst];
561                 inst_node.block = block.into();
562                 inst_node.prev = block_node.last_inst;
563                 debug_assert!(inst_node.next.is_none());
564             }
565             if block_node.first_inst.is_none() {
566                 block_node.first_inst = inst.into();
567             } else {
568                 self.insts[block_node.last_inst.unwrap()].next = inst.into();
569             }
570             block_node.last_inst = inst.into();
571         }
572         self.assign_inst_seq(inst);
573     }
574 
575     /// Fetch a block's first instruction.
576     pub fn first_inst(&self, block: Block) -> Option<Inst> {
577         self.blocks[block].first_inst.into()
578     }
579 
580     /// Fetch a block's last instruction.
581     pub fn last_inst(&self, block: Block) -> Option<Inst> {
582         self.blocks[block].last_inst.into()
583     }
584 
585     /// Fetch the instruction following `inst`.
586     pub fn next_inst(&self, inst: Inst) -> Option<Inst> {
587         self.insts[inst].next.expand()
588     }
589 
590     /// Fetch the instruction preceding `inst`.
591     pub fn prev_inst(&self, inst: Inst) -> Option<Inst> {
592         self.insts[inst].prev.expand()
593     }
594 
595     /// Fetch the first instruction in a block's terminal branch group.
596     pub fn canonical_branch_inst(&self, dfg: &DataFlowGraph, block: Block) -> Option<Inst> {
597         // Basic blocks permit at most two terminal branch instructions.
598         // If two, the former is conditional and the latter is unconditional.
599         let last = self.last_inst(block)?;
600         if let Some(prev) = self.prev_inst(last) {
601             if dfg[prev].opcode().is_branch() {
602                 return Some(prev);
603             }
604         }
605         Some(last)
606     }
607 
608     /// Insert `inst` before the instruction `before` in the same block.
609     pub fn insert_inst(&mut self, inst: Inst, before: Inst) {
610         debug_assert_eq!(self.inst_block(inst), None);
611         let block = self
612             .inst_block(before)
613             .expect("Instruction before insertion point not in the layout");
614         let after = self.insts[before].prev;
615         {
616             let inst_node = &mut self.insts[inst];
617             inst_node.block = block.into();
618             inst_node.next = before.into();
619             inst_node.prev = after;
620         }
621         self.insts[before].prev = inst.into();
622         match after.expand() {
623             None => self.blocks[block].first_inst = inst.into(),
624             Some(a) => self.insts[a].next = inst.into(),
625         }
626         self.assign_inst_seq(inst);
627     }
628 
629     /// Remove `inst` from the layout.
630     pub fn remove_inst(&mut self, inst: Inst) {
631         let block = self.inst_block(inst).expect("Instruction already removed.");
632         // Clear the `inst` node and extract links.
633         let prev;
634         let next;
635         {
636             let n = &mut self.insts[inst];
637             prev = n.prev;
638             next = n.next;
639             n.block = None.into();
640             n.prev = None.into();
641             n.next = None.into();
642         }
643         // Fix up links to `inst`.
644         match prev.expand() {
645             None => self.blocks[block].first_inst = next,
646             Some(p) => self.insts[p].next = next,
647         }
648         match next.expand() {
649             None => self.blocks[block].last_inst = prev,
650             Some(n) => self.insts[n].prev = prev,
651         }
652     }
653 
654     /// Iterate over the instructions in `block` in layout order.
655     pub fn block_insts(&self, block: Block) -> Insts {
656         Insts {
657             layout: self,
658             head: self.blocks[block].first_inst.into(),
659             tail: self.blocks[block].last_inst.into(),
660         }
661     }
662 
663     /// Iterate over a limited set of instruction which are likely the branches of `block` in layout
664     /// order. Any instruction not visited by this iterator is not a branch, but an instruction visited by this may not be a branch.
665     pub fn block_likely_branches(&self, block: Block) -> Insts {
666         // Note: Checking whether an instruction is a branch or not while walking backward might add
667         // extra overhead. However, we know that the number of branches is limited to 2 at the end of
668         // each block, and therefore we can just iterate over the last 2 instructions.
669         let mut iter = self.block_insts(block);
670         let head = iter.head;
671         let tail = iter.tail;
672         iter.next_back();
673         let head = iter.next_back().or(head);
674         Insts {
675             layout: self,
676             head,
677             tail,
678         }
679     }
680 
681     /// Split the block containing `before` in two.
682     ///
683     /// Insert `new_block` after the old block and move `before` and the following instructions to
684     /// `new_block`:
685     ///
686     /// ```text
687     /// old_block:
688     ///     i1
689     ///     i2
690     ///     i3 << before
691     ///     i4
692     /// ```
693     /// becomes:
694     ///
695     /// ```text
696     /// old_block:
697     ///     i1
698     ///     i2
699     /// new_block:
700     ///     i3 << before
701     ///     i4
702     /// ```
703     pub fn split_block(&mut self, new_block: Block, before: Inst) {
704         let old_block = self
705             .inst_block(before)
706             .expect("The `before` instruction must be in the layout");
707         debug_assert!(!self.is_block_inserted(new_block));
708 
709         // Insert new_block after old_block.
710         let next_block = self.blocks[old_block].next;
711         let last_inst = self.blocks[old_block].last_inst;
712         {
713             let node = &mut self.blocks[new_block];
714             node.prev = old_block.into();
715             node.next = next_block;
716             node.first_inst = before.into();
717             node.last_inst = last_inst;
718         }
719         self.blocks[old_block].next = new_block.into();
720 
721         // Fix backwards link.
722         if Some(old_block) == self.last_block {
723             self.last_block = Some(new_block);
724         } else {
725             self.blocks[next_block.unwrap()].prev = new_block.into();
726         }
727 
728         // Disconnect the instruction links.
729         let prev_inst = self.insts[before].prev;
730         self.insts[before].prev = None.into();
731         self.blocks[old_block].last_inst = prev_inst;
732         match prev_inst.expand() {
733             None => self.blocks[old_block].first_inst = None.into(),
734             Some(pi) => self.insts[pi].next = None.into(),
735         }
736 
737         // Fix the instruction -> block pointers.
738         let mut opt_i = Some(before);
739         while let Some(i) = opt_i {
740             debug_assert_eq!(self.insts[i].block.expand(), Some(old_block));
741             self.insts[i].block = new_block.into();
742             opt_i = self.insts[i].next.into();
743         }
744 
745         self.assign_block_seq(new_block);
746     }
747 }
748 
749 #[derive(Clone, Debug, Default)]
750 struct InstNode {
751     /// The Block containing this instruction, or `None` if the instruction is not yet inserted.
752     block: PackedOption<Block>,
753     prev: PackedOption<Inst>,
754     next: PackedOption<Inst>,
755     seq: SequenceNumber,
756 }
757 
758 /// Iterate over instructions in a block in layout order. See `Layout::block_insts()`.
759 pub struct Insts<'f> {
760     layout: &'f Layout,
761     head: Option<Inst>,
762     tail: Option<Inst>,
763 }
764 
765 impl<'f> Iterator for Insts<'f> {
766     type Item = Inst;
767 
768     fn next(&mut self) -> Option<Inst> {
769         let rval = self.head;
770         if let Some(inst) = rval {
771             if self.head == self.tail {
772                 self.head = None;
773                 self.tail = None;
774             } else {
775                 self.head = self.layout.insts[inst].next.into();
776             }
777         }
778         rval
779     }
780 }
781 
782 impl<'f> DoubleEndedIterator for Insts<'f> {
783     fn next_back(&mut self) -> Option<Inst> {
784         let rval = self.tail;
785         if let Some(inst) = rval {
786             if self.head == self.tail {
787                 self.head = None;
788                 self.tail = None;
789             } else {
790                 self.tail = self.layout.insts[inst].prev.into();
791             }
792         }
793         rval
794     }
795 }
796 
797 /// A custom serialize and deserialize implementation for [`Layout`].
798 ///
799 /// This doesn't use a derived implementation as [`Layout`] is a manual implementation of a linked
800 /// list. Storing it directly as a regular list saves a lot of space.
801 ///
802 /// The following format is used. (notated in EBNF form)
803 ///
804 /// ```plain
805 /// data = block_data * ;
806 /// block_data = "block_id" , "inst_count" , ( "inst_id" * ) ;
807 /// ```
808 #[cfg(feature = "enable-serde")]
809 mod serde {
810     use ::serde::de::{Deserializer, Error, SeqAccess, Visitor};
811     use ::serde::ser::{SerializeSeq, Serializer};
812     use ::serde::{Deserialize, Serialize};
813     use core::convert::TryFrom;
814     use core::fmt;
815     use core::marker::PhantomData;
816 
817     use super::*;
818 
819     impl Serialize for Layout {
820         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
821         where
822             S: Serializer,
823         {
824             let size = self.blocks().count() * 2
825                 + self
826                     .blocks()
827                     .map(|block| self.block_insts(block).count())
828                     .sum::<usize>();
829             let mut seq = serializer.serialize_seq(Some(size))?;
830             for block in self.blocks() {
831                 seq.serialize_element(&block)?;
832                 seq.serialize_element(&u32::try_from(self.block_insts(block).count()).unwrap())?;
833                 for inst in self.block_insts(block) {
834                     seq.serialize_element(&inst)?;
835                 }
836             }
837             seq.end()
838         }
839     }
840 
841     impl<'de> Deserialize<'de> for Layout {
842         fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
843         where
844             D: Deserializer<'de>,
845         {
846             deserializer.deserialize_seq(LayoutVisitor {
847                 marker: PhantomData,
848             })
849         }
850     }
851 
852     struct LayoutVisitor {
853         marker: PhantomData<fn() -> Layout>,
854     }
855 
856     impl<'de> Visitor<'de> for LayoutVisitor {
857         type Value = Layout;
858 
859         fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
860             write!(formatter, "a `cranelift_codegen::ir::Layout`")
861         }
862 
863         fn visit_seq<M>(self, mut access: M) -> Result<Self::Value, M::Error>
864         where
865             M: SeqAccess<'de>,
866         {
867             let mut layout = Layout::new();
868 
869             while let Some(block) = access.next_element::<Block>()? {
870                 layout.append_block(block);
871 
872                 let count = access
873                     .next_element::<u32>()?
874                     .ok_or_else(|| Error::missing_field("count"))?;
875                 for _ in 0..count {
876                     let inst = access
877                         .next_element::<Inst>()?
878                         .ok_or_else(|| Error::missing_field("inst"))?;
879                     layout.append_inst(inst, block);
880                 }
881             }
882 
883             Ok(layout)
884         }
885     }
886 }
887 
888 #[cfg(test)]
889 mod tests {
890     use super::Layout;
891     use crate::cursor::{Cursor, CursorPosition};
892     use crate::entity::EntityRef;
893     use crate::ir::{Block, Inst, ProgramOrder, SourceLoc};
894     use alloc::vec::Vec;
895     use core::cmp::Ordering;
896 
897     struct LayoutCursor<'f> {
898         /// Borrowed function layout. Public so it can be re-borrowed from this cursor.
899         pub layout: &'f mut Layout,
900         pos: CursorPosition,
901     }
902 
903     impl<'f> Cursor for LayoutCursor<'f> {
904         fn position(&self) -> CursorPosition {
905             self.pos
906         }
907 
908         fn set_position(&mut self, pos: CursorPosition) {
909             self.pos = pos;
910         }
911 
912         fn srcloc(&self) -> SourceLoc {
913             unimplemented!()
914         }
915 
916         fn set_srcloc(&mut self, _srcloc: SourceLoc) {
917             unimplemented!()
918         }
919 
920         fn layout(&self) -> &Layout {
921             self.layout
922         }
923 
924         fn layout_mut(&mut self) -> &mut Layout {
925             self.layout
926         }
927     }
928 
929     impl<'f> LayoutCursor<'f> {
930         /// Create a new `LayoutCursor` for `layout`.
931         /// The cursor holds a mutable reference to `layout` for its entire lifetime.
932         pub fn new(layout: &'f mut Layout) -> Self {
933             Self {
934                 layout,
935                 pos: CursorPosition::Nowhere,
936             }
937         }
938     }
939 
940     fn verify(layout: &mut Layout, blocks: &[(Block, &[Inst])]) {
941         // Check that blocks are inserted and instructions belong the right places.
942         // Check forward linkage with iterators.
943         // Check that layout sequence numbers are strictly monotonic.
944         {
945             let mut seq = 0;
946             let mut block_iter = layout.blocks();
947             for &(block, insts) in blocks {
948                 assert!(layout.is_block_inserted(block));
949                 assert_eq!(block_iter.next(), Some(block));
950                 assert!(layout.blocks[block].seq > seq);
951                 seq = layout.blocks[block].seq;
952 
953                 let mut inst_iter = layout.block_insts(block);
954                 for &inst in insts {
955                     assert_eq!(layout.inst_block(inst), Some(block));
956                     assert_eq!(inst_iter.next(), Some(inst));
957                     assert!(layout.insts[inst].seq > seq);
958                     seq = layout.insts[inst].seq;
959                 }
960                 assert_eq!(inst_iter.next(), None);
961             }
962             assert_eq!(block_iter.next(), None);
963         }
964 
965         // Check backwards linkage with a cursor.
966         let mut cur = LayoutCursor::new(layout);
967         for &(block, insts) in blocks.into_iter().rev() {
968             assert_eq!(cur.prev_block(), Some(block));
969             for &inst in insts.into_iter().rev() {
970                 assert_eq!(cur.prev_inst(), Some(inst));
971             }
972             assert_eq!(cur.prev_inst(), None);
973         }
974         assert_eq!(cur.prev_block(), None);
975     }
976 
977     #[test]
978     fn append_block() {
979         let mut layout = Layout::new();
980         let e0 = Block::new(0);
981         let e1 = Block::new(1);
982         let e2 = Block::new(2);
983 
984         {
985             let imm = &layout;
986             assert!(!imm.is_block_inserted(e0));
987             assert!(!imm.is_block_inserted(e1));
988         }
989         verify(&mut layout, &[]);
990 
991         layout.append_block(e1);
992         assert!(!layout.is_block_inserted(e0));
993         assert!(layout.is_block_inserted(e1));
994         assert!(!layout.is_block_inserted(e2));
995         let v: Vec<Block> = layout.blocks().collect();
996         assert_eq!(v, [e1]);
997 
998         layout.append_block(e2);
999         assert!(!layout.is_block_inserted(e0));
1000         assert!(layout.is_block_inserted(e1));
1001         assert!(layout.is_block_inserted(e2));
1002         let v: Vec<Block> = layout.blocks().collect();
1003         assert_eq!(v, [e1, e2]);
1004 
1005         layout.append_block(e0);
1006         assert!(layout.is_block_inserted(e0));
1007         assert!(layout.is_block_inserted(e1));
1008         assert!(layout.is_block_inserted(e2));
1009         let v: Vec<Block> = layout.blocks().collect();
1010         assert_eq!(v, [e1, e2, e0]);
1011 
1012         {
1013             let imm = &layout;
1014             let mut v = Vec::new();
1015             for e in imm {
1016                 v.push(e);
1017             }
1018             assert_eq!(v, [e1, e2, e0]);
1019         }
1020 
1021         // Test cursor positioning.
1022         let mut cur = LayoutCursor::new(&mut layout);
1023         assert_eq!(cur.position(), CursorPosition::Nowhere);
1024         assert_eq!(cur.next_inst(), None);
1025         assert_eq!(cur.position(), CursorPosition::Nowhere);
1026         assert_eq!(cur.prev_inst(), None);
1027         assert_eq!(cur.position(), CursorPosition::Nowhere);
1028 
1029         assert_eq!(cur.next_block(), Some(e1));
1030         assert_eq!(cur.position(), CursorPosition::Before(e1));
1031         assert_eq!(cur.next_inst(), None);
1032         assert_eq!(cur.position(), CursorPosition::After(e1));
1033         assert_eq!(cur.next_inst(), None);
1034         assert_eq!(cur.position(), CursorPosition::After(e1));
1035         assert_eq!(cur.next_block(), Some(e2));
1036         assert_eq!(cur.prev_inst(), None);
1037         assert_eq!(cur.position(), CursorPosition::Before(e2));
1038         assert_eq!(cur.next_block(), Some(e0));
1039         assert_eq!(cur.next_block(), None);
1040         assert_eq!(cur.position(), CursorPosition::Nowhere);
1041 
1042         // Backwards through the blocks.
1043         assert_eq!(cur.prev_block(), Some(e0));
1044         assert_eq!(cur.position(), CursorPosition::After(e0));
1045         assert_eq!(cur.prev_block(), Some(e2));
1046         assert_eq!(cur.prev_block(), Some(e1));
1047         assert_eq!(cur.prev_block(), None);
1048         assert_eq!(cur.position(), CursorPosition::Nowhere);
1049     }
1050 
1051     #[test]
1052     fn insert_block() {
1053         let mut layout = Layout::new();
1054         let e0 = Block::new(0);
1055         let e1 = Block::new(1);
1056         let e2 = Block::new(2);
1057 
1058         {
1059             let imm = &layout;
1060             assert!(!imm.is_block_inserted(e0));
1061             assert!(!imm.is_block_inserted(e1));
1062 
1063             let v: Vec<Block> = layout.blocks().collect();
1064             assert_eq!(v, []);
1065         }
1066 
1067         layout.append_block(e1);
1068         assert!(!layout.is_block_inserted(e0));
1069         assert!(layout.is_block_inserted(e1));
1070         assert!(!layout.is_block_inserted(e2));
1071         verify(&mut layout, &[(e1, &[])]);
1072 
1073         layout.insert_block(e2, e1);
1074         assert!(!layout.is_block_inserted(e0));
1075         assert!(layout.is_block_inserted(e1));
1076         assert!(layout.is_block_inserted(e2));
1077         verify(&mut layout, &[(e2, &[]), (e1, &[])]);
1078 
1079         layout.insert_block(e0, e1);
1080         assert!(layout.is_block_inserted(e0));
1081         assert!(layout.is_block_inserted(e1));
1082         assert!(layout.is_block_inserted(e2));
1083         verify(&mut layout, &[(e2, &[]), (e0, &[]), (e1, &[])]);
1084     }
1085 
1086     #[test]
1087     fn insert_block_after() {
1088         let mut layout = Layout::new();
1089         let e0 = Block::new(0);
1090         let e1 = Block::new(1);
1091         let e2 = Block::new(2);
1092 
1093         layout.append_block(e1);
1094         layout.insert_block_after(e2, e1);
1095         verify(&mut layout, &[(e1, &[]), (e2, &[])]);
1096 
1097         layout.insert_block_after(e0, e1);
1098         verify(&mut layout, &[(e1, &[]), (e0, &[]), (e2, &[])]);
1099     }
1100 
1101     #[test]
1102     fn append_inst() {
1103         let mut layout = Layout::new();
1104         let e1 = Block::new(1);
1105 
1106         layout.append_block(e1);
1107         let v: Vec<Inst> = layout.block_insts(e1).collect();
1108         assert_eq!(v, []);
1109 
1110         let i0 = Inst::new(0);
1111         let i1 = Inst::new(1);
1112         let i2 = Inst::new(2);
1113 
1114         assert_eq!(layout.inst_block(i0), None);
1115         assert_eq!(layout.inst_block(i1), None);
1116         assert_eq!(layout.inst_block(i2), None);
1117 
1118         layout.append_inst(i1, e1);
1119         assert_eq!(layout.inst_block(i0), None);
1120         assert_eq!(layout.inst_block(i1), Some(e1));
1121         assert_eq!(layout.inst_block(i2), None);
1122         let v: Vec<Inst> = layout.block_insts(e1).collect();
1123         assert_eq!(v, [i1]);
1124 
1125         layout.append_inst(i2, e1);
1126         assert_eq!(layout.inst_block(i0), None);
1127         assert_eq!(layout.inst_block(i1), Some(e1));
1128         assert_eq!(layout.inst_block(i2), Some(e1));
1129         let v: Vec<Inst> = layout.block_insts(e1).collect();
1130         assert_eq!(v, [i1, i2]);
1131 
1132         // Test double-ended instruction iterator.
1133         let v: Vec<Inst> = layout.block_insts(e1).rev().collect();
1134         assert_eq!(v, [i2, i1]);
1135 
1136         layout.append_inst(i0, e1);
1137         verify(&mut layout, &[(e1, &[i1, i2, i0])]);
1138 
1139         // Test cursor positioning.
1140         let mut cur = LayoutCursor::new(&mut layout).at_top(e1);
1141         assert_eq!(cur.position(), CursorPosition::Before(e1));
1142         assert_eq!(cur.prev_inst(), None);
1143         assert_eq!(cur.position(), CursorPosition::Before(e1));
1144         assert_eq!(cur.next_inst(), Some(i1));
1145         assert_eq!(cur.position(), CursorPosition::At(i1));
1146         assert_eq!(cur.next_inst(), Some(i2));
1147         assert_eq!(cur.next_inst(), Some(i0));
1148         assert_eq!(cur.prev_inst(), Some(i2));
1149         assert_eq!(cur.position(), CursorPosition::At(i2));
1150         assert_eq!(cur.next_inst(), Some(i0));
1151         assert_eq!(cur.position(), CursorPosition::At(i0));
1152         assert_eq!(cur.next_inst(), None);
1153         assert_eq!(cur.position(), CursorPosition::After(e1));
1154         assert_eq!(cur.next_inst(), None);
1155         assert_eq!(cur.position(), CursorPosition::After(e1));
1156         assert_eq!(cur.prev_inst(), Some(i0));
1157         assert_eq!(cur.prev_inst(), Some(i2));
1158         assert_eq!(cur.prev_inst(), Some(i1));
1159         assert_eq!(cur.prev_inst(), None);
1160         assert_eq!(cur.position(), CursorPosition::Before(e1));
1161 
1162         // Test remove_inst.
1163         cur.goto_inst(i2);
1164         assert_eq!(cur.remove_inst(), i2);
1165         verify(cur.layout, &[(e1, &[i1, i0])]);
1166         assert_eq!(cur.layout.inst_block(i2), None);
1167         assert_eq!(cur.remove_inst(), i0);
1168         verify(cur.layout, &[(e1, &[i1])]);
1169         assert_eq!(cur.layout.inst_block(i0), None);
1170         assert_eq!(cur.position(), CursorPosition::After(e1));
1171         cur.layout.remove_inst(i1);
1172         verify(cur.layout, &[(e1, &[])]);
1173         assert_eq!(cur.layout.inst_block(i1), None);
1174     }
1175 
1176     #[test]
1177     fn insert_inst() {
1178         let mut layout = Layout::new();
1179         let e1 = Block::new(1);
1180 
1181         layout.append_block(e1);
1182         let v: Vec<Inst> = layout.block_insts(e1).collect();
1183         assert_eq!(v, []);
1184 
1185         let i0 = Inst::new(0);
1186         let i1 = Inst::new(1);
1187         let i2 = Inst::new(2);
1188 
1189         assert_eq!(layout.inst_block(i0), None);
1190         assert_eq!(layout.inst_block(i1), None);
1191         assert_eq!(layout.inst_block(i2), None);
1192 
1193         layout.append_inst(i1, e1);
1194         assert_eq!(layout.inst_block(i0), None);
1195         assert_eq!(layout.inst_block(i1), Some(e1));
1196         assert_eq!(layout.inst_block(i2), None);
1197         let v: Vec<Inst> = layout.block_insts(e1).collect();
1198         assert_eq!(v, [i1]);
1199 
1200         layout.insert_inst(i2, i1);
1201         assert_eq!(layout.inst_block(i0), None);
1202         assert_eq!(layout.inst_block(i1), Some(e1));
1203         assert_eq!(layout.inst_block(i2), Some(e1));
1204         let v: Vec<Inst> = layout.block_insts(e1).collect();
1205         assert_eq!(v, [i2, i1]);
1206 
1207         layout.insert_inst(i0, i1);
1208         verify(&mut layout, &[(e1, &[i2, i0, i1])]);
1209     }
1210 
1211     #[test]
1212     fn multiple_blocks() {
1213         let mut layout = Layout::new();
1214 
1215         let e0 = Block::new(0);
1216         let e1 = Block::new(1);
1217 
1218         assert_eq!(layout.entry_block(), None);
1219         layout.append_block(e0);
1220         assert_eq!(layout.entry_block(), Some(e0));
1221         layout.append_block(e1);
1222         assert_eq!(layout.entry_block(), Some(e0));
1223 
1224         let i0 = Inst::new(0);
1225         let i1 = Inst::new(1);
1226         let i2 = Inst::new(2);
1227         let i3 = Inst::new(3);
1228 
1229         layout.append_inst(i0, e0);
1230         layout.append_inst(i1, e0);
1231         layout.append_inst(i2, e1);
1232         layout.append_inst(i3, e1);
1233 
1234         let v0: Vec<Inst> = layout.block_insts(e0).collect();
1235         let v1: Vec<Inst> = layout.block_insts(e1).collect();
1236         assert_eq!(v0, [i0, i1]);
1237         assert_eq!(v1, [i2, i3]);
1238     }
1239 
1240     #[test]
1241     fn split_block() {
1242         let mut layout = Layout::new();
1243 
1244         let e0 = Block::new(0);
1245         let e1 = Block::new(1);
1246         let e2 = Block::new(2);
1247 
1248         let i0 = Inst::new(0);
1249         let i1 = Inst::new(1);
1250         let i2 = Inst::new(2);
1251         let i3 = Inst::new(3);
1252 
1253         layout.append_block(e0);
1254         layout.append_inst(i0, e0);
1255         assert_eq!(layout.inst_block(i0), Some(e0));
1256         layout.split_block(e1, i0);
1257         assert_eq!(layout.inst_block(i0), Some(e1));
1258 
1259         {
1260             let mut cur = LayoutCursor::new(&mut layout);
1261             assert_eq!(cur.next_block(), Some(e0));
1262             assert_eq!(cur.next_inst(), None);
1263             assert_eq!(cur.next_block(), Some(e1));
1264             assert_eq!(cur.next_inst(), Some(i0));
1265             assert_eq!(cur.next_inst(), None);
1266             assert_eq!(cur.next_block(), None);
1267 
1268             // Check backwards links.
1269             assert_eq!(cur.prev_block(), Some(e1));
1270             assert_eq!(cur.prev_inst(), Some(i0));
1271             assert_eq!(cur.prev_inst(), None);
1272             assert_eq!(cur.prev_block(), Some(e0));
1273             assert_eq!(cur.prev_inst(), None);
1274             assert_eq!(cur.prev_block(), None);
1275         }
1276 
1277         layout.append_inst(i1, e0);
1278         layout.append_inst(i2, e0);
1279         layout.append_inst(i3, e0);
1280         layout.split_block(e2, i2);
1281 
1282         assert_eq!(layout.inst_block(i0), Some(e1));
1283         assert_eq!(layout.inst_block(i1), Some(e0));
1284         assert_eq!(layout.inst_block(i2), Some(e2));
1285         assert_eq!(layout.inst_block(i3), Some(e2));
1286 
1287         {
1288             let mut cur = LayoutCursor::new(&mut layout);
1289             assert_eq!(cur.next_block(), Some(e0));
1290             assert_eq!(cur.next_inst(), Some(i1));
1291             assert_eq!(cur.next_inst(), None);
1292             assert_eq!(cur.next_block(), Some(e2));
1293             assert_eq!(cur.next_inst(), Some(i2));
1294             assert_eq!(cur.next_inst(), Some(i3));
1295             assert_eq!(cur.next_inst(), None);
1296             assert_eq!(cur.next_block(), Some(e1));
1297             assert_eq!(cur.next_inst(), Some(i0));
1298             assert_eq!(cur.next_inst(), None);
1299             assert_eq!(cur.next_block(), None);
1300 
1301             assert_eq!(cur.prev_block(), Some(e1));
1302             assert_eq!(cur.prev_inst(), Some(i0));
1303             assert_eq!(cur.prev_inst(), None);
1304             assert_eq!(cur.prev_block(), Some(e2));
1305             assert_eq!(cur.prev_inst(), Some(i3));
1306             assert_eq!(cur.prev_inst(), Some(i2));
1307             assert_eq!(cur.prev_inst(), None);
1308             assert_eq!(cur.prev_block(), Some(e0));
1309             assert_eq!(cur.prev_inst(), Some(i1));
1310             assert_eq!(cur.prev_inst(), None);
1311             assert_eq!(cur.prev_block(), None);
1312         }
1313 
1314         // Check `ProgramOrder`.
1315         assert_eq!(layout.cmp(e2, e2), Ordering::Equal);
1316         assert_eq!(layout.cmp(e2, i2), Ordering::Less);
1317         assert_eq!(layout.cmp(i3, i2), Ordering::Greater);
1318 
1319         assert_eq!(layout.is_block_gap(i1, e2), true);
1320         assert_eq!(layout.is_block_gap(i3, e1), true);
1321         assert_eq!(layout.is_block_gap(i1, e1), false);
1322         assert_eq!(layout.is_block_gap(i2, e1), false);
1323     }
1324 }
1325