@@ -545,7 +545,9 @@ unsafe fn optimize(cgcx: &CodegenContext,
545545 llvm:: LLVMRustAddAnalysisPasses ( tm, fpm, llmod) ;
546546 llvm:: LLVMRustAddAnalysisPasses ( tm, mpm, llmod) ;
547547 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 ( ) ) ;
549551 with_llvm_pmb ( llmod, & config, opt_level, prepare_for_thin_lto, & mut |b| {
550552 llvm:: LLVMPassManagerBuilderPopulateFunctionPassManager ( b, fpm) ;
551553 llvm:: LLVMPassManagerBuilderPopulateModulePassManager ( b, mpm) ;
@@ -1320,6 +1322,8 @@ fn execute_work_item(cgcx: &CodegenContext,
13201322 unsafe {
13211323 optimize ( cgcx, & diag_handler, & module, config, timeline) ?;
13221324
1325+ let linker_does_lto = cgcx. opts . debugging_opts . cross_lang_lto . enabled ( ) ;
1326+
13231327 // After we've done the initial round of optimizations we need to
13241328 // decide whether to synchronously codegen this module or ship it
13251329 // back to the coordinator thread for further LTO processing (which
@@ -1330,6 +1334,11 @@ fn execute_work_item(cgcx: &CodegenContext,
13301334 let needs_lto = match cgcx. lto {
13311335 Lto :: No => false ,
13321336
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+
13331342 // Here we've got a full crate graph LTO requested. We ignore
13341343 // this, however, if the crate type is only an rlib as there's
13351344 // no full crate graph to process, that'll happen later.
@@ -1360,11 +1369,6 @@ fn execute_work_item(cgcx: &CodegenContext,
13601369 // settings.
13611370 let needs_lto = needs_lto && module. kind != ModuleKind :: Metadata ;
13621371
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-
13681372 if needs_lto {
13691373 Ok ( WorkItemResult :: NeedsLTO ( module) )
13701374 } else {
@@ -2344,8 +2348,18 @@ pub(crate) fn submit_codegened_module_to_llvm(tcx: TyCtxt,
23442348}
23452349
23462350fn 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+
23472357 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 ( )
23492363}
23502364
23512365// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
0 commit comments