提交 3cc3ae22 编写于 作者: M Michael Woerister

incr.comp.: Move result fingerprinting to DepGraph::with_task().

This makes sure that we don't introduce strange cases where we have
nodes outside the query system that could break red/green tracking
and it will allow to keep red/green neatly encapsulated within the
DepGraph implementation.
上级 e6c9a53d
......@@ -9,11 +9,15 @@
// except according to those terms.
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
StableHashingContextProvider};
use session::config::OutputType;
use std::cell::{Ref, RefCell};
use std::rc::Rc;
use util::common::{ProfileQueriesMsg, profq_msg};
use ich::Fingerprint;
use super::dep_node::{DepNode, DepKind, WorkProductId};
use super::query::DepGraphQuery;
use super::raii;
......@@ -71,10 +75,6 @@ pub fn in_ignore<'graph>(&'graph self) -> Option<raii::IgnoreTask<'graph>> {
self.data.as_ref().map(|data| raii::IgnoreTask::new(&data.edges))
}
pub fn in_task<'graph>(&'graph self, key: DepNode) -> Option<raii::DepTask<'graph>> {
self.data.as_ref().map(|data| raii::DepTask::new(&data.edges, key))
}
pub fn with_ignore<OP,R>(&self, op: OP) -> R
where OP: FnOnce() -> R
{
......@@ -109,24 +109,38 @@ pub fn with_ignore<OP,R>(&self, op: OP) -> R
/// `arg` parameter.
///
/// [README]: README.md
pub fn with_task<C, A, R>(&self,
key: DepNode,
cx: C,
arg: A,
task: fn(C, A) -> R)
-> (R, DepNodeIndex)
where C: DepGraphSafe
pub fn with_task<C, A, R, HCX>(&self,
key: DepNode,
cx: C,
arg: A,
task: fn(C, A) -> R)
-> (R, DepNodeIndex)
where C: DepGraphSafe + StableHashingContextProvider<ContextType=HCX>,
R: HashStable<HCX>,
{
if let Some(ref data) = self.data {
data.edges.borrow_mut().push_task(key);
if cfg!(debug_assertions) {
profq_msg(ProfileQueriesMsg::TaskBegin(key.clone()))
};
// In incremental mode, hash the result of the task. We don't
// do anything with the hash yet, but we are computing it
// anyway so that
// - we make sure that the infrastructure works and
// - we can get an idea of the runtime cost.
let mut hcx = cx.create_stable_hashing_context();
let result = task(cx, arg);
if cfg!(debug_assertions) {
profq_msg(ProfileQueriesMsg::TaskEnd)
};
let dep_node_index = data.edges.borrow_mut().pop_task(key);
let mut stable_hasher = StableHasher::new();
result.hash_stable(&mut hcx, &mut stable_hasher);
let _: Fingerprint = stable_hasher.finish();
(result, dep_node_index)
} else {
(task(cx, arg), DepNodeIndex::INVALID)
......
......@@ -58,6 +58,13 @@ impl<'a, A> DepGraphSafe for &'a A
{
}
/// Mut ref to dep-graph-safe stuff should still be dep-graph-safe.
impl<'a, A> DepGraphSafe for &'a mut A
where A: DepGraphSafe,
{
}
/// No data here! :)
impl DepGraphSafe for () {
}
......
......@@ -26,8 +26,8 @@
use syntax::symbol::Symbol;
use syntax_pos::Span;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
StableHasherResult};
use rustc_data_structures::stable_hasher::{HashStable, StableHashingContextProvider,
StableHasher, StableHasherResult};
use rustc_data_structures::accumulate_vec::AccumulateVec;
/// This is the context state available during incr. comp. hashing. It contains
......@@ -196,6 +196,12 @@ pub fn unop_can_panic_at_runtime(&self, unop: hir::UnOp) -> bool
}
}
impl<'a, 'gcx, 'lcx> StableHashingContextProvider for ty::TyCtxt<'a, 'gcx, 'lcx> {
type ContextType = StableHashingContext<'a, 'gcx, 'lcx>;
fn create_stable_hashing_context(&self) -> Self::ContextType {
StableHashingContext::new(*self)
}
}
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::NodeId {
fn hash_stable<W: StableHasherResult>(&self,
......
......@@ -14,7 +14,6 @@
use hir::def::{Def, Export};
use hir::{self, TraitCandidate, ItemLocalId};
use hir::svh::Svh;
use ich::{Fingerprint, StableHashingContext};
use lint;
use middle::const_val;
use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary};
......@@ -46,7 +45,7 @@
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use std::cell::{RefCell, RefMut, Cell};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use std::fmt::Debug;
use std::hash::Hash;
use std::marker::PhantomData;
......@@ -953,20 +952,6 @@ fn run_provider<'a, 'tcx, 'lcx>(tcx: TyCtxt<'a, 'tcx, 'lcx>,
tcx.dep_graph.read_index(dep_node_index);
// In incremental mode, hash the result of the query. We don't
// do anything with the hash yet, but we are computing it
// anyway so that
// - we make sure that the infrastructure works and
// - we can get an idea of the runtime cost.
if !dep_node.kind.is_anon() && tcx.sess.opts.incremental.is_some() {
let mut hcx = StableHashingContext::new(tcx);
let mut hasher = StableHasher::new();
result.hash_stable(&mut hcx, &mut hasher);
let _: Fingerprint = hasher.finish();
}
let value = QueryValue {
value: result,
index: dep_node_index,
......
......@@ -2575,6 +2575,10 @@ pub struct SymbolName {
pub name: InternedString
}
impl_stable_hash_for!(struct self::SymbolName {
name
});
impl Deref for SymbolName {
type Target = str;
......
......@@ -192,6 +192,28 @@ fn write_isize(&mut self, i: isize) {
}
/// Something that can provide a stable hashing context.
pub trait StableHashingContextProvider {
type ContextType;
fn create_stable_hashing_context(&self) -> Self::ContextType;
}
impl<'a, T: StableHashingContextProvider> StableHashingContextProvider for &'a T {
type ContextType = T::ContextType;
fn create_stable_hashing_context(&self) -> Self::ContextType {
(**self).create_stable_hashing_context()
}
}
impl<'a, T: StableHashingContextProvider> StableHashingContextProvider for &'a mut T {
type ContextType = T::ContextType;
fn create_stable_hashing_context(&self) -> Self::ContextType {
(**self).create_stable_hashing_context()
}
}
/// Something that implements `HashStable<CTX>` can be hashed in a way that is
/// stable across multiple compilation sessions.
pub trait HashStable<CTX> {
......@@ -292,7 +314,7 @@ fn hash_stable<W: StableHasherResult>(&self,
}
}
impl<T: HashStable<CTX>, CTX> HashStable<CTX> for Box<T> {
impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for Box<T> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
......@@ -301,7 +323,7 @@ fn hash_stable<W: StableHasherResult>(&self,
}
}
impl<T: HashStable<CTX>, CTX> HashStable<CTX> for ::std::rc::Rc<T> {
impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for ::std::rc::Rc<T> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
......@@ -310,7 +332,7 @@ fn hash_stable<W: StableHasherResult>(&self,
}
}
impl<T: HashStable<CTX>, CTX> HashStable<CTX> for ::std::sync::Arc<T> {
impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for ::std::sync::Arc<T> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
......
......@@ -1070,7 +1070,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let start_time = Instant::now();
all_stats.extend(tcx.compile_codegen_unit(*cgu.name()));
total_trans_time += start_time.elapsed();
ongoing_translation.check_for_errors(tcx.sess);
}
......@@ -1565,5 +1564,35 @@ pub fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
Visibility::Default => llvm::Visibility::Default,
Visibility::Hidden => llvm::Visibility::Hidden,
Visibility::Protected => llvm::Visibility::Protected,
}
// FIXME(mw): Anything that is produced via DepGraph::with_task() must implement
// the HashStable trait. Normally DepGraph::with_task() calls are
// hidden behind queries, but CGU creation is a special case in two
// ways: (1) it's not a query and (2) CGU are output nodes, so their
// Fingerprints are not actually needed. It remains to be clarified
// how exactly this case will be handled in the red/green system but
// for now we content ourselves with providing a no-op HashStable
// implementation for CGUs.
mod temp_stable_hash_impls {
use rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher,
HashStable};
use context::Stats;
use ModuleTranslation;
impl<HCX> HashStable<HCX> for Stats {
fn hash_stable<W: StableHasherResult>(&self,
_: &mut HCX,
_: &mut StableHasher<W>) {
// do nothing
}
}
impl<HCX> HashStable<HCX> for ModuleTranslation {
fn hash_stable<W: StableHasherResult>(&self,
_: &mut HCX,
_: &mut StableHasher<W>) {
// do nothing
}
}
}
......@@ -14,6 +14,7 @@
use rustc::dep_graph::{DepGraph, DepGraphSafe};
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::ich::StableHashingContext;
use rustc::traits;
use debuginfo;
use callee;
......@@ -25,6 +26,8 @@
use type_::Type;
use rustc_data_structures::base_n;
use rustc::middle::trans::Stats;
use rustc_data_structures::stable_hasher::StableHashingContextProvider;
use rustc::session::config::{self, NoDebugInfo, OutputFilenames};
use rustc::session::Session;
use rustc::session::config::{self, NoDebugInfo};
use rustc::ty::layout::{LayoutCx, LayoutError, LayoutTyper, TyLayout};
......@@ -134,6 +137,17 @@ pub fn new(shared: &'a SharedCrateContext<'a, 'tcx>,
impl<'a, 'tcx> DepGraphSafe for CrateContext<'a, 'tcx> {
}
impl<'a, 'tcx> DepGraphSafe for SharedCrateContext<'a, 'tcx> {
}
impl<'a, 'tcx> StableHashingContextProvider for SharedCrateContext<'a, 'tcx> {
type ContextType = StableHashingContext<'a, 'tcx, 'tcx>;
fn create_stable_hashing_context(&self) -> Self::ContextType {
StableHashingContext::new(self.tcx)
}
}
pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode {
let reloc_model_arg = match sess.opts.cg.relocation_model {
Some(ref s) => &s[..],
......
......@@ -14,7 +14,8 @@
//! We walk the set of items and, for each member, generate new constraints.
use hir::def_id::DefId;
use rustc::dep_graph::{AssertDepGraphSafe, DepKind};
use rustc::dep_graph::{DepGraphSafe, DepKind};
use rustc::ich::StableHashingContext;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt};
use syntax::ast;
......@@ -22,6 +23,7 @@
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc_data_structures::transitive_relation::TransitiveRelation;
use rustc_data_structures::stable_hasher::StableHashingContextProvider;
use super::terms::*;
use super::terms::VarianceTerm::*;
......@@ -138,6 +140,16 @@ fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) {
}
}
impl<'a, 'tcx> StableHashingContextProvider for ConstraintContext<'a, 'tcx> {
type ContextType = StableHashingContext<'a, 'tcx, 'tcx>;
fn create_stable_hashing_context(&self) -> Self::ContextType {
StableHashingContext::new(self.terms_cx.tcx)
}
}
impl<'a, 'tcx> DepGraphSafe for ConstraintContext<'a, 'tcx> {}
impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
fn visit_node_helper(&mut self, id: ast::NodeId) {
let tcx = self.terms_cx.tcx;
......@@ -151,14 +163,14 @@ fn visit_node_helper(&mut self, id: ast::NodeId) {
// on dep-graph management.
let dep_node = def_id.to_dep_node(tcx, DepKind::ItemVarianceConstraints);
tcx.dep_graph.with_task(dep_node,
AssertDepGraphSafe(self),
self,
def_id,
visit_item_task);
fn visit_item_task<'a, 'tcx>(ccx: AssertDepGraphSafe<&mut ConstraintContext<'a, 'tcx>>,
fn visit_item_task<'a, 'tcx>(ccx: &mut ConstraintContext<'a, 'tcx>,
def_id: DefId)
{
ccx.0.build_constraints_for_item(def_id);
ccx.build_constraints_for_item(def_id);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册