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