]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Allow targets to specify SIMD args are by-val
authorAlex Crichton <alex@alexcrichton.com>
Sat, 13 Oct 2018 00:04:31 +0000 (17:04 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Sat, 13 Oct 2018 00:04:31 +0000 (17:04 -0700)
The upcoming SIMD support in the wasm target is unique from the other
platforms where it's either unconditionally available or not available,
there's no halfway where a subsection of the program can use it but no
other parts of the program can use it. In this world it's valid for wasm
SIMD args to always be passed by value and there's no need to pass them
by reference.

This commit adds a new custom target specification option
`simd_types_indirect` which defaults to `true`, but the wasm backend
disables this and sets it to `false`.

src/librustc_codegen_llvm/abi.rs
src/librustc_target/spec/mod.rs
src/librustc_target/spec/wasm32_unknown_unknown.rs

index c8e8d0dc84ef038027ffc589c558923721a253d2..7b93d3e795ed8f29c41132a2ba11f65e87b1ccb6 100644 (file)
@@ -536,7 +536,10 @@ fn adjust_for_abi(&mut self,
                     // Note that the platform intrinsic ABI is exempt here as
                     // that's how we connect up to LLVM and it's unstable
                     // anyway, we control all calls to it in libstd.
-                    layout::Abi::Vector { .. } if abi != Abi::PlatformIntrinsic => {
+                    layout::Abi::Vector { .. }
+                        if abi != Abi::PlatformIntrinsic &&
+                            cx.sess().target.target.options.simd_types_indirect =>
+                    {
                         arg.make_indirect();
                         return
                     }
index 9c0f945326d148006c8f9cd54e7412d4ea9d92eb..9ee4582fabf7b3b594f444209a6c31d5d9dc2356 100644 (file)
@@ -680,6 +680,12 @@ pub struct TargetOptions {
     /// typically because the platform needs to unwind for things like stack
     /// unwinders.
     pub requires_uwtable: bool,
+
+    /// Whether or not SIMD types are passed by reference in the Rust ABI,
+    /// typically required if a target can be compiled with a mixed set of
+    /// target features. This is `true` by default, and `false` for targets like
+    /// wasm32 where the whole program either has simd or not.
+    pub simd_types_indirect: bool,
 }
 
 impl Default for TargetOptions {
@@ -760,6 +766,7 @@ fn default() -> TargetOptions {
             embed_bitcode: false,
             emit_debug_gdb_scripts: true,
             requires_uwtable: false,
+            simd_types_indirect: true,
         }
     }
 }
@@ -1041,6 +1048,7 @@ macro_rules! key {
         key!(embed_bitcode, bool);
         key!(emit_debug_gdb_scripts, bool);
         key!(requires_uwtable, bool);
+        key!(simd_types_indirect, bool);
 
         if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
             for name in array.iter().filter_map(|abi| abi.as_string()) {
@@ -1250,6 +1258,7 @@ macro_rules! target_option_val {
         target_option_val!(embed_bitcode);
         target_option_val!(emit_debug_gdb_scripts);
         target_option_val!(requires_uwtable);
+        target_option_val!(simd_types_indirect);
 
         if default.abi_blacklist != self.options.abi_blacklist {
             d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()
index c0455ceb8390ce669802e9bc9650153882e9ef08..46353068bd04588840787936f803949adc1d8d17 100644 (file)
@@ -54,6 +54,12 @@ pub fn target() -> Result<Target, String> {
         linker: Some("rust-lld".to_owned()),
         lld_flavor: LldFlavor::Wasm,
 
+        // No need for indirection here, simd types can always be passed by
+        // value as the whole module either has simd or not, which is different
+        // from x86 (for example) where programs can have functions that don't
+        // enable simd features.
+        simd_types_indirect: false,
+
         .. Default::default()
     };
     Ok(Target {