Skip to content

Commit

Permalink
Rollup merge of rust-lang#128697 - RalfJung:nullary-op, r=compiler-er…
Browse files Browse the repository at this point in the history
…rors

interpret: move nullary-op evaluation into operator.rs

We call it an operator, so we might as well treat it like one. :)

Also use more consistent naming for the "evaluate intrinsic" functions. "emulate" is really the wrong term, this *is* a genuine implementation of the intrinsic semantics after all.
  • Loading branch information
matthiaskrgr authored Aug 5, 2024
2 parents 77f57cb + 46896d6 commit c53698b
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 41 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
_unwind: mir::UnwindAction,
) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
// Shared intrinsics.
if ecx.emulate_intrinsic(instance, args, dest, target)? {
if ecx.eval_intrinsic(instance, args, dest, target)? {
return Ok(None);
}
let intrinsic_name = ecx.tcx.item_name(instance.def_id());
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Returns `true` if emulation happened.
/// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own
/// intrinsic handling.
pub fn emulate_intrinsic(
pub fn eval_intrinsic(
&mut self,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, M::Provenance>],
Expand Down Expand Up @@ -447,7 +447,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
Ok(true)
}

pub(super) fn emulate_nondiverging_intrinsic(
pub(super) fn eval_nondiverging_intrinsic(
&mut self,
intrinsic: &NonDivergingIntrinsic<'tcx>,
) -> InterpResult<'tcx> {
Expand Down
37 changes: 36 additions & 1 deletion compiler/rustc_const_eval/src/interpret/operator.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use either::Either;
use rustc_apfloat::{Float, FloatConvert};
use rustc_middle::mir::interpret::{InterpResult, Scalar};
use rustc_middle::mir::NullOp;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::{self, FloatTy, ScalarInt};
use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty};
use rustc_middle::{bug, mir, span_bug};
use rustc_span::symbol::sym;
use tracing::trace;
Expand Down Expand Up @@ -480,4 +481,38 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
}
}

pub fn nullary_op(
&self,
null_op: NullOp<'tcx>,
arg_ty: Ty<'tcx>,
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
use rustc_middle::mir::NullOp::*;

let layout = self.layout_of(arg_ty)?;
let usize_layout = || self.layout_of(self.tcx.types.usize).unwrap();

Ok(match null_op {
SizeOf => {
if !layout.abi.is_sized() {
span_bug!(self.cur_span(), "unsized type for `NullaryOp::SizeOf`");
}
let val = layout.size.bytes();
ImmTy::from_uint(val, usize_layout())
}
AlignOf => {
if !layout.abi.is_sized() {
span_bug!(self.cur_span(), "unsized type for `NullaryOp::AlignOf`");
}
let val = layout.align.abi.bytes();
ImmTy::from_uint(val, usize_layout())
}
OffsetOf(fields) => {
let val =
self.tcx.offset_of_subfield(self.param_env, layout, fields.iter()).bytes();
ImmTy::from_uint(val, usize_layout())
}
UbChecks => ImmTy::from_bool(self.tcx.sess.ub_checks(), *self.tcx),
})
}
}
43 changes: 8 additions & 35 deletions compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
use either::Either;
use rustc_index::IndexSlice;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::{bug, mir, span_bug};
use rustc_middle::{bug, mir};
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
use tracing::{info, instrument, trace};

Expand Down Expand Up @@ -94,7 +93,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
M::retag_place_contents(self, *kind, &dest)?;
}

Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?,
Intrinsic(box intrinsic) => self.eval_nondiverging_intrinsic(intrinsic)?,

// Evaluate the place expression, without reading from it.
PlaceMention(box place) => {
Expand Down Expand Up @@ -179,6 +178,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_immediate(*result, &dest)?;
}

NullaryOp(null_op, ty) => {
let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
let val = self.nullary_op(null_op, ty)?;
self.write_immediate(*val, &dest)?;
}

Aggregate(box ref kind, ref operands) => {
self.write_aggregate(kind, operands, &dest)?;
}
Expand Down Expand Up @@ -230,38 +235,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_immediate(*val, &dest)?;
}

NullaryOp(ref null_op, ty) => {
let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
let layout = self.layout_of(ty)?;
if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op
&& layout.is_unsized()
{
span_bug!(
self.frame().current_span(),
"{null_op:?} MIR operator called for unsized type {ty}",
);
}
let val = match null_op {
mir::NullOp::SizeOf => {
let val = layout.size.bytes();
Scalar::from_target_usize(val, self)
}
mir::NullOp::AlignOf => {
let val = layout.align.abi.bytes();
Scalar::from_target_usize(val, self)
}
mir::NullOp::OffsetOf(fields) => {
let val = self
.tcx
.offset_of_subfield(self.param_env, layout, fields.iter())
.bytes();
Scalar::from_target_usize(val, self)
}
mir::NullOp::UbChecks => Scalar::from_bool(self.tcx.sess.ub_checks()),
};
self.write_scalar(val, &dest)?;
}

ShallowInitBox(ref operand, _) => {
let src = self.eval_operand(operand, None)?;
let v = self.read_immediate(&src)?;
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let this = self.eval_context_mut();

// See if the core engine can handle this intrinsic.
if this.emulate_intrinsic(instance, args, dest, ret)? {
if this.eval_intrinsic(instance, args, dest, ret)? {
return Ok(None);
}
let intrinsic_name = this.tcx.item_name(instance.def_id());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:LL:CC: SizeOf MIR operator called for unsized type dyn Debug
error: internal compiler error: compiler/rustc_const_eval/src/interpret/operator.rs:LL:CC: unsized type for `NullaryOp::SizeOf`
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL

Box<dyn Any>
Expand Down

0 comments on commit c53698b

Please sign in to comment.