Skip to content

Commit

Permalink
Integrate PassMode::UnsizedIndirect into PassMode::Indirect.
Browse files Browse the repository at this point in the history
  • Loading branch information
qnighy committed Aug 18, 2018
1 parent a0c422a commit 6e15e7c
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 53 deletions.
33 changes: 15 additions & 18 deletions src/librustc_codegen_llvm/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
return;
}
let cx = bx.cx;
if self.is_indirect() {
if self.is_sized_indirect() {
OperandValue::Ref(val, self.layout.align).store(bx, dst)
} else if self.is_unsized_indirect() {
bug!("unsized ArgType must be handled through store_fn_arg");
Expand Down Expand Up @@ -248,10 +248,10 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
PassMode::Pair(..) => {
OperandValue::Pair(next(), next()).store(bx, dst);
}
PassMode::UnsizedIndirect(..) => {
PassMode::Indirect(_, Some(_)) => {
OperandValue::UnsizedRef(next(), next()).store(bx, dst);
}
PassMode::Direct(_) | PassMode::Indirect(_) | PassMode::Cast(_) => {
PassMode::Direct(_) | PassMode::Indirect(_, None) | PassMode::Cast(_) => {
self.store(bx, next(), dst);
}
}
Expand Down Expand Up @@ -547,9 +547,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
}

let size = arg.layout.size;
if arg.layout.is_unsized() {
arg.make_unsized_indirect(None);
} else if size > layout::Pointer.size(cx) {
if arg.layout.is_unsized() || size > layout::Pointer.size(cx) {
arg.make_indirect();
} else {
// We want to pass small aggregates as immediates, but using
Expand All @@ -565,7 +563,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
for arg in &mut self.args {
fixup(arg);
}
if let PassMode::Indirect(ref mut attrs) = self.ret.mode {
if let PassMode::Indirect(ref mut attrs, _) = self.ret.mode {
attrs.set(ArgAttribute::StructRet);
}
return;
Expand All @@ -582,7 +580,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 }
).sum();
let mut llargument_tys = Vec::with_capacity(
if let PassMode::Indirect(_) = self.ret.mode { 1 } else { 0 } + args_capacity
if let PassMode::Indirect(..) = self.ret.mode { 1 } else { 0 } + args_capacity
);

let llreturn_ty = match self.ret.mode {
Expand All @@ -591,11 +589,10 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
self.ret.layout.immediate_llvm_type(cx)
}
PassMode::Cast(cast) => cast.llvm_type(cx),
PassMode::Indirect(_) => {
PassMode::Indirect(..) => {
llargument_tys.push(self.ret.memory_ty(cx).ptr_to());
Type::void(cx)
}
PassMode::UnsizedIndirect(..) => bug!("return type must be sized"),
};

for arg in &self.args {
Expand All @@ -612,15 +609,15 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 1, true));
continue;
}
PassMode::UnsizedIndirect(..) => {
PassMode::Indirect(_, Some(_)) => {
let ptr_ty = cx.tcx.mk_mut_ptr(arg.layout.ty);
let ptr_layout = cx.layout_of(ptr_ty);
llargument_tys.push(ptr_layout.scalar_pair_element_llvm_type(cx, 0, true));
llargument_tys.push(ptr_layout.scalar_pair_element_llvm_type(cx, 1, true));
continue;
}
PassMode::Cast(cast) => cast.llvm_type(cx),
PassMode::Indirect(_) => arg.memory_ty(cx).ptr_to(),
PassMode::Indirect(_, None) => arg.memory_ty(cx).ptr_to(),
};
llargument_tys.push(llarg_ty);
}
Expand Down Expand Up @@ -659,7 +656,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
PassMode::Direct(ref attrs) => {
attrs.apply_llfn(llvm::AttributePlace::ReturnValue, llfn);
}
PassMode::Indirect(ref attrs) => apply(attrs),
PassMode::Indirect(ref attrs, _) => apply(attrs),
_ => {}
}
for arg in &self.args {
Expand All @@ -669,8 +666,8 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
match arg.mode {
PassMode::Ignore => {}
PassMode::Direct(ref attrs) |
PassMode::Indirect(ref attrs) => apply(attrs),
PassMode::UnsizedIndirect(ref attrs, ref extra_attrs) => {
PassMode::Indirect(ref attrs, None) => apply(attrs),
PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => {
apply(attrs);
apply(extra_attrs);
}
Expand All @@ -693,7 +690,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
PassMode::Direct(ref attrs) => {
attrs.apply_callsite(llvm::AttributePlace::ReturnValue, callsite);
}
PassMode::Indirect(ref attrs) => apply(attrs),
PassMode::Indirect(ref attrs, _) => apply(attrs),
_ => {}
}
if let layout::Abi::Scalar(ref scalar) = self.ret.layout.abi {
Expand All @@ -717,8 +714,8 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
match arg.mode {
PassMode::Ignore => {}
PassMode::Direct(ref attrs) |
PassMode::Indirect(ref attrs) => apply(attrs),
PassMode::UnsizedIndirect(ref attrs, ref extra_attrs) => {
PassMode::Indirect(ref attrs, None) => apply(attrs),
PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => {
apply(attrs);
apply(extra_attrs);
}
Expand Down
8 changes: 3 additions & 5 deletions src/librustc_codegen_llvm/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ impl FunctionCx<'a, 'll, 'tcx> {

mir::TerminatorKind::Return => {
let llval = match self.fn_ty.ret.mode {
PassMode::Ignore | PassMode::Indirect(_) => {
PassMode::Ignore | PassMode::Indirect(..) => {
bx.ret_void();
return;
}
Expand Down Expand Up @@ -270,8 +270,6 @@ impl FunctionCx<'a, 'll, 'tcx> {
bx.pointercast(llslot, cast_ty.llvm_type(bx.cx).ptr_to()),
self.fn_ty.ret.layout.align)
}

PassMode::UnsizedIndirect(..) => bug!("return value must be sized"),
};
bx.ret(llval);
}
Expand Down Expand Up @@ -667,7 +665,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
}
_ => bug!("codegen_argument: {:?} invalid for pair arugment", op)
}
} else if let PassMode::UnsizedIndirect(..) = arg.mode {
} else if arg.is_unsized_indirect() {
match op.val {
UnsizedRef(a, b) => {
llargs.push(a);
Expand All @@ -682,7 +680,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
let (mut llval, align, by_ref) = match op.val {
Immediate(_) | Pair(..) => {
match arg.mode {
PassMode::Indirect(_) | PassMode::Cast(_) => {
PassMode::Indirect(..) | PassMode::Cast(_) => {
let scratch = PlaceRef::alloca(bx, arg.layout, "arg");
op.val.store(bx, scratch);
(scratch.llval, scratch.align, true)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_llvm/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ fn arg_local_refs(
}
}

let place = if arg.is_indirect() {
let place = if arg.is_sized_indirect() {
// Don't copy an indirect argument to an alloca, the caller
// already put it in a temporary alloca and gave it up.
// FIXME: lifetimes
Expand Down
48 changes: 21 additions & 27 deletions src/librustc_target/abi/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ pub enum PassMode {
/// a single uniform or a pair of registers.
Cast(CastTarget),
/// Pass the argument indirectly via a hidden pointer.
Indirect(ArgAttributes),
/// Pass the unsized argument indirectly via a hidden pointer.
UnsizedIndirect(ArgAttributes, ArgAttributes),
/// The second value, if any, is for the extra data (vtable or length)
/// which indicates that it refers to an unsized rvalue.
Indirect(ArgAttributes, Option<ArgAttributes>),
}

// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest
Expand Down Expand Up @@ -370,38 +370,25 @@ impl<'a, Ty> ArgType<'a, Ty> {
// i686-pc-windows-msvc, it results in wrong stack offsets.
// attrs.pointee_align = Some(self.layout.align);

self.mode = PassMode::Indirect(attrs);
let extra_attrs = if self.layout.is_unsized() {
Some(ArgAttributes::new())
} else {
None
};

self.mode = PassMode::Indirect(attrs, extra_attrs);
}

pub fn make_indirect_byval(&mut self) {
self.make_indirect();
match self.mode {
PassMode::Indirect(ref mut attrs) => {
PassMode::Indirect(ref mut attrs, _) => {
attrs.set(ArgAttribute::ByVal);
}
_ => unreachable!()
}
}

pub fn make_unsized_indirect(&mut self, vtable_size: Option<Size>) {
self.make_indirect();

let attrs = if let PassMode::Indirect(attrs) = self.mode {
attrs
} else {
unreachable!()
};

let mut extra_attrs = ArgAttributes::new();
if let Some(vtable_size) = vtable_size {
extra_attrs.set(ArgAttribute::NoAlias)
.set(ArgAttribute::NonNull);
extra_attrs.pointee_size = vtable_size;
}

self.mode = PassMode::UnsizedIndirect(attrs, extra_attrs);
}

pub fn extend_integer_width_to(&mut self, bits: u64) {
// Only integers have signedness
if let Abi::Scalar(ref scalar) = self.layout.abi {
Expand Down Expand Up @@ -430,14 +417,21 @@ impl<'a, Ty> ArgType<'a, Ty> {

pub fn is_indirect(&self) -> bool {
match self.mode {
PassMode::Indirect(_) => true,
PassMode::Indirect(..) => true,
_ => false
}
}

pub fn is_sized_indirect(&self) -> bool {
match self.mode {
PassMode::Indirect(_, None) => true,
_ => false
}
}

pub fn is_unsized_indirect(&self) -> bool {
match self.mode {
PassMode::UnsizedIndirect(..) => true,
PassMode::Indirect(_, Some(_)) => true,
_ => false
}
}
Expand Down Expand Up @@ -534,7 +528,7 @@ impl<'a, Ty> FnType<'a, Ty> {
a => return Err(format!("unrecognized arch \"{}\" in target specification", a))
}

if let PassMode::Indirect(ref mut attrs) = self.ret.mode {
if let PassMode::Indirect(ref mut attrs, _) = self.ret.mode {
attrs.set(ArgAttribute::StructRet);
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_target/abi/call/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>, flavor: Flav
for arg in &mut fty.args {
let attrs = match arg.mode {
PassMode::Ignore |
PassMode::Indirect(_) => continue,
PassMode::Indirect(_, None) => continue,
PassMode::Direct(ref mut attrs) => attrs,
PassMode::Pair(..) |
PassMode::UnsizedIndirect(..) |
PassMode::Indirect(_, Some(_)) |
PassMode::Cast(_) => {
unreachable!("x86 shouldn't be passing arguments by {:?}", arg.mode)
}
Expand Down

0 comments on commit 6e15e7c

Please sign in to comment.