-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathstats.rs
More file actions
72 lines (65 loc) · 2.42 KB
/
Copy pathstats.rs
File metadata and controls
72 lines (65 loc) · 2.42 KB
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//! Post-specialization stats.
use fxhash::FxHashSet;
use waffle::{Block, Func, FunctionBody};
/// Stats per original/generic function.
#[derive(Clone, Debug, Default)]
pub(crate) struct SpecializationStats {
// --- stats computed once, for the generic function.
pub generic: Func,
pub generic_blocks: usize,
pub generic_insts: usize,
// --- stats accumulated over specializations:
pub specializations: usize,
pub specialized_blocks: usize,
pub specialized_insts: usize,
pub virtstack_reads: usize,
pub virtstack_writes: usize,
pub virtstack_reads_mem: usize,
pub virtstack_writes_mem: usize,
pub local_reads: usize,
pub local_writes: usize,
pub local_reads_mem: usize,
pub local_writes_mem: usize,
pub live_value_at_block_start: usize,
}
impl SpecializationStats {
pub fn new(generic: Func, body: &FunctionBody) -> Self {
let mut ret = Self::default();
ret.generic = generic;
let (blocks, insts, _) = count_reachable_blocks_and_insts(body);
ret.generic_blocks = blocks;
ret.generic_insts = insts;
ret
}
pub(crate) fn add_specialization(&mut self, stats: &SpecializationStats) {
self.specializations += 1;
self.specialized_blocks += stats.specialized_blocks;
self.specialized_insts += stats.specialized_insts;
self.virtstack_reads += stats.virtstack_reads;
self.virtstack_reads_mem += stats.virtstack_reads_mem;
self.virtstack_writes += stats.virtstack_writes;
self.virtstack_writes_mem += stats.virtstack_writes_mem;
self.local_reads += stats.local_reads;
self.local_reads_mem += stats.local_reads_mem;
self.local_writes += stats.local_writes;
self.local_writes_mem += stats.local_writes_mem;
self.live_value_at_block_start += stats.live_value_at_block_start;
}
}
pub(crate) fn count_reachable_blocks_and_insts(
body: &FunctionBody,
) -> (usize, usize, FxHashSet<Block>) {
let mut queue = vec![body.entry];
let mut visited = queue.iter().cloned().collect::<FxHashSet<_>>();
let mut insts = 0;
while let Some(block) = queue.pop() {
let block_insts = body.blocks[block].insts.len();
insts += block_insts;
body.blocks[block].terminator.visit_successors(|succ| {
if visited.insert(succ) {
queue.push(succ);
}
});
}
(visited.len(), insts, visited)
}