Skip to content
Closed
11 changes: 10 additions & 1 deletion compiler/rustc_data_structures/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ cfg_if! {
}
}

use std::ops::Add;
use std::ops::{Add, BitOr};
use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe};

/// This is a single threaded variant of AtomicCell provided by crossbeam.
Expand Down Expand Up @@ -147,6 +147,15 @@ cfg_if! {
}
}

impl<T: BitOr<Output=T> + Copy> Atomic<T> {
#[inline]
pub fn fetch_or(&self, val: T, _: Ordering) -> T {
let old = self.0.get();
self.0.set(old | val);
old
}
}

pub type AtomicUsize = Atomic<usize>;
pub type AtomicBool = Atomic<bool>;
pub type AtomicU32 = Atomic<u32>;
Expand Down
28 changes: 3 additions & 25 deletions compiler/rustc_incremental/src/persist/dirty_clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@
//! the required condition is not met.

use rustc_ast::{self as ast, Attribute, NestedMetaItem};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::Node as HirNode;
use rustc_hir::{ImplItemKind, ItemKind as HirItem, TraitItemKind};
use rustc_middle::dep_graph::{label_strs, DepNode, DepNodeExt};
use rustc_middle::dep_graph::{label_strs, DepNode, DepNodeColor, DepNodeExt};
use rustc_middle::hir::map::Map;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::{sym, Symbol};
Expand Down Expand Up @@ -391,39 +390,18 @@ impl DirtyCleanVisitor<'tcx> {
fn assert_dirty(&self, item_span: Span, dep_node: DepNode) {
debug!("assert_dirty({:?})", dep_node);

let current_fingerprint = self.get_fingerprint(&dep_node);
let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node);

if current_fingerprint == prev_fingerprint {
if self.tcx.dep_graph.node_color(&dep_node) == Some(DepNodeColor::Green) {
let dep_node_str = self.dep_node_str(&dep_node);
self.tcx
.sess
.span_err(item_span, &format!("`{}` should be dirty but is not", dep_node_str));
}
}

fn get_fingerprint(&self, dep_node: &DepNode) -> Option<Fingerprint> {
if self.tcx.dep_graph.dep_node_exists(dep_node) {
let dep_node_index = self.tcx.dep_graph.dep_node_index_of(dep_node);
Some(self.tcx.dep_graph.fingerprint_of(dep_node_index))
} else {
None
}
}

fn assert_clean(&self, item_span: Span, dep_node: DepNode) {
debug!("assert_clean({:?})", dep_node);

let current_fingerprint = self.get_fingerprint(&dep_node);
let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node);

// if the node wasn't previously evaluated and now is (or vice versa),
// then the node isn't actually clean or dirty.
if (current_fingerprint == None) ^ (prev_fingerprint == None) {
return;
}

if current_fingerprint != prev_fingerprint {
if self.tcx.dep_graph.node_color(&dep_node) == Some(DepNodeColor::Red) {
let dep_node_str = self.dep_node_str(&dep_node);
self.tcx
.sess
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_incremental/src/persist/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use rustc_data_structures::fx::FxHashMap;
use rustc_hir::definitions::Definitions;
use rustc_middle::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId};
use rustc_middle::dep_graph::{SerializedDepGraph, WorkProduct, WorkProductId};
use rustc_middle::ty::query::OnDiskCache;
use rustc_serialize::opaque::Decoder;
use rustc_serialize::Decodable as RustcDecodable;
Expand All @@ -22,8 +22,8 @@ pub enum LoadResult<T> {
Error { message: String },
}

impl LoadResult<(PreviousDepGraph, WorkProductMap)> {
pub fn open(self, sess: &Session) -> (PreviousDepGraph, WorkProductMap) {
impl LoadResult<(SerializedDepGraph, WorkProductMap)> {
pub fn open(self, sess: &Session) -> (SerializedDepGraph, WorkProductMap) {
match self {
LoadResult::Error { message } => {
sess.warn(&message);
Expand Down Expand Up @@ -84,7 +84,7 @@ impl<T> MaybeAsync<T> {
}
}

pub type DepGraphFuture = MaybeAsync<LoadResult<(PreviousDepGraph, WorkProductMap)>>;
pub type DepGraphFuture = MaybeAsync<LoadResult<(SerializedDepGraph, WorkProductMap)>>;

/// Launch a thread and load the dependency graph in the background.
pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
Expand Down Expand Up @@ -185,7 +185,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
let dep_graph = SerializedDepGraph::decode(&mut decoder)
.expect("Error reading cached dep-graph");

LoadResult::Ok { data: (PreviousDepGraph::new(dep_graph), prev_work_products) }
LoadResult::Ok { data: (dep_graph, prev_work_products) }
}
}
}))
Expand Down
139 changes: 139 additions & 0 deletions compiler/rustc_index/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -842,5 +842,144 @@ impl<I: Idx> FnMut<(usize,)> for IntoIdx<I> {
}
}

