Skip to content

Commit 78e4b6f

Browse files
committed
simplify deduplication and better utilize query caching
1 parent 53c0bab commit 78e4b6f

File tree

3 files changed

+118
-69
lines changed

3 files changed

+118
-69
lines changed

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_errors::ErrorReported;
1010
use rustc_hir as hir;
1111
use rustc_hir::def::DefKind;
1212
use rustc_middle::mir;
13-
use rustc_middle::mir::interpret::{ConstDedupResult, ErrorHandled};
13+
use rustc_middle::mir::interpret::ErrorHandled;
1414
use rustc_middle::mir::pretty::display_allocation;
1515
use rustc_middle::traits::Reveal;
1616
use rustc_middle::ty::layout::{LayoutError, LayoutOf};
@@ -235,8 +235,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
235235
match eval_nullary_intrinsic(tcx, param_env, def_id, substs) {
236236
Ok(val) => {
237237
// store result for deduplication
238-
let res = ConstDedupResult::new(reveal, val);
239-
tcx.save_const_value_for_dedup(id, res);
238+
tcx.save_const_value_for_dedup(id, reveal);
240239

241240
return Ok(val);
242241
}
@@ -251,17 +250,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
251250
}
252251
}
253252

254-
let result =
255-
tcx.dedup_eval_alloc_raw(key, None).map(|val| turn_into_const_value(tcx, val, key));
256-
257-
match result {
258-
Ok(val) => {
259-
tcx.save_const_value_for_dedup(id, ConstDedupResult::new(reveal, val));
260-
}
261-
_ => {}
262-
}
263-
264-
result
253+
tcx.dedup_eval_alloc_raw(key, None).map(|val| turn_into_const_value(tcx, val, key))
265254
}
266255

267256
#[instrument(skip(tcx), level = "debug")]
@@ -431,10 +420,9 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
431420
} else {
432421
// Convert to raw constant
433422
let const_alloc = ConstAlloc { alloc_id, ty: mplace.layout.ty };
434-
let val = ConstDedupResult::new(reveal, const_alloc);
435423

436-
// store result in order to deduplicate later
437-
tcx.save_alloc_for_dedup(cid, val);
424+
// store information that allows deduplication
425+
tcx.save_alloc_for_dedup(cid, reveal);
438426

439427
Ok(const_alloc)
440428
}

compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
810810
/// cause us to continue unwinding.
811811
pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx> {
812812
info!(
813-
"popping stack frame ({})",
813+
"popping following stack frame ({})",
814814
if unwinding { "during unwinding" } else { "returning from function" }
815815
);
816816

compiler/rustc_middle/src/mir/interpret/mod.rs

Lines changed: 112 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -485,32 +485,15 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> {
485485
}
486486
}
487487

488-
#[derive(Clone, Copy, Debug)]
489-
pub enum ConstDedupResult<T: Clone + Copy + Debug> {
490-
Selection(T),
491-
UserFacing(T),
492-
All(T),
493-
}
494-
495-
impl<T: Clone + Copy + Debug> ConstDedupResult<T> {
496-
pub fn new(reveal: Reveal, val: T) -> Self {
497-
match reveal {
498-
Reveal::Selection => ConstDedupResult::Selection(val),
499-
Reveal::UserFacing => ConstDedupResult::UserFacing(val),
500-
Reveal::All => ConstDedupResult::All(val),
501-
}
502-
}
503-
}
504-
505488
/// Used to store results of calls to `eval_to_allocation_raw` and
506489
/// `eval_to_const_value_raw`.
507490
#[derive(Debug)]
508491
pub struct ConstDedupMap<'tcx> {
509492
// interning for deduplication of `eval_to_allocation_raw`
510-
pub alloc_map: RefCell<FxHashMap<GlobalId<'tcx>, ConstDedupResult<ConstAlloc<'tcx>>>>,
493+
pub alloc_map: RefCell<FxHashMap<GlobalId<'tcx>, Reveal>>,
511494

512495
// interning for deduplication of `eval_to_const_value_raw`
513-
pub const_val_map: RefCell<FxHashMap<GlobalId<'tcx>, ConstDedupResult<ConstValue<'tcx>>>>,
496+
pub const_val_map: RefCell<FxHashMap<GlobalId<'tcx>, Reveal>>,
514497
}
515498

