Skip to content

incr.comp.: Track expanded spans instead of FileMaps. #42175

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 28, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
@@ -176,7 +176,6 @@ pub enum DepNode<D: Clone + Debug> {
IsMirAvailable(D),
ItemAttrs(D),
FnArgNames(D),
FileMap(D, Arc<String>),
}

impl<D: Clone + Debug> DepNode<D> {
@@ -307,7 +306,6 @@ impl<D: Clone + Debug> DepNode<D> {
ConstIsRvaluePromotableToStatic(ref d) => op(d).map(ConstIsRvaluePromotableToStatic),
IsMirAvailable(ref d) => op(d).map(IsMirAvailable),
GlobalMetaData(ref d, kind) => op(d).map(|d| GlobalMetaData(d, kind)),
FileMap(ref d, ref file_name) => op(d).map(|d| FileMap(d, file_name.clone())),
}
}
}
28 changes: 2 additions & 26 deletions src/librustc/ich/caching_codemap_view.rs
Original file line number Diff line number Diff line change
@@ -8,11 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use dep_graph::{DepGraph, DepNode};
use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
use rustc_data_structures::bitvec::BitVector;
use std::rc::Rc;
use std::sync::Arc;
use syntax::codemap::CodeMap;
use syntax_pos::{BytePos, FileMap};
use ty::TyCtxt;
@@ -31,14 +27,12 @@ pub struct CachingCodemapView<'tcx> {
codemap: &'tcx CodeMap,
line_cache: [CacheEntry; 3],
time_stamp: usize,
dep_graph: DepGraph,
dep_tracking_reads: BitVector,
}

