A trait defined by the register allocator client to provide access to its machine-instruction / CFG representation. See the [module-level documentation] for more details. [module-level documentation]: self (This trait's design is inspired by, and derives heavily from, the trait of the same name in regalloc2.)
| 596 | // (This trait's design is inspired by, and derives heavily from, the |
| 597 | // trait of the same name in regalloc2.) |
| 598 | pub trait Function { |
| 599 | // ------------- |
| 600 | // CFG traversal |
| 601 | // ------------- |
| 602 | |
| 603 | /// How many instructions are there? |
| 604 | fn num_insts(&self) -> usize; |
| 605 | |
| 606 | /// Iterator over all the [`Inst`]s in this function. |
| 607 | #[inline] |
| 608 | fn insts(&self) -> Keys<Inst> { |
| 609 | Keys::with_len(self.num_insts()) |
| 610 | } |
| 611 | |
| 612 | /// How many blocks are there? |
| 613 | /// |
| 614 | /// All blocks must be reachable from at least one entry point. |
| 615 | fn num_blocks(&self) -> usize; |
| 616 | |
| 617 | /// Iterator over all the [`Block`]s in this function. |
| 618 | #[inline] |
| 619 | fn blocks(&self) -> Keys<Block> { |
| 620 | Keys::with_len(self.num_blocks()) |
| 621 | } |
| 622 | |
| 623 | /// Returns the entry points of the CFG. |
| 624 | /// |
| 625 | /// This list must be non-empty and contain no duplicates. Entry points |
| 626 | /// must have no predecessors and no block parameters. |
| 627 | fn entry_points(&self) -> &[Block]; |
| 628 | |
| 629 | /// Provide the range of instruction indices contained in each block. |
| 630 | fn block_insts(&self, block: Block) -> InstRange; |
| 631 | |
| 632 | /// Returns the block containing the given instruction. |
| 633 | fn inst_block(&self, inst: Inst) -> Block; |
| 634 | |
| 635 | /// Get CFG successors for a given block. |
| 636 | fn block_succs(&self, block: Block) -> &[Block]; |
| 637 | |
| 638 | /// Get the CFG predecessors for a given block. |
| 639 | fn block_preds(&self, block: Block) -> &[Block]; |
| 640 | |
| 641 | /// Returns the immediate dominator of the given block. |
| 642 | /// |
| 643 | /// This returns `None` for entry points and for blocks whose only common |
| 644 | /// dominator would be the virtual root of a multi-entry CFG. |
| 645 | fn block_immediate_dominator(&self, block: Block) -> Option<Block>; |
| 646 | |
| 647 | /// Returns whether block `a` dominates block `b`. |
| 648 | /// |
| 649 | /// This should return true if `a == b`. |
| 650 | fn block_dominates(&self, a: Block, mut b: Block) -> bool { |
| 651 | // Walk b up the dominator tree until a is reached or we go past it. |
| 652 | // This works because the block ordering is required to be topologically |
| 653 | // ordered with regards to the dominator tree. |
| 654 | while a < b { |
| 655 | match self.block_immediate_dominator(b) { |
no outgoing calls
no test coverage detected