From 80d939fd22361cc8652cd4d7006fd1964d9ab699 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Sun, 6 Mar 2016 12:36:39 +0200 Subject: [PATCH] trans: Handle ignored arguments/returns uniformly. --- src/librustc_trans/trans/abi.rs | 76 ++++++++++++---------- src/librustc_trans/trans/cabi_aarch64.rs | 3 +- src/librustc_trans/trans/cabi_arm.rs | 3 +- src/librustc_trans/trans/cabi_asmjs.rs | 4 +- src/librustc_trans/trans/cabi_mips.rs | 7 +- src/librustc_trans/trans/cabi_powerpc.rs | 7 +- src/librustc_trans/trans/cabi_powerpc64.rs | 3 +- src/librustc_trans/trans/cabi_x86.rs | 11 ++-- src/librustc_trans/trans/cabi_x86_64.rs | 3 +- src/librustc_trans/trans/cabi_x86_win64.rs | 3 +- 10 files changed, 65 insertions(+), 55 deletions(-) diff --git a/src/librustc_trans/trans/abi.rs b/src/librustc_trans/trans/abi.rs index d796817fd0f..bd5de8efc19 100644 --- a/src/librustc_trans/trans/abi.rs +++ b/src/librustc_trans/trans/abi.rs @@ -9,7 +9,7 @@ // except according to those terms. use llvm::{self, ValueRef}; -use trans::common::{return_type_is_void, type_is_fat_ptr}; +use trans::common::{type_is_fat_ptr, Block}; use trans::context::CrateContext; use trans::cabi_x86; use trans::cabi_x86_64; @@ -20,7 +20,7 @@ use trans::cabi_powerpc; use trans::cabi_powerpc64; use trans::cabi_mips; use trans::cabi_asmjs; -use trans::machine::{llsize_of_alloc, llsize_of_real}; +use trans::machine::{llalign_of_min, llsize_of, llsize_of_real}; use trans::type_::Type; use trans::type_of; @@ -97,6 +97,8 @@ impl ArgType { } pub fn make_indirect(&mut self, ccx: &CrateContext) { + assert_eq!(self.kind, ArgKind::Direct); + // Wipe old attributes, likely not valid through indirection. self.attrs = llvm::Attributes::default(); @@ -113,6 +115,7 @@ impl ArgType { } pub fn ignore(&mut self) { + assert_eq!(self.kind, ArgKind::Direct); self.kind = ArgKind::Ignore; } @@ -200,39 +203,40 @@ impl FnType { arg.attrs.set(llvm::Attribute::ZExt); arg } else { - ArgType::new(type_of::type_of(ccx, ty), - type_of::sizing_type_of(ccx, ty)) + let mut arg = ArgType::new(type_of::type_of(ccx, ty), + type_of::sizing_type_of(ccx, ty)); + if llsize_of_real(ccx, arg.ty) == 0 { + arg.ignore(); + } + arg } }; - let mut ret = match sig.output { - ty::FnConverging(ret_ty) if !return_type_is_void(ccx, ret_ty) => { - arg_of(ret_ty) - } - _ => ArgType::new(Type::void(ccx), Type::void(ccx)) + let ret_ty = match sig.output { + ty::FnConverging(ret_ty) => ret_ty, + ty::FnDiverging => ccx.tcx().mk_nil() }; + let mut ret = arg_of(ret_ty); - if let ty::FnConverging(ret_ty) = sig.output { - if !type_is_fat_ptr(ccx.tcx(), ret_ty) { - // The `noalias` attribute on the return value is useful to a - // function ptr caller. - if let ty::TyBox(_) = ret_ty.sty { - // `Box` pointer return values never alias because ownership - // is transferred - ret.attrs.set(llvm::Attribute::NoAlias); - } + if !type_is_fat_ptr(ccx.tcx(), ret_ty) { + // The `noalias` attribute on the return value is useful to a + // function ptr caller. + if let ty::TyBox(_) = ret_ty.sty { + // `Box` pointer return values never alias because ownership + // is transferred + ret.attrs.set(llvm::Attribute::NoAlias); + } - // We can also mark the return value as `dereferenceable` in certain cases - match ret_ty.sty { - // These are not really pointers but pairs, (pointer, len) - ty::TyRef(_, ty::TypeAndMut { ty, .. }) | - ty::TyBox(ty) => { - let llty = type_of::sizing_type_of(ccx, ty); - let llsz = llsize_of_real(ccx, llty); - ret.attrs.set_dereferenceable(llsz); - } - _ => {} + // We can also mark the return value as `dereferenceable` in certain cases + match ret_ty.sty { + // These are not really pointers but pairs, (pointer, len) + ty::TyRef(_, ty::TypeAndMut { ty, .. }) | + ty::TyBox(ty) => { + let llty = type_of::sizing_type_of(ccx, ty); + let llsz = llsize_of_real(ccx, llty); + ret.attrs.set_dereferenceable(llsz); } + _ => {} } } @@ -318,8 +322,8 @@ impl FnType { // Scalars and vectors, always immediate. return; } - let size = llsize_of_alloc(ccx, arg.ty); - if size > llsize_of_alloc(ccx, ccx.int_type()) { + let size = llsize_of_real(ccx, arg.ty); + if size > llsize_of_real(ccx, ccx.int_type()) { arg.make_indirect(ccx); } else if size > 0 { // We want to pass small aggregates as immediates, but using @@ -376,7 +380,9 @@ impl FnType { pub fn llvm_type(&self, ccx: &CrateContext) -> Type { let mut llargument_tys = Vec::new(); - let llreturn_ty = if self.ret.is_indirect() { + let llreturn_ty = if self.ret.is_ignore() { + Type::void(ccx) + } else if self.ret.is_indirect() { llargument_tys.push(self.ret.original_ty.ptr_to()); Type::void(ccx) } else { @@ -410,7 +416,9 @@ impl FnType { pub fn apply_attrs_llfn(&self, llfn: ValueRef) { let mut i = if self.ret.is_indirect() { 1 } else { 0 }; - self.ret.attrs.apply_llfn(i, llfn); + if !self.ret.is_ignore() { + self.ret.attrs.apply_llfn(i, llfn); + } i += 1; for arg in &self.args { if !arg.is_ignore() { @@ -423,7 +431,9 @@ impl FnType { pub fn apply_attrs_callsite(&self, callsite: ValueRef) { let mut i = if self.ret.is_indirect() { 1 } else { 0 }; - self.ret.attrs.apply_callsite(i, callsite); + if !self.ret.is_ignore() { + self.ret.attrs.apply_callsite(i, callsite); + } i += 1; for arg in &self.args { if !arg.is_ignore() { diff --git a/src/librustc_trans/trans/cabi_aarch64.rs b/src/librustc_trans/trans/cabi_aarch64.rs index 4398e14fdcc..6eea8d472ba 100644 --- a/src/librustc_trans/trans/cabi_aarch64.rs +++ b/src/librustc_trans/trans/cabi_aarch64.rs @@ -229,11 +229,12 @@ fn is_reg_ty(ty: Type) -> bool { } pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { - if fty.ret.ty != Type::void(ccx) { + if !fty.ret.is_ignore() { classify_ret_ty(ccx, &mut fty.ret); } for arg in &mut fty.args { + if arg.is_ignore() { continue; } classify_arg_ty(ccx, arg); } } diff --git a/src/librustc_trans/trans/cabi_arm.rs b/src/librustc_trans/trans/cabi_arm.rs index 2146a9c5e21..14ca77836c2 100644 --- a/src/librustc_trans/trans/cabi_arm.rs +++ b/src/librustc_trans/trans/cabi_arm.rs @@ -179,11 +179,12 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType, flavor: Flavor) { Flavor::Ios => ios_ty_align as TyAlignFn, }; - if fty.ret.ty != Type::void(ccx) { + if !fty.ret.is_ignore() { classify_ret_ty(ccx, &mut fty.ret, align_fn); } for arg in &mut fty.args { + if arg.is_ignore() { continue; } classify_arg_ty(ccx, arg, align_fn); } } diff --git a/src/librustc_trans/trans/cabi_asmjs.rs b/src/librustc_trans/trans/cabi_asmjs.rs index 4ec547c3640..c901442f485 100644 --- a/src/librustc_trans/trans/cabi_asmjs.rs +++ b/src/librustc_trans/trans/cabi_asmjs.rs @@ -13,7 +13,6 @@ use llvm::{Struct, Array, Attribute}; use trans::abi::{FnType, ArgType}; use trans::context::CrateContext; -use trans::type_::Type; // Data layout: e-p:32:32-i64:64-v128:32:128-n32-S128 @@ -45,11 +44,12 @@ fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType) { } pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { - if fty.ret.ty != Type::void(ccx) { + if !fty.ret.is_ignore() { classify_ret_ty(ccx, &mut fty.ret); } for arg in &mut fty.args { + if arg.is_ignore() { continue; } classify_arg_ty(ccx, arg); } } diff --git a/src/librustc_trans/trans/cabi_mips.rs b/src/librustc_trans/trans/cabi_mips.rs index b4fe00f8d69..0d5e81be921 100644 --- a/src/librustc_trans/trans/cabi_mips.rs +++ b/src/librustc_trans/trans/cabi_mips.rs @@ -146,14 +146,13 @@ fn struct_ty(ccx: &CrateContext, ty: Type) -> Type { } pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { - if fty.ret.ty != Type::void(ccx) { - if !is_reg_ty(fty.ret.ty) { - fty.ret.make_indirect(ccx); - } + if !fty.ret.is_ignore() && !is_reg_ty(fty.ret.ty) { + fty.ret.make_indirect(ccx); } let mut offset = if fty.ret.is_indirect() { 4 } else { 0 }; for arg in &mut fty.args { + if arg.is_ignore() { continue; } classify_arg_ty(ccx, arg, &mut offset); } } diff --git a/src/librustc_trans/trans/cabi_powerpc.rs b/src/librustc_trans/trans/cabi_powerpc.rs index 8d9c6e8e1f8..9aa89a04d0a 100644 --- a/src/librustc_trans/trans/cabi_powerpc.rs +++ b/src/librustc_trans/trans/cabi_powerpc.rs @@ -141,14 +141,13 @@ fn struct_ty(ccx: &CrateContext, ty: Type) -> Type { } pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { - if fty.ret.ty != Type::void(ccx) { - if !is_reg_ty(fty.ret.ty) { - fty.ret.make_indirect(ccx); - } + if !fty.ret.is_ignore() && !is_reg_ty(fty.ret.ty) { + fty.ret.make_indirect(ccx); } let mut offset = if fty.ret.is_indirect() { 4 } else { 0 }; for arg in &mut fty.args { + if arg.is_ignore() { continue; } classify_arg_ty(ccx, arg, &mut offset); } } diff --git a/src/librustc_trans/trans/cabi_powerpc64.rs b/src/librustc_trans/trans/cabi_powerpc64.rs index 77858398f37..340de235732 100644 --- a/src/librustc_trans/trans/cabi_powerpc64.rs +++ b/src/librustc_trans/trans/cabi_powerpc64.rs @@ -232,11 +232,12 @@ fn struct_ty(ccx: &CrateContext, ty: Type) -> Type { } pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { - if fty.ret.ty != Type::void(ccx) { + if !fty.ret.is_ignore() { classify_ret_ty(ccx, &mut fty.ret); } for arg in &mut fty.args { + if arg.is_ignore() { continue; } classify_arg_ty(ccx, arg); } } diff --git a/src/librustc_trans/trans/cabi_x86.rs b/src/librustc_trans/trans/cabi_x86.rs index af194e8e5d7..9e6c4d9af42 100644 --- a/src/librustc_trans/trans/cabi_x86.rs +++ b/src/librustc_trans/trans/cabi_x86.rs @@ -15,7 +15,7 @@ use super::common::*; use super::machine::*; pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { - if fty.ret.ty.kind() == Struct { + if !fty.ret.is_ignore() && fty.ret.ty.kind() == Struct { // Returning a structure. Most often, this will use // a hidden first argument. On some platforms, though, // small structs are returned as integers. @@ -38,13 +38,10 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { } for arg in &mut fty.args { + if arg.is_ignore() { continue; } if arg.ty.kind() == Struct { - if llsize_of_alloc(ccx, arg.ty) == 0 { - arg.ignore(); - } else { - arg.make_indirect(ccx); - arg.attrs.set(Attribute::ByVal); - } + arg.make_indirect(ccx); + arg.attrs.set(Attribute::ByVal); } } } diff --git a/src/librustc_trans/trans/cabi_x86_64.rs b/src/librustc_trans/trans/cabi_x86_64.rs index c6f1dc9e671..47d373f9043 100644 --- a/src/librustc_trans/trans/cabi_x86_64.rs +++ b/src/librustc_trans/trans/cabi_x86_64.rs @@ -406,7 +406,7 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { let mut int_regs = 6; // RDI, RSI, RDX, RCX, R8, R9 let mut sse_regs = 8; // XMM0-7 - if fty.ret.ty != Type::void(ccx) { + if !fty.ret.is_ignore() { x86_64_ty(ccx, &mut fty.ret, |cls| { if cls.is_ret_bysret() { // `sret` parameter thus one less register available @@ -419,6 +419,7 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { } for arg in &mut fty.args { + if arg.is_ignore() { continue; } x86_64_ty(ccx, arg, |cls| { let needed_int = cls.iter().filter(|&&c| c == Int).count() as isize; let needed_sse = cls.iter().filter(|c| c.is_sse()).count() as isize; diff --git a/src/librustc_trans/trans/cabi_x86_win64.rs b/src/librustc_trans/trans/cabi_x86_win64.rs index 448789530a5..43f72c454cf 100644 --- a/src/librustc_trans/trans/cabi_x86_win64.rs +++ b/src/librustc_trans/trans/cabi_x86_win64.rs @@ -29,10 +29,11 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { } }; - if fty.ret.ty != Type::void(ccx) { + if !fty.ret.is_ignore() { fixup(&mut fty.ret); } for arg in &mut fty.args { + if arg.is_ignore() { continue; } fixup(arg); } }