-
Notifications
You must be signed in to change notification settings - Fork 13.3k
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
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have this new variable here? It doesn't serve an obvious purpose. =)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this basically copy-n-paste from the other encoders? (Not criticizing, just trying to understand.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Answer: this impl, anyway, is not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, most of them should panic.
@@ -49,6 +49,7 @@ pub struct OnDiskCache<'sess> { | |||
|
|||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this signal a shift away from the "reverse lookup by hash" strategy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the DefPathTables
are stored for facilitating the "reverse lookup by hash". The implementation in this PR does the following:
- Store a
DefId
unmodified in the cache. - When loading, we need to
- map the serialized
DefId
to the session-independentDefPathHash
and then - look up the new
DefId
by 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I see.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lovely.
src/librustc/hir/def_id.rs
Outdated
|
||
|
||
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] | ||
pub struct LocalDefId(DefIndex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: extra space.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice.
ty_codec::decode_const(self) | ||
} | ||
} | ||
implement_ty_decoder!( DecodeContext<'a, 'tcx> ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also nice.
@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_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