Skip to content

incr.comp.: Implement query result cache and use it to cache type checking tables. #46004

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 21 commits into from
Nov 17, 2017
Merged
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8cbc022
incr.comp.: Include header when loading cache files in order to get t…
michaelwoerister Nov 13, 2017
c08e03a
incr.comp.: Add position() method to TyEncoder.
michaelwoerister Nov 13, 2017
bc96d9d
incr.comp.: Implement UseSpecializedXXcodable for DefIndex and DefId.
michaelwoerister Nov 13, 2017
9ac1026
incr.comp.: Properly use ty::codec::decode_cnum() in rustc_metadata::…
michaelwoerister Nov 13, 2017
3bd333c
incr.comp.: Add CacheEncoder for encoding query results into the incr…
michaelwoerister Nov 13, 2017
15db165
incr.comp.: Implement TyDecoder for on_disk_cache::CacheDecoder.
michaelwoerister Nov 14, 2017
bedb44c
incr.comp.: Allow for mapping from prev-session-CrateNums to current-…
michaelwoerister Nov 14, 2017
de0317e
incr.comp.: Encode DefPathTables for reconstructing DefIds.
michaelwoerister Nov 14, 2017
2087d5e
incr.comp.: Do some verification on data decoded from incr. comp. cache.
michaelwoerister Nov 14, 2017
4bfab89
incr.comp.: Store the query result index which records where query re…
michaelwoerister Nov 14, 2017
0b14383
incr.comp.: Add 'tcx to QueryDescription.
michaelwoerister Nov 14, 2017
2c1aedd
incr.comp.: Cache TypeckTables and add -Zincremental-queries flag.
michaelwoerister Nov 14, 2017
279b6df
incr.comp.: Refactor query cache serialization to be more re-usable.
michaelwoerister Nov 15, 2017
13582c6
incr.comp.: Add missing [input] annotation for DepNode::MaybeUnusedEx…
michaelwoerister Nov 15, 2017
2f50e62
incr.comp.: Only save and load query result cache when -Zincremental-…
michaelwoerister Nov 15, 2017
24e54dd
Introduce LocalDefId which provides a type-level guarantee that the D…
michaelwoerister Nov 16, 2017
2f44ef2
incr.comp.: Encode DefIds as DefPathHashes instead of recomputing tho…
michaelwoerister Nov 16, 2017
723028f
incr.comp.: Remove some code duplication around TyDecoder by factorin…
michaelwoerister Nov 16, 2017
cb1ff24
incr.comp.: Remove default serialization implementations for things i…
michaelwoerister Nov 16, 2017
4c4f7a3
Fix some tidy errors in ty::codec.
michaelwoerister Nov 16, 2017
0a1f6dd
Add doc comment for LocalDefId.
michaelwoerister Nov 16, 2017
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
138 changes: 65 additions & 73 deletions src/librustc/ty/maps/on_disk_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
use dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
use errors::Diagnostic;
use hir;
use hir::def_id::{CrateNum, DefIndex, DefId, RESERVED_FOR_INCR_COMP_CACHE,
LOCAL_CRATE};
use hir::map::definitions::{Definitions, DefPathTable};
use hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId,
RESERVED_FOR_INCR_COMP_CACHE, LOCAL_CRATE};
use hir::map::definitions::DefPathHash;
use middle::const_val::ByteArray;
use middle::cstore::CrateStore;
use rustc_data_structures::fx::FxHashMap;
Expand All @@ -37,7 +37,6 @@ use ty::subst::Substs;
// Some magic values used for verifying that encoding and decoding. These are
// basically random numbers.
const PREV_DIAGNOSTICS_TAG: u64 = 0x1234_5678_A1A1_A1A1;
const DEF_PATH_TABLE_TAG: u64 = 0x1234_5678_B2B2_B2B2;
const QUERY_RESULT_INDEX_TAG: u64 = 0x1234_5678_C3C3_C3C3;

/// `OnDiskCache` provides an interface to incr. comp. data cached from the
Expand All @@ -56,10 +55,8 @@ pub struct OnDiskCache<'sess> {
// compilation session.
current_diagnostics: RefCell<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,


prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
cnum_map: RefCell<Option<IndexVec<CrateNum, Option<CrateNum>>>>,
prev_def_path_tables: Vec<DefPathTable>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice.


