1 //===-LTOCodeGenerator.cpp - LLVM Link Time Optimizer ---------------------===// 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 Link Time Optimization library. This library is 10 // intended to be used by linker to optimize code at link time. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/LTO/legacy/LTOCodeGenerator.h" 15 16 #include "llvm/ADT/Statistic.h" 17 #include "llvm/ADT/StringExtras.h" 18 #include "llvm/Analysis/Passes.h" 19 #include "llvm/Analysis/TargetLibraryInfo.h" 20 #include "llvm/Analysis/TargetTransformInfo.h" 21 #include "llvm/Bitcode/BitcodeWriter.h" 22 #include "llvm/CodeGen/CommandFlags.h" 23 #include "llvm/CodeGen/TargetSubtargetInfo.h" 24 #include "llvm/Config/config.h" 25 #include "llvm/IR/Constants.h" 26 #include "llvm/IR/DataLayout.h" 27 #include "llvm/IR/DebugInfo.h" 28 #include "llvm/IR/DerivedTypes.h" 29 #include "llvm/IR/DiagnosticInfo.h" 30 #include "llvm/IR/DiagnosticPrinter.h" 31 #include "llvm/IR/LLVMContext.h" 32 #include "llvm/IR/LLVMRemarkStreamer.h" 33 #include "llvm/IR/LegacyPassManager.h" 34 #include "llvm/IR/Mangler.h" 35 #include "llvm/IR/Module.h" 36 #include "llvm/IR/PassTimingInfo.h" 37 #include "llvm/IR/Verifier.h" 38 #include "llvm/LTO/LTO.h" 39 #include "llvm/LTO/LTOBackend.h" 40 #include "llvm/LTO/legacy/LTOModule.h" 41 #include "llvm/LTO/legacy/UpdateCompilerUsed.h" 42 #include "llvm/Linker/Linker.h" 43 #include "llvm/MC/MCAsmInfo.h" 44 #include "llvm/MC/MCContext.h" 45 #include "llvm/MC/TargetRegistry.h" 46 #include "llvm/Remarks/HotnessThresholdParser.h" 47 #include "llvm/Support/CommandLine.h" 48 #include "llvm/Support/FileSystem.h" 49 #include "llvm/Support/MemoryBuffer.h" 50 #include "llvm/Support/Process.h" 51 #include "llvm/Support/Signals.h" 52 #include "llvm/Support/TargetSelect.h" 53 #include "llvm/Support/ToolOutputFile.h" 54 #include "llvm/Support/YAMLTraits.h" 55 #include "llvm/Support/raw_ostream.h" 56 #include "llvm/Target/TargetOptions.h" 57 #include "llvm/TargetParser/Host.h" 58 #include "llvm/TargetParser/SubtargetFeature.h" 59 #include "llvm/Transforms/IPO.h" 60 #include "llvm/Transforms/IPO/Internalize.h" 61 #include "llvm/Transforms/IPO/WholeProgramDevirt.h" 62 #include "llvm/Transforms/ObjCARC.h" 63 #include "llvm/Transforms/Utils/ModuleUtils.h" 64 #include <optional> 65 #include <system_error> 66 using namespace llvm; 67 68 const char* LTOCodeGenerator::getVersionString() { 69 return PACKAGE_NAME " version " PACKAGE_VERSION; 70 } 71 72 namespace llvm { 73 cl::opt<bool> LTODiscardValueNames( 74 "lto-discard-value-names", 75 cl::desc("Strip names from Value during LTO (other than GlobalValue)."), 76 #ifdef NDEBUG 77 cl::init(true), 78 #else 79 cl::init(false), 80 #endif 81 cl::Hidden); 82 83 cl::opt<bool> RemarksWithHotness( 84 "lto-pass-remarks-with-hotness", 85 cl::desc("With PGO, include profile count in optimization remarks"), 86 cl::Hidden); 87 88 cl::opt<std::optional<uint64_t>, false, remarks::HotnessThresholdParser> 89 RemarksHotnessThreshold( 90 "lto-pass-remarks-hotness-threshold", 91 cl::desc("Minimum profile count required for an " 92 "optimization remark to be output." 93 " Use 'auto' to apply the threshold from profile summary."), 94 cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden); 95 96 cl::opt<std::string> 97 RemarksFilename("lto-pass-remarks-output", 98 cl::desc("Output filename for pass remarks"), 99 cl::value_desc("filename")); 100 101 cl::opt<std::string> 102 RemarksPasses("lto-pass-remarks-filter", 103 cl::desc("Only record optimization remarks from passes whose " 104 "names match the given regular expression"), 105 cl::value_desc("regex")); 106 107 cl::opt<std::string> RemarksFormat( 108 "lto-pass-remarks-format", 109 cl::desc("The format used for serializing remarks (default: YAML)"), 110 cl::value_desc("format"), cl::init("yaml")); 111 112 cl::opt<std::string> LTOStatsFile( 113 "lto-stats-file", 114 cl::desc("Save statistics to the specified file"), 115 cl::Hidden); 116 117 cl::opt<std::string> AIXSystemAssemblerPath( 118 "lto-aix-system-assembler", 119 cl::desc("Path to a system assembler, picked up on AIX only"), 120 cl::value_desc("path")); 121 122 cl::opt<bool> 123 LTORunCSIRInstr("cs-profile-generate", 124 cl::desc("Perform context sensitive PGO instrumentation")); 125 126 cl::opt<std::string> 127 LTOCSIRProfile("cs-profile-path", 128 cl::desc("Context sensitive profile file path")); 129 } // namespace llvm 130 131 LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context) 132 : Context(Context), MergedModule(new Module("ld-temp.o", Context)), 133 TheLinker(new Linker(*MergedModule)) { 134 Context.setDiscardValueNames(LTODiscardValueNames); 135 Context.enableDebugTypeODRUniquing(); 136 137 Config.CodeModel = std::nullopt; 138 Config.StatsFile = LTOStatsFile; 139 Config.PreCodeGenPassesHook = [](legacy::PassManager &PM) { 140 PM.add(createObjCARCContractPass()); 141 }; 142 143 Config.RunCSIRInstr = LTORunCSIRInstr; 144 Config.CSIRProfile = LTOCSIRProfile; 145 } 146 147 LTOCodeGenerator::~LTOCodeGenerator() = default; 148 149 void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) { 150 for (const StringRef &Undef : Mod->getAsmUndefinedRefs()) 151 AsmUndefinedRefs.insert(Undef); 152 } 153 154 bool LTOCodeGenerator::addModule(LTOModule *Mod) { 155 assert(&Mod->getModule().getContext() == &Context && 156 "Expected module in same context"); 157 158 bool ret = TheLinker->linkInModule(Mod->takeModule()); 159 setAsmUndefinedRefs(Mod); 160 161 // We've just changed the input, so let's make sure we verify it. 162 HasVerifiedInput = false; 163 164 return !ret; 165 } 166 167 void LTOCodeGenerator::setModule(std::unique_ptr<LTOModule> Mod) { 168 assert(&Mod->getModule().getContext() == &Context && 169 "Expected module in same context"); 170 171 AsmUndefinedRefs.clear(); 172 173 MergedModule = Mod->takeModule(); 174 TheLinker = std::make_unique<Linker>(*MergedModule); 175 setAsmUndefinedRefs(&*Mod); 176 177 // We've just changed the input, so let's make sure we verify it. 178 HasVerifiedInput = false; 179 } 180 181 void LTOCodeGenerator::setTargetOptions(const TargetOptions &Options) { 182 Config.Options = Options; 183 } 184 185 void LTOCodeGenerator::setDebugInfo(lto_debug_model Debug) { 186 switch (Debug) { 187 case LTO_DEBUG_MODEL_NONE: 188 EmitDwarfDebugInfo = false; 189 return; 190 191 case LTO_DEBUG_MODEL_DWARF: 192 EmitDwarfDebugInfo = true; 193 return; 194 } 195 llvm_unreachable("Unknown debug format!"); 196 } 197 198 void LTOCodeGenerator::setOptLevel(unsigned Level) { 199 Config.OptLevel = Level; 200 Config.PTO.LoopVectorization = Config.OptLevel > 1; 201 Config.PTO.SLPVectorization = Config.OptLevel > 1; 202 std::optional<CodeGenOptLevel> CGOptLevelOrNone = 203 CodeGenOpt::getLevel(Config.OptLevel); 204 assert(CGOptLevelOrNone && "Unknown optimization level!"); 205 Config.CGOptLevel = *CGOptLevelOrNone; 206 } 207 208 bool LTOCodeGenerator::writeMergedModules(StringRef Path) { 209 if (!determineTarget()) 210 return false; 211 212 // We always run the verifier once on the merged module. 213 verifyMergedModuleOnce(); 214 215 // mark which symbols can not be internalized 216 applyScopeRestrictions(); 217 218 // create output file 219 std::error_code EC; 220 ToolOutputFile Out(Path, EC, sys::fs::OF_None); 221 if (EC) { 222 std::string ErrMsg = "could not open bitcode file for writing: "; 223 ErrMsg += Path.str() + ": " + EC.message(); 224 emitError(ErrMsg); 225 return false; 226 } 227 228 // write bitcode to it 229 WriteBitcodeToFile(*MergedModule, Out.os(), ShouldEmbedUselists); 230 Out.os().close(); 231 232 if (Out.os().has_error()) { 233 std::string ErrMsg = "could not write bitcode file: "; 234 ErrMsg += Path.str() + ": " + Out.os().error().message(); 235 emitError(ErrMsg); 236 Out.os().clear_error(); 237 return false; 238 } 239 240 Out.keep(); 241 return true; 242 } 243 244 bool LTOCodeGenerator::useAIXSystemAssembler() { 245 const auto &Triple = TargetMach->getTargetTriple(); 246 return Triple.isOSAIX() && Config.Options.DisableIntegratedAS; 247 } 248 249 bool LTOCodeGenerator::runAIXSystemAssembler(SmallString<128> &AssemblyFile) { 250 assert(useAIXSystemAssembler() && 251 "Runing AIX system assembler when integrated assembler is available!"); 252 253 // Set the system assembler path. 254 SmallString<256> AssemblerPath("/usr/bin/as"); 255 if (!llvm::AIXSystemAssemblerPath.empty()) { 256 if (llvm::sys::fs::real_path(llvm::AIXSystemAssemblerPath, AssemblerPath, 257 /* expand_tilde */ true)) { 258 emitError( 259 "Cannot find the assembler specified by lto-aix-system-assembler"); 260 return false; 261 } 262 } 263 264 // Setup the LDR_CNTRL variable 265 std::string LDR_CNTRL_var = "LDR_CNTRL=MAXDATA32=0xA0000000@DSA"; 266 if (std::optional<std::string> V = sys::Process::GetEnv("LDR_CNTRL")) 267 LDR_CNTRL_var += ("@" + *V); 268 269 // Prepare inputs for the assember. 270 const auto &Triple = TargetMach->getTargetTriple(); 271 const char *Arch = Triple.isArch64Bit() ? "-a64" : "-a32"; 272 std::string ObjectFileName(AssemblyFile); 273 ObjectFileName[ObjectFileName.size() - 1] = 'o'; 274 SmallVector<StringRef, 8> Args = { 275 "/bin/env", LDR_CNTRL_var, 276 AssemblerPath, Arch, 277 "-many", "-o", 278 ObjectFileName, AssemblyFile}; 279 280 // Invoke the assembler. 281 int RC = sys::ExecuteAndWait(Args[0], Args); 282 283 // Handle errors. 284 if (RC < -1) { 285 emitError("LTO assembler exited abnormally"); 286 return false; 287 } 288 if (RC < 0) { 289 emitError("Unable to invoke LTO assembler"); 290 return false; 291 } 292 if (RC > 0) { 293 emitError("LTO assembler invocation returned non-zero"); 294 return false; 295 } 296 297 // Cleanup. 298 remove(AssemblyFile.c_str()); 299 300 // Fix the output file name. 301 AssemblyFile = ObjectFileName; 302 303 return true; 304 } 305 306 bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) { 307 if (useAIXSystemAssembler()) 308 setFileType(CodeGenFileType::AssemblyFile); 309 310 // make unique temp output file to put generated code 311 SmallString<128> Filename; 312 313 auto AddStream = 314 [&](size_t Task, 315 const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> { 316 StringRef Extension( 317 Config.CGFileType == CodeGenFileType::AssemblyFile ? "s" : "o"); 318 319 int FD; 320 std::error_code EC = 321 sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename); 322 if (EC) 323 emitError(EC.message()); 324 325 return std::make_unique<CachedFileStream>( 326 std::make_unique<llvm::raw_fd_ostream>(FD, true)); 327 }; 328 329 bool genResult = compileOptimized(AddStream, 1); 330 331 if (!genResult) { 332 sys::fs::remove(Twine(Filename)); 333 return false; 334 } 335 336 // If statistics were requested, save them to the specified file or 337 // print them out after codegen. 338 if (StatsFile) 339 PrintStatisticsJSON(StatsFile->os()); 340 else if (AreStatisticsEnabled()) 341 PrintStatistics(); 342 343 if (useAIXSystemAssembler()) 344 if (!runAIXSystemAssembler(Filename)) 345 return false; 346 347 NativeObjectPath = Filename.c_str(); 348 *Name = NativeObjectPath.c_str(); 349 return true; 350 } 351 352 std::unique_ptr<MemoryBuffer> 353 LTOCodeGenerator::compileOptimized() { 354 const char *name; 355 if (!compileOptimizedToFile(&name)) 356 return nullptr; 357 358 // read .o file into memory buffer 359 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFile( 360 name, /*IsText=*/false, /*RequiresNullTerminator=*/false); 361 if (std::error_code EC = BufferOrErr.getError()) { 362 emitError(EC.message()); 363 sys::fs::remove(NativeObjectPath); 364 return nullptr; 365 } 366 367 // remove temp files 368 sys::fs::remove(NativeObjectPath); 369 370 return std::move(*BufferOrErr); 371 } 372 373 bool LTOCodeGenerator::compile_to_file(const char **Name) { 374 if (!optimize()) 375 return false; 376 377 return compileOptimizedToFile(Name); 378 } 379 380 std::unique_ptr<MemoryBuffer> LTOCodeGenerator::compile() { 381 if (!optimize()) 382 return nullptr; 383 384 return compileOptimized(); 385 } 386 387 bool LTOCodeGenerator::determineTarget() { 388 if (TargetMach) 389 return true; 390 391 TripleStr = MergedModule->getTargetTriple(); 392 if (TripleStr.empty()) { 393 TripleStr = sys::getDefaultTargetTriple(); 394 MergedModule->setTargetTriple(TripleStr); 395 } 396 llvm::Triple Triple(TripleStr); 397 398 // create target machine from info for merged modules 399 std::string ErrMsg; 400 MArch = TargetRegistry::lookupTarget(TripleStr, ErrMsg); 401 if (!MArch) { 402 emitError(ErrMsg); 403 return false; 404 } 405 406 // Construct LTOModule, hand over ownership of module and target. Use MAttr as 407 // the default set of features. 408 SubtargetFeatures Features(join(Config.MAttrs, "")); 409 Features.getDefaultSubtargetFeatures(Triple); 410 FeatureStr = Features.getString(); 411 if (Config.CPU.empty()) 412 Config.CPU = lto::getThinLTODefaultCPU(Triple); 413 414 // If data-sections is not explicitly set or unset, set data-sections by 415 // default to match the behaviour of lld and gold plugin. 416 if (!codegen::getExplicitDataSections()) 417 Config.Options.DataSections = true; 418 419 TargetMach = createTargetMachine(); 420 assert(TargetMach && "Unable to create target machine"); 421 422 return true; 423 } 424 425 std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() { 426 assert(MArch && "MArch is not set!"); 427 return std::unique_ptr<TargetMachine>(MArch->createTargetMachine( 428 TripleStr, Config.CPU, FeatureStr, Config.Options, Config.RelocModel, 429 std::nullopt, Config.CGOptLevel)); 430 } 431 432 // If a linkonce global is present in the MustPreserveSymbols, we need to make 433 // sure we honor this. To force the compiler to not drop it, we add it to the 434 // "llvm.compiler.used" global. 435 void LTOCodeGenerator::preserveDiscardableGVs( 436 Module &TheModule, 437 llvm::function_ref<bool(const GlobalValue &)> mustPreserveGV) { 438 std::vector<GlobalValue *> Used; 439 auto mayPreserveGlobal = [&](GlobalValue &GV) { 440 if (!GV.isDiscardableIfUnused() || GV.isDeclaration() || 441 !mustPreserveGV(GV)) 442 return; 443 if (GV.hasAvailableExternallyLinkage()) 444 return emitWarning( 445 (Twine("Linker asked to preserve available_externally global: '") + 446 GV.getName() + "'").str()); 447 if (GV.hasInternalLinkage()) 448 return emitWarning((Twine("Linker asked to preserve internal global: '") + 449 GV.getName() + "'").str()); 450 Used.push_back(&GV); 451 }; 452 for (auto &GV : TheModule) 453 mayPreserveGlobal(GV); 454 for (auto &GV : TheModule.globals()) 455 mayPreserveGlobal(GV); 456 for (auto &GV : TheModule.aliases()) 457 mayPreserveGlobal(GV); 458 459 if (Used.empty()) 460 return; 461 462 appendToCompilerUsed(TheModule, Used); 463 } 464 465 void LTOCodeGenerator::applyScopeRestrictions() { 466 if (ScopeRestrictionsDone) 467 return; 468 469 // Declare a callback for the internalize pass that will ask for every 470 // candidate GlobalValue if it can be internalized or not. 471 Mangler Mang; 472 SmallString<64> MangledName; 473 auto mustPreserveGV = [&](const GlobalValue &GV) -> bool { 474 // Unnamed globals can't be mangled, but they can't be preserved either. 475 if (!GV.hasName()) 476 return false; 477 478 // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled 479 // with the linker supplied name, which on Darwin includes a leading 480 // underscore. 481 MangledName.clear(); 482 MangledName.reserve(GV.getName().size() + 1); 483 Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false); 484 return MustPreserveSymbols.count(MangledName); 485 }; 486 487 // Preserve linkonce value on linker request 488 preserveDiscardableGVs(*MergedModule, mustPreserveGV); 489 490 if (!ShouldInternalize) 491 return; 492 493 if (ShouldRestoreGlobalsLinkage) { 494 // Record the linkage type of non-local symbols so they can be restored 495 // prior 496 // to module splitting. 497 auto RecordLinkage = [&](const GlobalValue &GV) { 498 if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() && 499 GV.hasName()) 500 ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage())); 501 }; 502 for (auto &GV : *MergedModule) 503 RecordLinkage(GV); 504 for (auto &GV : MergedModule->globals()) 505 RecordLinkage(GV); 506 for (auto &GV : MergedModule->aliases()) 507 RecordLinkage(GV); 508 } 509 510 // Update the llvm.compiler_used globals to force preserving libcalls and 511 // symbols referenced from asm 512 updateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs); 513 514 internalizeModule(*MergedModule, mustPreserveGV); 515 516 ScopeRestrictionsDone = true; 517 } 518 519 /// Restore original linkage for symbols that may have been internalized 520 void LTOCodeGenerator::restoreLinkageForExternals() { 521 if (!ShouldInternalize || !ShouldRestoreGlobalsLinkage) 522 return; 523 524 assert(ScopeRestrictionsDone && 525 "Cannot externalize without internalization!"); 526 527 if (ExternalSymbols.empty()) 528 return; 529 530 auto externalize = [this](GlobalValue &GV) { 531 if (!GV.hasLocalLinkage() || !GV.hasName()) 532 return; 533 534 auto I = ExternalSymbols.find(GV.getName()); 535 if (I == ExternalSymbols.end()) 536 return; 537 538 GV.setLinkage(I->second); 539 }; 540 541 llvm::for_each(MergedModule->functions(), externalize); 542 llvm::for_each(MergedModule->globals(), externalize); 543 llvm::for_each(MergedModule->aliases(), externalize); 544 } 545 546 void LTOCodeGenerator::verifyMergedModuleOnce() { 547 // Only run on the first call. 548 if (HasVerifiedInput) 549 return; 550 HasVerifiedInput = true; 551 552 bool BrokenDebugInfo = false; 553 if (verifyModule(*MergedModule, &dbgs(), &BrokenDebugInfo)) 554 report_fatal_error("Broken module found, compilation aborted!"); 555 if (BrokenDebugInfo) { 556 emitWarning("Invalid debug info found, debug info will be stripped"); 557 StripDebugInfo(*MergedModule); 558 } 559 } 560 561 void LTOCodeGenerator::finishOptimizationRemarks() { 562 if (DiagnosticOutputFile) { 563 DiagnosticOutputFile->keep(); 564 // FIXME: LTOCodeGenerator dtor is not invoked on Darwin 565 DiagnosticOutputFile->os().flush(); 566 } 567 } 568 569 /// Optimize merged modules using various IPO passes 570 bool LTOCodeGenerator::optimize() { 571 if (!this->determineTarget()) 572 return false; 573 574 // libLTO parses options late, so re-set them here. 575 Context.setDiscardValueNames(LTODiscardValueNames); 576 577 auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks( 578 Context, RemarksFilename, RemarksPasses, RemarksFormat, 579 RemarksWithHotness, RemarksHotnessThreshold); 580 if (!DiagFileOrErr) { 581 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n"; 582 report_fatal_error("Can't get an output file for the remarks"); 583 } 584 DiagnosticOutputFile = std::move(*DiagFileOrErr); 585 586 // Setup output file to emit statistics. 587 auto StatsFileOrErr = lto::setupStatsFile(LTOStatsFile); 588 if (!StatsFileOrErr) { 589 errs() << "Error: " << toString(StatsFileOrErr.takeError()) << "\n"; 590 report_fatal_error("Can't get an output file for the statistics"); 591 } 592 StatsFile = std::move(StatsFileOrErr.get()); 593 594 // Currently there is no support for enabling whole program visibility via a 595 // linker option in the old LTO API, but this call allows it to be specified 596 // via the internal option. Must be done before WPD invoked via the optimizer 597 // pipeline run below. 598 updatePublicTypeTestCalls(*MergedModule, 599 /* WholeProgramVisibilityEnabledInLTO */ false); 600 updateVCallVisibilityInModule( 601 *MergedModule, 602 /* WholeProgramVisibilityEnabledInLTO */ false, 603 // FIXME: These need linker information via a 604 // TBD new interface. 605 /*DynamicExportSymbols=*/{}, 606 /*ValidateAllVtablesHaveTypeInfos=*/false, 607 /*IsVisibleToRegularObj=*/[](StringRef) { return true; }); 608 609 // We always run the verifier once on the merged module, the `DisableVerify` 610 // parameter only applies to subsequent verify. 611 verifyMergedModuleOnce(); 612 613 // Mark which symbols can not be internalized 614 this->applyScopeRestrictions(); 615 616 // Add an appropriate DataLayout instance for this module... 617 MergedModule->setDataLayout(TargetMach->createDataLayout()); 618 619 if (!SaveIRBeforeOptPath.empty()) { 620 std::error_code EC; 621 raw_fd_ostream OS(SaveIRBeforeOptPath, EC, sys::fs::OF_None); 622 if (EC) 623 report_fatal_error(Twine("Failed to open ") + SaveIRBeforeOptPath + 624 " to save optimized bitcode\n"); 625 WriteBitcodeToFile(*MergedModule, OS, 626 /* ShouldPreserveUseListOrder */ true); 627 } 628 629 ModuleSummaryIndex CombinedIndex(false); 630 TargetMach = createTargetMachine(); 631 if (!opt(Config, TargetMach.get(), 0, *MergedModule, /*IsThinLTO=*/false, 632 /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr, 633 /*CmdArgs*/ std::vector<uint8_t>())) { 634 emitError("LTO middle-end optimizations failed"); 635 return false; 636 } 637 638 return true; 639 } 640 641 bool LTOCodeGenerator::compileOptimized(AddStreamFn AddStream, 642 unsigned ParallelismLevel) { 643 if (!this->determineTarget()) 644 return false; 645 646 // We always run the verifier once on the merged module. If it has already 647 // been called in optimize(), this call will return early. 648 verifyMergedModuleOnce(); 649 650 // Re-externalize globals that may have been internalized to increase scope 651 // for splitting 652 restoreLinkageForExternals(); 653 654 ModuleSummaryIndex CombinedIndex(false); 655 656 Config.CodeGenOnly = true; 657 Error Err = backend(Config, AddStream, ParallelismLevel, *MergedModule, 658 CombinedIndex); 659 assert(!Err && "unexpected code-generation failure"); 660 (void)Err; 661 662 // If statistics were requested, save them to the specified file or 663 // print them out after codegen. 664 if (StatsFile) 665 PrintStatisticsJSON(StatsFile->os()); 666 else if (AreStatisticsEnabled()) 667 PrintStatistics(); 668 669 reportAndResetTimings(); 670 671 finishOptimizationRemarks(); 672 673 return true; 674 } 675 676 void LTOCodeGenerator::setCodeGenDebugOptions(ArrayRef<StringRef> Options) { 677 for (StringRef Option : Options) 678 CodegenOptions.push_back(Option.str()); 679 } 680 681 void LTOCodeGenerator::parseCodeGenDebugOptions() { 682 if (!CodegenOptions.empty()) 683 llvm::parseCommandLineOptions(CodegenOptions); 684 } 685 686 void llvm::parseCommandLineOptions(std::vector<std::string> &Options) { 687 if (!Options.empty()) { 688 // ParseCommandLineOptions() expects argv[0] to be program name. 689 std::vector<const char *> CodegenArgv(1, "libLLVMLTO"); 690 for (std::string &Arg : Options) 691 CodegenArgv.push_back(Arg.c_str()); 692 cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data()); 693 } 694 } 695 696 void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI) { 697 // Map the LLVM internal diagnostic severity to the LTO diagnostic severity. 698 lto_codegen_diagnostic_severity_t Severity; 699 switch (DI.getSeverity()) { 700 case DS_Error: 701 Severity = LTO_DS_ERROR; 702 break; 703 case DS_Warning: 704 Severity = LTO_DS_WARNING; 705 break; 706 case DS_Remark: 707 Severity = LTO_DS_REMARK; 708 break; 709 case DS_Note: 710 Severity = LTO_DS_NOTE; 711 break; 712 } 713 // Create the string that will be reported to the external diagnostic handler. 714 std::string MsgStorage; 715 raw_string_ostream Stream(MsgStorage); 716 DiagnosticPrinterRawOStream DP(Stream); 717 DI.print(DP); 718 Stream.flush(); 719 720 // If this method has been called it means someone has set up an external 721 // diagnostic handler. Assert on that. 722 assert(DiagHandler && "Invalid diagnostic handler"); 723 (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext); 724 } 725 726 namespace { 727 struct LTODiagnosticHandler : public DiagnosticHandler { 728 LTOCodeGenerator *CodeGenerator; 729 LTODiagnosticHandler(LTOCodeGenerator *CodeGenPtr) 730 : CodeGenerator(CodeGenPtr) {} 731 bool handleDiagnostics(const DiagnosticInfo &DI) override { 732 CodeGenerator->DiagnosticHandler(DI); 733 return true; 734 } 735 }; 736 } 737 738 void 739 LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler, 740 void *Ctxt) { 741 this->DiagHandler = DiagHandler; 742 this->DiagContext = Ctxt; 743 if (!DiagHandler) 744 return Context.setDiagnosticHandler(nullptr); 745 // Register the LTOCodeGenerator stub in the LLVMContext to forward the 746 // diagnostic to the external DiagHandler. 747 Context.setDiagnosticHandler(std::make_unique<LTODiagnosticHandler>(this), 748 true); 749 } 750 751 namespace { 752 class LTODiagnosticInfo : public DiagnosticInfo { 753 const Twine &Msg; 754 public: 755 LTODiagnosticInfo(const Twine &DiagMsg, DiagnosticSeverity Severity=DS_Error) 756 : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {} 757 void print(DiagnosticPrinter &DP) const override { DP << Msg; } 758 }; 759 } 760 761 void LTOCodeGenerator::emitError(const std::string &ErrMsg) { 762 if (DiagHandler) 763 (*DiagHandler)(LTO_DS_ERROR, ErrMsg.c_str(), DiagContext); 764 else 765 Context.diagnose(LTODiagnosticInfo(ErrMsg)); 766 } 767 768 void LTOCodeGenerator::emitWarning(const std::string &ErrMsg) { 769 if (DiagHandler) 770 (*DiagHandler)(LTO_DS_WARNING, ErrMsg.c_str(), DiagContext); 771 else 772 Context.diagnose(LTODiagnosticInfo(ErrMsg, DS_Warning)); 773 } 774