#[derive(Clone, PartialEq, Eq, Hash)]
pub struct IndexArray<I: Idx, T> {
pub raw: Box<[T]>,
_marker: PhantomData<fn(&I)>,
}

// Whether `IndexArray` is `Send` depends only on the data,
// not the phantom data.
unsafe impl<I: Idx, T> Send for IndexArray<I, T> where T: Send {}

impl<S: Encoder, I: Idx, T: Encodable<S>> Encodable<S> for IndexArray<I, T> {
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
Encodable::encode(&self.raw, s)
}
}

impl<S: Encoder, I: Idx, T: Encodable<S>> Encodable<S> for &IndexArray<I, T> {
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
Encodable::encode(&self.raw, s)
}
}

impl<D: Decoder, I: Idx, T: Decodable<D>> Decodable<D> for IndexArray<I, T> {
fn decode(d: &mut D) -> Result<Self, D::Error> {
Decodable::decode(d).map(|v| IndexArray { raw: v, _marker: PhantomData })
}
}

impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexArray<I, T> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.raw, fmt)
}
}

impl<I: Idx, T> IndexArray<I, T> {
#[inline]
pub fn new() -> Self {
IndexArray { raw: Box::default(), _marker: PhantomData }
}

#[inline]
pub fn from_raw(raw: Box<[T]>) -> Self {
IndexArray { raw, _marker: PhantomData }
}

#[inline]
pub fn from_vec(raw: Vec<T>) -> Self {
IndexArray { raw: raw.into(), _marker: PhantomData }
}

#[inline]
pub fn len(&self) -> usize {
self.raw.len()
}

#[inline]
pub fn is_empty(&self) -> bool {
self.raw.is_empty()
}

#[inline]
pub fn iter(&self) -> slice::Iter<'_, T> {
self.raw.iter()
}

#[inline]
pub fn iter_enumerated(&self) -> Enumerated<I, slice::Iter<'_, T>> {
self.raw.iter().enumerate().map(IntoIdx { _marker: PhantomData })
}

#[inline]
pub fn indices(&self) -> iter::Map<Range<usize>, IntoIdx<I>> {
(0..self.len()).map(IntoIdx { _marker: PhantomData })
}

#[inline]
pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
self.raw.iter_mut()
}

#[inline]
pub fn iter_enumerated_mut(&mut self) -> Enumerated<I, slice::IterMut<'_, T>> {
self.raw.iter_mut().enumerate().map(IntoIdx { _marker: PhantomData })
}
}

impl<I: Idx, T> Index<I> for IndexArray<I, T> {
type Output = T;

#[inline]
fn index(&self, index: I) -> &T {
&self.raw[index.index()]
}
}

impl<I: Idx, T> IndexMut<I> for IndexArray<I, T> {
#[inline]
fn index_mut(&mut self, index: I) -> &mut T {
&mut self.raw[index.index()]
}
}

impl<I: Idx, T> Default for IndexArray<I, T> {
#[inline]
fn default() -> Self {
Self::new()
}
}

impl<I: Idx, T> FromIterator<T> for IndexArray<I, T> {
#[inline]
fn from_iter<J>(iter: J) -> Self
where
J: IntoIterator<Item = T>,
{
IndexArray { raw: FromIterator::from_iter(iter), _marker: PhantomData }
}
}

impl<'a, I: Idx, T> IntoIterator for &'a IndexArray<I, T> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;

#[inline]
fn into_iter(self) -> slice::Iter<'a, T> {
self.raw.iter()
}
}

impl<'a, I: Idx, T> IntoIterator for &'a mut IndexArray<I, T> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;

#[inline]
fn into_iter(self) -> slice::IterMut<'a, T> {
self.raw.iter_mut()
}
}

#[cfg(test)]
mod tests;
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ use rustc_hir::HirId;
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::{DepContext, DepNodeColor, DepNodeParams};

