1 //===-LTOBackend.cpp - LLVM Link Time Optimizer Backend -------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the "backend" phase of LTO, i.e. it performs 10 // optimization and code generation on a loaded module. It is generally used 11 // internally by the LTO class but can also be used independently, for example 12 // to implement a standalone ThinLTO backend. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/LTO/LTOBackend.h" 17 #include "llvm/Analysis/AliasAnalysis.h" 18 #include "llvm/Analysis/CGSCCPassManager.h" 19 #include "llvm/Analysis/TargetLibraryInfo.h" 20 #include "llvm/Analysis/TargetTransformInfo.h" 21 #include "llvm/Bitcode/BitcodeReader.h" 22 #include "llvm/Bitcode/BitcodeWriter.h" 23 #include "llvm/IR/LLVMRemarkStreamer.h" 24 #include "llvm/IR/LegacyPassManager.h" 25 #include "llvm/IR/PassManager.h" 26 #include "llvm/IR/Verifier.h" 27 #include "llvm/LTO/LTO.h" 28 #include "llvm/MC/SubtargetFeature.h" 29 #include "llvm/Object/ModuleSymbolTable.h" 30 #include "llvm/Passes/PassBuilder.h" 31 #include "llvm/Passes/PassPlugin.h" 32 #include "llvm/Passes/StandardInstrumentations.h" 33 #include "llvm/Support/Error.h" 34 #include "llvm/Support/FileSystem.h" 35 #include "llvm/Support/MemoryBuffer.h" 36 #include "llvm/Support/Path.h" 37 #include "llvm/Support/Program.h" 38 #include "llvm/Support/SmallVectorMemoryBuffer.h" 39 #include "llvm/Support/TargetRegistry.h" 40 #include "llvm/Support/ThreadPool.h" 41 #include "llvm/Support/raw_ostream.h" 42 #include "llvm/Target/TargetMachine.h" 43 #include "llvm/Transforms/IPO.h" 44 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 45 #include "llvm/Transforms/Scalar/LoopPassManager.h" 46 #include "llvm/Transforms/Utils/FunctionImportUtils.h" 47 #include "llvm/Transforms/Utils/SplitModule.h" 48 49 using namespace llvm; 50 using namespace lto; 51 52 LLVM_ATTRIBUTE_NORETURN static void reportOpenError(StringRef Path, Twine Msg) { 53 errs() << "failed to open " << Path << ": " << Msg << '\n'; 54 errs().flush(); 55 exit(1); 56 } 57 58 Error Config::addSaveTemps(std::string OutputFileName, 59 bool UseInputModulePath) { 60 ShouldDiscardValueNames = false; 61 62 std::error_code EC; 63 ResolutionFile = std::make_unique<raw_fd_ostream>( 64 OutputFileName + "resolution.txt", EC, sys::fs::OpenFlags::OF_Text); 65 if (EC) { 66 ResolutionFile.reset(); 67 return errorCodeToError(EC); 68 } 69 70 auto setHook = [&](std::string PathSuffix, ModuleHookFn &Hook) { 71 // Keep track of the hook provided by the linker, which also needs to run. 72 ModuleHookFn LinkerHook = Hook; 73 Hook = [=](unsigned Task, const Module &M) { 74 // If the linker's hook returned false, we need to pass that result 75 // through. 76 if (LinkerHook && !LinkerHook(Task, M)) 77 return false; 78 79 std::string PathPrefix; 80 // If this is the combined module (not a ThinLTO backend compile) or the 81 // user hasn't requested using the input module's path, emit to a file 82 // named from the provided OutputFileName with the Task ID appended. 83 if (M.getModuleIdentifier() == "ld-temp.o" || !UseInputModulePath) { 84 PathPrefix = OutputFileName; 85 if (Task != (unsigned)-1) 86 PathPrefix += utostr(Task) + "."; 87 } else 88 PathPrefix = M.getModuleIdentifier() + "."; 89 std::string Path = PathPrefix + PathSuffix + ".bc"; 90 std::error_code EC; 91 raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::OF_None); 92 // Because -save-temps is a debugging feature, we report the error 93 // directly and exit. 94 if (EC) 95 reportOpenError(Path, EC.message()); 96 WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false); 97 return true; 98 }; 99 }; 100 101 setHook("0.preopt", PreOptModuleHook); 102 setHook("1.promote", PostPromoteModuleHook); 103 setHook("2.internalize", PostInternalizeModuleHook); 104 setHook("3.import", PostImportModuleHook); 105 setHook("4.opt", PostOptModuleHook); 106 setHook("5.precodegen", PreCodeGenModuleHook); 107 108 CombinedIndexHook = 109 [=](const ModuleSummaryIndex &Index, 110 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) { 111 std::string Path = OutputFileName + "index.bc"; 112 std::error_code EC; 113 raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::OF_None); 114 // Because -save-temps is a debugging feature, we report the error 115 // directly and exit. 116 if (EC) 117 reportOpenError(Path, EC.message()); 118 WriteIndexToFile(Index, OS); 119 120 Path = OutputFileName + "index.dot"; 121 raw_fd_ostream OSDot(Path, EC, sys::fs::OpenFlags::OF_None); 122 if (EC) 123 reportOpenError(Path, EC.message()); 124 Index.exportToDot(OSDot, GUIDPreservedSymbols); 125 return true; 126 }; 127 128 return Error::success(); 129 } 130 131 #define HANDLE_EXTENSION(Ext) \ 132 llvm::PassPluginLibraryInfo get##Ext##PluginInfo(); 133 #include "llvm/Support/Extension.def" 134 135 static void RegisterPassPlugins(ArrayRef<std::string> PassPlugins, 136 PassBuilder &PB) { 137 #define HANDLE_EXTENSION(Ext) \ 138 get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB); 139 #include "llvm/Support/Extension.def" 140 141 // Load requested pass plugins and let them register pass builder callbacks 142 for (auto &PluginFN : PassPlugins) { 143 auto PassPlugin = PassPlugin::Load(PluginFN); 144 if (!PassPlugin) { 145 errs() << "Failed to load passes from '" << PluginFN 146 << "'. Request ignored.\n"; 147 continue; 148 } 149 150 PassPlugin->registerPassBuilderCallbacks(PB); 151 } 152 } 153 154 namespace { 155 156 std::unique_ptr<TargetMachine> 157 createTargetMachine(const Config &Conf, const Target *TheTarget, Module &M) { 158 StringRef TheTriple = M.getTargetTriple(); 159 SubtargetFeatures Features; 160 Features.getDefaultSubtargetFeatures(Triple(TheTriple)); 161 for (const std::string &A : Conf.MAttrs) 162 Features.AddFeature(A); 163 164 Reloc::Model RelocModel; 165 if (Conf.RelocModel) 166 RelocModel = *Conf.RelocModel; 167 else 168 RelocModel = 169 M.getPICLevel() == PICLevel::NotPIC ? Reloc::Static : Reloc::PIC_; 170 171 Optional<CodeModel::Model> CodeModel; 172 if (Conf.CodeModel) 173 CodeModel = *Conf.CodeModel; 174 else 175 CodeModel = M.getCodeModel(); 176 177 return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine( 178 TheTriple, Conf.CPU, Features.getString(), Conf.Options, RelocModel, 179 CodeModel, Conf.CGOptLevel)); 180 } 181 182 static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, 183 unsigned OptLevel, bool IsThinLTO, 184 ModuleSummaryIndex *ExportSummary, 185 const ModuleSummaryIndex *ImportSummary) { 186 Optional<PGOOptions> PGOOpt; 187 if (!Conf.SampleProfile.empty()) 188 PGOOpt = PGOOptions(Conf.SampleProfile, "", Conf.ProfileRemapping, 189 PGOOptions::SampleUse, PGOOptions::NoCSAction, true); 190 else if (Conf.RunCSIRInstr) { 191 PGOOpt = PGOOptions("", Conf.CSIRProfile, Conf.ProfileRemapping, 192 PGOOptions::IRUse, PGOOptions::CSIRInstr); 193 } else if (!Conf.CSIRProfile.empty()) { 194 PGOOpt = PGOOptions(Conf.CSIRProfile, "", Conf.ProfileRemapping, 195 PGOOptions::IRUse, PGOOptions::CSIRUse); 196 } 197 198 PassInstrumentationCallbacks PIC; 199 StandardInstrumentations SI; 200 SI.registerCallbacks(PIC); 201 PassBuilder PB(TM, Conf.PTO, PGOOpt, &PIC); 202 AAManager AA; 203 204 // Parse a custom AA pipeline if asked to. 205 if (auto Err = PB.parseAAPipeline(AA, "default")) 206 report_fatal_error("Error parsing default AA pipeline"); 207 208 RegisterPassPlugins(Conf.PassPlugins, PB); 209 210 LoopAnalysisManager LAM(Conf.DebugPassManager); 211 FunctionAnalysisManager FAM(Conf.DebugPassManager); 212 CGSCCAnalysisManager CGAM(Conf.DebugPassManager); 213 ModuleAnalysisManager MAM(Conf.DebugPassManager); 214 215 // Register the AA manager first so that our version is the one used. 216 FAM.registerPass([&] { return std::move(AA); }); 217 218 // Register all the basic analyses with the managers. 219 PB.registerModuleAnalyses(MAM); 220 PB.registerCGSCCAnalyses(CGAM); 221 PB.registerFunctionAnalyses(FAM); 222 PB.registerLoopAnalyses(LAM); 223 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); 224 225 ModulePassManager MPM(Conf.DebugPassManager); 226 // FIXME (davide): verify the input. 227 228 PassBuilder::OptimizationLevel OL; 229 230 switch (OptLevel) { 231 default: 232 llvm_unreachable("Invalid optimization level"); 233 case 0: 234 OL = PassBuilder::OptimizationLevel::O0; 235 break; 236 case 1: 237 OL = PassBuilder::OptimizationLevel::O1; 238 break; 239 case 2: 240 OL = PassBuilder::OptimizationLevel::O2; 241 break; 242 case 3: 243 OL = PassBuilder::OptimizationLevel::O3; 244 break; 245 } 246 247 if (IsThinLTO) 248 MPM = PB.buildThinLTODefaultPipeline(OL, Conf.DebugPassManager, 249 ImportSummary); 250 else 251 MPM = PB.buildLTODefaultPipeline(OL, Conf.DebugPassManager, ExportSummary); 252 MPM.run(Mod, MAM); 253 254 // FIXME (davide): verify the output. 255 } 256 257 static void runNewPMCustomPasses(const Config &Conf, Module &Mod, 258 TargetMachine *TM, std::string PipelineDesc, 259 std::string AAPipelineDesc, 260 bool DisableVerify) { 261 PassBuilder PB(TM); 262 AAManager AA; 263 264 // Parse a custom AA pipeline if asked to. 265 if (!AAPipelineDesc.empty()) 266 if (auto Err = PB.parseAAPipeline(AA, AAPipelineDesc)) 267 report_fatal_error("unable to parse AA pipeline description '" + 268 AAPipelineDesc + "': " + toString(std::move(Err))); 269 270 RegisterPassPlugins(Conf.PassPlugins, PB); 271 272 LoopAnalysisManager LAM; 273 FunctionAnalysisManager FAM; 274 CGSCCAnalysisManager CGAM; 275 ModuleAnalysisManager MAM; 276 277 // Register the AA manager first so that our version is the one used. 278 FAM.registerPass([&] { return std::move(AA); }); 279 280 // Register all the basic analyses with the managers. 281 PB.registerModuleAnalyses(MAM); 282 PB.registerCGSCCAnalyses(CGAM); 283 PB.registerFunctionAnalyses(FAM); 284 PB.registerLoopAnalyses(LAM); 285 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); 286 287 ModulePassManager MPM; 288 289 // Always verify the input. 290 MPM.addPass(VerifierPass()); 291 292 // Now, add all the passes we've been requested to. 293 if (auto Err = PB.parsePassPipeline(MPM, PipelineDesc)) 294 report_fatal_error("unable to parse pass pipeline description '" + 295 PipelineDesc + "': " + toString(std::move(Err))); 296 297 if (!DisableVerify) 298 MPM.addPass(VerifierPass()); 299 MPM.run(Mod, MAM); 300 } 301 302 static void runOldPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, 303 bool IsThinLTO, ModuleSummaryIndex *ExportSummary, 304 const ModuleSummaryIndex *ImportSummary) { 305 legacy::PassManager passes; 306 passes.add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis())); 307 308 PassManagerBuilder PMB; 309 PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM->getTargetTriple())); 310 PMB.Inliner = createFunctionInliningPass(); 311 PMB.ExportSummary = ExportSummary; 312 PMB.ImportSummary = ImportSummary; 313 // Unconditionally verify input since it is not verified before this 314 // point and has unknown origin. 315 PMB.VerifyInput = true; 316 PMB.VerifyOutput = !Conf.DisableVerify; 317 PMB.LoopVectorize = true; 318 PMB.SLPVectorize = true; 319 PMB.OptLevel = Conf.OptLevel; 320 PMB.PGOSampleUse = Conf.SampleProfile; 321 PMB.EnablePGOCSInstrGen = Conf.RunCSIRInstr; 322 if (!Conf.RunCSIRInstr && !Conf.CSIRProfile.empty()) { 323 PMB.EnablePGOCSInstrUse = true; 324 PMB.PGOInstrUse = Conf.CSIRProfile; 325 } 326 if (IsThinLTO) 327 PMB.populateThinLTOPassManager(passes); 328 else 329 PMB.populateLTOPassManager(passes); 330 passes.run(Mod); 331 } 332 333 bool opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod, 334 bool IsThinLTO, ModuleSummaryIndex *ExportSummary, 335 const ModuleSummaryIndex *ImportSummary) { 336 // FIXME: Plumb the combined index into the new pass manager. 337 if (!Conf.OptPipeline.empty()) 338 runNewPMCustomPasses(Conf, Mod, TM, Conf.OptPipeline, Conf.AAPipeline, 339 Conf.DisableVerify); 340 else if (Conf.UseNewPM) 341 runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO, ExportSummary, 342 ImportSummary); 343 else 344 runOldPMPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary); 345 return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod); 346 } 347 348 static cl::opt<bool> EmbedBitcode( 349 "lto-embed-bitcode", cl::init(false), 350 cl::desc("Embed LLVM bitcode in object files produced by LTO")); 351 352 static void EmitBitcodeSection(Module &M, const Config &Conf) { 353 if (!EmbedBitcode) 354 return; 355 SmallVector<char, 0> Buffer; 356 raw_svector_ostream OS(Buffer); 357 WriteBitcodeToFile(M, OS); 358 359 std::unique_ptr<MemoryBuffer> Buf( 360 new SmallVectorMemoryBuffer(std::move(Buffer))); 361 llvm::EmbedBitcodeInModule(M, Buf->getMemBufferRef(), /*EmbedBitcode*/ true, 362 /*EmbedMarker*/ false, /*CmdArgs*/ nullptr); 363 } 364 365 void codegen(const Config &Conf, TargetMachine *TM, AddStreamFn AddStream, 366 unsigned Task, Module &Mod) { 367 if (Conf.PreCodeGenModuleHook && !Conf.PreCodeGenModuleHook(Task, Mod)) 368 return; 369 370 EmitBitcodeSection(Mod, Conf); 371 372 std::unique_ptr<ToolOutputFile> DwoOut; 373 SmallString<1024> DwoFile(Conf.SplitDwarfOutput); 374 if (!Conf.DwoDir.empty()) { 375 std::error_code EC; 376 if (auto EC = llvm::sys::fs::create_directories(Conf.DwoDir)) 377 report_fatal_error("Failed to create directory " + Conf.DwoDir + ": " + 378 EC.message()); 379 380 DwoFile = Conf.DwoDir; 381 sys::path::append(DwoFile, std::to_string(Task) + ".dwo"); 382 TM->Options.MCOptions.SplitDwarfFile = std::string(DwoFile); 383 } else 384 TM->Options.MCOptions.SplitDwarfFile = Conf.SplitDwarfFile; 385 386 if (!DwoFile.empty()) { 387 std::error_code EC; 388 DwoOut = std::make_unique<ToolOutputFile>(DwoFile, EC, sys::fs::OF_None); 389 if (EC) 390 report_fatal_error("Failed to open " + DwoFile + ": " + EC.message()); 391 } 392 393 auto Stream = AddStream(Task); 394 legacy::PassManager CodeGenPasses; 395 if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS, 396 DwoOut ? &DwoOut->os() : nullptr, 397 Conf.CGFileType)) 398 report_fatal_error("Failed to setup codegen"); 399 CodeGenPasses.run(Mod); 400 401 if (DwoOut) 402 DwoOut->keep(); 403 } 404 405 void splitCodeGen(const Config &C, TargetMachine *TM, AddStreamFn AddStream, 406 unsigned ParallelCodeGenParallelismLevel, 407 std::unique_ptr<Module> Mod) { 408 ThreadPool CodegenThreadPool( 409 heavyweight_hardware_concurrency(ParallelCodeGenParallelismLevel)); 410 unsigned ThreadCount = 0; 411 const Target *T = &TM->getTarget(); 412 413 SplitModule( 414 std::move(Mod), ParallelCodeGenParallelismLevel, 415 [&](std::unique_ptr<Module> MPart) { 416 // We want to clone the module in a new context to multi-thread the 417 // codegen. We do it by serializing partition modules to bitcode 418 // (while still on the main thread, in order to avoid data races) and 419 // spinning up new threads which deserialize the partitions into 420 // separate contexts. 421 // FIXME: Provide a more direct way to do this in LLVM. 422 SmallString<0> BC; 423 raw_svector_ostream BCOS(BC); 424 WriteBitcodeToFile(*MPart, BCOS); 425 426 // Enqueue the task 427 CodegenThreadPool.async( 428 [&](const SmallString<0> &BC, unsigned ThreadId) { 429 LTOLLVMContext Ctx(C); 430 Expected<std::unique_ptr<Module>> MOrErr = parseBitcodeFile( 431 MemoryBufferRef(StringRef(BC.data(), BC.size()), "ld-temp.o"), 432 Ctx); 433 if (!MOrErr) 434 report_fatal_error("Failed to read bitcode"); 435 std::unique_ptr<Module> MPartInCtx = std::move(MOrErr.get()); 436 437 std::unique_ptr<TargetMachine> TM = 438 createTargetMachine(C, T, *MPartInCtx); 439 440 codegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx); 441 }, 442 // Pass BC using std::move to ensure that it get moved rather than 443 // copied into the thread's context. 444 std::move(BC), ThreadCount++); 445 }, 446 false); 447 448 // Because the inner lambda (which runs in a worker thread) captures our local 449 // variables, we need to wait for the worker threads to terminate before we 450 // can leave the function scope. 451 CodegenThreadPool.wait(); 452 } 453 454 Expected<const Target *> initAndLookupTarget(const Config &C, Module &Mod) { 455 if (!C.OverrideTriple.empty()) 456 Mod.setTargetTriple(C.OverrideTriple); 457 else if (Mod.getTargetTriple().empty()) 458 Mod.setTargetTriple(C.DefaultTriple); 459 460 std::string Msg; 461 const Target *T = TargetRegistry::lookupTarget(Mod.getTargetTriple(), Msg); 462 if (!T) 463 return make_error<StringError>(Msg, inconvertibleErrorCode()); 464 return T; 465 } 466 } 467 468 Error lto::finalizeOptimizationRemarks( 469 std::unique_ptr<ToolOutputFile> DiagOutputFile) { 470 // Make sure we flush the diagnostic remarks file in case the linker doesn't 471 // call the global destructors before exiting. 472 if (!DiagOutputFile) 473 return Error::success(); 474 DiagOutputFile->keep(); 475 DiagOutputFile->os().flush(); 476 return Error::success(); 477 } 478 479 Error lto::backend(const Config &C, AddStreamFn AddStream, 480 unsigned ParallelCodeGenParallelismLevel, 481 std::unique_ptr<Module> Mod, 482 ModuleSummaryIndex &CombinedIndex) { 483 Expected<const Target *> TOrErr = initAndLookupTarget(C, *Mod); 484 if (!TOrErr) 485 return TOrErr.takeError(); 486 487 std::unique_ptr<TargetMachine> TM = createTargetMachine(C, *TOrErr, *Mod); 488 489 if (!C.CodeGenOnly) { 490 if (!opt(C, TM.get(), 0, *Mod, /*IsThinLTO=*/false, 491 /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr)) 492 return Error::success(); 493 } 494 495 if (ParallelCodeGenParallelismLevel == 1) { 496 codegen(C, TM.get(), AddStream, 0, *Mod); 497 } else { 498 splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLevel, 499 std::move(Mod)); 500 } 501 return Error::success(); 502 } 503 504 static void dropDeadSymbols(Module &Mod, const GVSummaryMapTy &DefinedGlobals, 505 const ModuleSummaryIndex &Index) { 506 std::vector<GlobalValue*> DeadGVs; 507 for (auto &GV : Mod.global_values()) 508 if (GlobalValueSummary *GVS = DefinedGlobals.lookup(GV.getGUID())) 509 if (!Index.isGlobalValueLive(GVS)) { 510 DeadGVs.push_back(&GV); 511 convertToDeclaration(GV); 512 } 513 514 // Now that all dead bodies have been dropped, delete the actual objects 515 // themselves when possible. 516 for (GlobalValue *GV : DeadGVs) { 517 GV->removeDeadConstantUsers(); 518 // Might reference something defined in native object (i.e. dropped a 519 // non-prevailing IR def, but we need to keep the declaration). 520 if (GV->use_empty()) 521 GV->eraseFromParent(); 522 } 523 } 524 525 Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream, 526 Module &Mod, const ModuleSummaryIndex &CombinedIndex, 527 const FunctionImporter::ImportMapTy &ImportList, 528 const GVSummaryMapTy &DefinedGlobals, 529 MapVector<StringRef, BitcodeModule> &ModuleMap) { 530 Expected<const Target *> TOrErr = initAndLookupTarget(Conf, Mod); 531 if (!TOrErr) 532 return TOrErr.takeError(); 533 534 std::unique_ptr<TargetMachine> TM = createTargetMachine(Conf, *TOrErr, Mod); 535 536 // Setup optimization remarks. 537 auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks( 538 Mod.getContext(), Conf.RemarksFilename, Conf.RemarksPasses, 539 Conf.RemarksFormat, Conf.RemarksWithHotness, Task); 540 if (!DiagFileOrErr) 541 return DiagFileOrErr.takeError(); 542 auto DiagnosticOutputFile = std::move(*DiagFileOrErr); 543 544 if (Conf.CodeGenOnly) { 545 codegen(Conf, TM.get(), AddStream, Task, Mod); 546 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); 547 } 548 549 if (Conf.PreOptModuleHook && !Conf.PreOptModuleHook(Task, Mod)) 550 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); 551 552 // When linking an ELF shared object, dso_local should be dropped. We 553 // conservatively do this for -fpic. 554 bool ClearDSOLocalOnDeclarations = 555 TM->getTargetTriple().isOSBinFormatELF() && 556 TM->getRelocationModel() != Reloc::Static && 557 Mod.getPIELevel() == PIELevel::Default; 558 renameModuleForThinLTO(Mod, CombinedIndex, ClearDSOLocalOnDeclarations); 559 560 dropDeadSymbols(Mod, DefinedGlobals, CombinedIndex); 561 562 thinLTOResolvePrevailingInModule(Mod, DefinedGlobals); 563 564 if (Conf.PostPromoteModuleHook && !Conf.PostPromoteModuleHook(Task, Mod)) 565 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); 566 567 if (!DefinedGlobals.empty()) 568 thinLTOInternalizeModule(Mod, DefinedGlobals); 569 570 if (Conf.PostInternalizeModuleHook && 571 !Conf.PostInternalizeModuleHook(Task, Mod)) 572 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); 573 574 auto ModuleLoader = [&](StringRef Identifier) { 575 assert(Mod.getContext().isODRUniquingDebugTypes() && 576 "ODR Type uniquing should be enabled on the context"); 577 auto I = ModuleMap.find(Identifier); 578 assert(I != ModuleMap.end()); 579 return I->second.getLazyModule(Mod.getContext(), 580 /*ShouldLazyLoadMetadata=*/true, 581 /*IsImporting*/ true); 582 }; 583 584 FunctionImporter Importer(CombinedIndex, ModuleLoader, 585 ClearDSOLocalOnDeclarations); 586 if (Error Err = Importer.importFunctions(Mod, ImportList).takeError()) 587 return Err; 588 589 if (Conf.PostImportModuleHook && !Conf.PostImportModuleHook(Task, Mod)) 590 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); 591 592 if (!opt(Conf, TM.get(), Task, Mod, /*IsThinLTO=*/true, 593 /*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex)) 594 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); 595 596 codegen(Conf, TM.get(), AddStream, Task, Mod); 597 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); 598 } 599