prev_filemap_starts: BTreeMap<BytePos, StableFilemapId>,
codemap: &'sess CodeMap,
Expand Down Expand Up @@ -92,14 +89,13 @@ impl<'sess> OnDiskCache<'sess> {
(header, decoder.position())
};

let (prev_diagnostics, prev_def_path_tables, query_result_index) = {
let (prev_diagnostics, query_result_index) = {
let mut decoder = CacheDecoder {
tcx: None,
opaque: opaque::Decoder::new(&data[..], post_header_pos),
codemap: sess.codemap(),
prev_filemap_starts: &header.prev_filemap_starts,
cnum_map: &IndexVec::new(),
prev_def_path_tables: &Vec::new(),
};

// Decode Diagnostics
Expand All @@ -111,11 +107,6 @@ impl<'sess> OnDiskCache<'sess> {
diagnostics.into_iter().collect()
};

// Decode DefPathTables
let prev_def_path_tables: Vec<DefPathTable> =
decode_tagged(&mut decoder, DEF_PATH_TABLE_TAG)
.expect("Error while trying to decode cached DefPathTables.");

// Decode the *position* of the query result index
let query_result_index_pos = {
let pos_pos = data.len() - IntEncodedWithFixedSize::ENCODED_SIZE;
Expand All @@ -131,7 +122,7 @@ impl<'sess> OnDiskCache<'sess> {
decode_tagged(decoder, QUERY_RESULT_INDEX_TAG)
}).expect("Error while trying to decode query result index.");

(prev_diagnostics, prev_def_path_tables, query_result_index)
(prev_diagnostics, query_result_index)
};

OnDiskCache {
Expand All @@ -140,7 +131,6 @@ impl<'sess> OnDiskCache<'sess> {
prev_filemap_starts: header.prev_filemap_starts,
prev_cnums: header.prev_cnums,
cnum_map: RefCell::new(None),
prev_def_path_tables,
codemap: sess.codemap(),
current_diagnostics: RefCell::new(FxHashMap()),
query_result_index: query_result_index.into_iter().collect(),
Expand All @@ -154,7 +144,6 @@ impl<'sess> OnDiskCache<'sess> {
prev_filemap_starts: BTreeMap::new(),
prev_cnums: vec![],
cnum_map: RefCell::new(None),
prev_def_path_tables: Vec::new(),
codemap,
current_diagnostics: RefCell::new(FxHashMap()),
query_result_index: FxHashMap(),
Expand All @@ -172,10 +161,10 @@ impl<'sess> OnDiskCache<'sess> {
let _in_ignore = tcx.dep_graph.in_ignore();

let mut encoder = CacheEncoder {
tcx,
encoder,
type_shorthands: FxHashMap(),
predicate_shorthands: FxHashMap(),
definitions: tcx.hir.definitions(),
};


Expand Down Expand Up @@ -212,22 +201,6 @@ impl<'sess> OnDiskCache<'sess> {
encoder.encode_tagged(PREV_DIAGNOSTICS_TAG, &diagnostics)?;


// Encode all DefPathTables
let upstream_def_path_tables = tcx.all_crate_nums(LOCAL_CRATE)
.iter()
.map(|&cnum| (cnum, cstore.def_path_table(cnum)))
.collect::<FxHashMap<_,_>>();
let def_path_tables: Vec<&DefPathTable> = sorted_cnums.into_iter().map(|cnum| {
if cnum == LOCAL_CRATE {
tcx.hir.definitions().def_path_table()
} else {
&*upstream_def_path_tables[&cnum]
}
}).collect();

encoder.encode_tagged(DEF_PATH_TABLE_TAG, &def_path_tables)?;


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

Expand Down Expand Up @@ -297,7 +270,6 @@ impl<'sess> OnDiskCache<'sess> {
codemap: self.codemap,
prev_filemap_starts: &self.prev_filemap_starts,
cnum_map: cnum_map.as_ref().unwrap(),
prev_def_path_tables: &self.prev_def_path_tables,
};

match decode_tagged(&mut decoder, dep_node_index) {
Expand Down Expand Up @@ -373,7 +345,6 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> {
codemap: &'x CodeMap,
prev_filemap_starts: &'x BTreeMap<BytePos, StableFilemapId>,
cnum_map: &'x IndexVec<CrateNum, Option<CrateNum>>,
prev_def_path_tables: &'x Vec<DefPathTable>,
}

impl<'a, 'tcx, 'x> CacheDecoder<'a, 'tcx, 'x> {
Expand Down Expand Up @@ -548,32 +519,24 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<DefIndex> for CacheDecoder<'a, 'tcx, 'x> {
// sessions, to map the old DefId to the new one.
impl<'a, 'tcx, 'x> SpecializedDecoder<DefId> for CacheDecoder<'a, 'tcx, 'x> {
fn specialized_decode(&mut self) -> Result<DefId, Self::Error> {
// Decode the unmapped CrateNum
let prev_cnum = CrateNum::default_decode(self)?;

// Decode the unmapped DefIndex
let def_index = DefIndex::default_decode(self)?;

// Unmapped CrateNum and DefIndex are valid keys for the *cached*
// DefPathTables, so we use them to look up the DefPathHash.
let def_path_hash = self.prev_def_path_tables[prev_cnum.index()]
.def_path_hash(def_index);
// Load the DefPathHash which is was we encoded the DefId as.
let def_path_hash = DefPathHash::decode(self)?;

// Using the DefPathHash, we can lookup the new DefId
Ok(self.tcx().def_path_hash_to_def_id.as_ref().unwrap()[&def_path_hash])
}
}

impl<'a, 'tcx, 'x> SpecializedDecoder<LocalDefId> for CacheDecoder<'a, 'tcx, 'x> {
fn specialized_decode(&mut self) -> Result<LocalDefId, Self::Error> {
Ok(LocalDefId::from_def_id(DefId::decode(self)?))
}
}

impl<'a, 'tcx, 'x> SpecializedDecoder<hir::HirId> for CacheDecoder<'a, 'tcx, 'x> {
fn specialized_decode(&mut self) -> Result<hir::HirId, Self::Error> {
// Decode the unmapped DefIndex of the HirId.
let def_index = DefIndex::default_decode(self)?;

// Use the unmapped DefIndex to look up the DefPathHash in the cached
// DefPathTable. For HirIds we know that we always have to look in the
// *local* DefPathTable.
let def_path_hash = self.prev_def_path_tables[LOCAL_CRATE.index()]
.def_path_hash(def_index);
// Load the DefPathHash which is was we encoded the DefIndex as.
let def_path_hash = DefPathHash::decode(self)?;

// Use the DefPathHash to map to the current DefId.
let def_id = self.tcx()
Expand Down Expand Up @@ -666,16 +629,17 @@ for CacheDecoder<'a, 'tcx, 'x> {

//- ENCODING -------------------------------------------------------------------

struct CacheEncoder<'enc, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder
struct CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder,
'tcx: 'a,
{
tcx: TyCtxt<'a, 'tcx, 'tcx>,
encoder: &'enc mut E,
type_shorthands: FxHashMap<ty::Ty<'tcx>, usize>,
predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
definitions: &'enc Definitions,
}

impl<'enc, 'tcx, E> CacheEncoder<'enc, 'tcx, E>
impl<'enc, 'a, 'tcx, E> CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder
{
/// Encode something with additional information that allows to do some
Expand All @@ -699,15 +663,15 @@ impl<'enc, 'tcx, E> CacheEncoder<'enc, 'tcx, E>
}
}

impl<'enc, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'enc, 'tcx, E>
impl<'enc, 'a, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder
{
fn position(&self) -> usize {
self.encoder.position()
}
}

impl<'enc, 'tcx, E> SpecializedEncoder<ty::Ty<'tcx>> for CacheEncoder<'enc, 'tcx, E>
impl<'enc, 'a, 'tcx, E> SpecializedEncoder<ty::Ty<'tcx>> for CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder
{
fn specialized_encode(&mut self, ty: &ty::Ty<'tcx>) -> Result<(), Self::Error> {
Expand All @@ -716,8 +680,8 @@ impl<'enc, 'tcx, E> SpecializedEncoder<ty::Ty<'tcx>> for CacheEncoder<'enc, 'tcx
}
}

impl<'enc, 'tcx, E> SpecializedEncoder<ty::GenericPredicates<'tcx>>
for CacheEncoder<'enc, 'tcx, E>
impl<'enc, 'a, 'tcx, E> SpecializedEncoder<ty::GenericPredicates<'tcx>>
for CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder
{
fn specialized_encode(&mut self,
Expand All @@ -728,7 +692,7 @@ impl<'enc, 'tcx, E> SpecializedEncoder<ty::GenericPredicates<'tcx>>
}
}

impl<'enc, 'tcx, E> SpecializedEncoder<hir::HirId> for CacheEncoder<'enc, 'tcx, E>
impl<'enc, 'a, 'tcx, E> SpecializedEncoder<hir::HirId> for CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder
{
fn specialized_encode(&mut self, id: &hir::HirId) -> Result<(), Self::Error> {
Expand All @@ -737,18 +701,46 @@ impl<'enc, 'tcx, E> SpecializedEncoder<hir::HirId> for CacheEncoder<'enc, 'tcx,
local_id,
} = *id;

owner.encode(self)?;
let def_path_hash = self.tcx.hir.definitions().def_path_hash(owner);

def_path_hash.encode(self)?;
local_id.encode(self)
}
}


impl<'enc, 'a, 'tcx, E> SpecializedEncoder<DefId> for CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder
{
fn specialized_encode(&mut self, id: &DefId) -> Result<(), Self::Error> {
let def_path_hash = self.tcx.def_path_hash(*id);
def_path_hash.encode(self)
}
}

impl<'enc, 'a, 'tcx, E> SpecializedEncoder<LocalDefId> for CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder
{
fn specialized_encode(&mut self, id: &LocalDefId) -> Result<(), Self::Error> {
id.to_def_id().encode(self)
}
}

impl<'enc, 'a, 'tcx, E> SpecializedEncoder<DefIndex> for CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder
{
fn specialized_encode(&mut self, _: &DefIndex) -> Result<(), Self::Error> {
bug!("Encoding DefIndex without context.")
}
}

// NodeIds are not stable across compilation sessions, so we store them in their
// HirId representation. This allows use to map them to the current NodeId.
impl<'enc, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'enc, 'tcx, E>
impl<'enc, 'a, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder
{
fn specialized_encode(&mut self, node_id: &NodeId) -> Result<(), Self::Error> {
let hir_id = self.definitions.node_to_hir_id(*node_id);
let hir_id = self.tcx.hir.node_to_hir_id(*node_id);
hir_id.encode(self)
}
}
Expand All @@ -761,7 +753,7 @@ macro_rules! encoder_methods {
}
}

impl<'enc, 'tcx, E> Encoder for CacheEncoder<'enc, 'tcx, E>
impl<'enc, 'a, 'tcx, E> Encoder for CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder
{
type Error = E::Error;
Expand Down Expand Up @@ -803,8 +795,8 @@ impl IntEncodedWithFixedSize {
impl UseSpecializedEncodable for IntEncodedWithFixedSize {}
impl UseSpecializedDecodable for IntEncodedWithFixedSize {}

impl<'enc, 'tcx, E> SpecializedEncoder<IntEncodedWithFixedSize>
for CacheEncoder<'enc, 'tcx, E>
impl<'enc, 'a, 'tcx, E> SpecializedEncoder<IntEncodedWithFixedSize>
for CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder
{
fn specialized_encode(&mut self, x: &IntEncodedWithFixedSize) -> Result<(), Self::Error> {
Expand Down Expand Up @@ -836,12 +828,12 @@ for CacheDecoder<'a, 'tcx, 'x> {
}
}

fn encode_query_results<'x, 'a, 'tcx, Q, E>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
encoder: &mut CacheEncoder<'x, 'tcx, E>,
query_result_index: &mut EncodedQueryResultIndex)
-> Result<(), E::Error>
fn encode_query_results<'enc, 'a, 'tcx, Q, E>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
encoder: &mut CacheEncoder<'enc, 'a, 'tcx, E>,
query_result_index: &mut EncodedQueryResultIndex)
-> Result<(), E::Error>
where Q: super::plumbing::GetCacheInternal<'tcx>,
E: 'x + TyEncoder,
E: 'enc + TyEncoder,
Q::Value: Encodable,
{
for (key, entry) in Q::get_cache_internal(tcx).map.iter() {
Expand Down