]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #58057 - michaelwoerister:stabilize-xlto, r=alexcrichton
authorMazdak Farrokhzad <twingoow@gmail.com>
Wed, 13 Feb 2019 03:36:59 +0000 (04:36 +0100)
committerGitHub <noreply@github.com>
Wed, 13 Feb 2019 03:36:59 +0000 (04:36 +0100)
Stabilize linker-plugin based LTO (aka cross-language LTO)

This PR stabilizes [linker plugin based LTO](https://github.com/rust-lang/rust/issues/49879), also known as "cross-language LTO" because it allows for doing inlining and other optimizations across language boundaries in mixed Rust/C/C++ projects.

As described in the tracking issue, it works by making `rustc` emit LLVM bitcode instead of machine code, the same as `clang` does. A linker with the proper plugin (like LLD) can then run (Thin)LTO across all modules.

The feature has been implemented over a number of pull requests and there are various [codegen](https://github.com/rust-lang/rust/blob/master/src/test/codegen/no-dllimport-w-cross-lang-lto.rs) and [run](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-clang)-[make](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs) [tests](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto) that make sure that it keeps working.

It also works for building big projects like [Firefox](https://treeherder.mozilla.org/#/jobs?repo=try&revision=2ce2d5ddcea6fbff790503eac406954e469b2f5d).

The PR makes the feature available under the `-C linker-plugin-lto` flag. As discussed in the tracking issue it is not cross-language specific and also not LLD specific. `-C linker-plugin-lto` is descriptive of what it does. If someone has a better name, let me know `:)`

1  2 
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc_codegen_llvm/back/link.rs
src/librustc_codegen_llvm/back/lto.rs
src/librustc_codegen_ssa/back/linker.rs
src/librustc_codegen_ssa/back/write.rs

index b6c7ca11f1f2b059f5bf4b494d9932cbd7ccda03,2130314b5eae6f7c62e7cd0b27560b6dd65b700e..5f807bf99e7e6e5ee0d732288c942f7113990bda
@@@ -96,18 -96,18 +96,18 @@@ pub enum LtoCli 
  }
  
  #[derive(Clone, PartialEq, Hash)]
- pub enum CrossLangLto {
+ pub enum LinkerPluginLto {
      LinkerPlugin(PathBuf),
      LinkerPluginAuto,
      Disabled
  }
  
- impl CrossLangLto {
+ impl LinkerPluginLto {
      pub fn enabled(&self) -> bool {
          match *self {
-             CrossLangLto::LinkerPlugin(_) |
-             CrossLangLto::LinkerPluginAuto => true,
-             CrossLangLto::Disabled => false,
+             LinkerPluginLto::LinkerPlugin(_) |
+             LinkerPluginLto::LinkerPluginAuto => true,
+             LinkerPluginLto::Disabled => false,
          }
      }
  }
@@@ -475,7 -475,7 +475,7 @@@ impl BorrowckMode 
  }
  
  pub enum Input {
 -    /// Load source from file
 +    /// Loads source from file
      File(PathBuf),
      Str {
          /// String that is shown in place of a filename
@@@ -523,7 -523,7 +523,7 @@@ impl OutputFilenames 
              .unwrap_or_else(|| self.temp_path(flavor, None))
      }
  
 -    /// Get the path where a compilation artifact of the given type for the
 +    /// Gets the path where a compilation artifact of the given type for the
      /// given codegen unit should be placed on disk. If codegen_unit_name is
      /// None, a path distinct from those of any codegen unit will be generated.
      pub fn temp_path(&self, flavor: OutputType, codegen_unit_name: Option<&str>) -> PathBuf {
      }
  
      /// Like temp_path, but also supports things where there is no corresponding
 -    /// OutputType, like no-opt-bitcode or lto-bitcode.
 +    /// OutputType, like noopt-bitcode or lto-bitcode.
      pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf {
          let base = self.out_directory.join(&self.filestem());
  
@@@ -616,7 -616,7 +616,7 @@@ impl Default for Options 
  }
  
  impl Options {
 -    /// True if there is a reason to build the dep graph.
 +    /// Returns `true` if there is a reason to build the dep graph.
      pub fn build_dep_graph(&self) -> bool {
          self.incremental.is_some() || self.debugging_opts.dump_dep_graph
              || self.debugging_opts.query_dep_graph
          FilePathMapping::new(self.remap_path_prefix.clone())
      }
  
 -    /// True if there will be an output file generated
 +    /// Returns `true` if there will be an output file generated
      pub fn will_create_output_file(&self) -> bool {
          !self.debugging_opts.parse_only && // The file is just being parsed
              !self.debugging_opts.ls // The file is just being queried
@@@ -812,7 -812,7 +812,7 @@@ macro_rules! options 
          pub const parse_lto: Option<&str> =
              Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \
                    `fat`, or omitted");
-         pub const parse_cross_lang_lto: Option<&str> =
+         pub const parse_linker_plugin_lto: Option<&str> =
              Some("either a boolean (`yes`, `no`, `on`, `off`, etc), \
                    or the path to the linker plugin");
          pub const parse_merge_functions: Option<&str> =
  
      #[allow(dead_code)]
      mod $mod_set {
-         use super::{$struct_name, Passes, Sanitizer, LtoCli, CrossLangLto};
+         use super::{$struct_name, Passes, Sanitizer, LtoCli, LinkerPluginLto};
          use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
          use std::path::PathBuf;
          use std::str::FromStr;
              true
          }
  
-         fn parse_cross_lang_lto(slot: &mut CrossLangLto, v: Option<&str>) -> bool {
+         fn parse_linker_plugin_lto(slot: &mut LinkerPluginLto, v: Option<&str>) -> bool {
              if v.is_some() {
                  let mut bool_arg = None;
                  if parse_opt_bool(&mut bool_arg, v) {
                      *slot = if bool_arg.unwrap() {
-                         CrossLangLto::LinkerPluginAuto
+                         LinkerPluginLto::LinkerPluginAuto
                      } else {
-                         CrossLangLto::Disabled
+                         LinkerPluginLto::Disabled
                      };
                      return true
                  }
              }
  
              *slot = match v {
-                 None => CrossLangLto::LinkerPluginAuto,
-                 Some(path) => CrossLangLto::LinkerPlugin(PathBuf::from(path)),
+                 None => LinkerPluginLto::LinkerPluginAuto,
+                 Some(path) => LinkerPluginLto::LinkerPlugin(PathBuf::from(path)),
              };
              true
          }
@@@ -1145,6 -1145,10 +1145,10 @@@ options! {CodegenOptions, CodegenSetter
          "allow the linker to link its default libraries"),
      linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
                                             "Linker flavor"),
+     linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled,
+         parse_linker_plugin_lto, [TRACKED],
+         "generate build artifacts that are compatible with linker-based LTO."),
  }
  
  options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
          "make the current crate share its generic instantiations"),
      chalk: bool = (false, parse_bool, [TRACKED],
          "enable the experimental Chalk-based trait solving engine"),
-     cross_lang_lto: CrossLangLto = (CrossLangLto::Disabled, parse_cross_lang_lto, [TRACKED],
-         "generate build artifacts that are compatible with linker-based LTO."),
      no_parallel_llvm: bool = (false, parse_bool, [UNTRACKED],
          "don't run LLVM in parallel (while keeping codegen-units and ThinLTO)"),
      no_leak_check: bool = (false, parse_bool, [UNTRACKED],
@@@ -2440,7 -2442,7 +2442,7 @@@ mod dep_tracking 
      use std::path::PathBuf;
      use std::collections::hash_map::DefaultHasher;
      use super::{CrateType, DebugInfo, ErrorOutputType, OptLevel, OutputTypes,
-                 Passes, Sanitizer, LtoCli, CrossLangLto};
+                 Passes, Sanitizer, LtoCli, LinkerPluginLto};
      use syntax::feature_gate::UnstableFeatures;
      use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel, TargetTriple};
      use syntax::edition::Edition;
      impl_dep_tracking_hash_via_hash!(Option<Sanitizer>);
      impl_dep_tracking_hash_via_hash!(TargetTriple);
      impl_dep_tracking_hash_via_hash!(Edition);
-     impl_dep_tracking_hash_via_hash!(CrossLangLto);
+     impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
  
      impl_dep_tracking_hash_for_sortable_vec_of!(String);
      impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
@@@ -2572,7 -2574,7 +2574,7 @@@ mod tests 
      use crate::lint;
      use crate::middle::cstore;
      use crate::session::config::{build_configuration, build_session_options_and_crate_config};
-     use crate::session::config::{LtoCli, CrossLangLto};
+     use crate::session::config::{LtoCli, LinkerPluginLto};
      use crate::session::build_session;
      use crate::session::search_paths::SearchPath;
      use std::collections::{BTreeMap, BTreeSet};
          opts = reference.clone();
          opts.cg.panic = Some(PanicStrategy::Abort);
          assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
+         opts = reference.clone();
+         opts.cg.linker_plugin_lto = LinkerPluginLto::LinkerPluginAuto;
+         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
      }
  
      #[test]
          opts.debugging_opts.relro_level = Some(RelroLevel::Full);
          assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
  
-         opts = reference.clone();
-         opts.debugging_opts.cross_lang_lto = CrossLangLto::LinkerPluginAuto;
-         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
          opts = reference.clone();
          opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled);
          assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
