Integrate PassMode::UnsizedIndirect into PassMode::Indirect.

This commit is contained in:
Masaki Hara 2018-08-03 23:32:21 +09:00
parent a0c422a752
commit 6e15e7c126
5 changed files with 42 additions and 53 deletions

View file

@ -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");
@ -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);
}
}
@ -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
@ -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;
@ -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 {
@ -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 {
@ -612,7 +609,7 @@ 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));
@ -620,7 +617,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
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);
}
@ -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 {
@ -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);
}
@ -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 {
@ -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);
}

View file

@ -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;
}
@ -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);
}
@ -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);
@ -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)

View file

@ -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