Skip to content
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

do not normalize all non-scalar constants to a ConstValue::ScalarPair #54693

Merged
merged 2 commits into from
Oct 2, 2018
Merged
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
5 changes: 0 additions & 5 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,11 +391,6 @@ for ::mir::interpret::ConstValue<'gcx> {
}
}

impl_stable_hash_for!(enum mir::interpret::ScalarMaybeUndef {
Scalar(v),
Undef
});

impl_stable_hash_for!(struct mir::interpret::Pointer {
alloc_id,
offset
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub use self::error::{
FrameInfo, ConstEvalResult,
};

pub use self::value::{Scalar, ConstValue, ScalarMaybeUndef};
pub use self::value::{Scalar, ConstValue};

use std::fmt;
use mir;
Expand Down
108 changes: 9 additions & 99 deletions src/librustc/mir/interpret/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,18 @@ pub enum ConstValue<'tcx> {
/// to allow HIR creation to happen for everything before needing to be able to run constant
/// evaluation
Unevaluated(DefId, &'tcx Substs<'tcx>),

/// Used only for types with layout::abi::Scalar ABI and ZSTs
///
/// Not using the enum `Value` to encode that this must not be `Undef`
Scalar(Scalar),
/// Used only for types with layout::abi::ScalarPair

/// Used only for *fat pointers* with layout::abi::ScalarPair
///
/// The second field may be undef in case of `Option<usize>::None`
ScalarPair(Scalar, ScalarMaybeUndef),
/// Used only for the remaining cases. An allocation + offset into the allocation.
/// Needed for pattern matching code related to slices and strings.
ScalarPair(Scalar, Scalar),

/// An allocation + offset into the allocation.
/// Invariant: The AllocId matches the allocation.
ByRef(AllocId, &'tcx Allocation, Size),
}
Expand Down Expand Up @@ -67,12 +70,12 @@ impl<'tcx> ConstValue<'tcx> {
ConstValue::ScalarPair(val, Scalar::Bits {
bits: len as u128,
size: cx.data_layout().pointer_size.bytes() as u8,
}.into())
})
}

#[inline]
pub fn new_dyn_trait(val: Scalar, vtable: Pointer) -> Self {
ConstValue::ScalarPair(val, Scalar::Ptr(vtable).into())
ConstValue::ScalarPair(val, Scalar::Ptr(vtable))
}
}

Expand Down Expand Up @@ -340,96 +343,3 @@ pub enum Scalar<Id=AllocId> {
/// relocation and its associated offset together as a `Pointer` here.
Ptr(Pointer<Id>),
}

#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
pub enum ScalarMaybeUndef<Id=AllocId> {
Scalar(Scalar<Id>),
Undef,
}

impl From<Scalar> for ScalarMaybeUndef {
#[inline(always)]
fn from(s: Scalar) -> Self {
ScalarMaybeUndef::Scalar(s)
}
}

impl<'tcx> ScalarMaybeUndef {
#[inline]
pub fn not_undef(self) -> EvalResult<'static, Scalar> {
match self {
ScalarMaybeUndef::Scalar(scalar) => Ok(scalar),
ScalarMaybeUndef::Undef => err!(ReadUndefBytes(Size::from_bytes(0))),
}
}

#[inline(always)]
pub fn to_ptr(self) -> EvalResult<'tcx, Pointer> {
self.not_undef()?.to_ptr()
}

#[inline(always)]
pub fn to_bits(self, target_size: Size) -> EvalResult<'tcx, u128> {
self.not_undef()?.to_bits(target_size)
}

#[inline(always)]
pub fn to_bool(self) -> EvalResult<'tcx, bool> {
self.not_undef()?.to_bool()
}

#[inline(always)]
pub fn to_char(self) -> EvalResult<'tcx, char> {
self.not_undef()?.to_char()
}

