Skip to content

Commit fbe42f6

Browse files
committed
Auto merge of #67397 - michaelwoerister:query-keys-in-self-profiling, r=<try>
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.
2 parents c605199 + ff5a81d commit fbe42f6

File tree

11 files changed

+584
-119
lines changed

11 files changed

+584
-119
lines changed

Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -2021,9 +2021,9 @@ dependencies = [
20212021

20222022
[[package]]
20232023
name = "measureme"
2024-
version = "0.5.0"
2024+
version = "0.7.0"
20252025
source = "registry+https://github.com/rust-lang/crates.io-index"
2026-
checksum = "c420bbc064623934620b5ab2dc0cf96451b34163329e82f95e7fa1b7b99a6ac8"
2026+
checksum = "ebefdcb02b2ddeee50178a218aeaf6d752d0777cd07914542f202cb7440e6e38"
20272027
dependencies = [
20282028
"byteorder",
20292029
"memmap",

src/librustc/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,6 @@ byteorder = { version = "1.3" }
3737
chalk-engine = { version = "0.9.0", default-features=false }
3838
rustc_fs_util = { path = "../librustc_fs_util" }
3939
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
40-
measureme = "0.5"
40+
measureme = "0.7.0"
4141
rustc_error_codes = { path = "../librustc_error_codes" }
4242
rustc_session = { path = "../librustc_session" }

src/librustc/dep_graph/graph.rs

+28-7
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
33
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
44
use rustc_index::vec::{Idx, IndexVec};
55
use smallvec::SmallVec;
6+
use rustc_data_structures::profiling::QueryInvocationId;
67
use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, AtomicU64, Ordering};
78
use rustc_data_structures::sharded::{self, Sharded};
8-
use std::sync::atomic::Ordering::SeqCst;
9+
use std::sync::atomic::Ordering::Relaxed;
910
use std::env;
1011
use std::hash::Hash;
1112
use std::collections::hash_map::Entry;
@@ -25,6 +26,12 @@ use super::prev::PreviousDepGraph;
2526
#[derive(Clone)]
2627
pub struct DepGraph {
2728
data: Option<Lrc<DepGraphData>>,
29+
30+
/// This field is used for assigning DepNodeIndices when running in
31+
/// non-incremental mode. Even in non-incremental mode we make sure that
32+
/// each task has a `DepNodeIndex` that uniquely identifies it. This unique
33+
/// ID is used for self-profiling.
34+
virtual_dep_node_index: Lrc<AtomicU32>,
2835
}
2936

3037
rustc_index::newtype_index! {
@@ -35,6 +42,13 @@ impl DepNodeIndex {
3542
pub const INVALID: DepNodeIndex = DepNodeIndex::MAX;
3643
}
3744

45+
impl std::convert::From<DepNodeIndex> for QueryInvocationId {
46+
#[inline]
47+
fn from(dep_node_index: DepNodeIndex) -> Self {
48+
QueryInvocationId(dep_node_index.as_u32())
49+
}
50+
}
51+
3852
#[derive(PartialEq)]
3953
pub enum DepNodeColor {
4054
Red,
@@ -103,12 +117,14 @@ impl DepGraph {
103117
previous: prev_graph,
104118
colors: DepNodeColorMap::new(prev_graph_node_count),
105119
})),
120+
virtual_dep_node_index: Lrc::new(AtomicU32::new(0)),
106121
}
107122
}
108123

109124
pub fn new_disabled() -> DepGraph {
110125
DepGraph {
111126
data: None,
127+
virtual_dep_node_index: Lrc::new(AtomicU32::new(0)),
112128
}
113129
}
114130

@@ -319,7 +335,7 @@ impl DepGraph {
319335

320336
(result, dep_node_index)
321337
} else {
322-
(task(cx, arg), DepNodeIndex::INVALID)
338+
(task(cx, arg), self.next_virtual_depnode_index())
323339
}
324340
}
325341

@@ -354,7 +370,7 @@ impl DepGraph {
354370
.complete_anon_task(dep_kind, task_deps);
355371
(result, dep_node_index)
356372
} else {
357-
(op(), DepNodeIndex::INVALID)
373+
(op(), self.next_virtual_depnode_index())
358374
}
359375
}
360376

@@ -485,8 +501,8 @@ impl DepGraph {
485501
if cfg!(debug_assertions) {
486502
let current_dep_graph = &self.data.as_ref().unwrap().current;
487503

488-
Some((current_dep_graph.total_read_count.load(SeqCst),
489-
current_dep_graph.total_duplicate_read_count.load(SeqCst)))
504+
Some((current_dep_graph.total_read_count.load(Relaxed),
505+
current_dep_graph.total_duplicate_read_count.load(Relaxed)))
490506
} else {
491507
None
492508
}
@@ -877,6 +893,11 @@ impl DepGraph {
877893
}
878894
}
879895
}
896+
897+
fn next_virtual_depnode_index(&self) -> DepNodeIndex {
898+
let index = self.virtual_dep_node_index.fetch_add(1, Relaxed);
899+
DepNodeIndex::from_u32(index)
900+
}
880901
}
881902

882903
/// A "work product" is an intermediate result that we save into the
@@ -1093,7 +1114,7 @@ impl DepGraphData {
10931114
if let Some(task_deps) = icx.task_deps {
10941115
let mut task_deps = task_deps.lock();
10951116
if cfg!(debug_assertions) {
1096-
self.current.total_read_count.fetch_add(1, SeqCst);
1117+
self.current.total_read_count.fetch_add(1, Relaxed);
10971118
}
10981119
if task_deps.read_set.insert(source) {
10991120
task_deps.reads.push(source);
@@ -1113,7 +1134,7 @@ impl DepGraphData {
11131134
}
11141135
}
11151136
} else if cfg!(debug_assertions) {
1116-
self.current.total_duplicate_read_count.fetch_add(1, SeqCst);
1137+
self.current.total_duplicate_read_count.fetch_add(1, Relaxed);
11171138
}
11181139
}
11191140
})

src/librustc/ty/query/config.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::dep_graph::{DepKind, DepNode};
33
use crate::hir::def_id::{CrateNum, DefId};
44
use crate::ty::TyCtxt;
55
use crate::ty::query::queries;
6-
use crate::ty::query::{Query, QueryName};
6+
use crate::ty::query::{Query};
77
use crate::ty::query::QueryCache;
88
use crate::ty::query::plumbing::CycleError;
99
use rustc_data_structures::profiling::ProfileCategory;
@@ -20,7 +20,7 @@ use crate::ich::StableHashingContext;
2020
// FIXME(eddyb) false positive, the lifetime parameter is used for `Key`/`Value`.
2121
#[allow(unused_lifetimes)]
2222
pub trait QueryConfig<'tcx> {
23-
const NAME: QueryName;
23+
const NAME: &'static str;
2424
const CATEGORY: ProfileCategory;
2525

2626
type Key: Eq + Hash + Clone + Debug;

src/librustc/ty/query/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ use self::config::QueryAccessors;
8282
mod on_disk_cache;
8383
pub use self::on_disk_cache::OnDiskCache;
8484

85+
mod profiling_support;
86+
pub use self::profiling_support::{IntoSelfProfilingString, QueryKeyStringBuilder};
87+
8588
// Each of these queries corresponds to a function pointer field in the
8689
// `Providers` struct for requesting a value of that type, and a method
8790
// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way

0 commit comments

Comments
 (0)