Move DepKind to rustc_query_system and define it as u16
This commit is contained in:
@@ -65,9 +65,9 @@ use rustc_hir::definitions::DefPathHash;
|
||||
use rustc_hir::{HirId, ItemLocalId, OwnerId};
|
||||
use rustc_query_system::dep_graph::FingerprintStyle;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use std::hash::Hash;
|
||||
|
||||
pub use rustc_query_system::dep_graph::{DepContext, DepNodeParams};
|
||||
pub use rustc_query_system::dep_graph::dep_node::DepKind;
|
||||
pub use rustc_query_system::dep_graph::{DepContext, DepNode, DepNodeParams};
|
||||
|
||||
macro_rules! define_dep_nodes {
|
||||
(
|
||||
@@ -84,55 +84,39 @@ macro_rules! define_dep_nodes {
|
||||
// encoding. The derived Encodable/Decodable uses leb128 encoding which is
|
||||
// dense when only considering this enum. But DepKind is encoded in a larger
|
||||
// struct, and there we can take advantage of the unused bits in the u16.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(u16)]
|
||||
pub enum DepKind {
|
||||
#[repr(u16)] // Must be kept in sync with the inner type of `DepKind`.
|
||||
enum DepKindDefs {
|
||||
$( $( #[$attr] )* $variant),*
|
||||
}
|
||||
|
||||
impl DepKind {
|
||||
// This const implements two things: A bounds check so that we can decode
|
||||
// a DepKind from a u16 with just one check, and a const check that the
|
||||
// discriminants of the variants have been assigned consecutively from 0
|
||||
// so that just the one comparison suffices to check that the u16 can be
|
||||
// transmuted to a DepKind.
|
||||
pub const VARIANTS: u16 = {
|
||||
let deps: &[DepKind] = &[$(DepKind::$variant,)*];
|
||||
let mut i = 0;
|
||||
while i < deps.len() {
|
||||
if i as u16 != deps[i] as u16 {
|
||||
panic!();
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
deps.len() as u16
|
||||
};
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub mod dep_kinds {
|
||||
use super::*;
|
||||
|
||||
$(
|
||||
// The `as u16` cast must be kept in sync with the inner type of `DepKind`.
|
||||
pub const $variant: DepKind = DepKind::new(DepKindDefs::$variant as u16);
|
||||
)*
|
||||
}
|
||||
|
||||
impl<S: rustc_serialize::Encoder> rustc_serialize::Encodable<S> for DepKind {
|
||||
#[inline]
|
||||
fn encode(&self, s: &mut S) {
|
||||
s.emit_u16(*self as u16);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: rustc_serialize::Decoder> rustc_serialize::Decodable<D> for DepKind {
|
||||
#[inline]
|
||||
fn decode(d: &mut D) -> DepKind {
|
||||
let discrim = d.read_u16();
|
||||
assert!(discrim < DepKind::VARIANTS);
|
||||
// SAFETY: DepKind::VARIANTS checks that the discriminant values permit
|
||||
// this one check to soundly guard the transmute.
|
||||
unsafe {
|
||||
std::mem::transmute::<u16, DepKind>(discrim)
|
||||
// This checks that the discriminants of the variants have been assigned consecutively
|
||||
// from 0 so that they can be used as a dense index.
|
||||
pub const DEP_KIND_VARIANTS: u16 = {
|
||||
let deps = &[$(dep_kinds::$variant,)*];
|
||||
let mut i = 0;
|
||||
while i < deps.len() {
|
||||
if i != deps[i].as_usize() {
|
||||
panic!();
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
deps.len() as u16
|
||||
};
|
||||
|
||||
pub(super) fn dep_kind_from_label_string(label: &str) -> Result<DepKind, ()> {
|
||||
match label {
|
||||
$(stringify!($variant) => Ok(DepKind::$variant),)*
|
||||
$(stringify!($variant) => Ok(dep_kinds::$variant),)*
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
@@ -158,12 +142,10 @@ rustc_query_append!(define_dep_nodes![
|
||||
[] fn CompileMonoItem() -> (),
|
||||
]);
|
||||
|
||||
static_assert_size!(DepKind, 2);
|
||||
|
||||
// WARNING: `construct` is generic and does not know that `CompileCodegenUnit` takes `Symbol`s as keys.
|
||||
// Be very careful changing this type signature!
|
||||
pub(crate) fn make_compile_codegen_unit(tcx: TyCtxt<'_>, name: Symbol) -> DepNode {
|
||||
DepNode::construct(tcx, DepKind::CompileCodegenUnit, &name)
|
||||
DepNode::construct(tcx, dep_kinds::CompileCodegenUnit, &name)
|
||||
}
|
||||
|
||||
// WARNING: `construct` is generic and does not know that `CompileMonoItem` takes `MonoItem`s as keys.
|
||||
@@ -172,20 +154,9 @@ pub(crate) fn make_compile_mono_item<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
mono_item: &MonoItem<'tcx>,
|
||||
) -> DepNode {
|
||||
DepNode::construct(tcx, DepKind::CompileMonoItem, mono_item)
|
||||
DepNode::construct(tcx, dep_kinds::CompileMonoItem, mono_item)
|
||||
}
|
||||
|
||||
pub type DepNode = rustc_query_system::dep_graph::DepNode<DepKind>;
|
||||
|
||||
// We keep a lot of `DepNode`s in memory during compilation. It's not
|
||||
// required that their size stay the same, but we don't want to change
|
||||
// it inadvertently. This assert just ensures we're aware of any change.
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
static_assert_size!(DepNode, 18);
|
||||
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
static_assert_size!(DepNode, 24);
|
||||
|
||||
pub trait DepNodeExt: Sized {
|
||||
/// Extracts the DefId corresponding to this DepNode. This will work
|
||||
/// if two conditions are met:
|
||||
|
||||
@@ -6,49 +6,24 @@ use rustc_session::Session;
|
||||
#[macro_use]
|
||||
mod dep_node;
|
||||
|
||||
pub use rustc_query_system::dep_graph::debug::EdgeFilter;
|
||||
pub use rustc_query_system::dep_graph::{
|
||||
debug::DepNodeFilter, hash_result, DepContext, DepNodeColor, DepNodeIndex,
|
||||
SerializedDepNodeIndex, WorkProduct, WorkProductId, WorkProductMap,
|
||||
debug::DepNodeFilter, hash_result, DepContext, DepGraphQuery, DepNodeColor, DepNodeIndex, Deps,
|
||||
SerializedDepGraph, SerializedDepNodeIndex, TaskDeps, TaskDepsRef, WorkProduct, WorkProductId,
|
||||
WorkProductMap,
|
||||
};
|
||||
|
||||
pub use dep_node::{label_strs, DepKind, DepNode, DepNodeExt};
|
||||
pub use dep_node::{dep_kinds, label_strs, DepKind, DepNode, DepNodeExt};
|
||||
pub(crate) use dep_node::{make_compile_codegen_unit, make_compile_mono_item};
|
||||
|
||||
pub type DepGraph = rustc_query_system::dep_graph::DepGraph<DepKind>;
|
||||
pub type DepGraph = rustc_query_system::dep_graph::DepGraph<DepsType>;
|
||||
|
||||
pub type TaskDeps = rustc_query_system::dep_graph::TaskDeps<DepKind>;
|
||||
pub type TaskDepsRef<'a> = rustc_query_system::dep_graph::TaskDepsRef<'a, DepKind>;
|
||||
pub type DepGraphQuery = rustc_query_system::dep_graph::DepGraphQuery<DepKind>;
|
||||
pub type SerializedDepGraph = rustc_query_system::dep_graph::SerializedDepGraph<DepKind>;
|
||||
pub type EdgeFilter = rustc_query_system::dep_graph::debug::EdgeFilter<DepKind>;
|
||||
pub type DepKindStruct<'tcx> = rustc_query_system::dep_graph::DepKindStruct<TyCtxt<'tcx>>;
|
||||
|
||||
impl rustc_query_system::dep_graph::DepKind for DepKind {
|
||||
const NULL: Self = DepKind::Null;
|
||||
const RED: Self = DepKind::Red;
|
||||
const MAX: u16 = DepKind::VARIANTS - 1;
|
||||
|
||||
fn debug_node(node: &DepNode, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:?}(", node.kind)?;
|
||||
|
||||
ty::tls::with_opt(|opt_tcx| {
|
||||
if let Some(tcx) = opt_tcx {
|
||||
if let Some(def_id) = node.extract_def_id(tcx) {
|
||||
write!(f, "{}", tcx.def_path_debug_str(def_id))?;
|
||||
} else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*node) {
|
||||
write!(f, "{s}")?;
|
||||
} else {
|
||||
write!(f, "{}", node.hash)?;
|
||||
}
|
||||
} else {
|
||||
write!(f, "{}", node.hash)?;
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
write!(f, ")")
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct DepsType;
|
||||
|
||||
impl Deps for DepsType {
|
||||
fn with_deps<OP, R>(task_deps: TaskDepsRef<'_>, op: OP) -> R
|
||||
where
|
||||
OP: FnOnce() -> R,
|
||||
@@ -70,24 +45,13 @@ impl rustc_query_system::dep_graph::DepKind for DepKind {
|
||||
})
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[inline]
|
||||
fn from_u16(u: u16) -> Self {
|
||||
if u > Self::MAX {
|
||||
panic!("Invalid DepKind {u}");
|
||||
}
|
||||
// SAFETY: See comment on DepKind::VARIANTS
|
||||
unsafe { std::mem::transmute(u) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_u16(self) -> u16 {
|
||||
self as u16
|
||||
}
|
||||
const DEP_KIND_NULL: DepKind = dep_kinds::Null;
|
||||
const DEP_KIND_RED: DepKind = dep_kinds::Red;
|
||||
const DEP_KIND_MAX: u16 = dep_node::DEP_KIND_VARIANTS - 1;
|
||||
}
|
||||
|
||||
impl<'tcx> DepContext for TyCtxt<'tcx> {
|
||||
type DepKind = DepKind;
|
||||
type Deps = DepsType;
|
||||
|
||||
#[inline]
|
||||
fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashingContext<'_>) -> R) -> R {
|
||||
@@ -111,6 +75,6 @@ impl<'tcx> DepContext for TyCtxt<'tcx> {
|
||||
|
||||
#[inline]
|
||||
fn dep_kind_info(&self, dk: DepKind) -> &DepKindStruct<'tcx> {
|
||||
&self.query_kinds[dk as usize]
|
||||
&self.query_kinds[dk.as_usize()]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user