Skip to content

Commit

Permalink
Auto merge of #67397 - michaelwoerister:query-keys-in-self-profiling,…
Browse files Browse the repository at this point in the history
… r=wesleywiser

self-profiling: Support recording query keys

This PR makes self-profiling able to record query keys. The implementation is not as efficient as it could be yet (all query keys except for `DefId`s cause string data to be duplicated) and the rendered strings could be nicer too. But the implementation is functional and introduces the basic framework for emitting per-query-invocation event data.

I tried to add proper documentation on how everything works. Let me know if more documentation is needed.

r? @wesleywiser

@Mark-Simulacrum, heads up: This updates `measureme` to 0.7.0 which means that `summarize` on perf.rlo needs to be update accordingly once this is merged.
  • Loading branch information
bors committed Jan 10, 2020
2 parents 2d8d559 + ad65e3e commit f795e8a
Show file tree
Hide file tree
Showing 11 changed files with 550 additions and 125 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1995,9 +1995,9 @@ dependencies = [

[[package]]
name = "measureme"
version = "0.5.0"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c420bbc064623934620b5ab2dc0cf96451b34163329e82f95e7fa1b7b99a6ac8"
checksum = "fef709d3257013bba7cff14fc504e07e80631d3fe0f6d38ce63b8f6510ccb932"
dependencies = [
"byteorder",
"memmap",
Expand Down Expand Up @@ -3079,6 +3079,7 @@ dependencies = [
"graphviz",
"jobserver",
"log",
"measureme",
"parking_lot",
"polonius-engine",
"rustc-rayon",
Expand Down
1 change: 1 addition & 0 deletions src/librustc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ parking_lot = "0.9"
byteorder = { version = "1.3" }
chalk-engine = { version = "0.9.0", default-features=false }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
measureme = "0.7.1"
rustc_error_codes = { path = "../librustc_error_codes" }
rustc_session = { path = "../librustc_session" }
36 changes: 28 additions & 8 deletions src/librustc/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::ty::{self, TyCtxt};
use errors::Diagnostic;
use parking_lot::{Condvar, Mutex};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::profiling::QueryInvocationId;
use rustc_data_structures::sharded::{self, Sharded};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering};
Expand All @@ -11,7 +12,7 @@ use std::collections::hash_map::Entry;
use std::env;
use std::hash::Hash;
use std::mem;
use std::sync::atomic::Ordering::SeqCst;
use std::sync::atomic::Ordering::Relaxed;

use crate::ich::{Fingerprint, StableHashingContext, StableHashingContextProvider};

Expand All @@ -25,6 +26,12 @@ use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
#[derive(Clone)]
pub struct DepGraph {
data: Option<Lrc<DepGraphData>>,

/// This field is used for assigning DepNodeIndices when running in
/// non-incremental mode. Even in non-incremental mode we make sure that
/// each task has a `DepNodeIndex` that uniquely identifies it. This unique
/// ID is used for self-profiling.
virtual_dep_node_index: Lrc<AtomicU32>,
}

rustc_index::newtype_index! {
Expand All @@ -35,6 +42,13 @@ impl DepNodeIndex {
pub const INVALID: DepNodeIndex = DepNodeIndex::MAX;
}

impl std::convert::From<DepNodeIndex> for QueryInvocationId {
#[inline]
fn from(dep_node_index: DepNodeIndex) -> Self {
QueryInvocationId(dep_node_index.as_u32())
}
}

#[derive(PartialEq)]
pub enum DepNodeColor {
Red,
Expand Down Expand Up @@ -105,11 +119,12 @@ impl DepGraph {
previous: prev_graph,
colors: DepNodeColorMap::new(prev_graph_node_count),
})),
virtual_dep_node_index: Lrc::new(AtomicU32::new(0)),
}
}

pub fn new_disabled() -> DepGraph {
DepGraph { data: None }
DepGraph { data: None, virtual_dep_node_index: Lrc::new(AtomicU32::new(0)) }
}

/// Returns `true` if we are actually building the full dep-graph, and `false` otherwise.
Expand Down Expand Up @@ -322,7 +337,7 @@ impl DepGraph {

(result, dep_node_index)
} else {
(task(cx, arg), DepNodeIndex::INVALID)
(task(cx, arg), self.next_virtual_depnode_index())
}
}

Expand Down Expand Up @@ -352,7 +367,7 @@ impl DepGraph {
let dep_node_index = data.current.complete_anon_task(dep_kind, task_deps);
(result, dep_node_index)
} else {
(op(), DepNodeIndex::INVALID)
(op(), self.next_virtual_depnode_index())
}
}

Expand Down Expand Up @@ -478,8 +493,8 @@ impl DepGraph {
let current_dep_graph = &self.data.as_ref().unwrap().current;

Some((
current_dep_graph.total_read_count.load(SeqCst),
current_dep_graph.total_duplicate_read_count.load(SeqCst),
current_dep_graph.total_read_count.load(Relaxed),
current_dep_graph.total_duplicate_read_count.load(Relaxed),
))
} else {
None
Expand Down Expand Up @@ -877,6 +892,11 @@ impl DepGraph {
}
}
}

fn next_virtual_depnode_index(&self) -> DepNodeIndex {
let index = self.virtual_dep_node_index.fetch_add(1, Relaxed);
DepNodeIndex::from_u32(index)
}
}

/// A "work product" is an intermediate result that we save into the
Expand Down Expand Up @@ -1087,7 +1107,7 @@ impl DepGraphData {
if let Some(task_deps) = icx.task_deps {
let mut task_deps = task_deps.lock();
if cfg!(debug_assertions) {
self.current.total_read_count.fetch_add(1, SeqCst);
self.current.total_read_count.fetch_add(1, Relaxed);
}
if task_deps.read_set.insert(source) {
task_deps.reads.push(source);
Expand All @@ -1105,7 +1125,7 @@ impl DepGraphData {
}
}
} else if cfg!(debug_assertions) {
self.current.total_duplicate_read_count.fetch_add(1, SeqCst);
self.current.total_duplicate_read_count.fetch_add(1, Relaxed);
}
}
})
Expand Down
5 changes: 2 additions & 3 deletions src/librustc/ty/query/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use crate::dep_graph::SerializedDepNodeIndex;
use crate::dep_graph::{DepKind, DepNode};
use crate::ty::query::plumbing::CycleError;
use crate::ty::query::queries;
use crate::ty::query::QueryCache;
use crate::ty::query::{Query, QueryName};
use crate::ty::query::{Query, QueryCache};
use crate::ty::TyCtxt;
use rustc_data_structures::profiling::ProfileCategory;
use rustc_hir::def_id::{CrateNum, DefId};
Expand All @@ -20,7 +19,7 @@ use std::hash::Hash;
// FIXME(eddyb) false positive, the lifetime parameter is used for `Key`/`Value`.
#[allow(unused_lifetimes)]
pub trait QueryConfig<'tcx> {
const NAME: QueryName;
const NAME: &'static str;
const CATEGORY: ProfileCategory;

type Key: Eq + Hash + Clone + Debug;
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/ty/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ pub(crate) use self::config::QueryDescription;
mod on_disk_cache;
pub use self::on_disk_cache::OnDiskCache;

mod profiling_support;
pub use self::profiling_support::{IntoSelfProfilingString, QueryKeyStringBuilder};

// Each of these queries corresponds to a function pointer field in the
// `Providers` struct for requesting a value of that type, and a method
// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
Expand Down
Loading

0 comments on commit f795e8a

Please sign in to comment.