about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-07-06 07:07:17 +0800
committerkennytm <kennytm@gmail.com>2018-07-06 08:49:20 +0800
commitffc453abf7227257ca64429c0ead14ce81bc0985 (patch)
tree442b0238955acc0fecb761344f25fe487b28ee91
parenta4846aebd8c6a95f4aa15880b00b31c4d33d8327 (diff)
parent65ff4141a5ed69223b29634a49a499b9415993ee (diff)
downloadrust-ffc453abf7227257ca64429c0ead14ce81bc0985.tar.gz
rust-ffc453abf7227257ca64429c0ead14ce81bc0985.zip
Rollup merge of #52019 - michaelwoerister:cross-lto-auto-plugin, r=alexcrichton
[cross-lang-lto] Allow the linker to choose the LTO-plugin (which is useful when using LLD)

This PR allows for not specifying an LTO-linker plugin but still let `rustc` invoke the linker with the correct plugin arguments. This is useful when using LLD which does not need the `-plugin` argument. Since LLD is the best linker for this scenario anyway, this change should improve ergonomics quite a bit.

r? @alexcrichton
-rw-r--r--src/librustc/session/config.rs4
-rw-r--r--src/librustc_codegen_llvm/back/linker.rs61
2 files changed, 39 insertions, 26 deletions
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index f97e11ef72f..fdd791c5eda 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -98,6 +98,7 @@ pub enum Lto {
 #[derive(Clone, PartialEq, Hash)]
 pub enum CrossLangLto {
     LinkerPlugin(PathBuf),
+    LinkerPluginAuto,
     NoLink,
     Disabled
 }
@@ -106,6 +107,7 @@ impl CrossLangLto {
     pub fn embed_bitcode(&self) -> bool {
         match *self {
             CrossLangLto::LinkerPlugin(_) |
+            CrossLangLto::LinkerPluginAuto |
             CrossLangLto::NoLink => true,
             CrossLangLto::Disabled => false,
         }
@@ -1020,7 +1022,7 @@ macro_rules! options {
                 let mut bool_arg = None;
                 if parse_opt_bool(&mut bool_arg, v) {
                     *slot = if bool_arg.unwrap() {
-                        CrossLangLto::NoLink
+                        CrossLangLto::LinkerPluginAuto
                     } else {
                         CrossLangLto::Disabled
                     };
diff --git a/src/librustc_codegen_llvm/back/linker.rs b/src/librustc_codegen_llvm/back/linker.rs
index dd1983bdc17..fffde30d5f6 100644
--- a/src/librustc_codegen_llvm/back/linker.rs
+++ b/src/librustc_codegen_llvm/back/linker.rs
@@ -182,6 +182,38 @@ impl<'a> GccLinker<'a> {
             self.hinted_static = false;
         }
     }
+
+    fn push_cross_lang_lto_args(&mut self, plugin_path: Option<&OsStr>) {
+        if let Some(plugin_path) = plugin_path {
+            let mut arg = OsString::from("-plugin=");
+            arg.push(plugin_path);
+            self.linker_arg(&arg);
+        }
+
+        let opt_level = match self.sess.opts.optimize {
+            config::OptLevel::No => "O0",
+            config::OptLevel::Less => "O1",
+            config::OptLevel::Default => "O2",
+            config::OptLevel::Aggressive => "O3",
+            config::OptLevel::Size => "Os",
+            config::OptLevel::SizeMin => "Oz",
+        };
+
+        self.linker_arg(&format!("-plugin-opt={}", opt_level));
+        self.linker_arg(&format!("-plugin-opt=mcpu={}", self.sess.target_cpu()));
+
+        match self.sess.opts.cg.lto {
+            config::Lto::Thin |
+            config::Lto::ThinLocal => {
+                self.linker_arg(&format!("-plugin-opt=thin"));
+            }
+            config::Lto::Fat |
+            config::Lto::Yes |
+            config::Lto::No => {
+                // default to regular LTO
+            }
+        }
+    }
 }
 
 impl<'a> Linker for GccLinker<'a> {
@@ -443,32 +475,11 @@ impl<'a> Linker for GccLinker<'a> {
             CrossLangLto::NoLink => {
                 // Nothing to do
             }
+            CrossLangLto::LinkerPluginAuto => {
+                self.push_cross_lang_lto_args(None);
+            }
             CrossLangLto::LinkerPlugin(ref path) => {
-                self.linker_arg(&format!("-plugin={}", path.display()));
-
-                let opt_level = match self.sess.opts.optimize {
-                    config::OptLevel::No => "O0",
-                    config::OptLevel::Less => "O1",
-                    config::OptLevel::Default => "O2",
-                    config::OptLevel::Aggressive => "O3",
-                    config::OptLevel::Size => "Os",
-                    config::OptLevel::SizeMin => "Oz",
-                };
-
-                self.linker_arg(&format!("-plugin-opt={}", opt_level));
-                self.linker_arg(&format!("-plugin-opt=mcpu={}", self.sess.target_cpu()));
-
-                match self.sess.opts.cg.lto {
-                    config::Lto::Thin |
-                    config::Lto::ThinLocal => {
-                        self.linker_arg(&format!("-plugin-opt=thin"));
-                    }
-                    config::Lto::Fat |
-                    config::Lto::Yes |
-                    config::Lto::No => {
-                        // default to regular LTO
-                    }
-                }
+                self.push_cross_lang_lto_args(Some(path.as_os_str()));
             }
         }
     }