impl<'tcx> CachingCodemapView<'tcx> {
pub fn new<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CachingCodemapView<'tcx> {
let codemap = tcx.sess.codemap();
let files = codemap.files_untracked();
let files = codemap.files();
let first_file = files[0].clone();
let entry = CacheEntry {
time_stamp: 0,
@@ -50,11 +44,9 @@ impl<'tcx> CachingCodemapView<'tcx> {
};

CachingCodemapView {
dep_graph: tcx.dep_graph.clone(),
codemap: codemap,
line_cache: [entry.clone(), entry.clone(), entry.clone()],
time_stamp: 0,
dep_tracking_reads: BitVector::new(files.len()),
}
}

@@ -67,9 +59,6 @@ impl<'tcx> CachingCodemapView<'tcx> {
for cache_entry in self.line_cache.iter_mut() {
if pos >= cache_entry.line_start && pos < cache_entry.line_end {
cache_entry.time_stamp = self.time_stamp;
if self.dep_tracking_reads.insert(cache_entry.file_index) {
self.dep_graph.read(dep_node(cache_entry));
}

return Some((cache_entry.file.clone(),
cache_entry.line_number,
@@ -90,7 +79,7 @@ impl<'tcx> CachingCodemapView<'tcx> {
// If the entry doesn't point to the correct file, fix it up
if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos {
let file_valid;
let files = self.codemap.files_untracked();
let files = self.codemap.files();

if files.len() > 0 {
let file_index = self.codemap.lookup_filemap_idx(pos);
@@ -120,21 +109,8 @@ impl<'tcx> CachingCodemapView<'tcx> {
cache_entry.line_end = line_bounds.1;
cache_entry.time_stamp = self.time_stamp;

if self.dep_tracking_reads.insert(cache_entry.file_index) {
self.dep_graph.read(dep_node(cache_entry));
}

return Some((cache_entry.file.clone(),
cache_entry.line_number,
pos - cache_entry.line_start));
}
}

fn dep_node(cache_entry: &CacheEntry) -> DepNode<DefId> {
let def_id = DefId {
krate: CrateNum::from_u32(cache_entry.file.crate_of_origin),
index: CRATE_DEF_INDEX,
};
let name = Arc::new(cache_entry.file.name.clone());
DepNode::FileMap(def_id, name)
}
5 changes: 5 additions & 0 deletions src/librustc/ich/hcx.rs
Original file line number Diff line number Diff line change
@@ -74,6 +74,11 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> {
}
}

pub fn force_span_hashing(mut self) -> Self {
self.hash_spans = true;
self
}

#[inline]
pub fn while_hashing_hir_bodies<F: FnOnce(&mut Self)>(&mut self,
hash_bodies: bool,
50 changes: 47 additions & 3 deletions src/librustc/ich/impls_mir.rs
Original file line number Diff line number Diff line change
@@ -22,11 +22,55 @@ impl_stable_hash_for!(struct mir::SourceInfo { span, scope });
impl_stable_hash_for!(enum mir::Mutability { Mut, Not });
impl_stable_hash_for!(enum mir::BorrowKind { Shared, Unique, Mut });
impl_stable_hash_for!(enum mir::LocalKind { Var, Temp, Arg, ReturnPointer });
impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { mutability, ty, name, source_info,
is_user_variable});
impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
mutability,
ty,
name,
source_info,
is_user_variable
});
impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref });
impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
impl_stable_hash_for!(struct mir::Terminator<'tcx> { source_info, kind });

impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Terminator<'tcx> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'tcx>,
hasher: &mut StableHasher<W>) {
let mir::Terminator {
ref kind,
ref source_info,
} = *self;

let hash_spans_unconditionally = match *kind {
mir::TerminatorKind::Assert { .. } => {
// Assert terminators generate a panic message that contains the
// source location, so we always have to feed its span into the
// ICH.
true
}
mir::TerminatorKind::Goto { .. } |
mir::TerminatorKind::SwitchInt { .. } |
mir::TerminatorKind::Resume |
mir::TerminatorKind::Return |
mir::TerminatorKind::Unreachable |
mir::TerminatorKind::Drop { .. } |
mir::TerminatorKind::DropAndReplace { .. } |
mir::TerminatorKind::Call { .. } => false,
};

if hash_spans_unconditionally {
hcx.while_hashing_spans(true, |hcx| {
source_info.hash_stable(hcx, hasher);
})
} else {
source_info.hash_stable(hcx, hasher);
}

kind.hash_stable(hcx, hasher);
}
}


impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Local {
#[inline]
23 changes: 4 additions & 19 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
@@ -11,8 +11,9 @@
pub use self::code_stats::{CodeStats, DataTypeKind, FieldInfo};
pub use self::code_stats::{SizeKind, TypeSizeInfo, VariantInfo};

use dep_graph::{DepGraph, DepNode};
use hir::def_id::{DefId, CrateNum, DefIndex, CRATE_DEF_INDEX};
use dep_graph::DepGraph;
use hir::def_id::{CrateNum, DefIndex};

use lint;
use middle::cstore::CrateStore;
use middle::dependency_format;
@@ -32,7 +33,7 @@ use syntax::parse::ParseSess;
use syntax::symbol::Symbol;
use syntax::{ast, codemap};
use syntax::feature_gate::AttributeType;
use syntax_pos::{Span, MultiSpan, FileMap};
use syntax_pos::{Span, MultiSpan};

use rustc_back::{LinkerFlavor, PanicStrategy};
use rustc_back::target::Target;
@@ -46,7 +47,6 @@ use std::io::Write;
use std::rc::Rc;
use std::fmt;
use std::time::Duration;
use std::sync::Arc;

mod code_stats;
pub mod config;
@@ -626,21 +626,6 @@ pub fn build_session_(sopts: config::Options,
};
let target_cfg = config::build_target_config(&sopts, &span_diagnostic);

// Hook up the codemap with a callback that allows it to register FileMap
// accesses with the dependency graph.
let cm_depgraph = dep_graph.clone();
let codemap_dep_tracking_callback = Box::new(move |filemap: &FileMap| {
let def_id = DefId {
krate: CrateNum::from_u32(filemap.crate_of_origin),
index: CRATE_DEF_INDEX,
};
let name = Arc::new(filemap.name.clone());
let dep_node = DepNode::FileMap(def_id, name);

cm_depgraph.read(dep_node);
});
codemap.set_dep_tracking_callback(codemap_dep_tracking_callback);

let p_s = parse::ParseSess::with_span_handler(span_diagnostic, codemap);
let default_sysroot = match sopts.maybe_sysroot {
Some(_) => None,
26 changes: 1 addition & 25 deletions src/librustc_incremental/calculate_svh/mod.rs
Original file line number Diff line number Diff line change
@@ -29,10 +29,9 @@
use std::cell::RefCell;
use std::hash::Hash;
use std::sync::Arc;
use rustc::dep_graph::DepNode;
use rustc::hir;
use rustc::hir::def_id::{LOCAL_CRATE, CRATE_DEF_INDEX, DefId};
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ich::{Fingerprint, StableHashingContext};
use rustc::ty::TyCtxt;
@@ -155,11 +154,6 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
// We want to incoporate these into the
// SVH.
}
DepNode::FileMap(..) => {
// These don't make a semantic
// difference, filter them out.
return None
}
DepNode::AllLocalTraitImpls => {
// These are already covered by hashing
// the HIR.
@@ -306,24 +300,6 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
visitor.compute_and_store_ich_for_item_like(DepNode::HirBody(def_id), true, macro_def);
}

for filemap in tcx.sess
.codemap()
.files_untracked()
.iter()
.filter(|fm| !fm.is_imported()) {
assert_eq!(LOCAL_CRATE.as_u32(), filemap.crate_of_origin);
let def_id = DefId {
krate: LOCAL_CRATE,
index: CRATE_DEF_INDEX,
};
let name = Arc::new(filemap.name.clone());
let dep_node = DepNode::FileMap(def_id, name);
let mut hasher = IchHasher::new();
filemap.hash_stable(&mut visitor.hcx, &mut hasher);
let fingerprint = hasher.finish();
visitor.hashes.insert(dep_node, fingerprint);
}

visitor.compute_and_store_ich_for_trait_impls(krate);
});

18 changes: 1 addition & 17 deletions src/librustc_incremental/persist/hash.rs
Original file line number Diff line number Diff line change
@@ -51,8 +51,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
match *dep_node {
DepNode::Krate |
DepNode::Hir(_) |
DepNode::HirBody(_) |
DepNode::FileMap(..) =>
DepNode::HirBody(_) =>
true,
DepNode::MetaData(def_id) |
DepNode::GlobalMetaData(def_id, _) => !def_id.is_local(),
@@ -77,20 +76,6 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
Some(self.incremental_hashes_map[dep_node])
}

DepNode::FileMap(def_id, ref name) => {
if def_id.is_local() {
// We will have been able to retrace the DefId (which is
// always the local CRATE_DEF_INDEX), but the file with the
// given name might have been removed, so we use get() in
// order to allow for that case.
self.incremental_hashes_map.get(dep_node).map(|x| *x)
} else {
Some(self.metadata_hash(DepNode::FileMap(def_id, name.clone()),
def_id.krate,
|this| &mut this.global_metadata_hashes))
}
}

// MetaData from other crates is an *input* to us.
// MetaData nodes from *our* crates are an *output*; we
// don't hash them, but we do compute a hash for them and
@@ -242,7 +227,6 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
let dep_node = match dep_node {
DepNode::GlobalMetaData(_, kind) => DepNode::GlobalMetaData(def_id, kind),
DepNode::FileMap(_, name) => DepNode::FileMap(def_id, name),
other => {
bug!("unexpected DepNode variant: {:?}", other)
}
22 changes: 4 additions & 18 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
use rustc::hir::map::definitions::DefPathTable;
use rustc::dep_graph::{DepNode, GlobalMetaDataKind};
use rustc::ich::{StableHashingContext, Fingerprint};
use rustc::ich::Fingerprint;
use rustc::middle::dependency_format::Linkage;
use rustc::middle::lang_items;
use rustc::mir;
@@ -29,15 +29,13 @@ use rustc::session::config::{self, CrateTypeProcMacro};
use rustc::util::nodemap::{FxHashMap, NodeSet};

use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};

use std::hash::Hash;
use std::intrinsics;
use std::io::prelude::*;
use std::io::Cursor;
use std::path::Path;
use std::rc::Rc;
use std::sync::Arc;
use std::u32;
use syntax::ast::{self, CRATE_NODE_ID};
use syntax::codemap::Spanned;
@@ -284,7 +282,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let codemap = self.tcx.sess.codemap();
let all_filemaps = codemap.files();

let hcx = &mut StableHashingContext::new(self.tcx);
let (working_dir, working_dir_was_remapped) = self.tcx.sess.working_dir.clone();

let adapted = all_filemaps.iter()
@@ -316,21 +313,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
adapted.name = abs_path;
Rc::new(adapted)
}
});

