about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-03-06 12:36:39 +0200
committerEduard Burtescu <edy.burt@gmail.com>2016-03-17 21:51:52 +0200
commit80d939fd22361cc8652cd4d7006fd1964d9ab699 (patch)
treea2da7b1e96e7eb4fc26c9c3891c579fd2c5cb363 /src
parent7454b5c61de7e4eb6ac0079d38d9a42d9f0d8539 (diff)
downloadrust-80d939fd22361cc8652cd4d7006fd1964d9ab699.tar.gz
rust-80d939fd22361cc8652cd4d7006fd1964d9ab699.zip
trans: Handle ignored arguments/returns uniformly.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_trans/trans/abi.rs78
-rw-r--r--src/librustc_trans/trans/cabi_aarch64.rs3
-rw-r--r--src/librustc_trans/trans/cabi_arm.rs3
-rw-r--r--src/librustc_trans/trans/cabi_asmjs.rs4
-rw-r--r--src/librustc_trans/trans/cabi_mips.rs7
-rw-r--r--src/librustc_trans/trans/cabi_powerpc.rs7
-rw-r--r--src/librustc_trans/trans/cabi_powerpc64.rs3
-rw-r--r--src/librustc_trans/trans/cabi_x86.rs11
-rw-r--r--src/librustc_trans/trans/cabi_x86_64.rs3
-rw-r--r--src/librustc_trans/trans/cabi_x86_win64.rs3
10 files changed, 66 insertions, 56 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 !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 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);
-                }
-
-                // 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);
     }
 }