rustc_trans: always keep track of the Align in LvalueRef.
This commit is contained in:
parent
7c6f242ca8
commit
16307465d5
@ -30,7 +30,7 @@ use cabi_sparc64;
|
||||
use cabi_nvptx;
|
||||
use cabi_nvptx64;
|
||||
use cabi_hexagon;
|
||||
use mir::place::{Alignment, PlaceRef};
|
||||
use mir::place::PlaceRef;
|
||||
use mir::operand::OperandValue;
|
||||
use type_::Type;
|
||||
use type_of::{LayoutLlvmExt, PointerKind};
|
||||
@ -561,7 +561,7 @@ impl<'a, 'tcx> ArgType<'tcx> {
|
||||
}
|
||||
let ccx = bcx.ccx;
|
||||
if self.is_indirect() {
|
||||
OperandValue::Ref(val, Alignment::AbiAligned).store(bcx, dst)
|
||||
OperandValue::Ref(val, self.layout.align).store(bcx, dst)
|
||||
} else if let PassMode::Cast(cast) = self.mode {
|
||||
// FIXME(eddyb): Figure out when the simpler Store is safe, clang
|
||||
// uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
|
||||
|
@ -316,7 +316,7 @@ pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
|
||||
if src_f.layout.ty == dst_f.layout.ty {
|
||||
memcpy_ty(bcx, dst_f.llval, src_f.llval, src_f.layout,
|
||||
(src_f.alignment | dst_f.alignment).non_abi());
|
||||
Some(src_f.align.min(dst_f.align)));
|
||||
} else {
|
||||
coerce_unsized_into(bcx, src_f, dst_f);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use intrinsics::{self, Intrinsic};
|
||||
use llvm;
|
||||
use llvm::{ValueRef};
|
||||
use abi::{Abi, FnType, PassMode};
|
||||
use mir::place::{PlaceRef, Alignment};
|
||||
use mir::place::PlaceRef;
|
||||
use mir::operand::{OperandRef, OperandValue};
|
||||
use base::*;
|
||||
use common::*;
|
||||
@ -106,7 +106,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
let name = &*tcx.item_name(def_id);
|
||||
|
||||
let llret_ty = ccx.layout_of(ret_ty).llvm_type(ccx);
|
||||
let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, Alignment::AbiAligned);
|
||||
let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align);
|
||||
|
||||
let simple = get_simple_intrinsic(ccx, name);
|
||||
let llval = match name {
|
||||
@ -254,7 +254,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
bcx.volatile_store(b, dst.project_field(bcx, 1).llval);
|
||||
} else {
|
||||
let val = if let OperandValue::Ref(ptr, align) = args[1].val {
|
||||
bcx.load(ptr, align.non_abi())
|
||||
bcx.load(ptr, Some(align))
|
||||
} else {
|
||||
if dst.layout.is_zst() {
|
||||
return;
|
||||
@ -330,9 +330,9 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
let overflow = bcx.zext(bcx.extract_value(pair, 1), Type::bool(ccx));
|
||||
|
||||
let dest = result.project_field(bcx, 0);
|
||||
bcx.store(val, dest.llval, dest.alignment.non_abi());
|
||||
bcx.store(val, dest.llval, dest.non_abi_align());
|
||||
let dest = result.project_field(bcx, 1);
|
||||
bcx.store(overflow, dest.llval, dest.alignment.non_abi());
|
||||
bcx.store(overflow, dest.llval, dest.non_abi_align());
|
||||
|
||||
return;
|
||||
},
|
||||
@ -473,9 +473,9 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
let success = bcx.zext(bcx.extract_value(pair, 1), Type::bool(bcx.ccx));
|
||||
|
||||
let dest = result.project_field(bcx, 0);
|
||||
bcx.store(val, dest.llval, dest.alignment.non_abi());
|
||||
bcx.store(val, dest.llval, dest.non_abi_align());
|
||||
let dest = result.project_field(bcx, 1);
|
||||
bcx.store(success, dest.llval, dest.alignment.non_abi());
|
||||
bcx.store(success, dest.llval, dest.non_abi_align());
|
||||
return;
|
||||
} else {
|
||||
return invalid_monomorphization(ty);
|
||||
@ -544,7 +544,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
let tp_ty = substs.type_at(0);
|
||||
let dst = args[0].deref(bcx.ccx);
|
||||
let val = if let OperandValue::Ref(ptr, align) = args[1].val {
|
||||
bcx.load(ptr, align.non_abi())
|
||||
bcx.load(ptr, Some(align))
|
||||
} else {
|
||||
from_immediate(bcx, args[1].immediate())
|
||||
};
|
||||
@ -677,7 +677,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
for i in 0..elems.len() {
|
||||
let dest = result.project_field(bcx, i);
|
||||
let val = bcx.extract_value(val, i as u64);
|
||||
bcx.store(val, dest.llval, dest.alignment.non_abi());
|
||||
bcx.store(val, dest.llval, dest.non_abi_align());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ use syntax_pos::Pos;
|
||||
|
||||
use super::{MirContext, LocalRef};
|
||||
use super::constant::Const;
|
||||
use super::place::{Alignment, PlaceRef};
|
||||
use super::place::PlaceRef;
|
||||
use super::operand::OperandRef;
|
||||
use super::operand::OperandValue::{Pair, Ref, Immediate};
|
||||
|
||||
@ -216,7 +216,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
PassMode::Direct(_) | PassMode::Pair(..) => {
|
||||
let op = self.trans_consume(&bcx, &mir::Place::Local(mir::RETURN_PLACE));
|
||||
if let Ref(llval, align) = op.val {
|
||||
bcx.load(llval, align.non_abi())
|
||||
bcx.load(llval, Some(align))
|
||||
} else {
|
||||
op.immediate_or_packed_pair(&bcx)
|
||||
}
|
||||
@ -228,7 +228,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
LocalRef::Operand(None) => bug!("use of return before def"),
|
||||
LocalRef::Place(tr_place) => {
|
||||
OperandRef {
|
||||
val: Ref(tr_place.llval, tr_place.alignment),
|
||||
val: Ref(tr_place.llval, tr_place.align),
|
||||
layout: tr_place.layout
|
||||
}
|
||||
}
|
||||
@ -240,7 +240,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
scratch.llval
|
||||
}
|
||||
Ref(llval, align) => {
|
||||
assert_eq!(align, Alignment::AbiAligned,
|
||||
assert_eq!(align.abi(), op.layout.align.abi(),
|
||||
"return place is unaligned!");
|
||||
llval
|
||||
}
|
||||
@ -579,7 +579,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
(&mir::Operand::Constant(_), Ref(..)) => {
|
||||
let tmp = PlaceRef::alloca(&bcx, op.layout, "const");
|
||||
op.val.store(&bcx, tmp);
|
||||
op.val = Ref(tmp.llval, tmp.alignment);
|
||||
op.val = Ref(tmp.llval, tmp.align);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -639,38 +639,40 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
PassMode::Indirect(_) | PassMode::Cast(_) => {
|
||||
let scratch = PlaceRef::alloca(bcx, arg.layout, "arg");
|
||||
op.val.store(bcx, scratch);
|
||||
(scratch.llval, Alignment::AbiAligned, true)
|
||||
(scratch.llval, scratch.align, true)
|
||||
}
|
||||
_ => {
|
||||
(op.immediate_or_packed_pair(bcx), Alignment::AbiAligned, false)
|
||||
(op.immediate_or_packed_pair(bcx), arg.layout.align, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
Ref(llval, align @ Alignment::Packed(_)) if arg.is_indirect() => {
|
||||
// `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I
|
||||
// think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't
|
||||
// have scary latent bugs around.
|
||||
Ref(llval, align) => {
|
||||
if arg.is_indirect() && align.abi() < arg.layout.align.abi() {
|
||||
// `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I
|
||||
// think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't
|
||||
// have scary latent bugs around.
|
||||
|
||||
let scratch = PlaceRef::alloca(bcx, arg.layout, "arg");
|
||||
base::memcpy_ty(bcx, scratch.llval, llval, op.layout, align.non_abi());
|
||||
(scratch.llval, Alignment::AbiAligned, true)
|
||||
let scratch = PlaceRef::alloca(bcx, arg.layout, "arg");
|
||||
base::memcpy_ty(bcx, scratch.llval, llval, op.layout, Some(align));
|
||||
(scratch.llval, scratch.align, true)
|
||||
} else {
|
||||
(llval, align, true)
|
||||
}
|
||||
}
|
||||
Ref(llval, align) => (llval, align, true)
|
||||
};
|
||||
|
||||
if by_ref && !arg.is_indirect() {
|
||||
// Have to load the argument, maybe while casting it.
|
||||
if let PassMode::Cast(ty) = arg.mode {
|
||||
llval = bcx.load(bcx.pointercast(llval, ty.llvm_type(bcx.ccx).ptr_to()),
|
||||
(align | Alignment::Packed(arg.layout.align))
|
||||
.non_abi());
|
||||
Some(align.min(arg.layout.align)));
|
||||
} else {
|
||||
// We can't use `PlaceRef::load` here because the argument
|
||||
// may have a type we don't treat as immediate, but the ABI
|
||||
// used for this call is passing it by-value. In that case,
|
||||
// the load would just produce `OperandValue::Ref` instead
|
||||
// of the `OperandValue::Immediate` we need for the call.
|
||||
llval = bcx.load(llval, align.non_abi());
|
||||
llval = bcx.load(llval, Some(align));
|
||||
if let layout::Abi::Scalar(ref scalar) = arg.layout.abi {
|
||||
if scalar.is_bool() {
|
||||
bcx.range_metadata(llval, 0..2);
|
||||
@ -820,21 +822,17 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
self.trans_place(bcx, dest)
|
||||
};
|
||||
if fn_ret.is_indirect() {
|
||||
match dest.alignment {
|
||||
Alignment::AbiAligned => {
|
||||
llargs.push(dest.llval);
|
||||
ReturnDest::Nothing
|
||||
},
|
||||
Alignment::Packed(_) => {
|
||||
// Currently, MIR code generation does not create calls
|
||||
// that store directly to fields of packed structs (in
|
||||
// fact, the calls it creates write only to temps),
|
||||
//
|
||||
// If someone changes that, please update this code path
|
||||
// to create a temporary.
|
||||
span_bug!(self.mir.span, "can't directly store to unaligned value");
|
||||
}
|
||||
if dest.align.abi() < dest.layout.align.abi() {
|
||||
// Currently, MIR code generation does not create calls
|
||||
// that store directly to fields of packed structs (in
|
||||
// fact, the calls it creates write only to temps),
|
||||
//
|
||||
// If someone changes that, please update this code path
|
||||
// to create a temporary.
|
||||
span_bug!(self.mir.span, "can't directly store to unaligned value");
|
||||
}
|
||||
llargs.push(dest.llval);
|
||||
ReturnDest::Nothing
|
||||
} else {
|
||||
ReturnDest::Store(dest)
|
||||
}
|
||||
@ -874,8 +872,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
let llty = src.layout.llvm_type(bcx.ccx);
|
||||
let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to());
|
||||
let align = src.layout.align.min(dst.layout.align);
|
||||
src.val.store(bcx,
|
||||
PlaceRef::new_sized(cast_ptr, src.layout, Alignment::Packed(align)));
|
||||
src.val.store(bcx, PlaceRef::new_sized(cast_ptr, src.layout, align));
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,7 +42,6 @@ use syntax::ast;
|
||||
use std::fmt;
|
||||
use std::ptr;
|
||||
|
||||
use super::place::Alignment;
|
||||
use super::operand::{OperandRef, OperandValue};
|
||||
use super::MirContext;
|
||||
|
||||
@ -182,12 +181,12 @@ impl<'a, 'tcx> Const<'tcx> {
|
||||
let align = ccx.align_of(self.ty);
|
||||
let ptr = consts::addr_of(ccx, self.llval, align, "const");
|
||||
OperandValue::Ref(consts::ptrcast(ptr, layout.llvm_type(ccx).ptr_to()),
|
||||
Alignment::AbiAligned)
|
||||
layout.align)
|
||||
};
|
||||
|
||||
OperandRef {
|
||||
val,
|
||||
layout: ccx.layout_of(self.ty)
|
||||
layout
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
pub use self::constant::trans_static_initializer;
|
||||
|
||||
use self::analyze::CleanupKind;
|
||||
use self::place::{Alignment, PlaceRef};
|
||||
use self::place::PlaceRef;
|
||||
use rustc::mir::traversal;
|
||||
|
||||
use self::operand::{OperandRef, OperandValue};
|
||||
@ -279,9 +279,7 @@ pub fn trans_mir<'a, 'tcx: 'a>(
|
||||
if local == mir::RETURN_PLACE && mircx.fn_ty.ret.is_indirect() {
|
||||
debug!("alloc: {:?} (return place) -> place", local);
|
||||
let llretptr = llvm::get_param(llfn, 0);
|
||||
LocalRef::Place(PlaceRef::new_sized(llretptr,
|
||||
layout,
|
||||
Alignment::AbiAligned))
|
||||
LocalRef::Place(PlaceRef::new_sized(llretptr, layout, layout.align))
|
||||
} else if memory_locals.contains(local.index()) {
|
||||
debug!("alloc: {:?} -> place", local);
|
||||
LocalRef::Place(PlaceRef::alloca(&bcx, layout, &format!("{:?}", local)))
|
||||
@ -474,7 +472,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
let llarg = llvm::get_param(bcx.llfn(), llarg_idx as c_uint);
|
||||
bcx.set_value_name(llarg, &name);
|
||||
llarg_idx += 1;
|
||||
PlaceRef::new_sized(llarg, arg.layout, Alignment::AbiAligned)
|
||||
PlaceRef::new_sized(llarg, arg.layout, arg.layout.align)
|
||||
} else {
|
||||
let tmp = PlaceRef::alloca(bcx, arg.layout, &name);
|
||||
arg.store_fn_arg(bcx, &mut llarg_idx, tmp);
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use llvm::ValueRef;
|
||||
use rustc::ty;
|
||||
use rustc::ty::layout::{self, LayoutOf, TyLayout};
|
||||
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
|
||||
use rustc::mir;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
||||
@ -25,7 +25,7 @@ use std::fmt;
|
||||
use std::ptr;
|
||||
|
||||
use super::{MirContext, LocalRef};
|
||||
use super::place::{Alignment, PlaceRef};
|
||||
use super::place::PlaceRef;
|
||||
|
||||
/// The representation of a Rust value. The enum variant is in fact
|
||||
/// uniquely determined by the value's type, but is kept as a
|
||||
@ -34,7 +34,7 @@ use super::place::{Alignment, PlaceRef};
|
||||
pub enum OperandValue {
|
||||
/// A reference to the actual operand. The data is guaranteed
|
||||
/// to be valid for the operand's lifetime.
|
||||
Ref(ValueRef, Alignment),
|
||||
Ref(ValueRef, Align),
|
||||
/// A single LLVM value.
|
||||
Immediate(ValueRef),
|
||||
/// A pair of immediate LLVM values. Used by fat pointers too.
|
||||
@ -107,11 +107,12 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
||||
OperandValue::Pair(llptr, llextra) => (llptr, llextra),
|
||||
OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self)
|
||||
};
|
||||
let layout = ccx.layout_of(projected_ty);
|
||||
PlaceRef {
|
||||
llval: llptr,
|
||||
llextra,
|
||||
layout: ccx.layout_of(projected_ty),
|
||||
alignment: Alignment::AbiAligned,
|
||||
layout,
|
||||
align: layout.align,
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,9 +223,9 @@ impl<'a, 'tcx> OperandValue {
|
||||
match self {
|
||||
OperandValue::Ref(r, source_align) =>
|
||||
base::memcpy_ty(bcx, dest.llval, r, dest.layout,
|
||||
(source_align | dest.alignment).non_abi()),
|
||||
Some(source_align.min(dest.align))),
|
||||
OperandValue::Immediate(s) => {
|
||||
bcx.store(base::from_immediate(bcx, s), dest.llval, dest.alignment.non_abi());
|
||||
bcx.store(base::from_immediate(bcx, s), dest.llval, dest.non_abi_align());
|
||||
}
|
||||
OperandValue::Pair(a, b) => {
|
||||
for (i, &x) in [a, b].iter().enumerate() {
|
||||
@ -233,7 +234,7 @@ impl<'a, 'tcx> OperandValue {
|
||||
if common::val_ty(x) == Type::i1(bcx.ccx) {
|
||||
llptr = bcx.pointercast(llptr, Type::i8p(bcx.ccx));
|
||||
}
|
||||
bcx.store(base::from_immediate(bcx, x), llptr, dest.alignment.non_abi());
|
||||
bcx.store(base::from_immediate(bcx, x), llptr, dest.non_abi_align());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,50 +24,10 @@ use value::Value;
|
||||
use glue;
|
||||
|
||||
use std::ptr;
|
||||
use std::ops;
|
||||
|
||||
use super::{MirContext, LocalRef};
|
||||
use super::operand::{OperandRef, OperandValue};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Alignment {
|
||||
Packed(Align),
|
||||
AbiAligned,
|
||||
}
|
||||
|
||||
impl ops::BitOr for Alignment {
|
||||
type Output = Self;
|
||||
|
||||
fn bitor(self, rhs: Self) -> Self {
|
||||
match (self, rhs) {
|
||||
(Alignment::Packed(a), Alignment::Packed(b)) => {
|
||||
Alignment::Packed(a.min(b))
|
||||
}
|
||||
(Alignment::Packed(x), _) | (_, Alignment::Packed(x)) => {
|
||||
Alignment::Packed(x)
|
||||
}
|
||||
(Alignment::AbiAligned, Alignment::AbiAligned) => {
|
||||
Alignment::AbiAligned
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<TyLayout<'a>> for Alignment {
|
||||
fn from(layout: TyLayout) -> Self {
|
||||
Alignment::Packed(layout.align)
|
||||
}
|
||||
}
|
||||
|
||||
impl Alignment {
|
||||
pub fn non_abi(self) -> Option<Align> {
|
||||
match self {
|
||||
Alignment::Packed(x) => Some(x),
|
||||
Alignment::AbiAligned => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct PlaceRef<'tcx> {
|
||||
/// Pointer to the contents of the place
|
||||
@ -79,20 +39,20 @@ pub struct PlaceRef<'tcx> {
|
||||
/// Monomorphized type of this place, including variant information
|
||||
pub layout: TyLayout<'tcx>,
|
||||
|
||||
/// Whether this place is known to be aligned according to its layout
|
||||
pub alignment: Alignment,
|
||||
/// What alignment we know for this place
|
||||
pub align: Align,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
pub fn new_sized(llval: ValueRef,
|
||||
layout: TyLayout<'tcx>,
|
||||
alignment: Alignment)
|
||||
align: Align)
|
||||
-> PlaceRef<'tcx> {
|
||||
PlaceRef {
|
||||
llval,
|
||||
llextra: ptr::null_mut(),
|
||||
layout,
|
||||
alignment
|
||||
align
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +60,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
-> PlaceRef<'tcx> {
|
||||
debug!("alloca({:?}: {:?})", name, layout);
|
||||
let tmp = bcx.alloca(layout.llvm_type(bcx.ccx), name, layout.align);
|
||||
Self::new_sized(tmp, layout, Alignment::AbiAligned)
|
||||
Self::new_sized(tmp, layout, layout.align)
|
||||
}
|
||||
|
||||
pub fn len(&self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef {
|
||||
@ -121,6 +81,14 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
!self.llextra.is_null()
|
||||
}
|
||||
|
||||
pub fn non_abi_align(self) -> Option<Align> {
|
||||
if self.align.abi() >= self.layout.align.abi() {
|
||||
None
|
||||
} else {
|
||||
Some(self.align)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load(&self, bcx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> {
|
||||
debug!("PlaceRef::load: {:?}", self);
|
||||
|
||||
@ -167,7 +135,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
let llval = if !const_llval.is_null() {
|
||||
const_llval
|
||||
} else {
|
||||
let load = bcx.load(self.llval, self.alignment.non_abi());
|
||||
let load = bcx.load(self.llval, self.non_abi_align());
|
||||
if let layout::Abi::Scalar(ref scalar) = self.layout.abi {
|
||||
scalar_load_metadata(load, scalar);
|
||||
}
|
||||
@ -181,7 +149,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
if scalar.is_bool() {
|
||||
llptr = bcx.pointercast(llptr, Type::i8p(bcx.ccx));
|
||||
}
|
||||
let load = bcx.load(llptr, self.alignment.non_abi());
|
||||
let load = bcx.load(llptr, self.non_abi_align());
|
||||
scalar_load_metadata(load, scalar);
|
||||
if scalar.is_bool() {
|
||||
bcx.trunc(load, Type::i1(bcx.ccx))
|
||||
@ -191,7 +159,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
};
|
||||
OperandValue::Pair(load(0, a), load(1, b))
|
||||
} else {
|
||||
OperandValue::Ref(self.llval, self.alignment)
|
||||
OperandValue::Ref(self.llval, self.align)
|
||||
};
|
||||
|
||||
OperandRef { val, layout: self.layout }
|
||||
@ -202,7 +170,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
let ccx = bcx.ccx;
|
||||
let field = self.layout.field(ccx, ix);
|
||||
let offset = self.layout.fields.offset(ix);
|
||||
let alignment = self.alignment | Alignment::from(self.layout);
|
||||
let align = self.align.min(self.layout.align).min(field.align);
|
||||
|
||||
let simple = || {
|
||||
// Unions and newtypes only use an offset of 0.
|
||||
@ -224,7 +192,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
ptr::null_mut()
|
||||
},
|
||||
layout: field,
|
||||
alignment,
|
||||
align,
|
||||
}
|
||||
};
|
||||
|
||||
@ -271,7 +239,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
let unaligned_offset = C_usize(ccx, offset.bytes());
|
||||
|
||||
// Get the alignment of the field
|
||||
let (_, align) = glue::size_and_align_of_dst(bcx, field.ty, meta);
|
||||
let (_, unsized_align) = glue::size_and_align_of_dst(bcx, field.ty, meta);
|
||||
|
||||
// Bump the unaligned offset up to the appropriate alignment using the
|
||||
// following expression:
|
||||
@ -279,9 +247,9 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
// (unaligned offset + (align - 1)) & -align
|
||||
|
||||
// Calculate offset
|
||||
let align_sub_1 = bcx.sub(align, C_usize(ccx, 1u64));
|
||||
let align_sub_1 = bcx.sub(unsized_align, C_usize(ccx, 1u64));
|
||||
let offset = bcx.and(bcx.add(unaligned_offset, align_sub_1),
|
||||
bcx.neg(align));
|
||||
bcx.neg(unsized_align));
|
||||
|
||||
debug!("struct_field_ptr: DST field offset: {:?}", Value(offset));
|
||||
|
||||
@ -297,7 +265,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
llval: bcx.pointercast(byte_ptr, ll_fty.ptr_to()),
|
||||
llextra: self.llextra,
|
||||
layout: field,
|
||||
alignment,
|
||||
align,
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,7 +338,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
.discriminant_for_variant(bcx.tcx(), variant_index)
|
||||
.to_u128_unchecked() as u64;
|
||||
bcx.store(C_int(ptr.layout.llvm_type(bcx.ccx), to as i64),
|
||||
ptr.llval, ptr.alignment.non_abi());
|
||||
ptr.llval, ptr.non_abi_align());
|
||||
}
|
||||
layout::Variants::NicheFilling {
|
||||
dataful_variant,
|
||||
@ -414,7 +382,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
llval: bcx.inbounds_gep(self.llval, &[C_usize(bcx.ccx, 0), llindex]),
|
||||
llextra: ptr::null_mut(),
|
||||
layout: self.layout.field(bcx.ccx, 0),
|
||||
alignment: self.alignment
|
||||
align: self.align
|
||||
}
|
||||
}
|
||||
|
||||
@ -463,9 +431,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
let result = match *place {
|
||||
mir::Place::Local(_) => bug!(), // handled above
|
||||
mir::Place::Static(box mir::Static { def_id, ty }) => {
|
||||
PlaceRef::new_sized(consts::get_static(ccx, def_id),
|
||||
ccx.layout_of(self.monomorphize(&ty)),
|
||||
Alignment::AbiAligned)
|
||||
let layout = ccx.layout_of(self.monomorphize(&ty));
|
||||
PlaceRef::new_sized(consts::get_static(ccx, def_id), layout, layout.align)
|
||||
},
|
||||
mir::Place::Projection(box mir::Projection {
|
||||
ref base,
|
||||
|
@ -104,7 +104,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
let start = dest.project_index(&bcx, C_usize(bcx.ccx, 0)).llval;
|
||||
|
||||
if let OperandValue::Immediate(v) = tr_elem.val {
|
||||
let align = dest.alignment.non_abi()
|
||||
let align = dest.non_abi_align()
|
||||
.unwrap_or(tr_elem.layout.align);
|
||||
let align = C_i32(bcx.ccx, align.abi() as i32);
|
||||
let size = C_usize(bcx.ccx, dest.layout.size.bytes());
|
||||
@ -139,7 +139,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
header_bcx.cond_br(keep_going, body_bcx.llbb(), next_bcx.llbb());
|
||||
|
||||
tr_elem.val.store(&body_bcx,
|
||||
PlaceRef::new_sized(current, tr_elem.layout, dest.alignment));
|
||||
PlaceRef::new_sized(current, tr_elem.layout, dest.align));
|
||||
|
||||
let next = body_bcx.inbounds_gep(current, &[C_usize(bcx.ccx, 1)]);
|
||||
body_bcx.br(header_bcx.llbb());
|
||||
|
Loading…
x
Reference in New Issue
Block a user