about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-11-30 15:21:09 +0000
committerbors <bors@rust-lang.org>2023-11-30 15:21:09 +0000
commitd368c4043c26800bf1d45103e482d3e9d3bf6010 (patch)
tree9500da2a806a8fa2c229e97350fe90c02bcd5f1d /compiler/rustc_codegen_ssa/src
parent33e8232b82efb5f57760fcf08045cb36b93ed8e4 (diff)
parentcd124409335f8830becb7f7ec7de1c6aa8a504e3 (diff)
downloadrust-d368c4043c26800bf1d45103e482d3e9d3bf6010.tar.gz
rust-d368c4043c26800bf1d45103e482d3e9d3bf6010.zip
Auto merge of #3197 - RalfJung:rustup, r=RalfJung
Rustup

also move some fail tests into suitable subdirectories
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs98
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs10
3 files changed, 75 insertions, 37 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index ac13d61229e..be895417bbe 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -44,7 +44,7 @@ use tempfile::Builder as TempFileBuilder;
 use itertools::Itertools;
 use std::cell::OnceCell;
 use std::collections::BTreeSet;
-use std::ffi::OsString;
+use std::ffi::{OsStr, OsString};
 use std::fs::{read, File, OpenOptions};
 use std::io::{BufWriter, Write};
 use std::ops::Deref;
@@ -2527,7 +2527,7 @@ fn add_native_libs_from_crate(
             NativeLibKind::WasmImportModule => {}
             NativeLibKind::LinkArg => {
                 if link_static {
-                    cmd.arg(name);
+                    cmd.linker_arg(OsStr::new(name), verbatim);
                 }
             }
         }
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 4dd688c2234..bb5f6e27e4d 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -196,6 +196,14 @@ pub trait Linker {
     fn add_no_exec(&mut self) {}
     fn add_as_needed(&mut self) {}
     fn reset_per_library_state(&mut self) {}
+    fn linker_arg(&mut self, arg: &OsStr, verbatim: bool) {
+        self.linker_args(&[arg], verbatim);
+    }
+    fn linker_args(&mut self, args: &[&OsStr], _verbatim: bool) {
+        args.into_iter().for_each(|a| {
+            self.cmd().arg(a);
+        });
+    }
 }
 
 impl dyn Linker + '_ {
