@@ -546,7 +546,9 @@ unsafe fn optimize(cgcx: &CodegenContext,
546
546
llvm:: LLVMRustAddAnalysisPasses ( tm, fpm, llmod) ;
547
547
llvm:: LLVMRustAddAnalysisPasses ( tm, mpm, llmod) ;
548
548
let opt_level = config. opt_level . unwrap_or ( llvm:: CodeGenOptLevel :: None ) ;
549
- let prepare_for_thin_lto = cgcx. lto == Lto :: Thin || cgcx. lto == Lto :: ThinLocal ;
549
+ let prepare_for_thin_lto = cgcx. lto == Lto :: Thin ||
550
+ cgcx. lto == Lto :: ThinLocal ||
551
+ ( cgcx. lto != Lto :: Fat && cgcx. opts . debugging_opts . cross_lang_lto . enabled ( ) ) ;
550
552
with_llvm_pmb ( llmod, & config, opt_level, prepare_for_thin_lto, & mut |b| {
551
553
llvm:: LLVMPassManagerBuilderPopulateFunctionPassManager ( b, fpm) ;
552
554
llvm:: LLVMPassManagerBuilderPopulateModulePassManager ( b, mpm) ;
@@ -1321,6 +1323,8 @@ fn execute_work_item(cgcx: &CodegenContext,
1321
1323
unsafe {
1322
1324
optimize ( cgcx, & diag_handler, & module, config, timeline) ?;
1323
1325
1326
+ let linker_does_lto = cgcx. opts . debugging_opts . cross_lang_lto . enabled ( ) ;
1327
+
1324
1328
// After we've done the initial round of optimizations we need to
1325
1329
// decide whether to synchronously codegen this module or ship it
1326
1330
// back to the coordinator thread for further LTO processing (which
@@ -1331,6 +1335,11 @@ fn execute_work_item(cgcx: &CodegenContext,
1331
1335
let needs_lto = match cgcx. lto {
1332
1336
Lto :: No => false ,
1333
1337
1338
+ // If the linker does LTO, we don't have to do it. Note that we
1339
+ // keep doing full LTO, if it is requested, as not to break the
1340
+ // assumption that the output will be a single module.
1341
+ Lto :: Thin | Lto :: ThinLocal if linker_does_lto => false ,
1342
+
1334
1343
// Here we've got a full crate graph LTO requested. We ignore
1335
1344
// this, however, if the crate type is only an rlib as there's
1336
1345
// no full crate graph to process, that'll happen later.
@@ -1361,11 +1370,6 @@ fn execute_work_item(cgcx: &CodegenContext,
1361
1370
// settings.
1362
1371
let needs_lto = needs_lto && module. kind != ModuleKind :: Metadata ;
1363
1372
1364
- // Don't run LTO passes when cross-lang LTO is enabled. The linker
1365
- // will do that for us in this case.
1366
- let needs_lto = needs_lto &&
1367
- !cgcx. opts . debugging_opts . cross_lang_lto . enabled ( ) ;
1368
-
1369
1373
if needs_lto {
1370
1374
Ok ( WorkItemResult :: NeedsLTO ( module) )
1371
1375
} else {
@@ -2345,8 +2349,18 @@ pub(crate) fn submit_codegened_module_to_llvm(tcx: TyCtxt,
2345
2349
}
2346
2350
2347
2351
fn msvc_imps_needed ( tcx : TyCtxt ) -> bool {
2352
+ // This should never be true (because it's not supported). If it is true,
2353
+ // something is wrong with commandline arg validation.
2354
+ assert ! ( !( tcx. sess. opts. debugging_opts. cross_lang_lto. enabled( ) &&
2355
+ tcx. sess. target. target. options. is_like_msvc &&
2356
+ tcx. sess. opts. cg. prefer_dynamic) ) ;
2357
+
2348
2358
tcx. sess . target . target . options . is_like_msvc &&
2349
- tcx. sess . crate_types . borrow ( ) . iter ( ) . any ( |ct| * ct == config:: CrateTypeRlib )
2359
+ tcx. sess . crate_types . borrow ( ) . iter ( ) . any ( |ct| * ct == config:: CrateTypeRlib ) &&
2360
+ // ThinLTO can't handle this workaround in all cases, so we don't
2361
+ // emit the `__imp_` symbols. Instead we make them unnecessary by disallowing
2362
+ // dynamic linking when cross-language LTO is enabled.
2363
+ !tcx. sess . opts . debugging_opts . cross_lang_lto . enabled ( )
2350
2364
}
2351
2365
2352
2366
// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
0 commit comments