/src/regalloc2/src/postorder.rs
Line | Count | Source |
1 | | /* |
2 | | * Released under the terms of the Apache 2.0 license with LLVM |
3 | | * exception. See `LICENSE` for details. |
4 | | */ |
5 | | |
6 | | //! Fast postorder computation. |
7 | | |
8 | | use crate::{Block, RegAllocError, VecExt}; |
9 | | use alloc::vec::Vec; |
10 | | use smallvec::{smallvec, SmallVec}; |
11 | | |
12 | 22.9k | pub fn calculate<'a, SuccFn: Fn(Block) -> &'a [Block]>( |
13 | 22.9k | num_blocks: usize, |
14 | 22.9k | entry: Block, |
15 | 22.9k | visited_scratch: &mut Vec<bool>, |
16 | 22.9k | out: &mut Vec<Block>, |
17 | 22.9k | succ_blocks: SuccFn, |
18 | 22.9k | ) -> Result<(), RegAllocError> { |
19 | | // State: visited-block map, and explicit DFS stack. |
20 | | struct State<'a> { |
21 | | block: Block, |
22 | | succs: core::slice::Iter<'a, Block>, |
23 | | } |
24 | | |
25 | 22.9k | let visited = visited_scratch.repopulate(num_blocks, false); |
26 | 22.9k | let mut stack: SmallVec<[State; 64]> = smallvec![]; |
27 | 22.9k | out.clear(); |
28 | | |
29 | 22.9k | let entry_visit = visited |
30 | 22.9k | .get_mut(entry.index()) |
31 | 22.9k | .ok_or(RegAllocError::BB(entry))?; |
32 | 22.9k | *entry_visit = true; |
33 | 22.9k | stack.push(State { |
34 | 22.9k | block: entry, |
35 | 22.9k | succs: succ_blocks(entry).iter(), |
36 | 22.9k | }); |
37 | | |
38 | 2.25M | while let Some(ref mut state) = stack.last_mut() { |
39 | | // Perform one action: push to new succ, skip an already-visited succ, or pop. |
40 | 2.23M | if let Some(&succ) = state.succs.next() { |
41 | 1.23M | let succ_visit = visited |
42 | 1.23M | .get_mut(succ.index()) |
43 | 1.23M | .ok_or(RegAllocError::BB(succ))?; |
44 | 1.23M | if !*succ_visit { |
45 | 979k | *succ_visit = true; |
46 | 979k | stack.push(State { |
47 | 979k | block: succ, |
48 | 979k | succs: succ_blocks(succ).iter(), |
49 | 979k | }); |
50 | 979k | } |
51 | 1.00M | } else { |
52 | 1.00M | out.push(state.block); |
53 | 1.00M | stack.pop(); |
54 | 1.00M | } |
55 | | } |
56 | 22.9k | Ok(()) |
57 | 22.9k | } regalloc2::postorder::calculate::<<regalloc2::cfg::CFGInfo>::init<regalloc2::fuzzing::func::Func>::{closure#0}>Line | Count | Source | 12 | 11.4k | pub fn calculate<'a, SuccFn: Fn(Block) -> &'a [Block]>( | 13 | 11.4k | num_blocks: usize, | 14 | 11.4k | entry: Block, | 15 | 11.4k | visited_scratch: &mut Vec<bool>, | 16 | 11.4k | out: &mut Vec<Block>, | 17 | 11.4k | succ_blocks: SuccFn, | 18 | 11.4k | ) -> Result<(), RegAllocError> { | 19 | | // State: visited-block map, and explicit DFS stack. | 20 | | struct State<'a> { | 21 | | block: Block, | 22 | | succs: core::slice::Iter<'a, Block>, | 23 | | } | 24 | | | 25 | 11.4k | let visited = visited_scratch.repopulate(num_blocks, false); | 26 | 11.4k | let mut stack: SmallVec<[State; 64]> = smallvec![]; | 27 | 11.4k | out.clear(); | 28 | | | 29 | 11.4k | let entry_visit = visited | 30 | 11.4k | .get_mut(entry.index()) | 31 | 11.4k | .ok_or(RegAllocError::BB(entry))?; | 32 | 11.4k | *entry_visit = true; | 33 | 11.4k | stack.push(State { | 34 | 11.4k | block: entry, | 35 | 11.4k | succs: succ_blocks(entry).iter(), | 36 | 11.4k | }); | 37 | | | 38 | 1.12M | while let Some(ref mut state) = stack.last_mut() { | 39 | | // Perform one action: push to new succ, skip an already-visited succ, or pop. | 40 | 1.11M | if let Some(&succ) = state.succs.next() { | 41 | 615k | let succ_visit = visited | 42 | 615k | .get_mut(succ.index()) | 43 | 615k | .ok_or(RegAllocError::BB(succ))?; | 44 | 615k | if !*succ_visit { | 45 | 489k | *succ_visit = true; | 46 | 489k | stack.push(State { | 47 | 489k | block: succ, | 48 | 489k | succs: succ_blocks(succ).iter(), | 49 | 489k | }); | 50 | 489k | } | 51 | 500k | } else { | 52 | 500k | out.push(state.block); | 53 | 500k | stack.pop(); | 54 | 500k | } | 55 | | } | 56 | 11.4k | Ok(()) | 57 | 11.4k | } |
regalloc2::postorder::calculate::<<regalloc2::fuzzing::func::FuncBuilder>::compute_doms::{closure#0}>Line | Count | Source | 12 | 11.4k | pub fn calculate<'a, SuccFn: Fn(Block) -> &'a [Block]>( | 13 | 11.4k | num_blocks: usize, | 14 | 11.4k | entry: Block, | 15 | 11.4k | visited_scratch: &mut Vec<bool>, | 16 | 11.4k | out: &mut Vec<Block>, | 17 | 11.4k | succ_blocks: SuccFn, | 18 | 11.4k | ) -> Result<(), RegAllocError> { | 19 | | // State: visited-block map, and explicit DFS stack. | 20 | | struct State<'a> { | 21 | | block: Block, | 22 | | succs: core::slice::Iter<'a, Block>, | 23 | | } | 24 | | | 25 | 11.4k | let visited = visited_scratch.repopulate(num_blocks, false); | 26 | 11.4k | let mut stack: SmallVec<[State; 64]> = smallvec![]; | 27 | 11.4k | out.clear(); | 28 | | | 29 | 11.4k | let entry_visit = visited | 30 | 11.4k | .get_mut(entry.index()) | 31 | 11.4k | .ok_or(RegAllocError::BB(entry))?; | 32 | 11.4k | *entry_visit = true; | 33 | 11.4k | stack.push(State { | 34 | 11.4k | block: entry, | 35 | 11.4k | succs: succ_blocks(entry).iter(), | 36 | 11.4k | }); | 37 | | | 38 | 1.12M | while let Some(ref mut state) = stack.last_mut() { | 39 | | // Perform one action: push to new succ, skip an already-visited succ, or pop. | 40 | 1.11M | if let Some(&succ) = state.succs.next() { | 41 | 616k | let succ_visit = visited | 42 | 616k | .get_mut(succ.index()) | 43 | 616k | .ok_or(RegAllocError::BB(succ))?; | 44 | 616k | if !*succ_visit { | 45 | 490k | *succ_visit = true; | 46 | 490k | stack.push(State { | 47 | 490k | block: succ, | 48 | 490k | succs: succ_blocks(succ).iter(), | 49 | 490k | }); | 50 | 490k | } | 51 | 501k | } else { | 52 | 501k | out.push(state.block); | 53 | 501k | stack.pop(); | 54 | 501k | } | 55 | | } | 56 | 11.4k | Ok(()) | 57 | 11.4k | } |
Unexecuted instantiation: regalloc2::postorder::calculate::<regalloc2::fuzzing::domtree::check::{closure#0}> |