use crate::pipeline::PassKind;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct PassStats {
kind: PassKind,
runs: u64,
changes: u64,
}
impl PassStats {
#[must_use]
pub const fn kind(&self) -> PassKind {
self.kind
}
#[must_use]
pub const fn runs(&self) -> u64 {
self.runs
}
#[must_use]
pub const fn changes(&self) -> u64 {
self.changes
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Stats {
pub(crate) functions: usize,
pub(crate) insts_before: usize,
pub(crate) insts_after: usize,
pub(crate) blocks_before: usize,
pub(crate) blocks_after: usize,
pub(crate) iterations: usize,
pub(crate) converged: usize,
pub(crate) budget_exhausted: usize,
pub(crate) passes: [PassStats; PassKind::ALL.len()],
}
impl Default for Stats {
fn default() -> Self {
let mut passes = [PassStats {
kind: PassKind::Dce,
runs: 0,
changes: 0,
}; PassKind::ALL.len()];
for (slot, kind) in passes.iter_mut().zip(PassKind::ALL) {
slot.kind = kind;
}
Stats {
functions: 0,
insts_before: 0,
insts_after: 0,
blocks_before: 0,
blocks_after: 0,
iterations: 0,
converged: 0,
budget_exhausted: 0,
passes,
}
}
}
impl Stats {
pub(crate) fn record(&mut self, kind: PassKind, changed: bool) {
if let Some(p) = self.passes.iter_mut().find(|p| p.kind == kind) {
p.runs += 1;
p.changes += u64::from(changed);
}
}
pub(crate) fn merge(&mut self, other: &Stats) {
self.functions += other.functions;
self.insts_before += other.insts_before;
self.insts_after += other.insts_after;
self.blocks_before += other.blocks_before;
self.blocks_after += other.blocks_after;
self.iterations += other.iterations;
self.converged += other.converged;
self.budget_exhausted += other.budget_exhausted;
for (a, b) in self.passes.iter_mut().zip(other.passes.iter()) {
a.runs += b.runs;
a.changes += b.changes;
}
}
#[must_use]
pub const fn functions(&self) -> usize {
self.functions
}
#[must_use]
pub const fn insts_before(&self) -> usize {
self.insts_before
}
#[must_use]
pub const fn insts_after(&self) -> usize {
self.insts_after
}
#[must_use]
pub const fn blocks_before(&self) -> usize {
self.blocks_before
}
#[must_use]
pub const fn blocks_after(&self) -> usize {
self.blocks_after
}
#[must_use]
pub const fn iterations(&self) -> usize {
self.iterations
}
#[must_use]
pub const fn converged(&self) -> usize {
self.converged
}
#[must_use]
pub const fn budget_exhausted(&self) -> usize {
self.budget_exhausted
}
#[must_use]
pub fn pass(&self, kind: PassKind) -> PassStats {
self.passes
.iter()
.copied()
.find(|p| p.kind == kind)
.unwrap_or(PassStats {
kind,
runs: 0,
changes: 0,
})
}
#[must_use]
pub fn passes(&self) -> &[PassStats] {
&self.passes
}
}