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