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

Refactorings in preparation for const value trees #77227

Merged
merged 26 commits into from
Nov 4, 2020
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
362123d
Split the "raw integer bytes" part out of `Scalar`
oli-obk Sep 26, 2020
eac3099
Encode `ScalarInt::bytes` as `u128` instead of `[u8; 16]` to see if t…
oli-obk Oct 1, 2020
ed7a4ad
32 bit platforms don't have 64 bit pointers
oli-obk Oct 1, 2020
02131f4
Use packed struct instead of manually packing into an array
oli-obk Oct 29, 2020
c478574
Explain the use of blocks around `self.data` accesses
oli-obk Oct 29, 2020
3a79708
Fix cranelift build
oli-obk Oct 29, 2020
df4d717
s/Scalar::Raw/Scalar::Int
oli-obk Nov 1, 2020
e5258e6
Remove outdated FIXME
oli-obk Nov 1, 2020
1eb300e
Unaligned reads are UB in Rust irrelevant on which platform we are
oli-obk Nov 1, 2020
3ef9dfd
Update comment
oli-obk Nov 1, 2020
b8751c1
No need for a `zst` constructor method when we can have a constant
oli-obk Nov 1, 2020
8282d52
Replace `Scalar::zst` with a `Scalar::ZST` constant
oli-obk Nov 1, 2020
d1074ed
catch conversion errors during `ptr_sized_op`
oli-obk Nov 1, 2020
0347ca7
Explain why we forward to self-printing during self-printing
oli-obk Nov 1, 2020
f03b18b
Add `is_null` helper
oli-obk Nov 1, 2020
500af76
Add helper for getting an `int` out of a `Scalar`
oli-obk Nov 1, 2020
dad0036
Do not raise interp errors from the scalar int module
oli-obk Nov 1, 2020
98b70c9
Simplify `assert_bits` impl
oli-obk Nov 1, 2020
cb1cf6a
Update compiler/rustc_middle/src/ty/consts/int.rs
oli-obk Nov 2, 2020
e67c768
Move ZST constant to the top of the impl block
oli-obk Nov 2, 2020
abacaf2
`u128` truncation and sign extension are not just interpreter related
oli-obk Nov 4, 2020
2e53625
Document an `unwrap`
oli-obk Nov 4, 2020
97bfff1
Make `ScalarInt` entirely independent of MIR interpretation
oli-obk Nov 4, 2020
6e6c8a8
`u64::try_from` will now fail if `ScalarInt` isn't exactly 64 bits, t…
oli-obk Nov 4, 2020
5f087f0
Update compiler/rustc_target/src/abi/mod.rs
oli-obk Nov 4, 2020
332750f
Update compiler/rustc_target/src/abi/mod.rs
oli-obk Nov 4, 2020
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
8 changes: 3 additions & 5 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ fn codegen_stmt<'tcx>(
UnOp::Neg => match layout.ty.kind() {
ty::Int(IntTy::I128) => {
// FIXME remove this case once ineg.i128 works
let zero = CValue::const_val(fx, layout, 0);
let zero = CValue::const_val(fx, layout, ty::ScalarInt::null(layout.size));
crate::num::codegen_int_binop(fx, BinOp::Sub, zero, operand)
}
ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout),
Expand Down Expand Up @@ -585,13 +585,11 @@ fn codegen_stmt<'tcx>(
.discriminant_for_variant(fx.tcx, *index)
.unwrap();
let discr = if discr.ty.is_signed() {
rustc_middle::mir::interpret::sign_extend(
discr.val,
fx.layout_of(discr.ty).size,
)
fx.layout_of(discr.ty).size.sign_extend(discr.val)
} else {
discr.val
};
let discr = discr.into();

let discr = CValue::const_val(fx, fx.layout_of(to_ty), discr);
lval.write_cvalue(fx, discr);
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_codegen_cranelift/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,8 @@ pub(crate) fn codegen_const_value<'tcx>(
}

