Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3c30dbb

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 efd420c + 967ba2f commit 3c30dbb

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)

AltStyle によって変換されたページ (->オリジナル) /