incr.comp.: Implement query result cache and use it to cache type checking tables.#46004
incr.comp.: Implement query result cache and use it to cache type checking tables.#46004bors merged 21 commits intorust-lang:masterfrom
Conversation
…he same byte offsets as when saving.
…session-CrateNums in OnDiskCaches.
…sults can be found in the cached.
…queries is specified.
|
Just found a bug in this: The Please do not merge until this is fixed. |
| let body = Body::decode(&mut decoder).unwrap(); | ||
| body.diagnostics.into_iter().collect() | ||
|
|
||
| let prev_diagnostics: FxHashMap<_, _> = { |
There was a problem hiding this comment.
Why do we have this new variable here? It doesn't serve an obvious purpose. =)
There was a problem hiding this comment.
It does in later commits where this block is used to limit the scope of the CacheDecoder.
| 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); |
There was a problem hiding this comment.
Is this basically copy-n-paste from the other encoders? (Not criticizing, just trying to understand.)
There was a problem hiding this comment.
Answer: this impl, anyway, is not.
There was a problem hiding this comment.
Yeah, I thought about writing a macro in ty::codec that would instantiate these implementations. Upfront, I wasn't sure though how many of them would end up just being copies.
| } | ||
| } | ||
|
|
||
| impl<'a, 'tcx, 'x> SpecializedDecoder<&'tcx Substs<'tcx>> for CacheDecoder<'a, 'tcx, 'x> { |
There was a problem hiding this comment.
If we forget one of these impls, what happens? I think it panics? (These impls are copy-n-paste, I assume.)
There was a problem hiding this comment.
Yeah, most of them should panic.
|
|
||
| prev_cnums: Vec<(u32, String, CrateDisambiguator)>, | ||
| cnum_map: RefCell<Option<IndexVec<CrateNum, Option<CrateNum>>>>, | ||
| prev_def_path_tables: Vec<DefPathTable>, |
There was a problem hiding this comment.
Does this signal a shift away from the "reverse lookup by hash" strategy?
There was a problem hiding this comment.
No, the DefPathTables are stored for facilitating the "reverse lookup by hash". The implementation in this PR does the following:
- Store a
DefIdunmodified in the cache. - When loading, we need to
- map the serialized
DefIdto the session-independentDefPathHashand then - look up the new
DefIdby thisDefPathHash.
- map the serialized
In order to be able to do step (i), we need the old DefPathTable because it maps DefIndices to DefPathHashes.
But,... I'm not surprised that this caught your eye. There is an alternative approach that is simpler to implement and maybe more robust: Map DefIds and DefIndices to DefPathHashes at serialization time and thus get rid of the requirement to store the old DefPathTables. I'm not sure if this affects performance and space requirements in a good or in a bad way. But I'd like to implement it soonish and measure the impact.
nikomatsakis
left a comment
There was a problem hiding this comment.
Did a first pass. Left some drive-by questions. The main "red flag" of sorts was that there seemed to be a bit more code duplication than I expected, though mostly it's just impls calling into common helpers, so perhaps it's fine. Not sure how best to avoid it, perhaps using a macro -- or there might be some specialization tricks we could use with a helper trait.
…efId is from the local crate.
…se during deserialization.
…g things into a macro.
…n rustc::hir::def_id so that we get an ICE instead of silently doing the wrong thing.
|
OK, this should be up-to-date now. I went ahead and implemented the "map to |
|
|
||
|
|
||
| #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] | ||
| pub struct LocalDefId(DefIndex); |
There was a problem hiding this comment.
I've wanted to add this type for so long. But can you please add a doc-comment explaining its role and why to use it, and also why it is bad to just use a raw DefIndex.
src/librustc/hir/def_id.rs
Outdated
| self.krate == LOCAL_CRATE | ||
| } | ||
|
|
||
| #[inline] |
|
|
||
| prev_cnums: Vec<(u32, String, CrateDisambiguator)>, | ||
| cnum_map: RefCell<Option<IndexVec<CrateNum, Option<CrateNum>>>>, | ||
| prev_def_path_tables: Vec<DefPathTable>, |
| ty_codec::decode_const(self) | ||
| } | ||
| } | ||
| implement_ty_decoder!( DecodeContext<'a, 'tcx> ); |
|
@bors r+ |
|
📌 Commit 4c4f7a3 has been approved by |
|
Er wait, I wanted something. @bors r- |
|
r=me with comment on |
5f4d5d3 to
0a1f6dd
Compare
|
@bors r=nikomatsakis |
|
📌 Commit 0a1f6dd has been approved by |
|
@bors p=1 (we'd like to get this tested on rust-icci asap) |
incr.comp.: Implement query result cache and use it to cache type checking tables. This is a spike implementation of caching more than LLVM IR and object files when doing incremental compilation. At the moment, only the `typeck_tables_of` query is cached but MIR and borrow-check will follow shortly. The feature is activated by running with `-Zincremental-queries` in addition to `-Zincremental`, it is not yet active by default. r? @nikomatsakis
|
☀️ Test successful - status-appveyor, status-travis |
|
Note, this is not expected to show up in any benchmarks yet since it's behind the |
This is a spike implementation of caching more than LLVM IR and object files when doing incremental compilation. At the moment, only the
typeck_tables_ofquery is cached but MIR and borrow-check will follow shortly. The feature is activated by running with-Zincremental-queriesin addition to-Zincremental, it is not yet active by default.r? @nikomatsakis