match x {
Scalar::Raw { data, size } => {
assert_eq!(u64::from(size), layout.size.bytes());
CValue::const_val(fx, layout, data)
Scalar::Int(int) => {
CValue::const_val(fx, layout, int)
}
Scalar::Ptr(ptr) => {
let alloc_kind = fx.tcx.get_global_alloc(ptr.alloc_id);
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_codegen_cranelift/src/discriminant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
.ty
.discriminant_for_variant(fx.tcx, variant_index)
.unwrap()
.val;
.val
.into();
let discr = CValue::const_val(fx, ptr.layout(), to);
ptr.write_cvalue(fx, discr);
}
Expand All @@ -49,7 +50,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
let niche = place.place_field(fx, mir::Field::new(tag_field));
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
let niche_value = u128::from(niche_value).wrapping_add(niche_start);
let niche_llval = CValue::const_val(fx, niche.layout(), niche_value);
let niche_llval = CValue::const_val(fx, niche.layout(), niche_value.into());
niche.write_cvalue(fx, niche_llval);
}
}
Expand Down Expand Up @@ -77,7 +78,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
.ty
.discriminant_for_variant(fx.tcx, *index)
.map_or(u128::from(index.as_u32()), |discr| discr.val);
return CValue::const_val(fx, dest_layout, discr_val);
return CValue::const_val(fx, dest_layout, discr_val.into());
}
Variants::Multiple {
tag,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,8 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(

fx.bcx.ins().call_indirect(f_sig, f, &[data]);

let ret_val = CValue::const_val(fx, ret.layout(), 0);
let layout = ret.layout();
let ret_val = CValue::const_val(fx, layout, ty::ScalarInt::null(layout.size));
ret.write_cvalue(fx, ret_val);
};

Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_codegen_cranelift/src/value_and_place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,22 +231,24 @@ impl<'tcx> CValue<'tcx> {
pub(crate) fn const_val(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
layout: TyAndLayout<'tcx>,
const_val: u128,
const_val: ty::ScalarInt,
) -> CValue<'tcx> {
assert_eq!(const_val.size(), layout.size);
use cranelift_codegen::ir::immediates::{Ieee32, Ieee64};

let clif_ty = fx.clif_type(layout.ty).unwrap();

if let ty::Bool = layout.ty.kind() {
assert!(
const_val == 0 || const_val == 1,
const_val == ty::ScalarInt::FALSE || const_val == ty::ScalarInt::TRUE,
"Invalid bool 0x{:032X}",
const_val
);
}

let val = match layout.ty.kind() {
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
let const_val = const_val.to_bits(layout.size).unwrap();
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64);
let msb = fx
.bcx
Expand All @@ -259,7 +261,7 @@ impl<'tcx> CValue<'tcx> {
fx
.bcx
.ins()
.iconst(clif_ty, u64::try_from(const_val).expect("uint") as i64)
.iconst(clif_ty, const_val.to_bits(layout.size).unwrap() as i64)
}
ty::Float(FloatTy::F32) => {
fx.bcx.ins().f32const(Ieee32::with_bits(u32::try_from(const_val).unwrap()))
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_llvm/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
use rustc_middle::bug;
use rustc_middle::mir::interpret::{Allocation, GlobalAlloc, Scalar};
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{layout::TyAndLayout, ScalarInt};
use rustc_span::symbol::Symbol;
use rustc_target::abi::{self, AddressSpace, HasDataLayout, LayoutOf, Pointer, Size};

Expand Down Expand Up @@ -230,12 +230,12 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn scalar_to_backend(&self, cv: Scalar, layout: &abi::Scalar, llty: &'ll Type) -> &'ll Value {
let bitsize = if layout.is_bool() { 1 } else { layout.value.size(self).bits() };
match cv {
Scalar::Raw { size: 0, .. } => {
Scalar::Int(ScalarInt::ZST) => {
assert_eq!(0, layout.value.size(self).bytes());
self.const_undef(self.type_ix(0))
}
Scalar::Raw { data, size } => {
assert_eq!(size as u64, layout.value.size(self).bytes());
Scalar::Int(int) => {
let data = int.assert_bits(layout.value.size(self));
let llval = self.const_uint_big(self.type_ix(bitsize), data);
if layout.value == Pointer {
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use rustc_hir::def::CtorKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::ich::NodeIdHashingMode;
use rustc_middle::mir::interpret::truncate;
use rustc_middle::mir::{self, Field, GeneratorLayout};
use rustc_middle::ty::layout::{self, IntegerExt, PrimitiveExt, TyAndLayout};
use rustc_middle::ty::subst::GenericArgKind;
Expand Down Expand Up @@ -1693,7 +1692,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
let value = (i.as_u32() as u128)
.wrapping_sub(niche_variants.start().as_u32() as u128)
.wrapping_add(niche_start);
let value = truncate(value, tag.value.size(cx));
let value = tag.value.size(cx).truncate(value);
// NOTE(eddyb) do *NOT* remove this assert, until
// we pass the full 128-bit value to LLVM, otherwise
// truncation will be silent and remain undetected.
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::{is_range_literal, ExprKind, Node};
use rustc_index::vec::Idx;
use rustc_middle::mir::interpret::{sign_extend, truncate};
use rustc_middle::ty::layout::{IntegerExt, SizeSkeleton};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable};
Expand Down Expand Up @@ -218,11 +217,11 @@ fn report_bin_hex_error(
cx.struct_span_lint(OVERFLOWING_LITERALS, expr.span, |lint| {
let (t, actually) = match ty {
attr::IntType::SignedInt(t) => {
let actually = sign_extend(val, size) as i128;
let actually = size.sign_extend(val) as i128;
(t.name_str(), actually.to_string())
}
attr::IntType::UnsignedInt(t) => {
let actually = truncate(val, size);
let actually = size.truncate(val);
(t.name_str(), actually.to_string())
}
};
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(array_windows)]
#![feature(assoc_char_funcs)]
#![feature(backtrace)]
#![feature(bool_to_option)]
#![feature(box_patterns)]
Expand Down
35 changes: 1 addition & 34 deletions compiler/rustc_middle/src/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_serialize::{Decodable, Encodable};
use rustc_target::abi::{Endian, Size};
use rustc_target::abi::Endian;

use crate::mir;
use crate::ty::codec::{TyDecoder, TyEncoder};
Expand Down Expand Up @@ -590,39 +590,6 @@ pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result<u128, i
uint
}

////////////////////////////////////////////////////////////////////////////////
// Methods to facilitate working with signed integers stored in a u128
////////////////////////////////////////////////////////////////////////////////

/// Truncates `value` to `size` bits and then sign-extend it to 128 bits
/// (i.e., if it is negative, fill with 1's on the left).
#[inline]
pub fn sign_extend(value: u128, size: Size) -> u128 {
let size = size.bits();
if size == 0 {
// Truncated until nothing is left.
return 0;
}
// Sign-extend it.
let shift = 128 - size;
// Shift the unsigned value to the left, then shift back to the right as signed
// (essentially fills with FF on the left).
(((value << shift) as i128) >> shift) as u128
}

/// Truncates `value` to `size` bits.
#[inline]
pub fn truncate(value: u128, size: Size) -> u128 {
let size = size.bits();
if size == 0 {
// Truncated until nothing is left.
return 0;
}
let shift = 128 - size;
// Truncate (shift left to drop out leftover values, shift right to fill with zeroes).
(value << shift) >> shift
}

/// Computes the unsigned absolute value without wrapping or panicking.
#[inline]
pub fn uabs(value: i64) -> u64 {
Expand Down
Loading