516499
impl<'tcx> ConstDedupMap<'tcx> {
@@ -519,14 +502,14 @@ impl<'tcx> ConstDedupMap<'tcx> {
519502
}
520503

521504
#[instrument(skip(self), level = "debug")]
522-
fn insert_alloc(&self, id: GlobalId<'tcx>, val: ConstDedupResult<ConstAlloc<'tcx>>) {
505+
fn insert_alloc(&self, id: GlobalId<'tcx>, val: Reveal) {
523506
let mut alloc_map = self.alloc_map.borrow_mut();
524507
alloc_map.insert(id, val);
525508
debug!("alloc_map after update: {:#?}", alloc_map);
526509
}
527510

528511
#[instrument(skip(self), level = "debug")]
529-
fn insert_const_val(&self, id: GlobalId<'tcx>, val: ConstDedupResult<ConstValue<'tcx>>) {
512+
fn insert_const_val(&self, id: GlobalId<'tcx>, val: Reveal) {
530513
let mut const_val_map = self.const_val_map.borrow_mut();
531514
const_val_map.insert(id, val);
532515
debug!("const_val_map after update: {:#?}", const_val_map);
@@ -645,19 +628,15 @@ impl<'tcx> TyCtxt<'tcx> {
645628
/// Store the result of a call to `eval_to_allocation_raw` in order to
646629
/// allow deduplication.
647630
#[instrument(skip(self), level = "debug")]
648-
pub fn save_alloc_for_dedup(self, id: GlobalId<'tcx>, val: ConstDedupResult<ConstAlloc<'tcx>>) {
631+
pub fn save_alloc_for_dedup(self, id: GlobalId<'tcx>, val: Reveal) {
649632
let dedup_const_map = self.dedup_const_map.lock();
650633
dedup_const_map.insert_alloc(id, val);
651634
debug!("dedup_const_map after insert: {:#?}", dedup_const_map);
652635
}
653636

654637
/// Store the result of a call to `eval_to_const_value_raw` in order to deduplicate it.
655638
#[instrument(skip(self), level = "debug")]
656-
pub fn save_const_value_for_dedup(
657-
self,
658-
id: GlobalId<'tcx>,
659-
val: ConstDedupResult<ConstValue<'tcx>>,
660-
) {
639+
pub fn save_const_value_for_dedup(self, id: GlobalId<'tcx>, val: Reveal) {
661640
let dedup_const_map = self.dedup_const_map.lock();
662641
dedup_const_map.insert_const_val(id, val);
663642
debug!("dedup_const_map after insert: {:#?}", dedup_const_map);
@@ -671,31 +650,72 @@ impl<'tcx> TyCtxt<'tcx> {
671650
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
672651
opt_span: Option<Span>,
673652
) -> EvalToAllocationRawResult<'tcx> {
674-
use ConstDedupResult::*;
675-
676653
let (param_env, id) = key.into_parts();
677654
let dedup_const_map = self.dedup_const_map.lock();
678655
debug!("dedup_const_map: {:#?}", dedup_const_map);
679656
let alloc_map = dedup_const_map.alloc_map.borrow();
680657
debug!("alloc_map: {:#?}", alloc_map);
681658

682-
let dedup_result = alloc_map.get(&id);
683-
debug!(?dedup_result);
659+
let dedup_reveal = alloc_map.get(&id);
660+
debug!(?dedup_reveal);
684661

685662
match param_env.reveal() {
686-
Reveal::Selection => match dedup_result {
687-
Some(Selection(alloc) | UserFacing(alloc)) => return Ok(*alloc),
663+
Reveal::Selection => match dedup_reveal {
664+
Some(Reveal::Selection) => {
665+
drop(alloc_map);
666+
drop(dedup_const_map);
667+
668+
// Use cached result of query
669+
return self.eval_to_allocation_raw(key);
670+
}
671+
Some(Reveal::UserFacing) => {
672+
drop(alloc_map);
673+
drop(dedup_const_map);
674+
675+
// can deduplicate query with Reveal::Selection from Reveal::UserFacing
676+
// since these only differ in the way errors are reported, but successful
677+
// query calls are equivalent.
678+
let new_key = param_env.with_user_facing().and(id);
679+
return self.eval_to_allocation_raw(new_key);
680+
}
688681
_ => {}
689682
},
690-
Reveal::UserFacing => match dedup_result {
691-
Some(Selection(alloc) | UserFacing(alloc)) => {
692-
return Ok(*alloc);
683+
Reveal::UserFacing => match dedup_reveal {
684+
Some(Reveal::UserFacing) => {
685+
drop(alloc_map);
686+
drop(dedup_const_map);
687+
688+
return self.eval_to_allocation_raw(key);
689+
}
690+
Some(Reveal::Selection) => {
691+
drop(alloc_map);
692+
drop(dedup_const_map);
693+
694+
let new_key = param_env.with_reveal_selection().and(id);
695+
return self.eval_to_allocation_raw(new_key);
693696
}
694697
_ => {}
695698
},
696-
Reveal::All => match dedup_result {
697-
Some(Selection(alloc) | UserFacing(alloc) | All(alloc)) => {
698-
return Ok(*alloc);
699+
Reveal::All => match dedup_reveal {
700+
Some(Reveal::Selection) => {
701+
drop(alloc_map);
702+
drop(dedup_const_map);
703+
704+
let new_key = param_env.with_reveal_selection().and(id);
705+
return self.eval_to_allocation_raw(new_key);
706+
}
707+
Some(Reveal::UserFacing) => {
708+
drop(alloc_map);
709+
drop(dedup_const_map);
710+
711+
let new_key = param_env.with_user_facing().and(id);
712+
return self.eval_to_allocation_raw(new_key);
713+
}
714+
Some(Reveal::All) => {
715+
drop(alloc_map);
716+
drop(dedup_const_map);
717+
718+
return self.eval_to_allocation_raw(key);
699719
}
700720
_ => {}
701721
},
@@ -722,31 +742,72 @@ impl<'tcx> TyCtxt<'tcx> {
722742
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
723743
opt_span: Option<Span>,
724744
) -> EvalToConstValueResult<'tcx> {
725-
use ConstDedupResult::*;
726-
727745
let (param_env, id) = key.into_parts();
728746
let dedup_const_map = self.dedup_const_map.lock();
729747
debug!("dedup_const_map: {:#?}", dedup_const_map);
730748
let const_val_map = dedup_const_map.const_val_map.borrow();
731749
debug!("const_val_map: {:#?}", const_val_map);
732750

733-
let dedup_result = const_val_map.get(&id);
734-
debug!(?dedup_result);
751+
let dedup_reveal = const_val_map.get(&id);
752+
debug!(?dedup_reveal);
735753

736754
match param_env.reveal() {
737-
Reveal::Selection => match dedup_result {
738-
Some(Selection(const_val) | UserFacing(const_val)) => return Ok(*const_val),
755+
Reveal::Selection => match dedup_reveal {
756+
Some(Reveal::Selection) => {
757+
drop(const_val_map);
758+
drop(dedup_const_map);
759+
760+
// Use cached result of query
761+
return self.eval_to_const_value_raw(key);
762+
}
763+
Some(Reveal::UserFacing) => {
764+
drop(const_val_map);
765+
drop(dedup_const_map);
766+
767+
// can deduplicate query with Reveal::Selection from Reveal::UserFacing
768+
// since these only differ in the way errors are reported, but successful
769+
// query calls are equivalent.
770+
let new_key = param_env.with_user_facing().and(id);
771+
return self.eval_to_const_value_raw(new_key);
772+
}
739773
_ => {}
740774
},
741-
Reveal::UserFacing => match dedup_result {
742-
Some(Selection(const_value) | UserFacing(const_value)) => {
743-
return Ok(*const_value);
775+
Reveal::UserFacing => match dedup_reveal {
776+
Some(Reveal::UserFacing) => {
777+
drop(const_val_map);
778+
drop(dedup_const_map);
779+
780+
return self.eval_to_const_value_raw(key);
781+
}
782+
Some(Reveal::Selection) => {
783+
drop(const_val_map);
784+
drop(dedup_const_map);
785+
786+
let new_key = param_env.with_reveal_selection().and(id);
787+
return self.eval_to_const_value_raw(new_key);
744788
}
745789
_ => {}
746790
},
747-
Reveal::All => match dedup_result {
748-
Some(Selection(const_value) | UserFacing(const_value) | All(const_value)) => {
749-
return Ok(*const_value);
791+
Reveal::All => match dedup_reveal {
792+
Some(Reveal::Selection) => {
793+
drop(const_val_map);
794+
drop(dedup_const_map);
795+
796+
let new_key = param_env.with_reveal_selection().and(id);
797+
return self.eval_to_const_value_raw(new_key);
798+
}
799+
Some(Reveal::UserFacing) => {
800+
drop(const_val_map);
801+
drop(dedup_const_map);
802+
803+
let new_key = param_env.with_user_facing().and(id);
804+
return self.eval_to_const_value_raw(new_key);
805+
}
806+
Some(Reveal::All) => {
807+
drop(const_val_map);
808+
drop(dedup_const_map);
809+
810+
return self.eval_to_const_value_raw(key);
750811
}
751812
_ => {}
752813
},

0 commit comments

Comments
 (0)