Skip to content

Commit 24093a6

Browse files
Allow for opting out of ThinLTO and clean up LTO related cli flag handling.
1 parent 4efc0a7 commit 24093a6

File tree

8 files changed

+97
-32
lines changed

8 files changed

+97
-32
lines changed

src/librustc/session/config.rs

+44-16
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,13 @@ pub enum OptLevel {
6868
SizeMin, // -Oz
6969
}
7070

71+
/// This is what the `LtoCli` values get mapped to after resolving defaults and
72+
/// and taking other command line options into account.
7173
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
7274
pub enum Lto {
7375
/// Don't do any LTO whatsoever
7476
No,
7577

76-
/// Do a full crate graph LTO. The flavor is determined by the compiler
77-
/// (currently the default is "fat").
78-
Yes,
79-
8078
/// Do a full crate graph LTO with ThinLTO
8179
Thin,
8280

@@ -88,6 +86,23 @@ pub enum Lto {
8886
Fat,
8987
}
9088

89+
/// The different settings that the `-C lto` flag can have.
90+
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
91+
pub enum LtoCli {
92+
/// `-C lto=no`
93+
No,
94+
/// `-C lto=yes`
95+
Yes,
96+
/// `-C lto`
97+
NoParam,
98+
/// `-C lto=thin`
99+
Thin,
100+
/// `-C lto=fat`
101+
Fat,
102+
/// No `-C lto` flag passed
103+
Unspecified,
104+
}
105+
91106
#[derive(Clone, PartialEq, Hash)]
92107
pub enum CrossLangLto {
93108
LinkerPlugin(PathBuf),
@@ -801,15 +816,16 @@ macro_rules! options {
801816
pub const parse_unpretty: Option<&'static str> =
802817
Some("`string` or `string=string`");
803818
pub const parse_lto: Option<&'static str> =
804-
Some("one of `thin`, `fat`, or omitted");
819+
Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \
820+
`fat`, or omitted");
805821
pub const parse_cross_lang_lto: Option<&'static str> =
806822
Some("either a boolean (`yes`, `no`, `on`, `off`, etc), \
807823
or the path to the linker plugin");
808824
}
809825

810826
#[allow(dead_code)]
811827
mod $mod_set {
812-
use super::{$struct_name, Passes, Sanitizer, Lto, CrossLangLto};
828+
use super::{$struct_name, Passes, Sanitizer, LtoCli, CrossLangLto};
813829
use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel};
814830
use std::path::PathBuf;
815831

@@ -1002,11 +1018,23 @@ macro_rules! options {
10021018
}
10031019
}
10041020

1005-
fn parse_lto(slot: &mut Lto, v: Option<&str>) -> bool {
1021+
fn parse_lto(slot: &mut LtoCli, v: Option<&str>) -> bool {
1022+
if v.is_some() {
1023+
let mut bool_arg = None;
1024+
if parse_opt_bool(&mut bool_arg, v) {
1025+
*slot = if bool_arg.unwrap() {
1026+
LtoCli::Yes
1027+
} else {
1028+
LtoCli::No
1029+
};
1030+
return true
1031+
}
1032+
}
1033+
10061034
*slot = match v {
1007-
None => Lto::Yes,
1008-
Some("thin") => Lto::Thin,
1009-
Some("fat") => Lto::Fat,
1035+
None => LtoCli::NoParam,
1036+
Some("thin") => LtoCli::Thin,
1037+
Some("fat") => LtoCli::Fat,
10101038
Some(_) => return false,
10111039
};
10121040
true
@@ -1047,7 +1075,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
10471075
"extra arguments to append to the linker invocation (space separated)"),
10481076
link_dead_code: bool = (false, parse_bool, [UNTRACKED],
10491077
"don't let linker strip dead code (turning it on can be used for code coverage)"),
1050-
lto: Lto = (Lto::No, parse_lto, [TRACKED],
1078+
lto: LtoCli = (LtoCli::Unspecified, parse_lto, [TRACKED],
10511079
"perform LLVM link-time optimizations"),
10521080
target_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
10531081
"select target processor (rustc --print target-cpus for details)"),
@@ -2373,8 +2401,8 @@ mod dep_tracking {
23732401
use std::hash::Hash;
23742402
use std::path::PathBuf;
23752403
use std::collections::hash_map::DefaultHasher;
2376-
use super::{CrateType, DebugInfo, ErrorOutputType, Lto, OptLevel, OutputTypes,
2377-
Passes, Sanitizer, CrossLangLto};
2404+
use super::{CrateType, DebugInfo, ErrorOutputType, OptLevel, OutputTypes,
2405+
Passes, Sanitizer, LtoCli, CrossLangLto};
23782406
use syntax::feature_gate::UnstableFeatures;
23792407
use rustc_target::spec::{PanicStrategy, RelroLevel, TargetTriple};
23802408
use syntax::edition::Edition;
@@ -2429,7 +2457,7 @@ mod dep_tracking {
24292457
impl_dep_tracking_hash_via_hash!(RelroLevel);
24302458
impl_dep_tracking_hash_via_hash!(Passes);
24312459
impl_dep_tracking_hash_via_hash!(OptLevel);
2432-
impl_dep_tracking_hash_via_hash!(Lto);
2460+
impl_dep_tracking_hash_via_hash!(LtoCli);
24332461
impl_dep_tracking_hash_via_hash!(DebugInfo);
24342462
impl_dep_tracking_hash_via_hash!(UnstableFeatures);
24352463
impl_dep_tracking_hash_via_hash!(OutputTypes);
@@ -2503,7 +2531,7 @@ mod tests {
25032531
use lint;
25042532
use middle::cstore;
25052533
use session::config::{build_configuration, build_session_options_and_crate_config};
2506-
use session::config::{Lto, CrossLangLto};
2534+
use session::config::{LtoCli, CrossLangLto};
25072535
use session::build_session;
25082536
use std::collections::{BTreeMap, BTreeSet};
25092537
use std::iter::FromIterator;
@@ -2937,7 +2965,7 @@ mod tests {
29372965

29382966
// Make sure changing a [TRACKED] option changes the hash
29392967
opts = reference.clone();
2940-
opts.cg.lto = Lto::Fat;
2968+
opts.cg.lto = LtoCli::Fat;
29412969
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
29422970

29432971
opts = reference.clone();

src/librustc/session/mod.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -547,9 +547,27 @@ impl Session {
547547
// lto` and we've for whatever reason forced off ThinLTO via the CLI,
548548
// then ensure we can't use a ThinLTO.
549549
match self.opts.cg.lto {
550-
config::Lto::No => {}
551-
config::Lto::Yes if self.opts.cli_forced_thinlto_off => return config::Lto::Fat,
552-
other => return other,
550+
config::LtoCli::Unspecified => {
551+
// The compiler was invoked without the `-Clto` flag. Fall
552+
// through to the default handling
553+
}
554+
config::LtoCli::No => {
555+
// The user explicitly opted out of any kind of LTO
556+
return config::Lto::No;
557+
}
558+
config::LtoCli::Yes |
559+
config::LtoCli::Fat |
560+
config::LtoCli::NoParam => {
561+
// All of these mean fat LTO
562+
return config::Lto::Fat;
563+
}
564+
config::LtoCli::Thin => {
565+
return if self.opts.cli_forced_thinlto_off {
566+
config::Lto::Fat
567+
} else {
568+
config::Lto::Thin
569+
};
570+
}
553571
}
554572

555573
// Ok at this point the target doesn't require anything and the user
@@ -1174,7 +1192,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
11741192

11751193
if sess.opts.incremental.is_some() {
11761194
match sess.lto() {
1177-
Lto::Yes |
11781195
Lto::Thin |
11791196
Lto::Fat => {
11801197
sess.err("can't perform LTO when compiling incrementally");

src/librustc_codegen_llvm/back/link.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1666,7 +1666,6 @@ fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool {
16661666

16671667
fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
16681668
match sess.lto() {
1669-
Lto::Yes |
16701669
Lto::Fat => true,
16711670
Lto::Thin => {
16721671
// If we defer LTO to the linker, we haven't run LTO ourselves, so

src/librustc_codegen_llvm/back/linker.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,12 @@ impl<'a> GccLinker<'a> {
205205
self.linker_arg(&format!("-plugin-opt={}", opt_level));
206206
self.linker_arg(&format!("-plugin-opt=mcpu={}", llvm_util::target_cpu(self.sess)));
207207

208-
match self.sess.opts.cg.lto {
208+
match self.sess.lto() {
209209
config::Lto::Thin |
210210
config::Lto::ThinLocal => {
211211
self.linker_arg("-plugin-opt=thin");
212212
}
213213
config::Lto::Fat |
214-
config::Lto::Yes |
215214
config::Lto::No => {
216215
// default to regular LTO
217216
}

src/librustc_codegen_llvm/back/lto.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ pub(crate) fn run(cgcx: &CodegenContext,
118118
Lto::ThinLocal => SymbolExportLevel::Rust,
119119

120120
// We're doing LTO for the entire crate graph
121-
Lto::Yes | Lto::Fat | Lto::Thin => {
121+
Lto::Fat | Lto::Thin => {
122122
symbol_export::crates_export_threshold(&cgcx.crate_types)
123123
}
124124

@@ -201,7 +201,6 @@ pub(crate) fn run(cgcx: &CodegenContext,
201201
.map(|c| c.as_ptr())
202202
.collect::<Vec<_>>();
203203
match cgcx.lto {
204-
Lto::Yes | // `-C lto` == fat LTO by default
205204
Lto::Fat => {
206205
assert!(cached_modules.is_empty());
207206
let opt_jobs = fat_lto(cgcx,

src/librustc_codegen_llvm/back/write.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,6 @@ fn need_pre_thin_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
928928
}
929929

930930
match sess.lto() {
931-
Lto::Yes |
932931
Lto::Fat |
933932
Lto::No => false,
934933
Lto::Thin |
@@ -1363,7 +1362,7 @@ fn execute_optimize_work_item(cgcx: &CodegenContext,
13631362
// require LTO so the request for LTO is always unconditionally
13641363
// passed down to the backend, but we don't actually want to do
13651364
// anything about it yet until we've got a final product.
1366-
Lto::Yes | Lto::Fat | Lto::Thin => {
1365+
Lto::Fat | Lto::Thin => {
13671366
cgcx.crate_types.len() != 1 ||
13681367
cgcx.crate_types[0] != config::CrateType::Rlib
13691368
}
@@ -1543,7 +1542,7 @@ fn start_executing_work(tcx: TyCtxt,
15431542
exported_symbols.insert(LOCAL_CRATE, copy_symbols(LOCAL_CRATE));
15441543
Some(Arc::new(exported_symbols))
15451544
}
1546-
Lto::Yes | Lto::Fat | Lto::Thin => {
1545+
Lto::Fat | Lto::Thin => {
15471546
exported_symbols.insert(LOCAL_CRATE, copy_symbols(LOCAL_CRATE));
15481547
for &cnum in tcx.crates().iter() {
15491548
exported_symbols.insert(cnum, copy_symbols(cnum));

src/test/run-make-fulldeps/codegen-options-parsing/Makefile

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ all:
1616
$(RUSTC) -C extra-filename=foo dummy.rs 2>&1
1717
#Option taking no argument
1818
$(RUSTC) -C lto= dummy.rs 2>&1 | \
19-
$(CGREP) 'codegen option `lto` - one of `thin`, `fat`, or'
19+
$(CGREP) 'codegen option `lto` - either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted'
2020
$(RUSTC) -C lto=1 dummy.rs 2>&1 | \
21-
$(CGREP) 'codegen option `lto` - one of `thin`, `fat`, or'
21+
$(CGREP) 'codegen option `lto` - either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted'
2222
$(RUSTC) -C lto=foo dummy.rs 2>&1 | \
23-
$(CGREP) 'codegen option `lto` - one of `thin`, `fat`, or'
23+
$(CGREP) 'codegen option `lto` - either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted'
2424
$(RUSTC) -C lto dummy.rs
2525

2626
# Should not link dead code...
+25-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
11
-include ../tools.mk
22

3-
all:
3+
all: noparam bool_true bool_false thin fat
4+
5+
noparam:
46
$(RUSTC) lib.rs
57
$(RUSTC) main.rs -C lto
68
$(call RUN,main)
9+
10+
bool_true:
11+
$(RUSTC) lib.rs
12+
$(RUSTC) main.rs -C lto=yes
13+
$(call RUN,main)
14+
15+
16+
bool_false:
17+
$(RUSTC) lib.rs
18+
$(RUSTC) main.rs -C lto=off
19+
$(call RUN,main)
20+
21+
thin:
22+
$(RUSTC) lib.rs
23+
$(RUSTC) main.rs -C lto=thin
24+
$(call RUN,main)
25+
26+
fat:
27+
$(RUSTC) lib.rs
28+
$(RUSTC) main.rs -C lto=fat
29+
$(call RUN,main)
30+

0 commit comments

Comments
 (0)