@@ -223,38 +231,12 @@ pub struct GccLinker<'a> {
 }
 
 impl<'a> GccLinker<'a> {
-    /// Passes an argument directly to the linker.
-    ///
-    /// When the linker is not ld-like such as when using a compiler as a linker, the argument is
-    /// prepended by `-Wl,`.
-    fn linker_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
-        self.linker_args(&[arg]);
-        self
+    fn linker_arg(&mut self, arg: impl AsRef<OsStr>) {
+        Linker::linker_arg(self, arg.as_ref(), false);
     }
-
-    /// Passes a series of arguments directly to the linker.
-    ///
-    /// When the linker is ld-like, the arguments are simply appended to the command. When the
-    /// linker is not ld-like such as when using a compiler as a linker, the arguments are joined by
-    /// commas to form an argument that is then prepended with `-Wl`. In this situation, only a
-    /// single argument is appended to the command to ensure that the order of the arguments is
-    /// preserved by the compiler.
-    fn linker_args(&mut self, args: &[impl AsRef<OsStr>]) -> &mut Self {
-        if self.is_ld {
-            args.into_iter().for_each(|a| {
-                self.cmd.arg(a);
-            });
-        } else {
-            if !args.is_empty() {
-                let mut s = OsString::from("-Wl");
-                for a in args {
-                    s.push(",");
-                    s.push(a);
-                }
-                self.cmd.arg(s);
-            }
-        }
-        self
+    fn linker_args(&mut self, args: &[impl AsRef<OsStr>]) {
+        let args_vec: Vec<&OsStr> = args.iter().map(|x| x.as_ref()).collect();
+        Linker::linker_args(self, &args_vec, false);
     }
 
     fn takes_hints(&self) -> bool {
@@ -361,6 +343,30 @@ impl<'a> GccLinker<'a> {
 }
 
 impl<'a> Linker for GccLinker<'a> {
+    /// Passes a series of arguments directly to the linker.
+    ///
+    /// When the linker is ld-like, the arguments are simply appended to the command. When the
+    /// linker is not ld-like such as when using a compiler as a linker, the arguments are joined by
+    /// commas to form an argument that is then prepended with `-Wl`. In this situation, only a
+    /// single argument is appended to the command to ensure that the order of the arguments is
+    /// preserved by the compiler.
+    fn linker_args(&mut self, args: &[&OsStr], verbatim: bool) {
+        if self.is_ld || verbatim {
+            args.into_iter().for_each(|a| {
+                self.cmd.arg(a);
+            });
+        } else {
+            if !args.is_empty() {
+                let mut s = OsString::from("-Wl");
+                for a in args {
+                    s.push(",");
+                    s.push(a);
+                }
+                self.cmd.arg(s);
+            }
+        }
+    }
+
     fn cmd(&mut self) -> &mut Command {
         &mut self.cmd
     }
@@ -531,7 +537,7 @@ impl<'a> Linker for GccLinker<'a> {
             self.linker_arg("-force_load");
             self.linker_arg(&lib);
         } else {
-            self.linker_arg("--whole-archive").cmd.arg(lib);
+            self.linker_args(&[OsString::from("--whole-archive"), lib.into()]);
             self.linker_arg("--no-whole-archive");
         }
     }
@@ -1302,6 +1308,8 @@ impl<'a> Linker for WasmLd<'a> {
     }
 
     fn optimize(&mut self) {
+        // The -O flag is, as of late 2023, only used for merging of strings and debuginfo, and
+        // only differentiates -O0 and -O1. It does not apply to LTO.
         self.cmd.arg(match self.sess.opts.optimize {
             OptLevel::No => "-O0",
             OptLevel::Less => "-O1",
@@ -1354,7 +1362,31 @@ impl<'a> Linker for WasmLd<'a> {
     fn subsystem(&mut self, _subsystem: &str) {}
 
     fn linker_plugin_lto(&mut self) {
-        // Do nothing for now
+        match self.sess.opts.cg.linker_plugin_lto {
+            LinkerPluginLto::Disabled => {
+                // Nothing to do
+            }
+            LinkerPluginLto::LinkerPluginAuto => {
+                self.push_linker_plugin_lto_args();
+            }
+            LinkerPluginLto::LinkerPlugin(_) => {
+                self.push_linker_plugin_lto_args();
+            }
+        }
+    }
+}
+
+impl<'a> WasmLd<'a> {
+    fn push_linker_plugin_lto_args(&mut self) {
+        let opt_level = match self.sess.opts.optimize {
+            config::OptLevel::No => "O0",
+            config::OptLevel::Less => "O1",
+            config::OptLevel::Default => "O2",
+            config::OptLevel::Aggressive => "O3",
+            // wasm-ld only handles integer LTO opt levels. Use O2
+            config::OptLevel::Size | config::OptLevel::SizeMin => "O2",
+        };
+        self.cmd.arg(&format!("--lto-{opt_level}"));
     }
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index a0d6e1885c2..bfd0a458884 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -216,6 +216,7 @@ impl CodegenResults {
         sess: &Session,
         rlink_file: &Path,
         codegen_results: &CodegenResults,
+        outputs: &OutputFilenames,
     ) -> Result<usize, io::Error> {
         let mut encoder = FileEncoder::new(rlink_file)?;
         encoder.emit_raw_bytes(RLINK_MAGIC);
@@ -224,10 +225,14 @@ impl CodegenResults {
         encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes());
         encoder.emit_str(sess.cfg_version);
         Encodable::encode(codegen_results, &mut encoder);
+        Encodable::encode(outputs, &mut encoder);
         encoder.finish().map_err(|(_path, err)| err)
     }
 
-    pub fn deserialize_rlink(sess: &Session, data: Vec<u8>) -> Result<Self, CodegenErrors> {
+    pub fn deserialize_rlink(
+        sess: &Session,
+        data: Vec<u8>,
+    ) -> Result<(Self, OutputFilenames), CodegenErrors> {
         // The Decodable machinery is not used here because it panics if the input data is invalid
         // and because its internal representation may change.
         if !data.starts_with(RLINK_MAGIC) {
@@ -256,6 +261,7 @@ impl CodegenResults {
         }
 
         let codegen_results = CodegenResults::decode(&mut decoder);
-        Ok(codegen_results)
+        let outputs = OutputFilenames::decode(&mut decoder);
+        Ok((codegen_results, outputs))
     }
 }