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