let filemaps: Vec<_> = if self.compute_ich {
adapted.inspect(|filemap| {
let mut hasher = StableHasher::new();
filemap.hash_stable(hcx, &mut hasher);
let fingerprint = hasher.finish();
let dep_node = DepNode::FileMap((), Arc::new(filemap.name.clone()));
self.metadata_hashes.global_hashes.push((dep_node, fingerprint));
}).collect()
} else {
adapted.collect()
};
})
.collect::<Vec<_>>();

self.lazy_seq_ref(filemaps.iter().map(|fm| &**fm))
self.lazy_seq_ref(adapted.iter().map(|rc| &**rc))
}

fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
12 changes: 11 additions & 1 deletion src/librustc_metadata/isolated_encoder.rs
Original file line number Diff line number Diff line change
@@ -35,7 +35,17 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
tcx: tcx,
ecx: ecx,
hcx: if compute_ich {
Some((StableHashingContext::new(tcx), StableHasher::new()))
// We are always hashing spans for things in metadata because
// don't know if a downstream crate will use them or not.
// Except when -Zquery-dep-graph is specified because we don't
// want to mess up our tests.
let hcx = if tcx.sess.opts.debugging_opts.query_dep_graph {
StableHashingContext::new(tcx)
} else {
StableHashingContext::new(tcx).force_span_hashing()
};

Some((hcx, StableHasher::new()))
} else {
None
}
28 changes: 0 additions & 28 deletions src/libsyntax/codemap.rs
Original file line number Diff line number Diff line change
@@ -103,18 +103,11 @@ impl FileLoader for RealFileLoader {
//

pub struct CodeMap {
// The `files` field should not be visible outside of libsyntax so that we
// can do proper dependency tracking.
pub(super) files: RefCell<Vec<Rc<FileMap>>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the pub(super) here anymore? I guess it doesn't hurt...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there is one instance in libsyntax where it is accessed via borrow_mut().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems good to me

file_loader: Box<FileLoader>,
// This is used to apply the file path remapping as specified via
// -Zremap-path-prefix to all FileMaps allocated within this CodeMap.
path_mapping: FilePathMapping,
// The CodeMap will invoke this callback whenever a specific FileMap is
// accessed. The callback starts out as a no-op but when the dependency
// graph becomes available later during the compilation process, it is
// be replaced with something that notifies the dep-tracking system.
dep_tracking_callback: RefCell<Box<Fn(&FileMap)>>,
}

impl CodeMap {
@@ -123,7 +116,6 @@ impl CodeMap {
files: RefCell::new(Vec::new()),
file_loader: Box::new(RealFileLoader),
path_mapping: path_mapping,
dep_tracking_callback: RefCell::new(Box::new(|_| {})),
}
}

@@ -134,18 +126,13 @@ impl CodeMap {
files: RefCell::new(Vec::new()),
file_loader: file_loader,
path_mapping: path_mapping,
dep_tracking_callback: RefCell::new(Box::new(|_| {})),
}
}

