Skip to content

Commit 21fd151

Browse files
committed
Auto merge of #116707 - cjgillot:slice-id, r=oli-obk,RalfJung
Create an `AllocId` for `ConstValue::Slice`. This PR modifies `ConstValue::Slice` to use an `AllocId` instead of directly manipulating the allocation. This was originally proposed by #115764 but was a perf regression. Almost 2 years later, enough code has changed to make this a perf improvement: #116707 (comment)
2 parents 6caa224 + 2bab5bf commit 21fd151

File tree

86 files changed

+628
-271
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+628
-271
lines changed

compiler/rustc_codegen_cranelift/src/constant.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub(crate) fn codegen_tls_ref<'tcx>(
7474
pub(crate) fn eval_mir_constant<'tcx>(
7575
fx: &FunctionCx<'_, '_, 'tcx>,
7676
constant: &ConstOperand<'tcx>,
77-
) -> (ConstValue<'tcx>, Ty<'tcx>) {
77+
) -> (ConstValue, Ty<'tcx>) {
7878
let cv = fx.monomorphize(constant.const_);
7979
// This cannot fail because we checked all required_consts in advance.
8080
let val = cv
@@ -93,7 +93,7 @@ pub(crate) fn codegen_constant_operand<'tcx>(
9393

9494
pub(crate) fn codegen_const_value<'tcx>(
9595
fx: &mut FunctionCx<'_, '_, 'tcx>,
96-
const_val: ConstValue<'tcx>,
96+
const_val: ConstValue,
9797
ty: Ty<'tcx>,
9898
) -> CValue<'tcx> {
9999
let layout = fx.layout_of(ty);
@@ -210,8 +210,7 @@ pub(crate) fn codegen_const_value<'tcx>(
210210
.offset_i64(fx, i64::try_from(offset.bytes()).unwrap()),
211211
layout,
212212
),
213-
ConstValue::Slice { data, meta } => {
214-
let alloc_id = fx.tcx.reserve_and_set_memory_alloc(data);
213+
ConstValue::Slice { alloc_id, meta } => {
215214
let ptr = pointer_for_allocation(fx, alloc_id).get_addr(fx);
216215
let len = fx.bcx.ins().iconst(fx.pointer_type, meta as i64);
217216
CValue::by_val_pair(ptr, len, layout)

compiler/rustc_codegen_ssa/src/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ pub(crate) fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
148148
pub fn asm_const_to_str<'tcx>(
149149
tcx: TyCtxt<'tcx>,
150150
sp: Span,
151-
const_value: mir::ConstValue<'tcx>,
151+
const_value: mir::ConstValue,
152152
ty_and_layout: TyAndLayout<'tcx>,
153153
) -> String {
154154
let mir::ConstValue::Scalar(scalar) = const_value else {

compiler/rustc_codegen_ssa/src/mir/constant.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
2020
OperandRef::from_const(bx, val, ty)
2121
}
2222

23-
pub fn eval_mir_constant(&self, constant: &mir::ConstOperand<'tcx>) -> mir::ConstValue<'tcx> {
23+
pub fn eval_mir_constant(&self, constant: &mir::ConstOperand<'tcx>) -> mir::ConstValue {
2424
// `MirUsedCollector` visited all required_consts before codegen began, so if we got here
2525
// there can be no more constants that fail to evaluate.
2626
self.monomorphize(constant.const_)

compiler/rustc_codegen_ssa/src/mir/operand.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
140140

141141
pub(crate) fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
142142
bx: &mut Bx,
143-
val: mir::ConstValue<'tcx>,
143+
val: mir::ConstValue,
144144
ty: Ty<'tcx>,
145145
) -> Self {
146146
let layout = bx.layout_of(ty);
@@ -154,14 +154,11 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
154154
OperandValue::Immediate(llval)
155155
}
156156
ConstValue::ZeroSized => return OperandRef::zero_sized(layout),
157-
ConstValue::Slice { data, meta } => {
157+
ConstValue::Slice { alloc_id, meta } => {
158158
let BackendRepr::ScalarPair(a_scalar, _) = layout.backend_repr else {
159159
bug!("from_const: invalid ScalarPair layout: {:#?}", layout);
160160
};
161-
let a = Scalar::from_pointer(
162-
Pointer::new(bx.tcx().reserve_and_set_memory_alloc(data).into(), Size::ZERO),
163-
&bx.tcx(),
164-
);
161+
let a = Scalar::from_pointer(Pointer::new(alloc_id.into(), Size::ZERO), &bx.tcx());
165162
let a_llval = bx.scalar_to_backend(
166163
a,
167164
a_scalar,

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ pub(crate) fn mk_eval_cx_to_read_const_val<'tcx>(
152152
pub fn mk_eval_cx_for_const_val<'tcx>(
153153
tcx: TyCtxtAt<'tcx>,
154154
typing_env: ty::TypingEnv<'tcx>,
155-
val: mir::ConstValue<'tcx>,
155+
val: mir::ConstValue,
156156
ty: Ty<'tcx>,
157157
) -> Option<(CompileTimeInterpCx<'tcx>, OpTy<'tcx>)> {
158158
let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, typing_env, CanAccessMutGlobal::No);
@@ -172,7 +172,7 @@ pub(super) fn op_to_const<'tcx>(
172172
ecx: &CompileTimeInterpCx<'tcx>,
173173
op: &OpTy<'tcx>,
174174
for_diagnostics: bool,
175-
) -> ConstValue<'tcx> {
175+
) -> ConstValue {
176176
// Handle ZST consistently and early.
177177
if op.layout.is_zst() {
178178
return ConstValue::ZeroSized;
@@ -241,10 +241,9 @@ pub(super) fn op_to_const<'tcx>(
241241
let (prov, offset) =
242242
ptr.into_pointer_or_addr().expect(msg).prov_and_relative_offset();
243243
let alloc_id = prov.alloc_id();
244-
let data = ecx.tcx.global_alloc(alloc_id).unwrap_memory();
245244
assert!(offset == abi::Size::ZERO, "{}", msg);
246245
let meta = b.to_target_usize(ecx).expect(msg);
247-
ConstValue::Slice { data, meta }
246+
ConstValue::Slice { alloc_id, meta }
248247
}
249248
Immediate::Uninit => bug!("`Uninit` is not a valid value for {}", op.layout.ty),
250249
},
@@ -256,7 +255,7 @@ pub(crate) fn turn_into_const_value<'tcx>(
256255
tcx: TyCtxt<'tcx>,
257256
constant: ConstAlloc<'tcx>,
258257
key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
259-
) -> ConstValue<'tcx> {
258+
) -> ConstValue {
260259
let cid = key.value;
261260
let def_id = cid.instance.def.def_id();
262261
let is_static = tcx.is_static(def_id);

compiler/rustc_const_eval/src/const_eval/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const VALTREE_MAX_NODES: usize = 100000;
2828
#[instrument(skip(tcx), level = "debug")]
2929
pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
3030
tcx: TyCtxt<'tcx>,
31-
val: mir::ConstValue<'tcx>,
31+
val: mir::ConstValue,
3232
ty: Ty<'tcx>,
3333
) -> Option<mir::DestructuredConstant<'tcx>> {
3434
let typing_env = ty::TypingEnv::fully_monomorphized();

compiler/rustc_const_eval/src/const_eval/valtrees.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ pub fn valtree_to_const_value<'tcx>(
259259
tcx: TyCtxt<'tcx>,
260260
typing_env: ty::TypingEnv<'tcx>,
261261
cv: ty::Value<'tcx>,
262-
) -> mir::ConstValue<'tcx> {
262+
) -> mir::ConstValue {
263263
// Basic idea: We directly construct `Scalar` values from trivial `ValTree`s
264264
// (those for constants with type bool, int, uint, float or char).
265265
// For all other types we create an `MPlace` and fill that by walking

compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -582,8 +582,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
582582
span: Span,
583583
layout: Option<TyAndLayout<'tcx>>,
584584
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
585-
M::eval_mir_constant(self, *val, span, layout, |ecx, val, span, layout| {
586-
let const_val = val.eval(*ecx.tcx, ecx.typing_env, span).map_err(|err| {
585+
let const_val = val.eval(*self.tcx, self.typing_env, span).map_err(|err| {
587586
if M::ALL_CONSTS_ARE_PRECHECKED {
588587
match err {
589588
ErrorHandled::TooGeneric(..) => {},
@@ -599,11 +598,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
599598
}
600599
}
601600
}
602-
err.emit_note(*ecx.tcx);
601+
err.emit_note(*self.tcx);
603602
err
604603
})?;
605-
ecx.const_val_to_op(const_val, val.ty(), layout)
606-
})
604+
self.const_val_to_op(const_val, val.ty(), layout)
607605
}
608606

609607
#[must_use]

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::assert_matches::assert_matches;
66

77
use rustc_abi::{FieldIdx, HasDataLayout, Size};
88
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
9-
use rustc_middle::mir::interpret::{read_target_uint, write_target_uint};
9+
use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, read_target_uint, write_target_uint};
1010
use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
1111
use rustc_middle::ty::layout::TyAndLayout;
1212
use rustc_middle::ty::{Ty, TyCtxt};
@@ -17,17 +17,18 @@ use tracing::trace;
1717
use super::memory::MemoryKind;
1818
use super::util::ensure_monomorphic_enough;
1919
use super::{
20-
Allocation, CheckInAllocMsg, ConstAllocation, ImmTy, InterpCx, InterpResult, Machine, OpTy,
21-
PlaceTy, Pointer, PointerArithmetic, Provenance, Scalar, err_ub_custom, err_unsup_format,
22-
interp_ok, throw_inval, throw_ub_custom, throw_ub_format,
20+
AllocId, CheckInAllocMsg, ImmTy, InterpCx, InterpResult, Machine, OpTy, PlaceTy, Pointer,
21+
PointerArithmetic, Provenance, Scalar, err_ub_custom, err_unsup_format, interp_ok, throw_inval,
22+
throw_ub_custom, throw_ub_format,
2323
};
2424
use crate::fluent_generated as fluent;
2525

