Add a compilation pass timing facility.

Individual compilation passes call the corresponding timing::*()
function and hold on to their timing token while they run. This causes
nested per-pass timing information to be recorded in thread-local
storage.

The --time-passes command line option prints a pass timing report to
stdout.
This commit is contained in:
Jakob Stoklund Olesen
2017-12-06 10:56:17 -08:00
parent feaea238bc
commit 60c456c1ec
29 changed files with 305 additions and 12 deletions

View File

@@ -18,6 +18,7 @@ use std::cmp::Ordering;
use std::iter::Peekable;
use std::mem;
use isa::{TargetIsa, EncInfo};
use timing;
/// Dominator forest.
///
@@ -282,6 +283,7 @@ impl Coalescing {
liveness: &mut Liveness,
virtregs: &mut VirtRegs,
) {
let _tt = timing::ra_cssa();
dbg!("Coalescing for:\n{}", func.display(isa));
let mut context = Context {
isa,

View File

@@ -57,6 +57,7 @@ use regalloc::liveness::Liveness;
use regalloc::liverange::{LiveRange, LiveRangeContext};
use regalloc::solver::{Solver, SolverError};
use std::mem;
use timing;
/// Data structures for the coloring pass.
@@ -123,6 +124,7 @@ impl Coloring {
liveness: &mut Liveness,
tracker: &mut LiveValueTracker,
) {
let _tt = timing::ra_coloring();
dbg!("Coloring for:\n{}", func.display(isa));
let mut ctx = Context {
usable_regs: isa.allocatable_registers(func),

View File

@@ -16,6 +16,7 @@ use regalloc::reload::Reload;
use regalloc::spilling::Spilling;
use regalloc::virtregs::VirtRegs;
use result::CtonResult;
use timing;
use topo_order::TopoOrder;
use verifier::{verify_context, verify_liveness, verify_cssa, verify_locations};
@@ -72,6 +73,7 @@ impl Context {
cfg: &ControlFlowGraph,
domtree: &mut DominatorTree,
) -> CtonResult {
let _tt = timing::regalloc();
debug_assert!(domtree.is_valid());
// `Liveness` and `Coloring` are self-clearing.

View File

@@ -184,6 +184,7 @@ use regalloc::affinity::Affinity;
use regalloc::liverange::{LiveRange, LiveRangeForest, LiveRangeContext};
use std::mem;
use std::ops::Index;
use timing;
/// A set of live ranges, indexed by value number.
type LiveRangeSet = SparseMap<Value, LiveRange>;
@@ -385,6 +386,7 @@ impl Liveness {
/// Compute the live ranges of all SSA values used in `func`.
/// This clears out any existing analysis stored in this data structure.
pub fn compute(&mut self, isa: &TargetIsa, func: &mut Function, cfg: &ControlFlowGraph) {
let _tt = timing::ra_liveness();
self.ranges.clear();
// Get ISA data structures used for computing live range affinities.

View File

@@ -19,6 +19,7 @@ use isa::{TargetIsa, Encoding, EncInfo, RecipeConstraints, ConstraintKind};
use regalloc::affinity::Affinity;
use regalloc::live_value_tracker::{LiveValue, LiveValueTracker};
use regalloc::liveness::Liveness;
use timing;
use topo_order::TopoOrder;
/// Reusable data structures for the reload pass.
@@ -69,6 +70,7 @@ impl Reload {
topo: &mut TopoOrder,
tracker: &mut LiveValueTracker,
) {
let _tt = timing::ra_reload();
dbg!("Reload for:\n{}", func.display(isa));
let mut ctx = Context {
cur: EncCursor::new(func, isa),

View File

@@ -26,6 +26,7 @@ use regalloc::liveness::Liveness;
use regalloc::pressure::Pressure;
use regalloc::virtregs::VirtRegs;
use std::fmt;
use timing;
use topo_order::TopoOrder;
/// Persistent data structures for the spilling pass.
@@ -87,6 +88,7 @@ impl Spilling {
topo: &mut TopoOrder,
tracker: &mut LiveValueTracker,
) {
let _tt = timing::ra_spilling();
dbg!("Spilling for:\n{}", func.display(isa));
let reginfo = isa.register_info();
let usable_regs = isa.allocatable_registers(func);