pub fn path_mapping(&self) -> &FilePathMapping {
&self.path_mapping
}

pub fn set_dep_tracking_callback(&self, cb: Box<Fn(&FileMap)>) {
*self.dep_tracking_callback.borrow_mut() = cb;
}

pub fn file_exists(&self, path: &Path) -> bool {
self.file_loader.file_exists(path)
}
@@ -156,15 +143,6 @@ impl CodeMap {
}

pub fn files(&self) -> Ref<Vec<Rc<FileMap>>> {
let files = self.files.borrow();
for file in files.iter() {
(self.dep_tracking_callback.borrow())(file);
}
files
}

/// Only use this if you do your own dependency tracking!
pub fn files_untracked(&self) -> Ref<Vec<Rc<FileMap>>> {
self.files.borrow()
}

@@ -311,8 +289,6 @@ impl CodeMap {
let files = self.files.borrow();
let f = (*files)[idx].clone();

(self.dep_tracking_callback.borrow())(&f);

match f.lookup_line(pos) {
Some(line) => Ok(FileMapAndLine { fm: f, line: line }),
None => Err(f)
@@ -502,7 +478,6 @@ impl CodeMap {
pub fn get_filemap(&self, filename: &str) -> Option<Rc<FileMap>> {
for fm in self.files.borrow().iter() {
if filename == fm.name {
(self.dep_tracking_callback.borrow())(fm);
return Some(fm.clone());
}
}
@@ -513,7 +488,6 @@ impl CodeMap {
pub fn lookup_byte_offset(&self, bpos: BytePos) -> FileMapAndBytePos {
let idx = self.lookup_filemap_idx(bpos);
let fm = (*self.files.borrow())[idx].clone();
(self.dep_tracking_callback.borrow())(&fm);
let offset = bpos - fm.start_pos;
FileMapAndBytePos {fm: fm, pos: offset}
}
@@ -524,8 +498,6 @@ impl CodeMap {
let files = self.files.borrow();
let map = &(*files)[idx];

(self.dep_tracking_callback.borrow())(map);

// The number of extra bytes due to multibyte chars in the FileMap
let mut total_extra_bytes = 0;

1 change: 1 addition & 0 deletions src/test/incremental/rlib_cross_crate/auxiliary/a.rs
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
// except according to those terms.

// no-prefer-dynamic
// compile-flags: -Z query-dep-graph

#![crate_type="rlib"]

2 changes: 2 additions & 0 deletions src/test/incremental/type_alias_cross_crate/auxiliary/a.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z query-dep-graph

#![crate_type="rlib"]

#[cfg(rpass1)]