mirror of https://github.com/rust-lang/rust.git
Auto merge of #122227 - Zoxc:query-hash-verify, r=michaelwoerister
Verify that query keys result in unique dep nodes This implements checking that query keys result into unique dep nodes as mentioned in https://github.com/rust-lang/rust/pull/112469. We could do a perf check to see how expensive this is. r? `@michaelwoerister`
This commit is contained in:
commit
d3555f3d8e
|
@ -321,6 +321,8 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.sess.time("serialize_dep_graph", || gcx.enter(rustc_incremental::save_dep_graph));
|
self.sess.time("serialize_dep_graph", || gcx.enter(rustc_incremental::save_dep_graph));
|
||||||
|
|
||||||
|
gcx.enter(rustc_query_impl::query_key_hash_verify_all);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The timer's lifetime spans the dropping of `queries`, which contains
|
// The timer's lifetime spans the dropping of `queries`, which contains
|
||||||
|
|
|
@ -41,7 +41,7 @@ use rustc_span::{ErrorGuaranteed, Span};
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod plumbing;
|
mod plumbing;
|
||||||
pub use crate::plumbing::QueryCtxt;
|
pub use crate::plumbing::{query_key_hash_verify_all, QueryCtxt};
|
||||||
|
|
||||||
mod profiling_support;
|
mod profiling_support;
|
||||||
pub use self::profiling_support::alloc_self_profile_query_strings;
|
pub use self::profiling_support::alloc_self_profile_query_strings;
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::rustc_middle::ty::TyEncoder;
|
||||||
use crate::QueryConfigRestored;
|
use crate::QueryConfigRestored;
|
||||||
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
|
||||||
use rustc_data_structures::sync::Lock;
|
use rustc_data_structures::sync::Lock;
|
||||||
|
use rustc_data_structures::unord::UnordMap;
|
||||||
use rustc_errors::DiagInner;
|
use rustc_errors::DiagInner;
|
||||||
|
|
||||||
use rustc_index::Idx;
|
use rustc_index::Idx;
|
||||||
|
@ -189,6 +190,16 @@ pub(super) fn encode_all_query_results<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn query_key_hash_verify_all<'tcx>(tcx: TyCtxt<'tcx>) {
|
||||||
|
if tcx.sess().opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions) {
|
||||||
|
tcx.sess.time("query_key_hash_verify_all", || {
|
||||||
|
for verify in super::QUERY_KEY_HASH_VERIFY.iter() {
|
||||||
|
verify(tcx);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! handle_cycle_error {
|
macro_rules! handle_cycle_error {
|
||||||
([]) => {{
|
([]) => {{
|
||||||
rustc_query_system::HandleCycleError::Error
|
rustc_query_system::HandleCycleError::Error
|
||||||
|
@ -370,6 +381,34 @@ pub(crate) fn encode_query_results<'a, 'tcx, Q>(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn query_key_hash_verify<'tcx>(
|
||||||
|
query: impl QueryConfig<QueryCtxt<'tcx>>,
|
||||||
|
qcx: QueryCtxt<'tcx>,
|
||||||
|
) {
|
||||||
|
let _timer =
|
||||||
|
qcx.profiler().generic_activity_with_arg("query_key_hash_verify_for", query.name());
|
||||||
|
|
||||||
|
let mut map = UnordMap::default();
|
||||||
|
|
||||||
|
let cache = query.query_cache(qcx);
|
||||||
|
cache.iter(&mut |key, _, _| {
|
||||||
|
let node = DepNode::construct(qcx.tcx, query.dep_kind(), key);
|
||||||
|
if let Some(other_key) = map.insert(node, *key) {
|
||||||
|
bug!(
|
||||||
|
"query key:\n\
|
||||||
|
`{:?}`\n\
|
||||||
|
and key:\n\
|
||||||
|
`{:?}`\n\
|
||||||
|
mapped to the same dep node:\n\
|
||||||
|
{:?}",
|
||||||
|
key,
|
||||||
|
other_key,
|
||||||
|
node
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn try_load_from_on_disk_cache<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode)
|
fn try_load_from_on_disk_cache<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode)
|
||||||
where
|
where
|
||||||
Q: QueryConfig<QueryCtxt<'tcx>>,
|
Q: QueryConfig<QueryCtxt<'tcx>>,
|
||||||
|
@ -691,6 +730,13 @@ macro_rules! define_queries {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
pub fn query_key_hash_verify<'tcx>(tcx: TyCtxt<'tcx>) {
|
||||||
|
$crate::plumbing::query_key_hash_verify(
|
||||||
|
query_impl::$name::QueryType::config(tcx),
|
||||||
|
QueryCtxt::new(tcx),
|
||||||
|
)
|
||||||
|
}
|
||||||
})*}
|
})*}
|
||||||
|
|
||||||
pub(crate) fn engine(incremental: bool) -> QueryEngine {
|
pub(crate) fn engine(incremental: bool) -> QueryEngine {
|
||||||
|
@ -730,6 +776,10 @@ macro_rules! define_queries {
|
||||||
>
|
>
|
||||||
] = &[$(expand_if_cached!([$($modifiers)*], query_impl::$name::encode_query_results)),*];
|
] = &[$(expand_if_cached!([$($modifiers)*], query_impl::$name::encode_query_results)),*];
|
||||||
|
|
||||||
|
const QUERY_KEY_HASH_VERIFY: &[
|
||||||
|
for<'tcx> fn(TyCtxt<'tcx>)
|
||||||
|
] = &[$(query_impl::$name::query_key_hash_verify),*];
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
mod query_callbacks {
|
mod query_callbacks {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -1674,7 +1674,9 @@ options! {
|
||||||
"print high-level information about incremental reuse (or the lack thereof) \
|
"print high-level information about incremental reuse (or the lack thereof) \
|
||||||
(default: no)"),
|
(default: no)"),
|
||||||
incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED],
|
incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED],
|
||||||
"verify incr. comp. hashes of green query instances (default: no)"),
|
"verify extended properties for incr. comp. (default: no):
|
||||||
|
- hashes of green query instances
|
||||||
|
- hash collisions of query keys"),
|
||||||
inline_in_all_cgus: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
inline_in_all_cgus: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||||
"control whether `#[inline]` functions are in all CGUs"),
|
"control whether `#[inline]` functions are in all CGUs"),
|
||||||
inline_llvm: bool = (true, parse_bool, [TRACKED],
|
inline_llvm: bool = (true, parse_bool, [TRACKED],
|
||||||
|
|
Loading…
Reference in New Issue