Skip to content

Commit 02eed2e

Browse files
committed
Auto merge of #46004 - michaelwoerister:cached-mir-wip-3, r=nikomatsakis
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
2 parents b32267f + 0a1f6dd commit 02eed2e

File tree

29 files changed

+1161
-370
lines changed

29 files changed

+1161
-370
lines changed

src/librustc/dep_graph/dep_node.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ define_dep_nodes!( <'tcx>
618618

619619
[input] Freevars(DefId),
620620
[input] MaybeUnusedTraitImport(DefId),
621-
[] MaybeUnusedExternCrates,
621+
[input] MaybeUnusedExternCrates,
622622
[] StabilityIndex,
623623
[input] AllCrateNums,
624624
[] ExportedSymbols(CrateNum),

src/librustc/dep_graph/graph.rs

+6
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ impl DepGraph {
327327
}
328328
}
329329

330+
#[inline]
330331
pub fn fingerprint_of(&self, dep_node: &DepNode) -> Fingerprint {
331332
match self.fingerprints.borrow().get(dep_node) {
332333
Some(&fingerprint) => fingerprint,
@@ -340,6 +341,11 @@ impl DepGraph {
340341
self.data.as_ref().unwrap().previous.fingerprint_of(dep_node)
341342
}
342343

344+
#[inline]
345+
pub fn prev_dep_node_index_of(&self, dep_node: &DepNode) -> SerializedDepNodeIndex {
346+
self.data.as_ref().unwrap().previous.node_to_index(dep_node)
347+
}
348+
343349
/// Indicates that a previous work product exists for `v`. This is
344350
/// invoked during initial start-up based on what nodes are clean
345351
/// (and what files exist in the incr. directory).

src/librustc/dep_graph/prev.rs

+5
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ impl PreviousDepGraph {
4444
self.data.nodes[dep_node_index].0
4545
}
4646

47+
#[inline]
48+
pub fn node_to_index(&self, dep_node: &DepNode) -> SerializedDepNodeIndex {
49+
self.index[dep_node]
50+
}
51+
4752
#[inline]
4853
pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
4954
self.index

src/librustc/hir/def_id.rs

+58-16
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
use ty;
1212

1313
use rustc_data_structures::indexed_vec::Idx;
14-
use serialize::{self, Encoder, Decoder};
15-
14+
use serialize;
1615
use std::fmt;
1716
use std::u32;
1817

@@ -32,6 +31,10 @@ newtype_index!(CrateNum
3231

3332
/// A CrateNum value that indicates that something is wrong.
3433
const INVALID_CRATE = u32::MAX - 1,
34+
35+
/// A special CrateNum that we use for the tcx.rcache when decoding from
36+
/// the incr. comp. cache.
37+
const RESERVED_FOR_INCR_COMP_CACHE = u32::MAX - 2,
3538
});
3639

3740
impl CrateNum {
@@ -61,17 +64,8 @@ impl fmt::Display for CrateNum {
6164
}
6265
}
6366

64-
impl serialize::UseSpecializedEncodable for CrateNum {
65-
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
66-
s.emit_u32(self.0)
67-
}
68-
}
69-
70-
impl serialize::UseSpecializedDecodable for CrateNum {
71-
fn default_decode<D: Decoder>(d: &mut D) -> Result<CrateNum, D::Error> {
72-
d.read_u32().map(CrateNum)
73-
}
74-
}
67+
impl serialize::UseSpecializedEncodable for CrateNum {}
68+
impl serialize::UseSpecializedDecodable for CrateNum {}
7569