index 51b6205facb9e9003dd299874ef7bbec2ec8892d,e4b293558e5922da8f9d1228f26d424af99a6d30..bfd447e8dd81c060322f20dd064227d2facdc67f
@@@ -51,7 -51,7 +51,7 @@@ pub mod filesearch
  pub mod search_paths;
  
  pub struct OptimizationFuel {
 -    /// If -zfuel=crate=n is specified, initially set to n. Otherwise 0.
 +    /// If `-zfuel=crate=n` is specified, initially set to `n`, otherwise `0`.
      remaining: u64,
      /// We're rejecting all further optimizations.
      out_of_fuel: bool,
@@@ -64,7 -64,7 +64,7 @@@ pub struct Session 
      pub host: Target,
      pub opts: config::Options,
      pub host_tlib_path: SearchPath,
 -    /// This is `None` if the host and target are the same.
 +    /// `None` if the host and target are the same.
      pub target_tlib_path: Option<SearchPath>,
      pub parse_sess: ParseSess,
      pub sysroot: PathBuf,
      /// The maximum length of types during monomorphization.
      pub type_length_limit: Once<usize>,
  
 -    /// The maximum number of stackframes allowed in const eval
 +    /// The maximum number of stackframes allowed in const eval.
      pub const_eval_stack_frame_limit: usize,
  
      /// The metadata::creader module may inject an allocator/panic_runtime
      /// `-Zquery-dep-graph` is specified.
      pub cgu_reuse_tracker: CguReuseTracker,
  
 -    /// Used by -Z profile-queries in util::common
 +    /// Used by `-Z profile-queries` in `util::common`.
      pub profile_channel: Lock<Option<mpsc::Sender<ProfileQueriesMsg>>>,
  
 -    /// Used by -Z self-profile
 +    /// Used by `-Z self-profile`.
      pub self_profiling_active: bool,
  
 -    /// Used by -Z self-profile
 +    /// Used by `-Z self-profile`.
      pub self_profiling: Lock<SelfProfiler>,
  
      /// Some measurements that are being gathered during compilation.
  
      next_node_id: OneThread<Cell<ast::NodeId>>,
  
 -    /// If -zfuel=crate=n is specified, Some(crate).
 +    /// If `-zfuel=crate=n` is specified, `Some(crate)`.
      optimization_fuel_crate: Option<String>,
  
 -    /// Tracks fuel info if If -zfuel=crate=n is specified
 +    /// Tracks fuel info if `-zfuel=crate=n` is specified.
      optimization_fuel: Lock<OptimizationFuel>,
  
      // The next two are public because the driver needs to read them.
 -    /// If -zprint-fuel=crate, Some(crate).
 +    /// If `-zprint-fuel=crate`, `Some(crate)`.
      pub print_fuel_crate: Option<String>,
      /// Always set to zero and incremented so that we can print fuel expended by a crate.
      pub print_fuel: AtomicU64,
      /// false positives about a job server in our environment.
      pub jobserver: Client,
  
 -    /// Metadata about the allocators for the current crate being compiled
 +    /// Metadata about the allocators for the current crate being compiled.
      pub has_global_allocator: Once<bool>,
  
 -    /// Metadata about the panic handlers for the current crate being compiled
 +    /// Metadata about the panic handlers for the current crate being compiled.
      pub has_panic_handler: Once<bool>,
  
      /// Cap lint level specified by a driver specifically.
  }
  
  pub struct PerfStats {
 -    /// The accumulated time spent on computing symbol hashes
 +    /// The accumulated time spent on computing symbol hashes.
      pub symbol_hash_time: Lock<Duration>,
 -    /// The accumulated time spent decoding def path tables from metadata
 +    /// The accumulated time spent decoding def path tables from metadata.
      pub decode_def_path_tables_time: Lock<Duration>,
      /// Total number of values canonicalized queries constructed.
      pub queries_canonicalized: AtomicUsize,
@@@ -539,7 -539,7 +539,7 @@@ impl Session 
          self.opts.debugging_opts.print_llvm_passes
      }
  
 -    /// Get the features enabled for the current compilation session.
 +    /// Gets the features enabled for the current compilation session.
      /// DO NOT USE THIS METHOD if there is a TyCtxt available, as it circumvents
      /// dependency tracking. Use tcx.features() instead.
      #[inline]
          self.opts.edition
      }
  
 -    /// True if we cannot skip the PLT for shared library calls.
 +    /// Returns `true` if we cannot skip the PLT for shared library calls.
      pub fn needs_plt(&self) -> bool {
          // Check if the current target usually needs PLT to be enabled.
          // The user can use the command line flag to override it.
@@@ -1267,7 -1267,7 +1267,7 @@@ fn validate_commandline_args_with_sessi
      // bitcode during ThinLTO. Therefore we disallow dynamic linking on MSVC
      // when compiling for LLD ThinLTO. This way we can validly just not generate
      // the `dllimport` attributes and `__imp_` symbols in that case.
-     if sess.opts.debugging_opts.cross_lang_lto.enabled() &&
+     if sess.opts.cg.linker_plugin_lto.enabled() &&
         sess.opts.cg.prefer_dynamic &&
         sess.target.target.options.is_like_msvc {
          sess.err("Linker plugin based LTO is not supported together with \
index 725009e1377aff25df06ad4ae8ce62d5603336d9,8bb985ecc25fa7676a3ae77decbcaeac24e8b25e..548c94abc076f49cc855da34b8906e0a3eecfe26
@@@ -42,7 -42,7 +42,7 @@@ pub use rustc_codegen_utils::link::{fin
                                      out_filename, check_file_is_writeable};
  
  
 -/// Perform the linkage portion of the compilation phase. This will generate all
 +/// Performs the linkage portion of the compilation phase. This will generate all
  /// of the requested outputs for this compilation session.
  pub(crate) fn link_binary(sess: &Session,
                            codegen_results: &CodegenResults,
@@@ -857,7 -857,7 +857,7 @@@ fn link_args(cmd: &mut dyn Linker
               codegen_results: &CodegenResults) {
  
      // Linker plugins should be specified early in the list of arguments
-     cmd.cross_lang_lto();
+     cmd.linker_plugin_lto();
  
      // The default library location, we need this to find the runtime.
      // The location of crates will be determined as needed.
@@@ -1491,7 -1491,7 +1491,7 @@@ fn are_upstream_rust_objects_already_in
          Lto::Thin => {
              // If we defer LTO to the linker, we haven't run LTO ourselves, so
              // any upstream object files have not been copied yet.
-             !sess.opts.debugging_opts.cross_lang_lto.enabled()
+             !sess.opts.cg.linker_plugin_lto.enabled()
          }
          Lto::No |
          Lto::ThinLocal => false,
index be7733bf554bb44f0eec86b5a26660181116e223,b6b880c7ec4aceda3019365bf35f401371a4e032..ac55244d8d931f93b772177183095911f0c8f0e2
@@@ -159,7 -159,7 +159,7 @@@ pub(crate) fn run_thin(cgcx: &CodegenCo
      let symbol_white_list = symbol_white_list.iter()
                                               .map(|c| c.as_ptr())
                                               .collect::<Vec<_>>();
-     if cgcx.opts.debugging_opts.cross_lang_lto.enabled() {
+     if cgcx.opts.cg.linker_plugin_lto.enabled() {
          unreachable!("We should never reach this case if the LTO step \
                        is deferred to the linker");
      }
@@@ -791,7 -791,7 +791,7 @@@ impl ThinLTOImports 
          self.imports.get(llvm_module_name).map(|v| &v[..]).unwrap_or(&[])
      }
  
 -    /// Load the ThinLTO import map from ThinLTOData.
 +    /// Loads the ThinLTO import map from ThinLTOData.
      unsafe fn from_thin_lto_data(data: *const llvm::ThinLTOData) -> ThinLTOImports {
          unsafe extern "C" fn imported_module_callback(payload: *mut libc::c_void,
                                                        importing_module_name: *const libc::c_char,
index 3cbe3793f10cf02edf55111bd630c97ee4256991,765b0e91d921a8538cb9618be1ea1214405d7918..356bb8d50ad0d45ecb74e849307b9e62d42c3532
@@@ -13,7 -13,7 +13,7 @@@ use rustc::hir::def_id::{LOCAL_CRATE, C
  use rustc::middle::dependency_format::Linkage;
  use rustc::session::Session;
  use rustc::session::config::{self, CrateType, OptLevel, DebugInfo,
-                              CrossLangLto, Lto};
+                              LinkerPluginLto, Lto};
  use rustc::ty::TyCtxt;
  use rustc_target::spec::{LinkerFlavor, LldFlavor};
  use serialize::{json, Encoder};
@@@ -91,7 -91,7 +91,7 @@@ impl LinkerInfo 
      }
  }
  
 -/// Linker abstraction used by back::link to build up the command to invoke a
 +/// Linker abstraction used by `back::link` to build up the command to invoke a
  /// linker.
  ///
  /// This trait is the total list of requirements needed by `back::link` and
@@@ -127,7 -127,7 +127,7 @@@ pub trait Linker 
      fn subsystem(&mut self, subsystem: &str);
      fn group_start(&mut self);
      fn group_end(&mut self);
-     fn cross_lang_lto(&mut self);
+     fn linker_plugin_lto(&mut self);
      // Should have been finalize(self), but we don't support self-by-value on trait objects (yet?).
      fn finalize(&mut self) -> Command;
  }
@@@ -145,7 -145,7 +145,7 @@@ pub struct GccLinker<'a> 
  impl<'a> GccLinker<'a> {
      /// Argument that must be passed *directly* to the linker
      ///
 -    /// These arguments need to be prepended with '-Wl,' when a gcc-style linker is used
 +    /// These arguments need to be prepended with `-Wl`, when a GCC-style linker is used.
      fn linker_arg<S>(&mut self, arg: S) -> &mut Self
          where S: AsRef<OsStr>
      {
          }
      }
  
-     fn push_cross_lang_lto_args(&mut self, plugin_path: Option<&OsStr>) {
+     fn push_linker_plugin_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);
@@@ -454,16 -454,16 +454,16 @@@ impl<'a> Linker for GccLinker<'a> 
          }
      }
  
-     fn cross_lang_lto(&mut self) {
-         match self.sess.opts.debugging_opts.cross_lang_lto {
-             CrossLangLto::Disabled => {
+     fn linker_plugin_lto(&mut self) {
+         match self.sess.opts.cg.linker_plugin_lto {
+             LinkerPluginLto::Disabled => {
                  // Nothing to do
              }
-             CrossLangLto::LinkerPluginAuto => {
-                 self.push_cross_lang_lto_args(None);
+             LinkerPluginLto::LinkerPluginAuto => {
+                 self.push_linker_plugin_lto_args(None);
              }
-             CrossLangLto::LinkerPlugin(ref path) => {
-                 self.push_cross_lang_lto_args(Some(path.as_os_str()));
+             LinkerPluginLto::LinkerPlugin(ref path) => {
+                 self.push_linker_plugin_lto_args(Some(path.as_os_str()));
              }
          }
      }
@@@ -697,7 -697,7 +697,7 @@@ impl<'a> Linker for MsvcLinker<'a> 
      fn group_start(&mut self) {}
      fn group_end(&mut self) {}
  
-     fn cross_lang_lto(&mut self) {
+     fn linker_plugin_lto(&mut self) {
          // Do nothing
      }
  }
@@@ -865,7 -865,7 +865,7 @@@ impl<'a> Linker for EmLinker<'a> 
      fn group_start(&mut self) {}
      fn group_end(&mut self) {}
  
-     fn cross_lang_lto(&mut self) {
+     fn linker_plugin_lto(&mut self) {
          // Do nothing
      }
  }
@@@ -1047,7 -1047,7 +1047,7 @@@ impl<'a> Linker for WasmLd<'a> 
      fn group_start(&mut self) {}
      fn group_end(&mut self) {}
  
-     fn cross_lang_lto(&mut self) {
+     fn linker_plugin_lto(&mut self) {
          // Do nothing for now
      }
  }
@@@ -1207,6 -1207,6 +1207,6 @@@ impl<'a> Linker for PtxLinker<'a> 
      fn group_end(&mut self) {
      }
  
-     fn cross_lang_lto(&mut self) {
+     fn linker_plugin_lto(&mut self) {
      }
  }
index 79662a4bfe53f12d0673cfd873b01deca86524c4,81952c9c820b0b8e2dca25807738612536421770..2922d326c3b355e80c06f76ee7d1c31549499b38
@@@ -126,7 -126,7 +126,7 @@@ impl ModuleConfig 
          self.time_passes = sess.time_passes();
          self.inline_threshold = sess.opts.cg.inline_threshold;
          self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode ||
-                               sess.opts.debugging_opts.cross_lang_lto.enabled();
+                               sess.opts.cg.linker_plugin_lto.enabled();
          let embed_bitcode = sess.target.target.options.embed_bitcode ||
                              sess.opts.debugging_opts.embed_bitcode;
          if embed_bitcode {
@@@ -662,7 -662,7 +662,7 @@@ pub enum WorkItem<B: WriteBackendMethod
      /// Copy the post-LTO artifacts from the incremental cache to the output
      /// directory.
      CopyPostLtoArtifacts(CachedModuleCodegen),
 -    /// Perform (Thin)LTO on the given module.
 +    /// Performs (Thin)LTO on the given module.
      LTO(lto::LtoModuleCodegen<B>),
  }
  
@@@ -737,7 -737,7 +737,7 @@@ fn execute_optimize_work_item<B: ExtraB
      // If the linker does LTO, we don't have to do it. Note that we
      // keep doing full LTO, if it is requested, as not to break the
      // assumption that the output will be a single module.
-     let linker_does_lto = cgcx.opts.debugging_opts.cross_lang_lto.enabled();
+     let linker_does_lto = cgcx.opts.cg.linker_plugin_lto.enabled();
  
      // When we're automatically doing ThinLTO for multi-codegen-unit
      // builds we don't actually want to LTO the allocator modules if
@@@ -1797,7 -1797,7 +1797,7 @@@ impl<B: ExtraBackendMethods> OngoingCod
          drop(self.coordinator_send.send(Box::new(Message::CodegenComplete::<B>)));
      }
  
 -    /// Consume this context indicating that codegen was entirely aborted, and
 +    /// Consumes this context indicating that codegen was entirely aborted, and
      /// we need to exit as quickly as possible.
      ///
      /// This method blocks the current thread until all worker threads have
@@@ -1883,7 -1883,7 +1883,7 @@@ pub fn pre_lto_bitcode_filename(module_
  fn msvc_imps_needed(tcx: TyCtxt) -> bool {
      // This should never be true (because it's not supported). If it is true,
      // something is wrong with commandline arg validation.
-     assert!(!(tcx.sess.opts.debugging_opts.cross_lang_lto.enabled() &&
+     assert!(!(tcx.sess.opts.cg.linker_plugin_lto.enabled() &&
                tcx.sess.target.target.options.is_like_msvc &&
                tcx.sess.opts.cg.prefer_dynamic));
  
          tcx.sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateType::Rlib) &&
      // ThinLTO can't handle this workaround in all cases, so we don't
      // emit the `__imp_` symbols. Instead we make them unnecessary by disallowing
-     // dynamic linking when cross-language LTO is enabled.
-     !tcx.sess.opts.debugging_opts.cross_lang_lto.enabled()
+     // dynamic linking when linker plugin LTO is enabled.
+     !tcx.sess.opts.cg.linker_plugin_lto.enabled()
  }