about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMasaki Hara <ackie.h.gmai@gmail.com>2018-08-03 23:32:21 +0900
committerMasaki Hara <ackie.h.gmai@gmail.com>2018-08-19 08:07:33 +0900
commit6e15e7c1267e26d2bab3d0ded8454a2a45669d55 (patch)
treee544800e450215f882aa6667cdbdd12318772531
parenta0c422a752bdbe8f68b89f7656835bd7f36b2428 (diff)
downloadrust-6e15e7c1267e26d2bab3d0ded8454a2a45669d55.tar.gz
rust-6e15e7c1267e26d2bab3d0ded8454a2a45669d55.zip
Integrate PassMode::UnsizedIndirect into PassMode::Indirect.
-rw-r--r--src/librustc_codegen_llvm/abi.rs33
-rw-r--r--src/librustc_codegen_llvm/mir/block.rs8
-rw-r--r--src/librustc_codegen_llvm/mir/mod.rs2
-rw-r--r--src/librustc_target/abi/call/mod.rs48
-rw-r--r--src/librustc_target/abi/call/x86.rs4
5 files changed, 42 insertions, 53 deletions
diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs
index b8a67a60e62..d699d786d19 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/src/librustc_codegen_llvm/abi.rs
@@ -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);
                 }
diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs
index 52f8576d0d1..1bd7bf48cda 100644
--- a/src/librustc_codegen_llvm/mir/block.rs
+++ b/src/librustc_codegen_llvm/mir/block.rs
@@ -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)
diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs
index d7bad05a66c..5991bb80c30 100644
--- a/src/librustc_codegen_llvm/mir/mod.rs
+++ b/src/librustc_codegen_llvm/mir/mod.rs
@@ -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
diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs
index 8647beef3d5..78ed4b2d615 100644
--- a/src/librustc_target/abi/call/mod.rs
+++ b/src/librustc_target/abi/call/mod.rs
@@ -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
@@ -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 {
@@ -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
         }
     }
@@ -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);
         }
 
diff --git a/src/librustc_target/abi/call/x86.rs b/src/librustc_target/abi/call/x86.rs
index 6e64210a890..1dcaafcf77f 100644
--- a/src/librustc_target/abi/call/x86.rs
+++ b/src/librustc_target/abi/call/x86.rs
@@ -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)
                 }