Skip to content

Commit 43d95e2

Browse files
committed
Auto merge of #45032 - alexcrichton:target-cfu, r=michaelwoerister
rustc: Allow target-specific default cgus Some targets, like msp430 and nvptx, don't work with multiple codegen units right now for bugs or fundamental reasons. To expose this allow targets to express a default. Closes #45000
2 parents 2d73972 + 5187763 commit 43d95e2

File tree

7 files changed

+56
-50
lines changed

7 files changed

+56
-50
lines changed

Diff for: src/librustc/session/config.rs

+3-45
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ top_level_options!(
352352
actually_rustdoc: bool [TRACKED],
353353

354354
// Number of object files/codegen units to produce on the backend
355-
codegen_units: usize [UNTRACKED],
355+
cli_forced_codegen_units: Option<usize> [UNTRACKED],
356356
}
357357
);
358358

@@ -505,7 +505,7 @@ pub fn basic_options() -> Options {
505505
unstable_features: UnstableFeatures::Disallow,
506506
debug_assertions: true,
507507
actually_rustdoc: false,
508-
codegen_units: 1,
508+
cli_forced_codegen_units: None,
509509
}
510510
}
511511

@@ -1711,48 +1711,6 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
17111711

17121712
let incremental = debugging_opts.incremental.as_ref().map(|m| PathBuf::from(m));
17131713

1714-
let codegen_units = codegen_units.unwrap_or_else(|| {
1715-
match opt_level {
1716-
// If we're compiling at `-O0` then default to 16 codegen units.
1717-
// The number here shouldn't matter too too much as debug mode
1718-
// builds don't rely on performance at all, meaning that lost
1719-
// opportunities for inlining through multiple codegen units is
1720-
// a non-issue.
1721-
//
1722-
// Note that the high number here doesn't mean that we'll be
1723-
// spawning a large number of threads in parallel. The backend
1724-
// of rustc contains global rate limiting through the
1725-
// `jobserver` crate so we'll never overload the system with too
1726-
// much work, but rather we'll only be optimizing when we're
1727-
// otherwise cooperating with other instances of rustc.
1728-
//
1729-
// Rather the high number here means that we should be able to
1730-
// keep a lot of idle cpus busy. By ensuring that no codegen
1731-
// unit takes *too* long to build we'll be guaranteed that all
1732-
// cpus will finish pretty closely to one another and we should
1733-
// make relatively optimal use of system resources
1734-
//
1735-
// Another note worth mentioning here, however, is that this number
1736-
// isn't *too* high. When codegen units are increased that means we
1737-
// currently have to codegen `#[inline]` functions into each codegen
1738-
// unit, which means the more codegen units we're using the more we
1739-
// may be generating. In other words, increasing codegen units may
1740-
// increase the overall work the compiler does. If we don't have
1741-
// enough cores to make up for this loss then increasing the number
1742-
// of codegen units could become an overall loss!
1743-
//
1744-
// As a result we choose a hopefully conservative value 16, which
1745-
// should be more than the number of cpus of most hardware compiling
1746-
// Rust but also not too much for 2-4 core machines to have too much
1747-
// loss of compile time.
1748-
OptLevel::No => 16,
1749-
1750-
// All other optimization levels default use one codegen unit,
1751-
// the historical default in Rust for a Long Time.
1752-
_ => 1,
1753-
}
1754-
});
1755-
17561714
(Options {
17571715
crate_types,
17581716
optimize: opt_level,
@@ -1777,7 +1735,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
17771735
unstable_features: UnstableFeatures::from_environment(),
17781736
debug_assertions,
17791737
actually_rustdoc: false,
1780-
codegen_units,
1738+
cli_forced_codegen_units: codegen_units,
17811739
},
17821740
cfg)
17831741
}

Diff for: src/librustc/session/mod.rs

+37
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,43 @@ impl Session {
636636
}
637637
ret
638638
}
639+
640+
/// Returns the number of codegen units that should be used for this
641+
/// compilation
642+
pub fn codegen_units(&self) -> usize {
643+
if let Some(n) = self.opts.cli_forced_codegen_units {
644+
return n
645+
}
646+
if let Some(n) = self.target.target.options.default_codegen_units {
647+
return n as usize
648+
}
649+
650+
match self.opts.optimize {
651+
// If we're compiling at `-O0` then default to 16 codegen units.
652+
// The number here shouldn't matter too too much as debug mode
653+
// builds don't rely on performance at all, meaning that lost
654+
// opportunities for inlining through multiple codegen units is
655+
// a non-issue.
656+
//
657+
// Note that the high number here doesn't mean that we'll be
658+
// spawning a large number of threads in parallel. The backend
659+
// of rustc contains global rate limiting through the
660+
// `jobserver` crate so we'll never overload the system with too
661+
// much work, but rather we'll only be optimizing when we're
662+
// otherwise cooperating with other instances of rustc.
663+
//
664+
// Rather the high number here means that we should be able to
665+
// keep a lot of idle cpus busy. By ensuring that no codegen
666+
// unit takes *too* long to build we'll be guaranteed that all
667+
// cpus will finish pretty closely to one another and we should
668+
// make relatively optimal use of system resources
669+
config::OptLevel::No => 16,
670+
671+
// All other optimization levels default use one codegen unit,
672+
// the historical default in Rust for a Long Time.
673+
_ => 1,
674+
}
675+
}
639676
}
640677

