Skip to content

Commit 4ec9a9b

Browse files
committed
Make the allocator shim participate in LTO again
1 parent ad85bc5 commit 4ec9a9b

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
334334
pub output_filenames: Arc<OutputFilenames>,
335335
pub invocation_temp: Option<String>,
336336
pub module_config: Arc<ModuleConfig>,
337+
pub allocator_config: Arc<ModuleConfig>,
337338
pub tm_factory: TargetMachineFactoryFn<B>,
338339
pub msvc_imps_needed: bool,
339340
pub is_pe_coff: bool,
@@ -794,12 +795,19 @@ pub(crate) fn compute_per_cgu_lto_type(
794795
sess_lto: &Lto,
795796
opts: &config::Options,
796797
sess_crate_types: &[CrateType],
798+
module_kind: ModuleKind,
797799
) -> ComputedLtoType {
798800
// If the linker does LTO, we don't have to do it. Note that we
799801
// keep doing full LTO, if it is requested, as not to break the
800802
// assumption that the output will be a single module.
801803
let linker_does_lto = opts.cg.linker_plugin_lto.enabled();
802804

805+
// When we're automatically doing ThinLTO for multi-codegen-unit
806+
// builds we don't actually want to LTO the allocator modules if
807+
// it shows up. This is due to various linker shenanigans that
808+
// we'll encounter later.
809+
let is_allocator = module_kind == ModuleKind::Allocator;
810+
803811
// We ignore a request for full crate graph LTO if the crate type
804812
// is only an rlib, as there is no full crate graph to process,
805813
// that'll happen later.
@@ -811,7 +819,7 @@ pub(crate) fn compute_per_cgu_lto_type(
811819
let is_rlib = matches!(sess_crate_types, [CrateType::Rlib]);
812820

813821
match sess_lto {
814-
Lto::ThinLocal if !linker_does_lto => ComputedLtoType::Thin,
822+
Lto::ThinLocal if !linker_does_lto && !is_allocator => ComputedLtoType::Thin,
815823
Lto::Thin if !linker_does_lto && !is_rlib => ComputedLtoType::Thin,
816824
Lto::Fat if !is_rlib => ComputedLtoType::Fat,
817825
_ => ComputedLtoType::No,
@@ -825,18 +833,23 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
825833
let dcx = cgcx.create_dcx();
826834
let dcx = dcx.handle();
827835

828-
B::optimize(cgcx, dcx, &mut module, &cgcx.module_config);
836+
let module_config = match module.kind {
837+
ModuleKind::Regular => &cgcx.module_config,
838+
ModuleKind::Allocator => &cgcx.allocator_config,
839+
};
840+
841+
B::optimize(cgcx, dcx, &mut module, module_config);
829842

830843
// After we've done the initial round of optimizations we need to
831844
// decide whether to synchronously codegen this module or ship it
832845
// back to the coordinator thread for further LTO processing (which
833846
// has to wait for all the initial modules to be optimized).
834847

835-
let lto_type = compute_per_cgu_lto_type(&cgcx.lto, &cgcx.opts, &cgcx.crate_types);
848+
let lto_type = compute_per_cgu_lto_type(&cgcx.lto, &cgcx.opts, &cgcx.crate_types, module.kind);
836849

837850
// If we're doing some form of incremental LTO then we need to be sure to
838851
// save our module to disk first.
839-
let bitcode = if cgcx.module_config.emit_pre_lto_bc {
852+
let bitcode = if module_config.emit_pre_lto_bc {
840853
let filename = pre_lto_bitcode_filename(&module.name);
841854
cgcx.incr_comp_session_dir.as_ref().map(|path| path.join(&filename))
842855
} else {
@@ -845,7 +858,7 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
845858

846859
match lto_type {
847860
ComputedLtoType::No => {
848-
let module = B::codegen(cgcx, module, &cgcx.module_config);
861+
let module = B::codegen(cgcx, module, module_config);
849862
WorkItemResult::Finished(module)
850863
}
851864
ComputedLtoType::Thin => {
@@ -1133,6 +1146,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
11331146
diag_emitter: shared_emitter.clone(),
11341147
output_filenames: Arc::clone(tcx.output_filenames(())),
11351148
module_config: regular_config,
1149+
allocator_config,
11361150
tm_factory: backend.target_machine_factory(tcx.sess, ol, backend_features),
11371151
msvc_imps_needed: msvc_imps_needed(tcx),
11381152
is_pe_coff: tcx.sess.target.is_like_windows,
@@ -1147,11 +1161,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
11471161
invocation_temp: sess.invocation_temp.clone(),
11481162
};
11491163

1150-
let compiled_allocator_module = allocator_module.map(|mut allocator_module| {
1151-
B::optimize(&cgcx, tcx.sess.dcx(), &mut allocator_module, &allocator_config);
1152-
B::codegen(&cgcx, allocator_module, &allocator_config)
1153-
});
1154-
11551164
// This is the "main loop" of parallel work happening for parallel codegen.
11561165
// It's here that we manage parallelism, schedule work, and work with
11571166
// messages coming from clients.
@@ -1331,6 +1340,17 @@ fn start_executing_work<B: ExtraBackendMethods>(
13311340

13321341
let mut llvm_start_time: Option<VerboseTimingGuard<'_>> = None;
13331342

1343+
let compiled_allocator_module = allocator_module.and_then(|allocator_module| {
1344+
match execute_optimize_work_item(&cgcx, allocator_module) {
1345+
WorkItemResult::Finished(compiled_module) => return Some(compiled_module),
1346+
WorkItemResult::NeedsFatLto(fat_lto_input) => needs_fat_lto.push(fat_lto_input),
1347+
WorkItemResult::NeedsThinLto(name, thin_buffer) => {
1348+
needs_thin_lto.push((name, thin_buffer))
1349+
}
1350+
}
1351+
None
1352+
});
1353+
13341354
// Run the message loop while there's still anything that needs message
13351355
// processing. Note that as soon as codegen is aborted we simply want to
13361356
// wait for all existing work to finish, so many of the conditions here

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ use crate::meth::load_vtable;
4646
use crate::mir::operand::OperandValue;
4747
use crate::mir::place::PlaceRef;
4848
use crate::traits::*;
49-
use crate::{CachedModuleCodegen, CodegenLintLevels, CrateInfo, ModuleCodegen, errors, meth, mir};
49+
use crate::{
50+
CachedModuleCodegen, CodegenLintLevels, CrateInfo, ModuleCodegen, ModuleKind, errors, meth, mir,
51+
};
5052

5153
pub(crate) fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate {
5254
match (op, signed) {
@@ -1124,7 +1126,12 @@ pub fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) ->
11241126
// We can re-use either the pre- or the post-thinlto state. If no LTO is
11251127
// being performed then we can use post-LTO artifacts, otherwise we must
11261128
// reuse pre-LTO artifacts
1127-
match compute_per_cgu_lto_type(&tcx.sess.lto(), &tcx.sess.opts, tcx.crate_types()) {
1129+
match compute_per_cgu_lto_type(
1130+
&tcx.sess.lto(),
1131+
&tcx.sess.opts,
1132+
tcx.crate_types(),
1133+
ModuleKind::Regular,
1134+
) {
11281135
ComputedLtoType::No => CguReuse::PostLto,
11291136
_ => CguReuse::PreLto,
11301137
}

0 commit comments

Comments
 (0)