Skip to content

Create an AllocId for ConstValue::Slice. #116707

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions compiler/rustc_codegen_cranelift/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub(crate) fn codegen_tls_ref<'tcx>(
pub(crate) fn eval_mir_constant<'tcx>(
fx: &FunctionCx<'_, '_, 'tcx>,
constant: &ConstOperand<'tcx>,
) -> (ConstValue<'tcx>, Ty<'tcx>) {
) -> (ConstValue, Ty<'tcx>) {
let cv = fx.monomorphize(constant.const_);
// This cannot fail because we checked all required_consts in advance.
let val = cv
Expand All @@ -93,7 +93,7 @@ pub(crate) fn codegen_constant_operand<'tcx>(

pub(crate) fn codegen_const_value<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
const_val: ConstValue<'tcx>,
const_val: ConstValue,
ty: Ty<'tcx>,
) -> CValue<'tcx> {
let layout = fx.layout_of(ty);
Expand Down Expand Up @@ -210,8 +210,7 @@ pub(crate) fn codegen_const_value<'tcx>(
.offset_i64(fx, i64::try_from(offset.bytes()).unwrap()),
layout,
),
ConstValue::Slice { data, meta } => {
let alloc_id = fx.tcx.reserve_and_set_memory_alloc(data);
ConstValue::Slice { alloc_id, meta } => {
let ptr = pointer_for_allocation(fx, alloc_id).get_addr(fx);
let len = fx.bcx.ins().iconst(fx.pointer_type, meta as i64);
CValue::by_val_pair(ptr, len, layout)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ pub(crate) fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
pub fn asm_const_to_str<'tcx>(
tcx: TyCtxt<'tcx>,
sp: Span,
const_value: mir::ConstValue<'tcx>,
const_value: mir::ConstValue,
ty_and_layout: TyAndLayout<'tcx>,
) -> String {
let mir::ConstValue::Scalar(scalar) = const_value else {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
OperandRef::from_const(bx, val, ty)
}

pub fn eval_mir_constant(&self, constant: &mir::ConstOperand<'tcx>) -> mir::ConstValue<'tcx> {
pub fn eval_mir_constant(&self, constant: &mir::ConstOperand<'tcx>) -> mir::ConstValue {
// `MirUsedCollector` visited all required_consts before codegen began, so if we got here
// there can be no more constants that fail to evaluate.
self.monomorphize(constant.const_)
Expand Down
9 changes: 3 additions & 6 deletions compiler/rustc_codegen_ssa/src/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {

pub(crate) fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
bx: &mut Bx,
val: mir::ConstValue<'tcx>,
val: mir::ConstValue,
ty: Ty<'tcx>,
) -> Self {
let layout = bx.layout_of(ty);
Expand All @@ -154,14 +154,11 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
OperandValue::Immediate(llval)
}
ConstValue::ZeroSized => return OperandRef::zero_sized(layout),
ConstValue::Slice { data, meta } => {
ConstValue::Slice { alloc_id, meta } => {
let BackendRepr::ScalarPair(a_scalar, _) = layout.backend_repr else {
bug!("from_const: invalid ScalarPair layout: {:#?}", layout);
};
let a = Scalar::from_pointer(
Pointer::new(bx.tcx().reserve_and_set_memory_alloc(data).into(), Size::ZERO),
&bx.tcx(),
);
let a = Scalar::from_pointer(Pointer::new(alloc_id.into(), Size::ZERO), &bx.tcx());
let a_llval = bx.scalar_to_backend(
a,
a_scalar,
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ pub(crate) fn mk_eval_cx_to_read_const_val<'tcx>(
pub fn mk_eval_cx_for_const_val<'tcx>(
tcx: TyCtxtAt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
val: mir::ConstValue<'tcx>,
val: mir::ConstValue,
ty: Ty<'tcx>,
) -> Option<(CompileTimeInterpCx<'tcx>, OpTy<'tcx>)> {
let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, typing_env, CanAccessMutGlobal::No);
Expand All @@ -167,7 +167,7 @@ pub(super) fn op_to_const<'tcx>(
ecx: &CompileTimeInterpCx<'tcx>,
op: &OpTy<'tcx>,
for_diagnostics: bool,
) -> ConstValue<'tcx> {
) -> ConstValue {
// Handle ZST consistently and early.
if op.layout.is_zst() {
return ConstValue::ZeroSized;
Expand Down Expand Up @@ -236,10 +236,9 @@ pub(super) fn op_to_const<'tcx>(
let (prov, offset) =
ptr.into_pointer_or_addr().expect(msg).prov_and_relative_offset();
let alloc_id = prov.alloc_id();
let data = ecx.tcx.global_alloc(alloc_id).unwrap_memory();
assert!(offset == abi::Size::ZERO, "{}", msg);
let meta = b.to_target_usize(ecx).expect(msg);
ConstValue::Slice { data, meta }
ConstValue::Slice { alloc_id, meta }
}
Immediate::Uninit => bug!("`Uninit` is not a valid value for {}", op.layout.ty),
},
Expand All @@ -251,7 +250,7 @@ pub(crate) fn turn_into_const_value<'tcx>(
tcx: TyCtxt<'tcx>,
constant: ConstAlloc<'tcx>,
key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
) -> ConstValue<'tcx> {
) -> ConstValue {
let cid = key.value;
let def_id = cid.instance.def.def_id();
let is_static = tcx.is_static(def_id);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const VALTREE_MAX_NODES: usize = 100000;
#[instrument(skip(tcx), level = "debug")]
pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
tcx: TyCtxt<'tcx>,
val: mir::ConstValue<'tcx>,
val: mir::ConstValue,
ty: Ty<'tcx>,
) -> Option<mir::DestructuredConstant<'tcx>> {
let typing_env = ty::TypingEnv::fully_monomorphized();
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ pub fn valtree_to_const_value<'tcx>(
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
cv: ty::Value<'tcx>,
) -> mir::ConstValue<'tcx> {
) -> mir::ConstValue {
// Basic idea: We directly construct `Scalar` values from trivial `ValTree`s
// (those for constants with type bool, int, uint, float or char).
// For all other types we create an `MPlace` and fill that by walking
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,8 +559,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
span: Span,
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
M::eval_mir_constant(self, *val, span, layout, |ecx, val, span, layout| {
let const_val = val.eval(*ecx.tcx, ecx.typing_env, span).map_err(|err| {
let const_val = val.eval(*self.tcx, self.typing_env, span).map_err(|err| {
if M::ALL_CONSTS_ARE_PRECHECKED {
match err {
ErrorHandled::TooGeneric(..) => {},
Expand All @@ -576,11 +575,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
}
}
err.emit_note(*ecx.tcx);
err.emit_note(*self.tcx);
err
})?;
ecx.const_val_to_op(const_val, val.ty(), layout)
})
self.const_val_to_op(const_val, val.ty(), layout)
}

#[must_use]
Expand Down
18 changes: 10 additions & 8 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::assert_matches::assert_matches;

use rustc_abi::{FieldIdx, Size};
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
use rustc_middle::mir::interpret::CTFE_ALLOC_SALT;
use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{Ty, TyCtxt};
Expand All @@ -16,17 +17,18 @@ use tracing::trace;
use super::memory::MemoryKind;
use super::util::ensure_monomorphic_enough;
use super::{
Allocation, CheckInAllocMsg, ConstAllocation, ImmTy, InterpCx, InterpResult, Machine, OpTy,
PlaceTy, Pointer, PointerArithmetic, Provenance, Scalar, err_ub_custom, err_unsup_format,
interp_ok, throw_inval, throw_ub_custom, throw_ub_format,
AllocId, CheckInAllocMsg, ImmTy, InterpCx, InterpResult, Machine, OpTy, PlaceTy, Pointer,
PointerArithmetic, Provenance, Scalar, err_ub_custom, err_unsup_format, interp_ok, throw_inval,
throw_ub_custom, throw_ub_format,
};
use crate::fluent_generated as fluent;

/// Directly returns an `Allocation` containing an absolute path representation of the given type.
pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> {
pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (AllocId, u64) {
let path = crate::util::type_name(tcx, ty);
let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes(), ());
tcx.mk_const_alloc(alloc)
let bytes = path.into_bytes();
let len = bytes.len().try_into().unwrap();
(tcx.allocate_bytes_dedup(bytes, CTFE_ALLOC_SALT), len)
}
impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Generates a value of `TypeId` for `ty` in-place.
Expand Down Expand Up @@ -75,8 +77,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
sym::type_name => {
let tp_ty = instance.args.type_at(0);
ensure_monomorphic_enough(tcx, tp_ty)?;
let alloc = alloc_type_name(tcx, tp_ty);
let val = ConstValue::Slice { data: alloc, meta: alloc.inner().size().bytes() };
let (alloc_id, meta) = alloc_type_name(tcx, tp_ty);
let val = ConstValue::Slice { alloc_id, meta };
let val = self.const_val_to_op(val, dest.layout.ty, Some(dest.layout))?;
self.copy_op(&val, dest)?;
}
Expand Down
22 changes: 0 additions & 22 deletions compiler/rustc_const_eval/src/interpret/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::{mir, ty};
use rustc_span::Span;
use rustc_span::def_id::DefId;
use rustc_target::callconv::FnAbi;

Expand Down Expand Up @@ -587,27 +586,6 @@ pub trait Machine<'tcx>: Sized {
interp_ok(())
}

/// Evaluate the given constant. The `eval` function will do all the required evaluation,
/// but this hook has the chance to do some pre/postprocessing.
#[inline(always)]
fn eval_mir_constant<F>(
ecx: &InterpCx<'tcx, Self>,
val: mir::Const<'tcx>,
span: Span,
layout: Option<TyAndLayout<'tcx>>,
eval: F,
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>
where
F: Fn(
&InterpCx<'tcx, Self>,
mir::Const<'tcx>,
Span,
Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>,
{
eval(ecx, val, span, layout)
}

/// Returns the salt to be used for a deduplicated global alloation.
/// If the allocation is for a function, the instance is provided as well
/// (this lets Miri ensure unique addresses for some functions).
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

pub(crate) fn const_val_to_op(
&self,
val_val: mir::ConstValue<'tcx>,
val_val: mir::ConstValue,
ty: Ty<'tcx>,
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
Expand All @@ -860,9 +860,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
mir::ConstValue::Scalar(x) => adjust_scalar(x)?.into(),
mir::ConstValue::ZeroSized => Immediate::Uninit,
mir::ConstValue::Slice { data, meta } => {
mir::ConstValue::Slice { alloc_id, meta } => {
// This is const data, no mutation allowed.
let alloc_id = self.tcx.reserve_and_set_memory_alloc(data);
let ptr = Pointer::new(CtfeProvenance::from(alloc_id).as_immutable(), Size::ZERO);
Immediate::new_slice(self.global_root_pointer(ptr)?.into(), meta, self)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/util/caller_location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub(crate) fn const_caller_location_provider(
file: Symbol,
line: u32,
col: u32,
) -> mir::ConstValue<'_> {
) -> mir::ConstValue {
trace!("const_caller_location: {}:{}:{}", file, line, col);
let mut ecx = mk_eval_cx_to_read_const_val(
tcx,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/hooks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ macro_rules! declare_hooks {
declare_hooks! {
/// Tries to destructure an `mir::Const` ADT or array into its variant index
/// and its field values. This should only be used for pretty printing.
hook try_destructure_mir_constant_for_user_output(val: mir::ConstValue<'tcx>, ty: Ty<'tcx>) -> Option<mir::DestructuredConstant<'tcx>>;
hook try_destructure_mir_constant_for_user_output(val: mir::ConstValue, ty: Ty<'tcx>) -> Option<mir::DestructuredConstant<'tcx>>;

/// Getting a &core::panic::Location referring to a span.
hook const_caller_location(file: rustc_span::Symbol, line: u32, col: u32) -> mir::ConstValue<'tcx>;
hook const_caller_location(file: rustc_span::Symbol, line: u32, col: u32) -> mir::ConstValue;

/// Returns `true` if this def is a function-like thing that is eligible for
/// coverage instrumentation under `-Cinstrument-coverage`.
Expand Down
Loading
Loading