#[inline(always)]
pub fn to_f32(self) -> EvalResult<'tcx, f32> {
self.not_undef()?.to_f32()
}

#[inline(always)]
pub fn to_f64(self) -> EvalResult<'tcx, f64> {
self.not_undef()?.to_f64()
}

#[inline(always)]
pub fn to_u8(self) -> EvalResult<'tcx, u8> {
self.not_undef()?.to_u8()
}

#[inline(always)]
pub fn to_u32(self) -> EvalResult<'tcx, u32> {
self.not_undef()?.to_u32()
}

#[inline(always)]
pub fn to_u64(self) -> EvalResult<'tcx, u64> {
self.not_undef()?.to_u64()
}

#[inline(always)]
pub fn to_usize(self, cx: impl HasDataLayout) -> EvalResult<'tcx, u64> {
self.not_undef()?.to_usize(cx)
}

#[inline(always)]
pub fn to_i8(self) -> EvalResult<'tcx, i8> {
self.not_undef()?.to_i8()
}

#[inline(always)]
pub fn to_i32(self) -> EvalResult<'tcx, i32> {
self.not_undef()?.to_i32()
}

#[inline(always)]
pub fn to_i64(self) -> EvalResult<'tcx, i64> {
self.not_undef()?.to_i64()
}

#[inline(always)]
pub fn to_isize(self, cx: impl HasDataLayout) -> EvalResult<'tcx, i64> {
self.not_undef()?.to_isize(cx)
}
}
4 changes: 2 additions & 2 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use hir::def::CtorKind;
use hir::def_id::DefId;
use hir::{self, HirId, InlineAsm};
use middle::region;
use mir::interpret::{ConstValue, EvalErrorKind, Scalar, ScalarMaybeUndef};
use mir::interpret::{ConstValue, EvalErrorKind, Scalar};
use mir::visit::MirVisitable;
use rustc_apfloat::ieee::{Double, Single};
use rustc_apfloat::Float;
Expand Down Expand Up @@ -2397,7 +2397,7 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: &ty::Const) -> fmt::Result {
// print string literals
if let ConstValue::ScalarPair(ptr, len) = value {
if let Scalar::Ptr(ptr) = ptr {
if let ScalarMaybeUndef::Scalar(Scalar::Bits { bits: len, .. }) = len {
if let Scalar::Bits { bits: len, .. } = len {
if let Ref(_, &ty::TyS { sty: Str, .. }, _) = ty.sty {
return ty::tls::with(|tcx| {
let alloc = tcx.alloc_map.lock().get(ptr.alloc_id);
Expand Down
18 changes: 7 additions & 11 deletions src/librustc_codegen_llvm/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc::mir::interpret::ConstEvalErr;
use rustc::mir::interpret::{ConstValue, ConstEvalErr};
use rustc::mir;
use rustc::mir::interpret::{ConstValue, ScalarMaybeUndef};
use rustc::ty;
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
use rustc_data_structures::sync::Lrc;
Expand Down Expand Up @@ -114,15 +113,12 @@ impl OperandRef<'ll, 'tcx> {
layout.scalar_pair_element_llvm_type(bx.cx, 0, true),
);
let b_layout = layout.scalar_pair_element_llvm_type(bx.cx, 1, true);
let b_llval = match b {
ScalarMaybeUndef::Scalar(b) => scalar_to_llvm(
bx.cx,
b,
b_scalar,
b_layout,
),
ScalarMaybeUndef::Undef => C_undef(b_layout),
};
let b_llval = scalar_to_llvm(
bx.cx,
b,
b_scalar,
b_layout,
);
OperandValue::Pair(a_llval, b_llval)
},
ConstValue::ByRef(_, alloc, offset) => {
Expand Down
16 changes: 13 additions & 3 deletions src/librustc_mir/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc::hir::{self, def_id::DefId};
use rustc::mir::interpret::ConstEvalErr;
use rustc::mir;
use rustc::ty::{self, TyCtxt, Instance, query::TyCtxtAt};
use rustc::ty::layout::{LayoutOf, TyLayout};
use rustc::ty::layout::{self, LayoutOf, TyLayout};
use rustc::ty::subst::Subst;
use rustc_data_structures::indexed_vec::IndexVec;

Expand Down Expand Up @@ -97,8 +97,18 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
pub fn op_to_const<'tcx>(
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
op: OpTy<'tcx>,
normalize: bool,
may_normalize: bool,
) -> EvalResult<'tcx, &'tcx ty::Const<'tcx>> {
// We do not normalize just any data. Only scalar layout and fat pointers.
let normalize = may_normalize
&& match op.layout.abi {
layout::Abi::Scalar(..) => true,
layout::Abi::ScalarPair(..) => {
// Must be a fat pointer
op.layout.ty.builtin_deref(true).is_some()
},
_ => false,
};
let normalized_op = if normalize {
ecx.try_read_value(op)?
} else {
Expand All @@ -125,7 +135,7 @@ pub fn op_to_const<'tcx>(
Ok(Value::Scalar(x)) =>
ConstValue::Scalar(x.not_undef()?),
Ok(Value::ScalarPair(a, b)) =>
ConstValue::ScalarPair(a.not_undef()?, b),
ConstValue::ScalarPair(a.not_undef()?, b.not_undef()?),
};
Ok(ty::Const::from_const_value(ecx.tcx.tcx, val, op.layout.ty))
}
Expand Down
7 changes: 0 additions & 7 deletions src/librustc_mir/hair/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1124,13 +1124,6 @@ pub fn compare_const_vals<'a, 'tcx>(
len_b,
),
) if ptr_a.offset.bytes() == 0 && ptr_b.offset.bytes() == 0 => {
let len_a = len_a.not_undef().ok();
let len_b = len_b.not_undef().ok();
if len_a.is_none() || len_b.is_none() {
tcx.sess.struct_err("str slice len is undef").delay_as_bug();
}
let len_a = len_a?;
let len_b = len_b?;
if let Ok(len_a) = len_a.to_bits(tcx.data_layout.pointer_size) {
if let Ok(len_b) = len_b.to_bits(tcx.data_layout.pointer_size) {
if len_a == len_b {
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_mir/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@ use rustc_data_structures::indexed_vec::IndexVec;
use rustc::mir::interpret::{
GlobalId, Scalar, FrameInfo, AllocId,
EvalResult, EvalErrorKind,
ScalarMaybeUndef,
truncate, sign_extend,
};

use syntax::source_map::{self, Span};

use super::{
Value, Operand, MemPlace, MPlaceTy, Place,
Value, Operand, MemPlace, MPlaceTy, Place, ScalarMaybeUndef,
Memory, Machine
};

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ use std::ptr;

use rustc::ty::{self, Instance, query::TyCtxtAt};
use rustc::ty::layout::{self, Align, TargetDataLayout, Size, HasDataLayout};
use rustc::mir::interpret::{Pointer, AllocId, Allocation, ConstValue, ScalarMaybeUndef, GlobalId,
use rustc::mir::interpret::{Pointer, AllocId, Allocation, ConstValue, GlobalId,
EvalResult, Scalar, EvalErrorKind, AllocType, PointerArithmetic,
truncate};
pub use rustc::mir::interpret::{write_target_uint, read_target_uint};
use rustc_data_structures::fx::{FxHashSet, FxHashMap};

use syntax::ast::Mutability;

use super::Machine;
use super::{Machine, ScalarMaybeUndef};

#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
pub enum MemoryKind<T> {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ pub use self::memory::{Memory, MemoryKind};

pub use self::machine::Machine;

pub use self::operand::{Value, ValTy, Operand, OpTy};
pub use self::operand::{ScalarMaybeUndef, Value, ValTy, Operand, OpTy};
Loading