Skip to content

Commit 7360d6d

Browse files
committed
Auto merge of #49833 - oli-obk:incremental_miri_regression, r=michaelwoerister
Don't recurse into allocations, use a global table instead r? @michaelwoerister fixes #49663
2 parents 602b395 + 7f7d4c3 commit 7360d6d

File tree

12 files changed

+271
-307
lines changed

12 files changed

+271
-307
lines changed

src/librustc/ich/impls_ty.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -398,12 +398,12 @@ impl_stable_hash_for!(struct mir::interpret::MemoryPointer {
398398

399399
enum AllocDiscriminant {
400400
Alloc,
401-
ExternStatic,
401+
Static,
402402
Function,
403403
}
404404
impl_stable_hash_for!(enum self::AllocDiscriminant {
405405
Alloc,
406-
ExternStatic,
406+
Static,
407407
Function
408408
});
409409

@@ -414,24 +414,25 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
414414
hasher: &mut StableHasher<W>,
415415
) {
416416
ty::tls::with_opt(|tcx| {
417+
trace!("hashing {:?}", *self);
417418
let tcx = tcx.expect("can't hash AllocIds during hir lowering");
418-
if let Some(alloc) = tcx.interpret_interner.get_alloc(*self) {
419+
if let Some(def_id) = tcx.interpret_interner.get_static(*self) {
420+
AllocDiscriminant::Static.hash_stable(hcx, hasher);
421+
trace!("hashing {:?} as static {:?}", *self, def_id);
422+
def_id.hash_stable(hcx, hasher);
423+
} else if let Some(alloc) = tcx.interpret_interner.get_alloc(*self) {
419424
AllocDiscriminant::Alloc.hash_stable(hcx, hasher);
420425
if hcx.alloc_id_recursion_tracker.insert(*self) {
421-
tcx
422-
.interpret_interner
423-
.get_corresponding_static_def_id(*self)
424-
.hash_stable(hcx, hasher);
426+
trace!("hashing {:?} as alloc {:#?}", *self, alloc);
425427
alloc.hash_stable(hcx, hasher);
426428
assert!(hcx.alloc_id_recursion_tracker.remove(self));
429+
} else {
430+
trace!("skipping hashing of {:?} due to recursion", *self);
427431
}
428432
} else if let Some(inst) = tcx.interpret_interner.get_fn(*self) {
433+
trace!("hashing {:?} as fn {:#?}", *self, inst);
429434
AllocDiscriminant::Function.hash_stable(hcx, hasher);
430435
inst.hash_stable(hcx, hasher);
431-
} else if let Some(def_id) = tcx.interpret_interner
432-
.get_corresponding_static_def_id(*self) {
433-
AllocDiscriminant::ExternStatic.hash_stable(hcx, hasher);
434-
def_id.hash_stable(hcx, hasher);
435436
} else {
436437
bug!("no allocation for {}", self);
437438
}

src/librustc/mir/interpret/mod.rs

+23-40
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,12 @@ pub struct AllocId(pub u64);
154154
impl ::rustc_serialize::UseSpecializedEncodable for AllocId {}
155155
impl ::rustc_serialize::UseSpecializedDecodable for AllocId {}
156156

157-
pub const ALLOC_DISCRIMINANT: usize = 0;
158-
pub const FN_DISCRIMINANT: usize = 1;
159-
pub const EXTERN_STATIC_DISCRIMINANT: usize = 2;
160-
pub const SHORTHAND_START: usize = 3;
157+
#[derive(RustcDecodable, RustcEncodable)]
158+
enum AllocKind {
159+
Alloc,
160+
Fn,
161+
Static,
162+
}
161163

162164
pub fn specialized_encode_alloc_id<
163165
'a, 'tcx,
@@ -166,26 +168,18 @@ pub fn specialized_encode_alloc_id<
166168
encoder: &mut E,
167169
tcx: TyCtxt<'a, 'tcx, 'tcx>,
168170
alloc_id: AllocId,
169-
shorthand: Option<usize>,
170171
) -> Result<(), E::Error> {
171-
if let Some(shorthand) = shorthand {
172-
return shorthand.encode(encoder);
173-
}
174172
if let Some(alloc) = tcx.interpret_interner.get_alloc(alloc_id) {
175173
trace!("encoding {:?} with {:#?}", alloc_id, alloc);
176-
ALLOC_DISCRIMINANT.encode(encoder)?;
174+
AllocKind::Alloc.encode(encoder)?;
177175
alloc.encode(encoder)?;
178-
// encode whether this allocation is the root allocation of a static
179-
tcx.interpret_interner
180-
.get_corresponding_static_def_id(alloc_id)
181-
.encode(encoder)?;
182176
} else if let Some(fn_instance) = tcx.interpret_interner.get_fn(alloc_id) {
183177
trace!("encoding {:?} with {:#?}", alloc_id, fn_instance);
184-
FN_DISCRIMINANT.encode(encoder)?;
178+
AllocKind::Fn.encode(encoder)?;
185179
fn_instance.encode(encoder)?;
186-
} else if let Some(did) = tcx.interpret_interner.get_corresponding_static_def_id(alloc_id) {
187-
// extern "C" statics don't have allocations, just encode its def_id
188-
EXTERN_STATIC_DISCRIMINANT.encode(encoder)?;
180+
} else if let Some(did) = tcx.interpret_interner.get_static(alloc_id) {
181+
// referring to statics doesn't need to know about their allocations, just about its DefId
182+
AllocKind::Static.encode(encoder)?;
189183
did.encode(encoder)?;
190184
} else {
191185
bug!("alloc id without corresponding allocation: {}", alloc_id);
@@ -196,53 +190,42 @@ pub fn specialized_encode_alloc_id<
196190
pub fn specialized_decode_alloc_id<
197191
'a, 'tcx,
198192
D: Decoder,
199-
CACHE: FnOnce(&mut D, usize, AllocId),
200-
SHORT: FnOnce(&mut D, usize) -> Result<AllocId, D::Error>
193+
CACHE: FnOnce(&mut D, AllocId),
201194
>(
202195
decoder: &mut D,
203196
tcx: TyCtxt<'a, 'tcx, 'tcx>,
204-
pos: usize,
205197
cache: CACHE,
206-
short: SHORT,
207198
) -> Result<AllocId, D::Error> {
208-
match usize::decode(decoder)? {
209-
ALLOC_DISCRIMINANT => {
199+
match AllocKind::decode(decoder)? {
200+
AllocKind::Alloc => {
210201
let alloc_id = tcx.interpret_interner.reserve();
211-
trace!("creating alloc id {:?} at {}", alloc_id, pos);
202+
trace!("creating alloc id {:?}", alloc_id);
212203
// insert early to allow recursive allocs
213-
cache(decoder, pos, alloc_id);
204+
cache(decoder, alloc_id);
214205

215206
let allocation = Allocation::decode(decoder)?;
216207
trace!("decoded alloc {:?} {:#?}", alloc_id, allocation);
217208
let allocation = tcx.intern_const_alloc(allocation);
218209
tcx.interpret_interner.intern_at_reserved(alloc_id, allocation);
219210

220-
if let Some(glob) = Option::<DefId>::decode(decoder)? {
221-
tcx.interpret_interner.cache(glob, alloc_id);
222-
}
223-
224211
Ok(alloc_id)
225212
},
226-
FN_DISCRIMINANT => {
227-
trace!("creating fn alloc id at {}", pos);
213+
AllocKind::Fn => {
214+
trace!("creating fn alloc id");
228215
let instance = ty::Instance::decode(decoder)?;
229216
trace!("decoded fn alloc instance: {:?}", instance);
230217
let id = tcx.interpret_interner.create_fn_alloc(instance);
231218
trace!("created fn alloc id: {:?}", id);
232-
cache(decoder, pos, id);
219+
cache(decoder, id);
233220
Ok(id)
234221
},
235-
EXTERN_STATIC_DISCRIMINANT => {
236-
trace!("creating extern static alloc id at {}", pos);
222+
AllocKind::Static => {
223+
trace!("creating extern static alloc id at");
237224
let did = DefId::decode(decoder)?;
238-
let alloc_id = tcx.interpret_interner.reserve();
239-
tcx.interpret_interner.cache(did, alloc_id);
225+
let alloc_id = tcx.interpret_interner.cache_static(did);
226+
cache(decoder, alloc_id);
240227
Ok(alloc_id)
241228
},
242-
shorthand => {
243-
trace!("loading shorthand {}", shorthand);
244-
short(decoder, shorthand)
245-
},
246229
}
247230
}
248231

src/librustc/ty/context.rs

+16-23
Original file line numberDiff line numberDiff line change
@@ -956,18 +956,16 @@ struct InterpretInternerInner<'tcx> {
956956
/// Allows obtaining const allocs via a unique identifier
957957
alloc_by_id: FxHashMap<interpret::AllocId, &'tcx interpret::Allocation>,
958958

959-
/// Reverse map of `alloc_cache`
960-
global_cache: FxHashMap<interpret::AllocId, DefId>,
959+
/// Allows obtaining static def ids via a unique id
960+
statics: FxHashMap<interpret::AllocId, DefId>,
961961

962962
/// The AllocId to assign to the next new regular allocation.
963963
/// Always incremented, never gets smaller.
964964
next_id: interpret::AllocId,
965965

966-
/// Allows checking whether a static already has an allocation
967-
///
968-
/// This is only important for detecting statics referring to themselves
969-
// FIXME(oli-obk) move it to the EvalContext?
970-
alloc_cache: FxHashMap<DefId, interpret::AllocId>,
966+
/// Inverse map of `statics`
967+
/// Used so we don't allocate a new pointer every time we need one
968+
static_cache: FxHashMap<DefId, interpret::AllocId>,
971969

972970
/// A cache for basic byte allocations keyed by their contents. This is used to deduplicate
973971
/// allocations for string and bytestring literals.
@@ -1001,30 +999,25 @@ impl<'tcx> InterpretInterner<'tcx> {
1001999
self.inner.borrow().alloc_by_id.get(&id).cloned()
10021000
}
10031001

1004-
pub fn get_cached(
1005-
&self,
1006-
static_id: DefId,
1007-
) -> Option<interpret::AllocId> {
1008-
self.inner.borrow().alloc_cache.get(&static_id).cloned()
1009-
}
1010-
1011-
pub fn cache(
1002+
pub fn cache_static(
10121003
&self,
10131004
static_id: DefId,
1014-
alloc_id: interpret::AllocId,
1015-
) {
1016-
let mut inner = self.inner.borrow_mut();
1017-
inner.global_cache.insert(alloc_id, static_id);
1018-
if let Some(old) = inner.alloc_cache.insert(static_id, alloc_id) {
1019-
bug!("tried to cache {:?}, but was already existing as {:#?}", static_id, old);
1005+
) -> interpret::AllocId {
1006+
if let Some(alloc_id) = self.inner.borrow().static_cache.get(&static_id).cloned() {
1007+
return alloc_id;
10201008
}
1009+
let alloc_id = self.reserve();
1010+
let mut inner = self.inner.borrow_mut();
1011+
inner.static_cache.insert(static_id, alloc_id);
1012+
inner.statics.insert(alloc_id, static_id);
1013+
alloc_id
10211014
}
10221015

1023-
pub fn get_corresponding_static_def_id(
1016+
pub fn get_static(
10241017
&self,
10251018
ptr: interpret::AllocId,
10261019
) -> Option<DefId> {
1027-
self.inner.borrow().global_cache.get(&ptr).cloned()
1020+
self.inner.borrow().statics.get(&ptr).cloned()
10281021
}
10291022

10301023
pub fn intern_at_reserved(

0 commit comments

Comments
 (0)