Skip to content

Commit

Permalink
Auto merge of #115920 - Zoxc:depkind-u16, r=cjgillot
Browse files Browse the repository at this point in the history
Move `DepKind` to `rustc_query_system` and define it as `u16`

This moves the `DepKind` type to `rustc_query_system` where it's defined with an inner `u16` field. This decouples it from `rustc_middle` and is a step towards letting other crates define dep kinds. It also allows some type parameters to be removed. The `DepKind` trait is replaced with a `Deps` trait. That's used when some operations or information about dep kinds which is unavailable in `rustc_query_system` are still needed.

r? `@cjgillot`
  • Loading branch information
bors committed Sep 21, 2023
2 parents 0fd7ce9 + 1806efe commit fcb7961
Show file tree
Hide file tree
Showing 24 changed files with 508 additions and 518 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_incremental/src/assert_dep_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
use rustc_hir::intravisit::{self, Visitor};
use rustc_middle::dep_graph::{
DepGraphQuery, DepKind, DepNode, DepNodeExt, DepNodeFilter, EdgeFilter,
dep_kinds, DepGraphQuery, DepKind, DepNode, DepNodeExt, DepNodeFilter, EdgeFilter,
};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::TyCtxt;
Expand Down Expand Up @@ -129,7 +129,7 @@ impl<'tcx> IfThisChanged<'tcx> {
let dep_node_interned = self.argument(attr);
let dep_node = match dep_node_interned {
None => {
DepNode::from_def_path_hash(self.tcx, def_path_hash, DepKind::hir_owner)
DepNode::from_def_path_hash(self.tcx, def_path_hash, dep_kinds::hir_owner)
}
Some(n) => {
match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_incremental/src/persist/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::errors;
use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::unord::UnordMap;
use rustc_middle::dep_graph::{SerializedDepGraph, WorkProductMap};
use rustc_middle::dep_graph::{DepsType, SerializedDepGraph, WorkProductMap};
use rustc_middle::query::on_disk_cache::OnDiskCache;
use rustc_serialize::opaque::MemDecoder;
use rustc_serialize::Decodable;
Expand Down Expand Up @@ -208,7 +208,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
return LoadResult::DataOutOfDate;
}

let dep_graph = SerializedDepGraph::decode(&mut decoder);
let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder);

LoadResult::Ok { data: (dep_graph, prev_work_products) }
}
Expand Down
43 changes: 42 additions & 1 deletion compiler/rustc_interface/src/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
//! origin crate when the `TyCtxt` is not present in TLS.
use rustc_errors::{Diagnostic, TRACK_DIAGNOSTICS};
use rustc_middle::dep_graph::TaskDepsRef;
use rustc_middle::dep_graph::{DepNodeExt, TaskDepsRef};
use rustc_middle::ty::tls;
use rustc_query_system::dep_graph::dep_node::default_dep_kind_debug;
use rustc_query_system::dep_graph::{DepContext, DepKind, DepNode};
use std::fmt;

fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
Expand Down Expand Up @@ -59,10 +61,49 @@ fn def_id_debug(def_id: rustc_hir::def_id::DefId, f: &mut fmt::Formatter<'_>) ->
write!(f, ")")
}

/// This is a callback from `rustc_query_system` as it cannot access the implicit state
/// in `rustc_middle` otherwise.
pub fn dep_kind_debug(kind: DepKind, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
tls::with_opt(|opt_tcx| {
if let Some(tcx) = opt_tcx {
write!(f, "{}", tcx.dep_kind_info(kind).name)
} else {
default_dep_kind_debug(kind, f)
}
})
}

/// This is a callback from `rustc_query_system` as it cannot access the implicit state
/// in `rustc_middle` otherwise.
pub fn dep_node_debug(node: DepNode, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}(", node.kind)?;

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, ")")
}

/// Sets up the callbacks in prior crates which we want to refer to the
/// TyCtxt in.
pub fn setup_callbacks() {
rustc_span::SPAN_TRACK.swap(&(track_span_parent as fn(_)));
rustc_hir::def_id::DEF_ID_DEBUG.swap(&(def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
rustc_query_system::dep_graph::dep_node::DEP_KIND_DEBUG
.swap(&(dep_kind_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
rustc_query_system::dep_graph::dep_node::DEP_NODE_DEBUG
.swap(&(dep_node_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
TRACK_DIAGNOSTICS.swap(&(track_diagnostic as _));
}
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ macro_rules! provide_one {
// External query providers call `crate_hash` in order to register a dependency
// on the crate metadata. The exception is `crate_hash` itself, which obviously
// doesn't need to do this (and can't, as it would cause a query cycle).
use rustc_middle::dep_graph::DepKind;
if DepKind::$name != DepKind::crate_hash && $tcx.dep_graph.is_fully_enabled() {
use rustc_middle::dep_graph::dep_kinds;
if dep_kinds::$name != dep_kinds::crate_hash && $tcx.dep_graph.is_fully_enabled() {
$tcx.ensure().crate_hash($def_id.krate);
}

Expand Down
79 changes: 25 additions & 54 deletions compiler/rustc_middle/src/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
(
Expand All @@ -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::*;

impl<S: rustc_serialize::Encoder> rustc_serialize::Encodable<S> for DepKind {
#[inline]
fn encode(&self, s: &mut S) {
s.emit_u16(*self as u16);
}
$(
// 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<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(()),
}
}
Expand All @@ -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.
Expand All @@ -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:
Expand Down
64 changes: 14 additions & 50 deletions compiler/rustc_middle/src/dep_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 {
Expand All @@ -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()]
}
}
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#![allow(unused_parens)]

use crate::dep_graph;
use crate::dep_graph::DepKind;
use crate::infer::canonical::{self, Canonical};
use crate::lint::LintExpectation;
use crate::metadata::ModChild;
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub struct DynamicQuery<'tcx, C: QueryCache> {
pub eval_always: bool,
pub dep_kind: DepKind,
pub handle_cycle_error: HandleCycleError,
pub query_state: FieldOffset<QueryStates<'tcx>, QueryState<C::Key, DepKind>>,
pub query_state: FieldOffset<QueryStates<'tcx>, QueryState<C::Key>>,
pub query_cache: FieldOffset<QueryCaches<'tcx>, C>,
pub cache_on_disk: fn(tcx: TyCtxt<'tcx>, key: &C::Key) -> bool,
pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value,
Expand All @@ -53,7 +53,7 @@ pub struct DynamicQuery<'tcx, C: QueryCache> {
fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool,
pub hash_result: HashResult<C::Value>,
pub value_from_cycle_error:
fn(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<DepKind>], guar: ErrorGuaranteed) -> C::Value,
fn(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo], guar: ErrorGuaranteed) -> C::Value,
pub format_value: fn(&C::Value) -> String,
}

Expand Down Expand Up @@ -402,7 +402,7 @@ macro_rules! define_callbacks {
#[derive(Default)]
pub struct QueryStates<'tcx> {
$(
pub $name: QueryState<$($K)*, DepKind>,
pub $name: QueryState<$($K)*>,
)*
}

Expand Down Expand Up @@ -516,7 +516,7 @@ macro_rules! define_feedable {
}
}
None => {
let dep_node = dep_graph::DepNode::construct(tcx, dep_graph::DepKind::$name, &key);
let dep_node = dep_graph::DepNode::construct(tcx, dep_graph::dep_kinds::$name, &key);
let dep_node_index = tcx.dep_graph.with_feed_task(
dep_node,
tcx,
Expand Down
Loading

0 comments on commit fcb7961

Please sign in to comment.