@@ -552,7 +552,8 @@ unsafe fn optimize(cgcx: &CodegenContext,
552
552
llvm:: LLVMRustAddAnalysisPasses ( tm, fpm, llmod) ;
553
553
llvm:: LLVMRustAddAnalysisPasses ( tm, mpm, llmod) ;
554
554
let opt_level = config. opt_level . unwrap_or ( llvm:: CodeGenOptLevel :: None ) ;
555
- let prepare_for_thin_lto = cgcx. lto == Lto :: Thin || cgcx. lto == Lto :: ThinLocal ;
555
+ let prepare_for_thin_lto = cgcx. lto == Lto :: Thin || cgcx. lto == Lto :: ThinLocal ||
556
+ ( cgcx. lto != Lto :: Fat && cgcx. opts . debugging_opts . cross_lang_lto . enabled ( ) ) ;
556
557
have_name_anon_globals_pass = have_name_anon_globals_pass || prepare_for_thin_lto;
557
558
if using_thin_buffers && !prepare_for_thin_lto {
558
559
assert ! ( addpass( "name-anon-globals" ) ) ;
@@ -1351,6 +1352,8 @@ fn execute_work_item(cgcx: &CodegenContext,
1351
1352
unsafe {
1352
1353
optimize ( cgcx, & diag_handler, & module, config, timeline) ?;
1353
1354
1355
+ let linker_does_lto = cgcx. opts . debugging_opts . cross_lang_lto . enabled ( ) ;
1356
+
1354
1357
// After we've done the initial round of optimizations we need to
1355
1358
// decide whether to synchronously codegen this module or ship it
1356
1359
// back to the coordinator thread for further LTO processing (which
@@ -1361,6 +1364,11 @@ fn execute_work_item(cgcx: &CodegenContext,
1361
1364
let needs_lto = match cgcx. lto {
1362
1365
Lto :: No => false ,
1363
1366
1367
+ // If the linker does LTO, we don't have to do it. Note that we
1368
+ // keep doing full LTO, if it is requested, as not to break the
1369
+ // assumption that the output will be a single module.
1370
+ Lto :: Thin | Lto :: ThinLocal if linker_does_lto => false ,
1371
+
1364
1372
// Here we've got a full crate graph LTO requested. We ignore
1365
1373
// this, however, if the crate type is only an rlib as there's
1366
1374
// no full crate graph to process, that'll happen later.
@@ -1391,11 +1399,6 @@ fn execute_work_item(cgcx: &CodegenContext,
1391
1399
// settings.
1392
1400
let needs_lto = needs_lto && module. kind != ModuleKind :: Metadata ;
1393
1401
1394
- // Don't run LTO passes when cross-lang LTO is enabled. The linker
1395
- // will do that for us in this case.
1396
- let needs_lto = needs_lto &&
1397
- !cgcx. opts . debugging_opts . cross_lang_lto . enabled ( ) ;
1398
-
1399
1402
if needs_lto {
1400
1403
Ok ( WorkItemResult :: NeedsLTO ( module) )
1401
1404
} else {
@@ -2375,8 +2378,18 @@ pub(crate) fn submit_codegened_module_to_llvm(tcx: TyCtxt,
2375
2378
}
2376
2379
2377
2380
fn msvc_imps_needed ( tcx : TyCtxt ) -> bool {
2381
+ // This should never be true (because it's not supported). If it is true,
2382
+ // something is wrong with commandline arg validation.
2383
+ assert ! ( !( tcx. sess. opts. debugging_opts. cross_lang_lto. enabled( ) &&
2384
+ tcx. sess. target. target. options. is_like_msvc &&
2385
+ tcx. sess. opts. cg. prefer_dynamic) ) ;
2386
+
2378
2387
tcx. sess . target . target . options . is_like_msvc &&
2379
- tcx. sess . crate_types . borrow ( ) . iter ( ) . any ( |ct| * ct == config:: CrateType :: Rlib )
2388
+ tcx. sess . crate_types . borrow ( ) . iter ( ) . any ( |ct| * ct == config:: CrateType :: Rlib ) &&
2389
+ // ThinLTO can't handle this workaround in all cases, so we don't
2390
+ // emit the `__imp_` symbols. Instead we make them unnecessary by disallowing
2391
+ // dynamic linking when cross-language LTO is enabled.
2392
+ !tcx. sess . opts . debugging_opts . cross_lang_lto . enabled ( )
2380
2393
}
2381
2394
2382
2395
// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
0 commit comments