/// This struct stores metadata about each DepKind.
///
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/dep_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pub use dep_node::{label_strs, DepKind, DepNode, DepNodeExt};
pub type DepGraph = rustc_query_system::dep_graph::DepGraph<DepKind>;
pub type TaskDeps = rustc_query_system::dep_graph::TaskDeps<DepKind>;
pub type DepGraphQuery = rustc_query_system::dep_graph::DepGraphQuery<DepKind>;
pub type PreviousDepGraph = rustc_query_system::dep_graph::PreviousDepGraph<DepKind>;
pub type SerializedDepGraph = rustc_query_system::dep_graph::SerializedDepGraph<DepKind>;

impl rustc_query_system::dep_graph::DepKind for DepKind {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
use rustc_hir::lang_items::{LangItem, LanguageItems};
use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
use rustc_query_system::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
use rustc_serialize::opaque;
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
use rustc_session::utils::NativeLibKind;
Expand Down Expand Up @@ -237,6 +238,7 @@ macro_rules! define_callbacks {
tcx: TyCtxt<'tcx>,
encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>,
query_result_index: &mut on_disk_cache::EncodedQueryResultIndex,
remap: &IndexVec<DepNodeIndex, Option<SerializedDepNodeIndex>>,
) -> opaque::FileEncodeResult;

fn exec_cache_promotions(&'tcx self, tcx: TyCtxt<'tcx>);
Expand Down
13 changes: 8 additions & 5 deletions compiler/rustc_middle/src/ty/query/on_disk_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rustc_errors::Diagnostic;
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
use rustc_hir::definitions::DefPathHash;
use rustc_hir::definitions::Definitions;
use rustc_index::vec::{Idx, IndexVec};
use rustc_index::vec::IndexVec;
use rustc_query_system::dep_graph::DepContext;
use rustc_query_system::query::QueryContext;
use rustc_serialize::{
Expand Down Expand Up @@ -303,13 +303,15 @@ impl<'sess> OnDiskCache<'sess> {
latest_foreign_def_path_hashes,
};

let remap = tcx.dep_graph.compression_map();

// Encode query results.
let mut query_result_index = EncodedQueryResultIndex::new();

tcx.sess.time("encode_query_results", || -> FileEncodeResult {
let enc = &mut encoder;
let qri = &mut query_result_index;
tcx.queries.encode_query_results(tcx, enc, qri)
tcx.queries.encode_query_results(tcx, enc, qri, &remap)
})?;

// Encode diagnostics.
Expand All @@ -318,11 +320,11 @@ impl<'sess> OnDiskCache<'sess> {
.borrow()
.iter()
.map(
|(dep_node_index, diagnostics)| -> Result<_, <FileEncoder as Encoder>::Error> {
|(&dep_node_index, diagnostics)| -> Result<_, <FileEncoder as Encoder>::Error> {
let pos = AbsoluteBytePos::new(encoder.position());
// Let's make sure we get the expected type here.
let diagnostics: &EncodedDiagnostics = diagnostics;
let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index());
let dep_node_index = remap[dep_node_index].unwrap();
encoder.encode_tagged(dep_node_index, diagnostics)?;

Ok((dep_node_index, pos))
Expand Down Expand Up @@ -1220,6 +1222,7 @@ pub fn encode_query_results<'a, 'tcx, CTX, Q>(
tcx: CTX,
encoder: &mut CacheEncoder<'a, 'tcx, FileEncoder>,
query_result_index: &mut EncodedQueryResultIndex,
remap: &IndexVec<DepNodeIndex, Option<SerializedDepNodeIndex>>,
) -> FileEncodeResult
where
CTX: QueryContext + 'tcx,
Expand All @@ -1236,7 +1239,7 @@ where
cache.iter_results(|results| {
for (key, value, dep_node) in results {
if Q::cache_on_disk(tcx, &key, Some(value)) {
let dep_node = SerializedDepNodeIndex::new(dep_node.index());
let dep_node = remap[dep_node].unwrap();

// Record position of the cache entry.
query_result_index
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_query_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use rustc_middle::ich::StableHashingContext;
use rustc_middle::ty::query::{query_keys, query_storage, query_stored, query_values};
use rustc_middle::ty::query::{Providers, QueryEngine};
use rustc_middle::ty::{self, TyCtxt};
use rustc_query_system::dep_graph::{DepNodeColor, DepNodeIndex, SerializedDepNodeIndex};
use rustc_serialize::opaque;
use rustc_span::{Span, DUMMY_SP};

Expand Down
Loading