2626
/// Directly returns an `Allocation` containing an absolute path representation of the given type.
27-
pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> {
27+
pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (AllocId, u64) {
2828
let path = crate::util::type_name(tcx, ty);
29-
let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes(), ());
30-
tcx.mk_const_alloc(alloc)
29+
let bytes = path.into_bytes();
30+
let len = bytes.len().try_into().unwrap();
31+
(tcx.allocate_bytes_dedup(bytes, CTFE_ALLOC_SALT), len)
3132
}
3233
impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
3334
/// Generates a value of `TypeId` for `ty` in-place.
@@ -126,8 +127,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
126127
sym::type_name => {
127128
let tp_ty = instance.args.type_at(0);
128129
ensure_monomorphic_enough(tcx, tp_ty)?;
129-
let alloc = alloc_type_name(tcx, tp_ty);
130-
let val = ConstValue::Slice { data: alloc, meta: alloc.inner().size().bytes() };
130+
let (alloc_id, meta) = alloc_type_name(tcx, tp_ty);
131+
let val = ConstValue::Slice { alloc_id, meta };
131132
let val = self.const_val_to_op(val, dest.layout.ty, Some(dest.layout))?;
132133
self.copy_op(&val, dest)?;
133134
}

compiler/rustc_const_eval/src/interpret/machine.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use rustc_middle::query::TyCtxtAt;
1212
use rustc_middle::ty::Ty;
1313
use rustc_middle::ty::layout::TyAndLayout;
1414
use rustc_middle::{mir, ty};
15-
use rustc_span::Span;
1615
use rustc_span::def_id::DefId;
1716
use rustc_target::callconv::FnAbi;
1817

@@ -587,27 +586,6 @@ pub trait Machine<'tcx>: Sized {
587586
interp_ok(())
588587
}
589588

590-
/// Evaluate the given constant. The `eval` function will do all the required evaluation,
591-
/// but this hook has the chance to do some pre/postprocessing.
592-
#[inline(always)]
593-
fn eval_mir_constant<F>(
594-
ecx: &InterpCx<'tcx, Self>,
595-
val: mir::Const<'tcx>,
596-
span: Span,
597-
layout: Option<TyAndLayout<'tcx>>,
598-
eval: F,
599-
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>
600-
where
601-
F: Fn(
602-
&InterpCx<'tcx, Self>,
603-
mir::Const<'tcx>,
604-
Span,
605-
Option<TyAndLayout<'tcx>>,
606-
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>,
607-
{
608-
eval(ecx, val, span, layout)
609-
}
610-
611589
/// Returns the salt to be used for a deduplicated global alloation.
612590
/// If the allocation is for a function, the instance is provided as well
613591
/// (this lets Miri ensure unique addresses for some functions).

0 commit comments

Comments
 (0)