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<CodeGenOptLevel> 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(CodeGenFileType::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( 318 Config.CGFileType == CodeGenFileType::AssemblyFile ? "s" : "o"); 319 320 int FD; 321 std::error_code EC = 322 sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename); 323 if (EC) 324 emitError(EC.message()); 325 326 return std::make_unique<CachedFileStream>( 327 std::make_unique<llvm::raw_fd_ostream>(FD, true)); 328 }; 329 330 bool genResult = compileOptimized(AddStream, 1); 331 332 if (!genResult) { 333 sys::fs::remove(Twine(Filename)); 334 return false; 335 } 336 337 // If statistics were requested, save them to the specified file or 338 // print them out after codegen. 339 if (StatsFile) 340 PrintStatisticsJSON(StatsFile->os()); 341 else if (AreStatisticsEnabled()) 342 PrintStatistics(); 343 344 if (useAIXSystemAssembler()) 345 if (!runAIXSystemAssembler(Filename)) 346 return false; 347 348 NativeObjectPath = Filename.c_str(); 349 *Name = NativeObjectPath.c_str(); 350 return true; 351 } 352 353 std::unique_ptr<MemoryBuffer> 354 LTOCodeGenerator::compileOptimized() { 355 const char *name; 356 if (!compileOptimizedToFile(&name)) 357 return nullptr; 358 359 // read .o file into memory buffer 360 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFile( 361 name, /*IsText=*/false, /*RequiresNullTerminator=*/false); 362 if (std::error_code EC = BufferOrErr.getError()) { 363 emitError(EC.message()); 364 sys::fs::remove(NativeObjectPath); 365 return nullptr; 366 } 367 368 // remove temp files 369 sys::fs::remove(NativeObjectPath); 370 371 return std::move(*BufferOrErr); 372 } 373 374 bool LTOCodeGenerator::compile_to_file(const char **Name) { 375 if (!optimize()) 376 return false; 377 378 return compileOptimizedToFile(Name); 379 } 380 381 std::unique_ptr<MemoryBuffer> LTOCodeGenerator::compile() { 382 if (!optimize()) 383 return nullptr; 384 385 return compileOptimized(); 386 } 387 388 bool LTOCodeGenerator::determineTarget() { 389 if (TargetMach) 390 return true; 391 392 TripleStr = MergedModule->getTargetTriple(); 393 if (TripleStr.empty()) { 394 TripleStr = sys::getDefaultTargetTriple(); 395 MergedModule->setTargetTriple(TripleStr); 396 } 397 llvm::Triple Triple(TripleStr); 398 399 // create target machine from info for merged modules 400 std::string ErrMsg; 401 MArch = TargetRegistry::lookupTarget(TripleStr, ErrMsg); 402 if (!MArch) { 403 emitError(ErrMsg); 404 return false; 405 } 406 407 // Construct LTOModule, hand over ownership of module and target. Use MAttr as 408 // the default set of features. 409 SubtargetFeatures Features(join(Config.MAttrs, "")); 410 Features.getDefaultSubtargetFeatures(Triple); 411 FeatureStr = Features.getString(); 412 // Set a default CPU for Darwin triples. 413 if (Config.CPU.empty() && Triple.isOSDarwin()) { 414 if (Triple.getArch() == llvm::Triple::x86_64) 415 Config.CPU = "core2"; 416 else if (Triple.getArch() == llvm::Triple::x86) 417 Config.CPU = "yonah"; 418 else if (Triple.isArm64e()) 419 Config.CPU = "apple-a12"; 420 else if (Triple.getArch() == llvm::Triple::aarch64 || 421 Triple.getArch() == llvm::Triple::aarch64_32) 422 Config.CPU = "cyclone"; 423 } 424 425 // If data-sections is not explicitly set or unset, set data-sections by 426 // default to match the behaviour of lld and gold plugin. 427 if (!codegen::getExplicitDataSections()) 428 Config.Options.DataSections = true; 429 430 TargetMach = createTargetMachine(); 431 assert(TargetMach && "Unable to create target machine"); 432 433 return true; 434 } 435 436 std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() { 437 assert(MArch && "MArch is not set!"); 438 return std::unique_ptr<TargetMachine>(MArch->createTargetMachine( 439 TripleStr, Config.CPU, FeatureStr, Config.Options, Config.RelocModel, 440 std::nullopt, Config.CGOptLevel)); 441 } 442 443 // If a linkonce global is present in the MustPreserveSymbols, we need to make 444 // sure we honor this. To force the compiler to not drop it, we add it to the 445 // "llvm.compiler.used" global. 446 void LTOCodeGenerator::preserveDiscardableGVs( 447 Module &TheModule, 448 llvm::function_ref<bool(const GlobalValue &)> mustPreserveGV) { 449 std::vector<GlobalValue *> Used; 450 auto mayPreserveGlobal = [&](GlobalValue &GV) { 451 if (!GV.isDiscardableIfUnused() || GV.isDeclaration() || 452 !mustPreserveGV(GV)) 453 return; 454 if (GV.hasAvailableExternallyLinkage()) 455 return emitWarning( 456 (Twine("Linker asked to preserve available_externally global: '") + 457 GV.getName() + "'").str()); 458 if (GV.hasInternalLinkage()) 459 return emitWarning((Twine("Linker asked to preserve internal global: '") + 460 GV.getName() + "'").str()); 461 Used.push_back(&GV); 462 }; 463 for (auto &GV : TheModule) 464 mayPreserveGlobal(GV); 465 for (auto &GV : TheModule.globals()) 466 mayPreserveGlobal(GV); 467 for (auto &GV : TheModule.aliases()) 468 mayPreserveGlobal(GV); 469 470 if (Used.empty()) 471 return; 472 473 appendToCompilerUsed(TheModule, Used); 474 } 475 476 void LTOCodeGenerator::applyScopeRestrictions() { 477 if (ScopeRestrictionsDone) 478 return; 479 480 // Declare a callback for the internalize pass that will ask for every 481 // candidate GlobalValue if it can be internalized or not. 482 Mangler Mang; 483 SmallString<64> MangledName; 484 auto mustPreserveGV = [&](const GlobalValue &GV) -> bool { 485 // Unnamed globals can't be mangled, but they can't be preserved either. 486 if (!GV.hasName()) 487 return false; 488 489 // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled 490 // with the linker supplied name, which on Darwin includes a leading 491 // underscore. 492 MangledName.clear(); 493 MangledName.reserve(GV.getName().size() + 1); 494 Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false); 495 return MustPreserveSymbols.count(MangledName); 496 }; 497 498 // Preserve linkonce value on linker request 499 preserveDiscardableGVs(*MergedModule, mustPreserveGV); 500 501 if (!ShouldInternalize) 502 return; 503 504 if (ShouldRestoreGlobalsLinkage) { 505 // Record the linkage type of non-local symbols so they can be restored 506 // prior 507 // to module splitting. 508 auto RecordLinkage = [&](const GlobalValue &GV) { 509 if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() && 510 GV.hasName()) 511 ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage())); 512 }; 513 for (auto &GV : *MergedModule) 514 RecordLinkage(GV); 515 for (auto &GV : MergedModule->globals()) 516 RecordLinkage(GV); 517 for (auto &GV : MergedModule->aliases()) 518 RecordLinkage(GV); 519 } 520 521 // Update the llvm.compiler_used globals to force preserving libcalls and 522 // symbols referenced from asm 523 updateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs); 524 525 internalizeModule(*MergedModule, mustPreserveGV); 526 527 ScopeRestrictionsDone = true; 528 } 529 530 /// Restore original linkage for symbols that may have been internalized 531 void LTOCodeGenerator::restoreLinkageForExternals() { 532 if (!ShouldInternalize || !ShouldRestoreGlobalsLinkage) 533 return; 534 535 assert(ScopeRestrictionsDone && 536 "Cannot externalize without internalization!"); 537 538 if (ExternalSymbols.empty()) 539 return; 540 541 auto externalize = [this](GlobalValue &GV) { 542 if (!GV.hasLocalLinkage() || !GV.hasName()) 543 return; 544 545 auto I = ExternalSymbols.find(GV.getName()); 546 if (I == ExternalSymbols.end()) 547 return; 548 549 GV.setLinkage(I->second); 550 }; 551 552 llvm::for_each(MergedModule->functions(), externalize); 553 llvm::for_each(MergedModule->globals(), externalize); 554 llvm::for_each(MergedModule->aliases(), externalize); 555 } 556 557 void LTOCodeGenerator::verifyMergedModuleOnce() { 558 // Only run on the first call. 559 if (HasVerifiedInput) 560 return; 561 HasVerifiedInput = true; 562 563 bool BrokenDebugInfo = false; 564 if (verifyModule(*MergedModule, &dbgs(), &BrokenDebugInfo)) 565 report_fatal_error("Broken module found, compilation aborted!"); 566 if (BrokenDebugInfo) { 567 emitWarning("Invalid debug info found, debug info will be stripped"); 568 StripDebugInfo(*MergedModule); 569 } 570 } 571 572 void LTOCodeGenerator::finishOptimizationRemarks() { 573 if (DiagnosticOutputFile) { 574 DiagnosticOutputFile->keep(); 575 // FIXME: LTOCodeGenerator dtor is not invoked on Darwin 576 DiagnosticOutputFile->os().flush(); 577 } 578 } 579 580 /// Optimize merged modules using various IPO passes 581 bool LTOCodeGenerator::optimize() { 582 if (!this->determineTarget()) 583 return false; 584 585 auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks( 586 Context, RemarksFilename, RemarksPasses, RemarksFormat, 587 RemarksWithHotness, RemarksHotnessThreshold); 588 if (!DiagFileOrErr) { 589 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n"; 590 report_fatal_error("Can't get an output file for the remarks"); 591 } 592 DiagnosticOutputFile = std::move(*DiagFileOrErr); 593 594 // Setup output file to emit statistics. 595 auto StatsFileOrErr = lto::setupStatsFile(LTOStatsFile); 596 if (!StatsFileOrErr) { 597 errs() << "Error: " << toString(StatsFileOrErr.takeError()) << "\n"; 598 report_fatal_error("Can't get an output file for the statistics"); 599 } 600 StatsFile = std::move(StatsFileOrErr.get()); 601 602 // Currently there is no support for enabling whole program visibility via a 603 // linker option in the old LTO API, but this call allows it to be specified 604 // via the internal option. Must be done before WPD invoked via the optimizer 605 // pipeline run below. 606 updatePublicTypeTestCalls(*MergedModule, 607 /* WholeProgramVisibilityEnabledInLTO */ false); 608 updateVCallVisibilityInModule( 609 *MergedModule, 610 /* WholeProgramVisibilityEnabledInLTO */ false, 611 // FIXME: These need linker information via a 612 // TBD new interface. 613 /*DynamicExportSymbols=*/{}, 614 /*ValidateAllVtablesHaveTypeInfos=*/false, 615 /*IsVisibleToRegularObj=*/[](StringRef) { return true; }); 616 617 // We always run the verifier once on the merged module, the `DisableVerify` 618 // parameter only applies to subsequent verify. 619 verifyMergedModuleOnce(); 620 621 // Mark which symbols can not be internalized 622 this->applyScopeRestrictions(); 623 624 // Add an appropriate DataLayout instance for this module... 625 MergedModule->setDataLayout(TargetMach->createDataLayout()); 626 627 if (!SaveIRBeforeOptPath.empty()) { 628 std::error_code EC; 629 raw_fd_ostream OS(SaveIRBeforeOptPath, EC, sys::fs::OF_None); 630 if (EC) 631 report_fatal_error(Twine("Failed to open ") + SaveIRBeforeOptPath + 632 " to save optimized bitcode\n"); 633 WriteBitcodeToFile(*MergedModule, OS, 634 /* ShouldPreserveUseListOrder */ true); 635 } 636 637 ModuleSummaryIndex CombinedIndex(false); 638 TargetMach = createTargetMachine(); 639 if (!opt(Config, TargetMach.get(), 0, *MergedModule, /*IsThinLTO=*/false, 640 /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr, 641 /*CmdArgs*/ std::vector<uint8_t>())) { 642 emitError("LTO middle-end optimizations failed"); 643 return false; 644 } 645 646 return true; 647 } 648 649 bool LTOCodeGenerator::compileOptimized(AddStreamFn AddStream, 650 unsigned ParallelismLevel) { 651 if (!this->determineTarget()) 652 return false; 653 654 // We always run the verifier once on the merged module. If it has already 655 // been called in optimize(), this call will return early. 656 verifyMergedModuleOnce(); 657 658 // Re-externalize globals that may have been internalized to increase scope 659 // for splitting 660 restoreLinkageForExternals(); 661 662 ModuleSummaryIndex CombinedIndex(false); 663 664 Config.CodeGenOnly = true; 665 Error Err = backend(Config, AddStream, ParallelismLevel, *MergedModule, 666 CombinedIndex); 667 assert(!Err && "unexpected code-generation failure"); 668 (void)Err; 669 670 // If statistics were requested, save them to the specified file or 671 // print them out after codegen. 672 if (StatsFile) 673 PrintStatisticsJSON(StatsFile->os()); 674 else if (AreStatisticsEnabled()) 675 PrintStatistics(); 676 677 reportAndResetTimings(); 678 679 finishOptimizationRemarks(); 680 681 return true; 682 } 683 684 void LTOCodeGenerator::setCodeGenDebugOptions(ArrayRef<StringRef> Options) { 685 for (StringRef Option : Options) 686 CodegenOptions.push_back(Option.str()); 687 } 688 689 void LTOCodeGenerator::parseCodeGenDebugOptions() { 690 if (!CodegenOptions.empty()) 691 llvm::parseCommandLineOptions(CodegenOptions); 692 } 693 694 void llvm::parseCommandLineOptions(std::vector<std::string> &Options) { 695 if (!Options.empty()) { 696 // ParseCommandLineOptions() expects argv[0] to be program name. 697 std::vector<const char *> CodegenArgv(1, "libLLVMLTO"); 698 for (std::string &Arg : Options) 699 CodegenArgv.push_back(Arg.c_str()); 700 cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data()); 701 } 702 } 703 704 void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI) { 705 // Map the LLVM internal diagnostic severity to the LTO diagnostic severity. 706 lto_codegen_diagnostic_severity_t Severity; 707 switch (DI.getSeverity()) { 708 case DS_Error: 709 Severity = LTO_DS_ERROR; 710 break; 711 case DS_Warning: 712 Severity = LTO_DS_WARNING; 713 break; 714 case DS_Remark: 715 Severity = LTO_DS_REMARK; 716 break; 717 case DS_Note: 718 Severity = LTO_DS_NOTE; 719 break; 720 } 721 // Create the string that will be reported to the external diagnostic handler. 722 std::string MsgStorage; 723 raw_string_ostream Stream(MsgStorage); 724 DiagnosticPrinterRawOStream DP(Stream); 725 DI.print(DP); 726 Stream.flush(); 727 728 // If this method has been called it means someone has set up an external 729 // diagnostic handler. Assert on that. 730 assert(DiagHandler && "Invalid diagnostic handler"); 731 (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext); 732 } 733 734 namespace { 735 struct LTODiagnosticHandler : public DiagnosticHandler { 736 LTOCodeGenerator *CodeGenerator; 737 LTODiagnosticHandler(LTOCodeGenerator *CodeGenPtr) 738 : CodeGenerator(CodeGenPtr) {} 739 bool handleDiagnostics(const DiagnosticInfo &DI) override { 740 CodeGenerator->DiagnosticHandler(DI); 741 return true; 742 } 743 }; 744 } 745 746 void 747 LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler, 748 void *Ctxt) { 749 this->DiagHandler = DiagHandler; 750 this->DiagContext = Ctxt; 751 if (!DiagHandler) 752 return Context.setDiagnosticHandler(nullptr); 753 // Register the LTOCodeGenerator stub in the LLVMContext to forward the 754 // diagnostic to the external DiagHandler. 755 Context.setDiagnosticHandler(std::make_unique<LTODiagnosticHandler>(this), 756 true); 757 } 758 759 namespace { 760 class LTODiagnosticInfo : public DiagnosticInfo { 761 const Twine &Msg; 762 public: 763 LTODiagnosticInfo(const Twine &DiagMsg, DiagnosticSeverity Severity=DS_Error) 764 : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {} 765 void print(DiagnosticPrinter &DP) const override { DP << Msg; } 766 }; 767 } 768 769 void LTOCodeGenerator::emitError(const std::string &ErrMsg) { 770 if (DiagHandler) 771 (*DiagHandler)(LTO_DS_ERROR, ErrMsg.c_str(), DiagContext); 772 else 773 Context.diagnose(LTODiagnosticInfo(ErrMsg)); 774 } 775 776 void LTOCodeGenerator::emitWarning(const std::string &ErrMsg) { 777 if (DiagHandler) 778 (*DiagHandler)(LTO_DS_WARNING, ErrMsg.c_str(), DiagContext); 779 else 780 Context.diagnose(LTODiagnosticInfo(ErrMsg, DS_Warning)); 781 } 782