641678
pub fn build_session(sopts: config::Options,

Diff for: src/librustc_back/target/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,9 @@ pub struct TargetOptions {
430430

431431
/// The minimum alignment for global symbols.
432432
pub min_global_align: Option<u64>,
433+
434+
/// Default number of codegen units to use in debug mode
435+
pub default_codegen_units: Option<u64>,
433436
}
434437

435438
impl Default for TargetOptions {
@@ -492,6 +495,7 @@ impl Default for TargetOptions {
492495
crt_static_respected: false,
493496
stack_probes: false,
494497
min_global_align: None,
498+
default_codegen_units: None,
495499
}
496500
}
497501
}
@@ -732,6 +736,7 @@ impl Target {
732736
key!(crt_static_respected, bool);
733737
key!(stack_probes, bool);
734738
key!(min_global_align, Option<u64>);
739+
key!(default_codegen_units, Option<u64>);
735740

736741
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
737742
for name in array.iter().filter_map(|abi| abi.as_string()) {
@@ -924,6 +929,7 @@ impl ToJson for Target {
924929
target_option_val!(crt_static_respected);
925930
target_option_val!(stack_probes);
926931
target_option_val!(min_global_align);
932+
target_option_val!(default_codegen_units);
927933

928934
if default.abi_blacklist != self.options.abi_blacklist {
929935
d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()

Diff for: src/librustc_back/target/msp430_none_elf.rs

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ pub fn target() -> TargetResult {
4848
// code because of the extra costs it involves.
4949
relocation_model: "static".to_string(),
5050

51+
// Right now we invoke an external assembler and this isn't
52+
// compatible with multiple codegen units, and plus we probably
53+
// don't want to invoke that many gcc instances.
54+
default_codegen_units: Some(1),
55+
5156
.. Default::default( )
5257
}
5358
})

Diff for: src/librustc_trans/back/link.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ fn link_rlib<'a>(sess: &'a Session,
467467
// of when we do and don't keep .#module-name#.bc files around.
468468
let user_wants_numbered_bitcode =
469469
sess.opts.output_types.contains_key(&OutputType::Bitcode) &&
470-
sess.opts.codegen_units > 1;
470+
sess.codegen_units() > 1;
471471
if !sess.opts.cg.save_temps && !user_wants_numbered_bitcode {
472472
remove(sess, &bc_filename);
473473
}

Diff for: src/librustc_trans/back/write.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1037,10 +1037,10 @@ fn produce_final_output_artifacts(sess: &Session,
10371037
let needs_crate_object = crate_output.outputs.contains_key(&OutputType::Exe);
10381038

10391039
let keep_numbered_bitcode = needs_crate_bitcode ||
1040-
(user_wants_bitcode && sess.opts.codegen_units > 1);
1040+
(user_wants_bitcode && sess.codegen_units() > 1);
10411041

10421042
let keep_numbered_objects = needs_crate_object ||
1043-
(user_wants_objects && sess.opts.codegen_units > 1);
1043+
(user_wants_objects && sess.codegen_units() > 1);
10441044

10451045
for module in compiled_modules.modules.iter() {
10461046
let module_name = Some(&module.name[..]);
@@ -2052,7 +2052,7 @@ impl OngoingCrateTranslation {
20522052

20532053
// FIXME: time_llvm_passes support - does this use a global context or
20542054
// something?
2055-
if sess.opts.codegen_units == 1 && sess.time_llvm_passes() {
2055+
if sess.codegen_units() == 1 && sess.time_llvm_passes() {
20562056
unsafe { llvm::LLVMRustPrintPassTimings(); }
20572057
}
20582058

Diff for: src/librustc_trans/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1218,7 +1218,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(
12181218
let strategy = if tcx.sess.opts.debugging_opts.incremental.is_some() {
12191219
PartitioningStrategy::PerModule
12201220
} else {
1221-
PartitioningStrategy::FixedUnitCount(tcx.sess.opts.codegen_units)
1221+
PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units())
12221222
};
12231223

12241224
let codegen_units = time(time_passes, "codegen unit partitioning", || {

0 commit comments

Comments
 (0)