Skip to content

Commit d318b9c

Browse files
committed
rustc: move CEnum's signedness into Primitive::Int.
1 parent 61c2bd9 commit d318b9c

File tree

8 files changed

+65
-80
lines changed

8 files changed

+65
-80
lines changed

src/librustc/ty/layout.rs

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ impl<'a, 'tcx> Integer {
498498

499499
let wanted = align.abi();
500500
for &candidate in &[I8, I16, I32, I64] {
501-
let ty = Int(candidate);
501+
let ty = Int(candidate, false);
502502
if wanted == ty.align(dl).abi() && wanted == ty.size(dl).bytes() {
503503
return Some(candidate);
504504
}
@@ -577,7 +577,14 @@ impl<'a, 'tcx> Integer {
577577
/// Fundamental unit of memory access and layout.
578578
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
579579
pub enum Primitive {
580-
Int(Integer),
580+
/// The `bool` is the signedness of the `Integer` type.
581+
///
582+
/// One would think we would not care about such details this low down,
583+
/// but some ABIs are described in terms of C types and ISAs where the
584+
/// integer arithmetic is done on {sign,zero}-extended registers, e.g.
585+
/// a negative integer passed by zero-extension will appear positive in
586+
/// the callee, and most operations on it will produce the wrong values.
587+
Int(Integer, bool),
581588
F32,
582589
F64,
583590
Pointer
@@ -588,11 +595,9 @@ impl<'a, 'tcx> Primitive {
588595
let dl = cx.data_layout();
589596

590597
match self {
591-
Int(I1) | Int(I8) => Size::from_bits(8),
592-
Int(I16) => Size::from_bits(16),
593-
Int(I32) | F32 => Size::from_bits(32),
594-
Int(I64) | F64 => Size::from_bits(64),
595-
Int(I128) => Size::from_bits(128),
598+
Int(i, _) => i.size(),
599+
F32 => Size::from_bits(32),
600+
F64 => Size::from_bits(64),
596601
Pointer => dl.pointer_size
597602
}
598603
}
@@ -601,12 +606,7 @@ impl<'a, 'tcx> Primitive {
601606
let dl = cx.data_layout();
602607

603608
match self {
604-
Int(I1) => dl.i1_align,
605-
Int(I8) => dl.i8_align,
606-
Int(I16) => dl.i16_align,
607-
Int(I32) => dl.i32_align,
608-
Int(I64) => dl.i64_align,
609-
Int(I128) => dl.i128_align,
609+
Int(i, _) => i.align(dl),
610610
F32 => dl.f32_align,
611611
F64 => dl.f64_align,
612612
Pointer => dl.pointer_align
@@ -615,7 +615,7 @@ impl<'a, 'tcx> Primitive {
615615

616616
pub fn to_ty(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
617617
match *self {
618-
Int(i) => i.to_ty(tcx, false),
618+
Int(i, signed) => i.to_ty(tcx, signed),
619619
F32 => tcx.types.f32,
620620
F64 => tcx.types.f64,
621621
Pointer => tcx.mk_mut_ptr(tcx.mk_nil()),
@@ -1098,7 +1098,6 @@ pub enum Layout {
10981098
/// C-like enums; basically an integer.
10991099
CEnum {
11001100
discr: Primitive,
1101-
signed: bool,
11021101
/// Inclusive discriminant range.
11031102
/// If min > max, it represents min...u64::MAX followed by 0...max.
11041103
// FIXME(eddyb) always use the shortest range, e.g. by finding
@@ -1287,7 +1286,7 @@ impl<'a, 'tcx> Layout {
12871286
let metadata = match unsized_part.sty {
12881287
ty::TyForeign(..) => return Ok(Scalar(Pointer)),
12891288
ty::TySlice(_) | ty::TyStr => {
1290-
Int(dl.ptr_sized_integer())
1289+
Int(dl.ptr_sized_integer(), false)
12911290
}
12921291
ty::TyDynamic(..) => Pointer,
12931292
_ => return Err(LayoutError::Unknown(unsized_part))
@@ -1298,13 +1297,13 @@ impl<'a, 'tcx> Layout {
12981297

12991298
let layout = match ty.sty {
13001299
// Basic scalars.
1301-
ty::TyBool => Scalar(Int(I1)),
1302-
ty::TyChar => Scalar(Int(I32)),
1300+
ty::TyBool => Scalar(Int(I1, false)),
1301+
ty::TyChar => Scalar(Int(I32, false)),
13031302
ty::TyInt(ity) => {
1304-
Scalar(Int(Integer::from_attr(dl, attr::SignedInt(ity))))
1303+
Scalar(Int(Integer::from_attr(dl, attr::SignedInt(ity)), true))
13051304
}
13061305
ty::TyUint(ity) => {
1307-
Scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity))))
1306+
Scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity)), false))
13081307
}
13091308
ty::TyFloat(FloatTy::F32) => Scalar(F32),
13101309
ty::TyFloat(FloatTy::F64) => Scalar(F64),
@@ -1453,8 +1452,7 @@ impl<'a, 'tcx> Layout {
14531452
// grok.
14541453
let (discr, signed) = Integer::repr_discr(tcx, ty, &def.repr, min, max);
14551454
return success(CEnum {
1456-
discr: Int(discr),
1457-
signed,
1455+
discr: Int(discr, signed),
14581456
// FIXME: should be u128?
14591457
min: min as u64,
14601458
max: max as u64
@@ -1629,8 +1627,8 @@ impl<'a, 'tcx> Layout {
16291627
ity = min_ity;
16301628
} else {
16311629
// Patch up the variants' first few fields.
1632-
let old_ity_size = Int(min_ity).size(dl);
1633-
let new_ity_size = Int(ity).size(dl);
1630+
let old_ity_size = min_ity.size();
1631+
let new_ity_size = ity.size();
16341632
for variant in &mut variants {
16351633
for i in variant.offsets.iter_mut() {
16361634
if *i <= old_ity_size {
@@ -1646,7 +1644,7 @@ impl<'a, 'tcx> Layout {
16461644
}
16471645

16481646
General {
1649-
discr: Int(ity),
1647+
discr: Int(ity, false),
16501648
variants,
16511649
size,
16521650
align,
@@ -2417,9 +2415,8 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Layout
24172415
FatPointer(ref metadata) => {
24182416
metadata.hash_stable(hcx, hasher);
24192417
}
2420-
CEnum { discr, signed, min, max } => {
2418+
CEnum { discr, min, max } => {
24212419
discr.hash_stable(hcx, hasher);
2422-
signed.hash_stable(hcx, hasher);
24232420
min.hash_stable(hcx, hasher);
24242421
max.hash_stable(hcx, hasher);
24252422
}
@@ -2505,7 +2502,7 @@ impl_stable_hash_for!(enum ::ty::layout::Integer {
25052502
});
25062503

25072504
impl_stable_hash_for!(enum ::ty::layout::Primitive {
2508-
Int(integer),
2505+
Int(integer, signed),
25092506
F32,
25102507
F64,
25112508
Pointer

src/librustc_trans/abi.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ impl<'tcx> LayoutExt<'tcx> for FullLayout<'tcx> {
288288
// The primitive for this algorithm.
289289
layout::Abi::Scalar(value) => {
290290
let kind = match value {
291-
layout::Int(_) |
291+
layout::Int(..) |
292292
layout::Pointer => RegKind::Integer,
293293
layout::F32 |
294294
layout::F64 => RegKind::Float
@@ -467,24 +467,18 @@ impl<'a, 'tcx> ArgType<'tcx> {
467467

468468
pub fn extend_integer_width_to(&mut self, bits: u64) {
469469
// Only integers have signedness
470-
let (i, signed) = match *self.layout {
471-
Layout::Scalar(layout::Int(i)) if self.layout.ty.is_integral() => {
472-
(i, self.layout.ty.is_signed())
470+
match self.layout.abi {
471+
layout::Abi::Scalar(layout::Int(i, signed)) => {
472+
if i.size().bits() < bits {
473+
self.attrs.set(if signed {
474+
ArgAttribute::SExt
475+
} else {
476+
ArgAttribute::ZExt
477+
});
478+
}
473479
}
474480

475-
// Rust enum types that map onto C enums also need to follow
476-
// the target ABI zero-/sign-extension rules.
477-
Layout::CEnum { discr: layout::Int(i), signed, .. } => (i, signed),
478-
479-
_ => return
480-
};
481-
482-
if i.size().bits() < bits {
483-
self.attrs.set(if signed {
484-
ArgAttribute::SExt
485-
} else {
486-
ArgAttribute::ZExt
487-
});
481+
_ => {}
488482
}
489483
}
490484

src/librustc_trans/adt.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,3 @@ pub fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
230230
result
231231
}
232232

233-
pub fn is_discr_signed<'tcx>(l: &layout::Layout) -> bool {
234-
match *l {
235-
layout::CEnum { signed, .. }=> signed,
236-
_ => false,
237-
}
238-
}

src/librustc_trans/cabi_x86_64.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>)
6767
match layout.abi {
6868
layout::Abi::Scalar(value) => {
6969
let reg = match value {
70-
layout::Int(_) |
70+
layout::Int(..) |
7171
layout::Pointer => Class::Int,
7272
layout::F32 |
7373
layout::F64 => Class::Sse

src/librustc_trans/debuginfo/metadata.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,7 +1451,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
14511451
})
14521452
.collect();
14531453

1454-
let discriminant_type_metadata = |discr: layout::Primitive, signed: bool| {
1454+
let discriminant_type_metadata = |discr: layout::Primitive| {
14551455
let disr_type_key = (enum_def_id, discr);
14561456
let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
14571457
.borrow()
@@ -1462,12 +1462,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
14621462
let (discriminant_size, discriminant_align) =
14631463
(discr.size(cx), discr.align(cx));
14641464
let discriminant_base_type_metadata =
1465-
type_metadata(cx,
1466-
match discr {
1467-
layout::Int(i) => i.to_ty(cx.tcx(), signed),
1468-
_ => discr.to_ty(cx.tcx())
1469-
},
1470-
syntax_pos::DUMMY_SP);
1465+
type_metadata(cx, discr.to_ty(cx.tcx()), syntax_pos::DUMMY_SP);
14711466
let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
14721467

14731468
let name = CString::new(discriminant_name.as_bytes()).unwrap();
@@ -1496,11 +1491,11 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
14961491
let type_rep = cx.layout_of(enum_type);
14971492

14981493
let discriminant_type_metadata = match *type_rep {
1499-
layout::CEnum { discr, signed, .. } => {
1500-
return FinalMetadata(discriminant_type_metadata(discr, signed))
1494+
layout::CEnum { discr, .. } => {
1495+
return FinalMetadata(discriminant_type_metadata(discr))
15011496
},
15021497
layout::NullablePointer { .. } | layout::Univariant { .. } => None,
1503-
layout::General { discr, .. } => Some(discriminant_type_metadata(discr, false)),
1498+
layout::General { discr, .. } => Some(discriminant_type_metadata(discr)),
15041499
ref l @ _ => bug!("Not an enum layout: {:#?}", l)
15051500
};
15061501

src/librustc_trans/mir/constant.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc::ty::cast::{CastTy, IntTy};
2323
use rustc::ty::subst::{Kind, Substs, Subst};
2424
use rustc_apfloat::{ieee, Float, Status};
2525
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
26-
use {adt, base};
26+
use base;
2727
use abi::{self, Abi};
2828
use callee;
2929
use builder::Builder;
@@ -683,11 +683,9 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
683683
let r_t_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
684684
let ll_t_out = self.ccx.immediate_llvm_type_of(cast_ty);
685685
let llval = operand.llval;
686-
let signed = if let CastTy::Int(IntTy::CEnum) = r_t_in {
687-
let l = self.ccx.layout_of(operand.ty);
688-
adt::is_discr_signed(&l)
689-
} else {
690-
operand.ty.is_signed()
686+
let signed = match self.ccx.layout_of(operand.ty).abi {
687+
layout::Abi::Scalar(layout::Int(_, signed)) => signed,
688+
_ => false
691689
};
692690

693691
unsafe {

src/librustc_trans/mir/lvalue.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
352352

353353
/// Helper for cases where the discriminant is simply loaded.
354354
fn load_discr(self, bcx: &Builder, discr: layout::Primitive, min: u64, max: u64) -> ValueRef {
355-
if let layout::Int(ity) = discr {
355+
if let layout::Int(ity, _) = discr {
356356
let bits = ity.size().bits();
357357
assert!(bits <= 64);
358358
let bits = bits as usize;
@@ -380,25 +380,30 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
380380
let l = bcx.ccx.layout_of(self.ty.to_ty(bcx.tcx()));
381381

382382
let cast_to = bcx.ccx.immediate_llvm_type_of(cast_to);
383-
let val = match *l {
383+
let (val, discr) = match *l {
384384
layout::Univariant { .. } |
385385
layout::UntaggedUnion { .. } => return C_uint(cast_to, 0),
386386
layout::CEnum { discr, min, max, .. } => {
387-
self.load_discr(bcx, discr, min, max)
387+
(self.load_discr(bcx, discr, min, max), discr)
388388
}
389389
layout::General { discr, ref variants, .. } => {
390390
let ptr = self.project_field(bcx, 0);
391-
ptr.load_discr(bcx, discr, 0, variants.len() as u64 - 1)
391+
(ptr.load_discr(bcx, discr, 0, variants.len() as u64 - 1), discr)
392392
}
393393
layout::NullablePointer { nndiscr, .. } => {
394394
let ptr = self.project_field(bcx, 0);
395395
let lldiscr = bcx.load(ptr.llval, ptr.alignment.non_abi());
396396
let cmp = if nndiscr == 0 { llvm::IntEQ } else { llvm::IntNE };
397-
bcx.icmp(cmp, lldiscr, C_null(bcx.ccx.llvm_type_of(ptr.ty.to_ty(bcx.tcx()))))
397+
(bcx.icmp(cmp, lldiscr, C_null(bcx.ccx.llvm_type_of(ptr.ty.to_ty(bcx.tcx())))),
398+
layout::Int(layout::I1, false))
398399
},
399400
_ => bug!("{} is not an enum", l.ty)
400401
};
401-
bcx.intcast(val, cast_to, adt::is_discr_signed(&l))
402+
let signed = match discr {
403+
layout::Int(_, signed) => signed,
404+
_ => false
405+
};
406+
bcx.intcast(val, cast_to, signed)
402407
}
403408

404409
/// Set the discriminant for a new value of the given case of the given

src/librustc_trans/mir/rvalue.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use llvm::{self, ValueRef};
1212
use rustc::ty::{self, Ty};
1313
use rustc::ty::cast::{CastTy, IntTy};
14-
use rustc::ty::layout::{Layout, LayoutOf};
14+
use rustc::ty::layout::{self, Layout, LayoutOf};
1515
use rustc::mir;
1616
use rustc::middle::lang_items::ExchangeMallocFnLangItem;
1717
use rustc_apfloat::{ieee, Float, Status, Round};
@@ -276,7 +276,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
276276
let ll_t_out = bcx.ccx.immediate_llvm_type_of(cast_ty);
277277
let llval = operand.immediate();
278278
let l = bcx.ccx.layout_of(operand.ty);
279-
let signed = if let Layout::CEnum { signed, min, max, .. } = *l {
279+
280+
if let Layout::CEnum { min, max, .. } = *l {
280281
if max > min {
281282
// We want `table[e as usize]` to not
282283
// have bound checks, and this is the most
@@ -285,13 +286,14 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
285286
base::call_assume(&bcx, bcx.icmp(
286287
llvm::IntULE,
287288
llval,
288-
C_uint(common::val_ty(llval), max)
289+
C_uint(ll_t_in, max)
289290
));
290291
}
292+
}
291293

292-
signed
293-
} else {
294-
operand.ty.is_signed()
294+
let signed = match l.abi {
295+
layout::Abi::Scalar(layout::Int(_, signed)) => signed,
296+
_ => false
295297
};
296298

297299
let newval = match (r_t_in, r_t_out) {

0 commit comments

Comments
 (0)