7670
/// A DefIndex is an index into the hir-map for a crate, identifying a
7771
/// particular definition. It should really be considered an interned
@@ -88,6 +82,7 @@ impl serialize::UseSpecializedDecodable for CrateNum {
8882
/// don't have to care about these ranges.
8983
newtype_index!(DefIndex
9084
{
85+
ENCODABLE = custom
9186
DEBUG_FORMAT = custom,
9287

9388
/// The start of the "high" range of DefIndexes.
@@ -146,6 +141,9 @@ impl DefIndex {
146141
}
147142
}
148143

144+
impl serialize::UseSpecializedEncodable for DefIndex {}
145+
impl serialize::UseSpecializedDecodable for DefIndex {}
146+
149147
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
150148
pub enum DefIndexAddressSpace {
151149
Low = 0,
@@ -166,7 +164,7 @@ impl DefIndexAddressSpace {
166164

167165
/// A DefId identifies a particular *definition*, by combining a crate
168166
/// index and a def index.
169-
#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, RustcDecodable, Hash, Copy)]
167+
#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, Hash, Copy)]
170168
pub struct DefId {
171169
pub krate: CrateNum,
172170
pub index: DefIndex,
@@ -188,14 +186,58 @@ impl fmt::Debug for DefId {
188186
}
189187
}
190188

191-
192189
impl DefId {
193190
/// Make a local `DefId` with the given index.
191+
#[inline]
194192
pub fn local(index: DefIndex) -> DefId {
195193
DefId { krate: LOCAL_CRATE, index: index }
196194
}
197195

198-
pub fn is_local(&self) -> bool {
196+
#[inline]
197+
pub fn is_local(self) -> bool {
199198
self.krate == LOCAL_CRATE
200199
}
200+
201+
#[inline]
202+
pub fn to_local(self) -> LocalDefId {
203+
LocalDefId::from_def_id(self)
204+
}
201205
}
206+
207+
impl serialize::UseSpecializedEncodable for DefId {}
208+
impl serialize::UseSpecializedDecodable for DefId {}
209+
210+
/// A LocalDefId is equivalent to a DefId with `krate == LOCAL_CRATE`. Since
211+
/// we encode this information in the type, we can ensure at compile time that
212+
/// no DefIds from upstream crates get thrown into the mix. There are quite a
213+
/// few cases where we know that only DefIds from the local crate are expected
214+
/// and a DefId from a different crate would signify a bug somewhere. This
215+
/// is when LocalDefId comes in handy.
216+
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
217+
pub struct LocalDefId(DefIndex);
218+
219+
impl LocalDefId {
220+
221+
#[inline]
222+
pub fn from_def_id(def_id: DefId) -> LocalDefId {
223+
assert!(def_id.is_local());
224+
LocalDefId(def_id.index)
225+
}
226+
227+
#[inline]
228+
pub fn to_def_id(self) -> DefId {
229+
DefId {
230+
krate: LOCAL_CRATE,
231+
index: self.0
232+
}
233+
}
234+
}
235+
236+
impl fmt::Debug for LocalDefId {
237+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
238+
self.to_def_id().fmt(f)
239+
}
240+
}
241+
242+
impl serialize::UseSpecializedEncodable for LocalDefId {}
243+
impl serialize::UseSpecializedDecodable for LocalDefId {}

src/librustc/hir/map/mod.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData,
1717

1818
use dep_graph::{DepGraph, DepNode, DepKind, DepNodeIndex};
1919

20-
use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndexAddressSpace};
20+
use hir::def_id::{CRATE_DEF_INDEX, DefId, LocalDefId, DefIndexAddressSpace};
2121

2222
use syntax::abi::Abi;
2323
use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID};
@@ -359,6 +359,16 @@ impl<'hir> Map<'hir> {
359359
self.definitions.as_local_node_id(DefId::local(def_index)).unwrap()
360360
}
361361

362+
#[inline]
363+
pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
364+
self.definitions.def_index_to_hir_id(def_id.to_def_id().index)
365+
}
366+
367+
#[inline]
368+
pub fn local_def_id_to_node_id(&self, def_id: LocalDefId) -> NodeId {
369+
self.definitions.as_local_node_id(def_id.to_def_id()).unwrap()
370+
}
371+
362372
fn entry_count(&self) -> usize {
363373
self.map.len()
364374
}

src/librustc/hir/mod.rs

+27-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use ty::AdtKind;
4545

4646
use rustc_data_structures::indexed_vec;
4747

48+
use serialize::{self, Encoder, Encodable, Decoder, Decodable};
4849
use std::collections::BTreeMap;
4950
use std::fmt;
5051

@@ -85,13 +86,37 @@ pub mod svh;
8586
/// the local_id part of the HirId changing, which is a very useful property in
8687
/// incremental compilation where we have to persist things through changes to
8788
/// the code base.
88-
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug,
89-
RustcEncodable, RustcDecodable)]
89+
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
9090
pub struct HirId {
9191
pub owner: DefIndex,
9292
pub local_id: ItemLocalId,
9393
}
9494

95+
impl serialize::UseSpecializedEncodable for HirId {
96+
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
97+
let HirId {
98+
owner,
99+
local_id,
100+
} = *self;
101+
102+
owner.encode(s)?;
103+
local_id.encode(s)
104+
}
105+
}
106+
107+
impl serialize::UseSpecializedDecodable for HirId {
108+
fn default_decode<D: Decoder>(d: &mut D) -> Result<HirId, D::Error> {
109+
let owner = DefIndex::decode(d)?;
110+
let local_id = ItemLocalId::decode(d)?;
111+
112+
Ok(HirId {
113+
owner,
114+
local_id
115+
})
116+
}
117+
}
118+
119+
95120
/// An `ItemLocalId` uniquely identifies something within a given "item-like",
96121
/// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no
97122
/// guarantee that the numerical value of a given `ItemLocalId` corresponds to

src/librustc/ich/impls_hir.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
1414
use hir;
1515
use hir::map::DefPathHash;
16-
use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
16+
use hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX};
1717
use ich::{StableHashingContext, NodeIdHashingMode};
1818
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
1919
StableHasher, StableHasherResult};
@@ -38,6 +38,24 @@ impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for DefId {
3838
}
3939
}
4040

