}
#[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,
}
}
}
}
pub enum Input {
- /// Load source from file
+ /// Loads source from file
File(PathBuf),
Str {
/// String that is shown in place of a filename
.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());
}
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
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
}
"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],
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);
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());
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,
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,
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.
// 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 \
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,
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.
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,
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");
}
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,
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};
}
}
-/// 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
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;
}
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);
}
}
- 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()));
}
}
}
fn group_start(&mut self) {}
fn group_end(&mut self) {}
- fn cross_lang_lto(&mut self) {
+ fn linker_plugin_lto(&mut self) {
// Do nothing
}
}
fn group_start(&mut self) {}
fn group_end(&mut self) {}
- fn cross_lang_lto(&mut self) {
+ fn linker_plugin_lto(&mut self) {
// Do nothing
}
}
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
}
}
fn group_end(&mut self) {
}
- fn cross_lang_lto(&mut self) {
+ fn linker_plugin_lto(&mut self) {
}
}
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 {
/// 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>),
}
// 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
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
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()
}