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