41+
impl<'gcx> HashStable<StableHashingContext<'gcx>> for LocalDefId {
42+
#[inline]
43+
fn hash_stable<W: StableHasherResult>(&self,
44+
hcx: &mut StableHashingContext<'gcx>,
45+
hasher: &mut StableHasher<W>) {
46+
hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
47+
}
48+
}
49+
50+
impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for LocalDefId {
51+
type KeyType = DefPathHash;
52+
53+
#[inline]
54+
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'gcx>) -> DefPathHash {
55+
hcx.def_path_hash(self.to_def_id())
56+
}
57+
}
58+
4159
impl<'gcx> HashStable<StableHashingContext<'gcx>> for CrateNum {
4260
#[inline]
4361
fn hash_stable<W: StableHasherResult>(&self,

src/librustc/middle/cstore.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
2525
use hir;
2626
use hir::def;
27-
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
27+
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
2828
use hir::map as hir_map;
2929
use hir::map::definitions::{Definitions, DefKey, DefPathTable};
3030
use hir::svh::Svh;
@@ -180,7 +180,7 @@ impl EncodedMetadata {
180180
/// upstream crate.
181181
#[derive(Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
182182
pub struct EncodedMetadataHash {
183-
pub def_index: DefIndex,
183+
pub def_index: u32,
184184
pub hash: ich::Fingerprint,
185185
}
186186

src/librustc/middle/expr_use_visitor.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use self::TrackMatchMode::*;
2020
use self::OverloadedCallType::*;
2121

2222
use hir::def::Def;
23-
use hir::def_id::{DefId};
23+
use hir::def_id::DefId;
2424
use infer::InferCtxt;
2525
use middle::mem_categorization as mc;
2626
use middle::region;
@@ -915,7 +915,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
915915
let closure_def_id = self.tcx().hir.local_def_id(closure_expr.id);
916916
let upvar_id = ty::UpvarId {
917917
var_id: var_hir_id,
918-
closure_expr_id: closure_def_id.index
918+
closure_expr_id: closure_def_id.to_local(),
919919
};
920920
let upvar_capture = self.mc.tables.upvar_capture(upvar_id);
921921
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,

src/librustc/middle/mem_categorization.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub use self::Note::*;
7070
use self::Aliasability::*;
7171

7272
use middle::region;
73-
use hir::def_id::{DefId, DefIndex};
73+
use hir::def_id::{DefId, LocalDefId};
7474
use hir::map as hir_map;
7575
use infer::InferCtxt;
7676
use hir::def::{Def, CtorKind};
@@ -191,7 +191,7 @@ pub type cmt<'tcx> = Rc<cmt_<'tcx>>;
191191

192192
pub enum ImmutabilityBlame<'tcx> {
193193
ImmLocal(ast::NodeId),
194-
ClosureEnv(DefIndex),
194+
ClosureEnv(LocalDefId),
195195
LocalDeref(ast::NodeId),
196196
AdtFieldDeref(&'tcx ty::AdtDef, &'tcx ty::FieldDef)
197197
}
@@ -759,11 +759,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
759759
ref t => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", t),
760760
};
761761

762-
let closure_expr_def_index = self.tcx.hir.local_def_id(fn_node_id).index;
762+
let closure_expr_def_id = self.tcx.hir.local_def_id(fn_node_id);
763763
let var_hir_id = self.tcx.hir.node_to_hir_id(var_id);
764764
let upvar_id = ty::UpvarId {
765765
var_id: var_hir_id,
766-
closure_expr_id: closure_expr_def_index
766+
closure_expr_id: closure_expr_def_id.to_local(),
767767
};
768768

769769
let var_ty = self.node_ty(var_hir_id)?;
@@ -838,7 +838,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
838838
// The environment of a closure is guaranteed to
839839
// outlive any bindings introduced in the body of the
840840
// closure itself.
841-
scope: DefId::local(upvar_id.closure_expr_id),
841+
scope: upvar_id.closure_expr_id.to_def_id(),
842842
bound_region: ty::BrEnv
843843
}));
844844

src/librustc/session/config.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
10421042
"enable incremental compilation (experimental)"),
10431043
incremental_cc: bool = (false, parse_bool, [UNTRACKED],
10441044
"enable cross-crate incremental compilation (even more experimental)"),
1045+
incremental_queries: bool = (true, parse_bool, [UNTRACKED],
1046+
"enable incremental compilation support for queries (experimental)"),
10451047
incremental_info: bool = (false, parse_bool, [UNTRACKED],
10461048
"print high-level information about incremental reuse (or the lack thereof)"),
10471049
incremental_dump_hash: bool = (false, parse_bool, [UNTRACKED],

0 commit comments

Comments
 (0)