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