1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use crate::Block;
use smallvec::{smallvec, SmallVec};
pub fn calculate<'a, SuccFn: Fn(Block) -> &'a [Block]>(
num_blocks: usize,
entry: Block,
succ_blocks: SuccFn,
) -> Vec<Block> {
let mut ret = vec![];
let mut visited = vec![];
visited.resize(num_blocks, false);
struct State<'a> {
block: Block,
succs: &'a [Block],
next_succ: usize,
}
let mut stack: SmallVec<[State; 64]> = smallvec![];
visited[entry.index()] = true;
stack.push(State {
block: entry,
succs: succ_blocks(entry),
next_succ: 0,
});
while let Some(ref mut state) = stack.last_mut() {
if state.next_succ < state.succs.len() {
let succ = state.succs[state.next_succ];
state.next_succ += 1;
if !visited[succ.index()] {
visited[succ.index()] = true;
stack.push(State {
block: succ,
succs: succ_blocks(succ),
next_succ: 0,
});
}
} else {
ret.push(state.block);
stack.pop();
}
}
ret
}