Skip to content

Commit b7b90b5

Browse files
committed
Directly intern values instead of copying them.
1 parent 4815bfc commit b7b90b5

File tree

4 files changed

+54
-5
lines changed

4 files changed

+54
-5
lines changed

compiler/rustc_const_eval/src/interpret/intern.rs

+44
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,50 @@ pub fn intern_const_alloc_recursive<
450450
Ok(())
451451
}
452452

453+
/// Intern `ret`, checking it references no other allocation.
454+
#[instrument(level = "debug", skip(ecx))]
455+
pub fn intern_const_alloc_for_constprop<
456+
'mir,
457+
'tcx: 'mir,
458+
T,
459+
M: CompileTimeMachine<'mir, 'tcx, T>,
460+
>(
461+
ecx: &mut InterpCx<'mir, 'tcx, M>,
462+
ret: &MPlaceTy<'tcx>,
463+
) -> InterpResult<'tcx, ()> {
464+
let Some((size, align)) = ecx.size_and_align_of_mplace(ret)? else {
465+
throw_inval!(ConstPropNonsense)
466+
};
467+
468+
let alloc_ref = ecx.get_ptr_alloc(ret.ptr(), size, align)?.unwrap();
469+
// Do not try interning a value that contains provenance.
470+
if alloc_ref.has_provenance() {
471+
throw_inval!(ConstPropNonsense)
472+
}
473+
474+
// remove allocation
475+
let alloc_id = ret.ptr().provenance.unwrap();
476+
let Some((_, mut alloc)) = ecx.memory.alloc_map.remove(&alloc_id) else {
477+
// Pointer not found in local memory map. It is either a pointer to the global
478+
// map, or dangling.
479+
if ecx.tcx.try_get_global_alloc(alloc_id).is_none() {
480+
throw_ub!(DeadLocal)
481+
}
482+
// The constant is already in global memory. Do nothing.
483+
return Ok(());
484+
};
485+
486+
alloc.mutability = Mutability::Not;
487+
488+
// link the alloc id to the actual allocation
489+
assert!(alloc.provenance().ptrs().is_empty());
490+
491+
let alloc = ecx.tcx.mk_const_alloc(alloc);
492+
ecx.tcx.set_alloc_id_memory(alloc_id, alloc);
493+
494+
Ok(())
495+
}
496+
453497
impl<'mir, 'tcx: 'mir, M: super::intern::CompileTimeMachine<'mir, 'tcx, !>>
454498
InterpCx<'mir, 'tcx, M>
455499
{

compiler/rustc_const_eval/src/interpret/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ mod visitor;
2121
pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in one place: here
2222

2323
pub use self::eval_context::{Frame, FrameInfo, InterpCx, StackPopCleanup};
24-
pub use self::intern::{intern_const_alloc_recursive, InternKind};
24+
pub use self::intern::{
25+
intern_const_alloc_for_constprop, intern_const_alloc_recursive, InternKind,
26+
};
2527
pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackPopJump};
2628
pub use self::memory::{AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind};
2729
pub use self::operand::{ImmTy, Immediate, OpTy, Readable};

compiler/rustc_mir_transform/src/gvn.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
//! _c = *_b // replaced by _c = _a
5454
//! ```
5555
56-
use rustc_const_eval::interpret::MemoryKind;
56+
use rustc_const_eval::interpret::{intern_const_alloc_for_constprop, MemoryKind};
5757
use rustc_const_eval::interpret::{ImmTy, InterpCx, MemPlaceMeta, OpTy, Projectable, Scalar};
5858
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
5959
use rustc_data_structures::graph::dominators::Dominators;
@@ -833,10 +833,13 @@ fn op_to_prop_const<'tcx>(
833833
if let Either::Left(mplace) = op.as_mplace_or_imm()
834834
&& let MemPlaceMeta::None = mplace.meta()
835835
{
836+
intern_const_alloc_for_constprop(ecx, &mplace).ok()?;
836837
let pointer = mplace.ptr().into_pointer_or_addr().ok()?;
837838
let (alloc_id, offset) = pointer.into_parts();
838-
if matches!(ecx.tcx.try_get_global_alloc(alloc_id), Some(GlobalAlloc::Memory(_))) {
839-
return Some(ConstValue::Indirect { alloc_id, offset })
839+
match ecx.tcx.global_alloc(alloc_id) {
840+
GlobalAlloc::Memory(_) => return Some(ConstValue::Indirect { alloc_id, offset }),
841+
// Fallthrough to copying the data.
842+
_ => {}
840843
}
841844
}
842845

tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
}
9090
}
9191

92-
alloc12 (size: 4, align: 2) {
92+
alloc11 (size: 4, align: 2) {
9393
01 00 63 00 │ ..c.
9494
}
9595

0 commit comments

Comments
 (0)