Home | History | Annotate | Line # | Download | only in LTO
      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/ParallelCG.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/InitializePasses.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/SubtargetFeature.h"
     47 #include "llvm/Remarks/HotnessThresholdParser.h"
     48 #include "llvm/Support/CommandLine.h"
     49 #include "llvm/Support/FileSystem.h"
     50 #include "llvm/Support/Host.h"
     51 #include "llvm/Support/MemoryBuffer.h"
     52 #include "llvm/Support/Signals.h"
     53 #include "llvm/Support/TargetRegistry.h"
     54 #include "llvm/Support/TargetSelect.h"
     55 #include "llvm/Support/ToolOutputFile.h"
     56 #include "llvm/Support/YAMLTraits.h"
     57 #include "llvm/Support/raw_ostream.h"
     58 #include "llvm/Target/TargetOptions.h"
     59 #include "llvm/Transforms/IPO.h"
     60 #include "llvm/Transforms/IPO/Internalize.h"
     61 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
     62 #include "llvm/Transforms/IPO/WholeProgramDevirt.h"
     63 #include "llvm/Transforms/ObjCARC.h"
     64 #include "llvm/Transforms/Utils/ModuleUtils.h"
     65 #include <system_error>
     66 using namespace llvm;
     67 
     68 const char* LTOCodeGenerator::getVersionString() {
     69 #ifdef LLVM_VERSION_INFO
     70   return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
     71 #else
     72   return PACKAGE_NAME " version " PACKAGE_VERSION;
     73 #endif
     74 }
     75 
     76 namespace llvm {
     77 cl::opt<bool> LTODiscardValueNames(
     78     "lto-discard-value-names",
     79     cl::desc("Strip names from Value during LTO (other than GlobalValue)."),
     80 #ifdef NDEBUG
     81     cl::init(true),
     82 #else
     83     cl::init(false),
     84 #endif
     85     cl::Hidden);
     86 
     87 cl::opt<bool> RemarksWithHotness(
     88     "lto-pass-remarks-with-hotness",
     89     cl::desc("With PGO, include profile count in optimization remarks"),
     90     cl::Hidden);
     91 
     92 cl::opt<Optional<uint64_t>, false, remarks::HotnessThresholdParser>
     93     RemarksHotnessThreshold(
     94         "lto-pass-remarks-hotness-threshold",
     95         cl::desc("Minimum profile count required for an "
     96                  "optimization remark to be output."
     97                  " Use 'auto' to apply the threshold from profile summary."),
     98         cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden);
     99 
    100 cl::opt<std::string>
    101     RemarksFilename("lto-pass-remarks-output",
    102                     cl::desc("Output filename for pass remarks"),
    103                     cl::value_desc("filename"));
    104 
    105 cl::opt<std::string>
    106     RemarksPasses("lto-pass-remarks-filter",
    107                   cl::desc("Only record optimization remarks from passes whose "
    108                            "names match the given regular expression"),
    109                   cl::value_desc("regex"));
    110 
    111 cl::opt<std::string> RemarksFormat(
    112     "lto-pass-remarks-format",
    113     cl::desc("The format used for serializing remarks (default: YAML)"),
    114     cl::value_desc("format"), cl::init("yaml"));
    115 
    116 cl::opt<std::string> LTOStatsFile(
    117     "lto-stats-file",
    118     cl::desc("Save statistics to the specified file"),
    119     cl::Hidden);
    120 }
    121 
    122 LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
    123     : Context(Context), MergedModule(new Module("ld-temp.o", Context)),
    124       TheLinker(new Linker(*MergedModule)) {
    125   Context.setDiscardValueNames(LTODiscardValueNames);
    126   Context.enableDebugTypeODRUniquing();
    127 
    128   Config.CodeModel = None;
    129   Config.StatsFile = LTOStatsFile;
    130   Config.PreCodeGenPassesHook = [](legacy::PassManager &PM) {
    131     PM.add(createObjCARCContractPass());
    132   };
    133 }
    134 
    135 LTOCodeGenerator::~LTOCodeGenerator() {}
    136 
    137 void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) {
    138   const std::vector<StringRef> &undefs = Mod->getAsmUndefinedRefs();
    139   for (int i = 0, e = undefs.size(); i != e; ++i)
    140     AsmUndefinedRefs.insert(undefs[i]);
    141 }
    142 
    143 bool LTOCodeGenerator::addModule(LTOModule *Mod) {
    144   assert(&Mod->getModule().getContext() == &Context &&
    145          "Expected module in same context");
    146 
    147   bool ret = TheLinker->linkInModule(Mod->takeModule());
    148   setAsmUndefinedRefs(Mod);
    149 
    150   // We've just changed the input, so let's make sure we verify it.
    151   HasVerifiedInput = false;
    152 
    153   return !ret;
    154 }
    155 
    156 void LTOCodeGenerator::setModule(std::unique_ptr<LTOModule> Mod) {
    157   assert(&Mod->getModule().getContext() == &Context &&
    158          "Expected module in same context");
    159 
    160   AsmUndefinedRefs.clear();
    161 
    162   MergedModule = Mod->takeModule();
    163   TheLinker = std::make_unique<Linker>(*MergedModule);
    164   setAsmUndefinedRefs(&*Mod);
    165 
    166   // We've just changed the input, so let's make sure we verify it.
    167   HasVerifiedInput = false;
    168 }
    169 
    170 void LTOCodeGenerator::setTargetOptions(const TargetOptions &Options) {
    171   Config.Options = Options;
    172 }
    173 
    174 void LTOCodeGenerator::setDebugInfo(lto_debug_model Debug) {
    175   switch (Debug) {
    176   case LTO_DEBUG_MODEL_NONE:
    177     EmitDwarfDebugInfo = false;
    178     return;
    179 
    180   case LTO_DEBUG_MODEL_DWARF:
    181     EmitDwarfDebugInfo = true;
    182     return;
    183   }
    184   llvm_unreachable("Unknown debug format!");
    185 }
    186 
    187 void LTOCodeGenerator::setOptLevel(unsigned Level) {
    188   Config.OptLevel = Level;
    189   Config.PTO.LoopVectorization = Config.OptLevel > 1;
    190   Config.PTO.SLPVectorization = Config.OptLevel > 1;
    191   switch (Config.OptLevel) {
    192   case 0:
    193     Config.CGOptLevel = CodeGenOpt::None;
    194     return;
    195   case 1:
    196     Config.CGOptLevel = CodeGenOpt::Less;
    197     return;
    198   case 2:
    199     Config.CGOptLevel = CodeGenOpt::Default;
    200     return;
    201   case 3:
    202     Config.CGOptLevel = CodeGenOpt::Aggressive;
    203     return;
    204   }
    205   llvm_unreachable("Unknown optimization level!");
    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::compileOptimizedToFile(const char **Name) {
    245   // make unique temp output file to put generated code
    246   SmallString<128> Filename;
    247 
    248   auto AddStream =
    249       [&](size_t Task) -> std::unique_ptr<lto::NativeObjectStream> {
    250     StringRef Extension(Config.CGFileType == CGFT_AssemblyFile ? "s" : "o");
    251 
    252     int FD;
    253     std::error_code EC =
    254         sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename);
    255     if (EC)
    256       emitError(EC.message());
    257 
    258     return std::make_unique<lto::NativeObjectStream>(
    259         std::make_unique<llvm::raw_fd_ostream>(FD, true));
    260   };
    261 
    262   bool genResult = compileOptimized(AddStream, 1);
    263 
    264   if (!genResult) {
    265     sys::fs::remove(Twine(Filename));
    266     return false;
    267   }
    268 
    269   // If statistics were requested, save them to the specified file or
    270   // print them out after codegen.
    271   if (StatsFile)
    272     PrintStatisticsJSON(StatsFile->os());
    273   else if (AreStatisticsEnabled())
    274     PrintStatistics();
    275 
    276   NativeObjectPath = Filename.c_str();
    277   *Name = NativeObjectPath.c_str();
    278   return true;
    279 }
    280 
    281 std::unique_ptr<MemoryBuffer>
    282 LTOCodeGenerator::compileOptimized() {
    283   const char *name;
    284   if (!compileOptimizedToFile(&name))
    285     return nullptr;
    286 
    287   // read .o file into memory buffer
    288   ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFile(
    289       name, /*IsText=*/false, /*RequiresNullTerminator=*/false);
    290   if (std::error_code EC = BufferOrErr.getError()) {
    291     emitError(EC.message());
    292     sys::fs::remove(NativeObjectPath);
    293     return nullptr;
    294   }
    295 
    296   // remove temp files
    297   sys::fs::remove(NativeObjectPath);
    298 
    299   return std::move(*BufferOrErr);
    300 }
    301 
    302 bool LTOCodeGenerator::compile_to_file(const char **Name) {
    303   if (!optimize())
    304     return false;
    305 
    306   return compileOptimizedToFile(Name);
    307 }
    308 
    309 std::unique_ptr<MemoryBuffer> LTOCodeGenerator::compile() {
    310   if (!optimize())
    311     return nullptr;
    312 
    313   return compileOptimized();
    314 }
    315 
    316 bool LTOCodeGenerator::determineTarget() {
    317   if (TargetMach)
    318     return true;
    319 
    320   TripleStr = MergedModule->getTargetTriple();
    321   if (TripleStr.empty()) {
    322     TripleStr = sys::getDefaultTargetTriple();
    323     MergedModule->setTargetTriple(TripleStr);
    324   }
    325   llvm::Triple Triple(TripleStr);
    326 
    327   // create target machine from info for merged modules
    328   std::string ErrMsg;
    329   MArch = TargetRegistry::lookupTarget(TripleStr, ErrMsg);
    330   if (!MArch) {
    331     emitError(ErrMsg);
    332     return false;
    333   }
    334 
    335   // Construct LTOModule, hand over ownership of module and target. Use MAttr as
    336   // the default set of features.
    337   SubtargetFeatures Features(join(Config.MAttrs, ""));
    338   Features.getDefaultSubtargetFeatures(Triple);
    339   FeatureStr = Features.getString();
    340   // Set a default CPU for Darwin triples.
    341   if (Config.CPU.empty() && Triple.isOSDarwin()) {
    342     if (Triple.getArch() == llvm::Triple::x86_64)
    343       Config.CPU = "core2";
    344     else if (Triple.getArch() == llvm::Triple::x86)
    345       Config.CPU = "yonah";
    346     else if (Triple.isArm64e())
    347       Config.CPU = "apple-a12";
    348     else if (Triple.getArch() == llvm::Triple::aarch64 ||
    349              Triple.getArch() == llvm::Triple::aarch64_32)
    350       Config.CPU = "cyclone";
    351   }
    352 
    353   TargetMach = createTargetMachine();
    354   assert(TargetMach && "Unable to create target machine");
    355 
    356   return true;
    357 }
    358 
    359 std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() {
    360   assert(MArch && "MArch is not set!");
    361   return std::unique_ptr<TargetMachine>(MArch->createTargetMachine(
    362       TripleStr, Config.CPU, FeatureStr, Config.Options, Config.RelocModel,
    363       None, Config.CGOptLevel));
    364 }
    365 
    366 // If a linkonce global is present in the MustPreserveSymbols, we need to make
    367 // sure we honor this. To force the compiler to not drop it, we add it to the
    368 // "llvm.compiler.used" global.
    369 void LTOCodeGenerator::preserveDiscardableGVs(
    370     Module &TheModule,
    371     llvm::function_ref<bool(const GlobalValue &)> mustPreserveGV) {
    372   std::vector<GlobalValue *> Used;
    373   auto mayPreserveGlobal = [&](GlobalValue &GV) {
    374     if (!GV.isDiscardableIfUnused() || GV.isDeclaration() ||
    375         !mustPreserveGV(GV))
    376       return;
    377     if (GV.hasAvailableExternallyLinkage())
    378       return emitWarning(
    379           (Twine("Linker asked to preserve available_externally global: '") +
    380            GV.getName() + "'").str());
    381     if (GV.hasInternalLinkage())
    382       return emitWarning((Twine("Linker asked to preserve internal global: '") +
    383                    GV.getName() + "'").str());
    384     Used.push_back(&GV);
    385   };
    386   for (auto &GV : TheModule)
    387     mayPreserveGlobal(GV);
    388   for (auto &GV : TheModule.globals())
    389     mayPreserveGlobal(GV);
    390   for (auto &GV : TheModule.aliases())
    391     mayPreserveGlobal(GV);
    392 
    393   if (Used.empty())
    394     return;
    395 
    396   appendToCompilerUsed(TheModule, Used);
    397 }
    398 
    399 void LTOCodeGenerator::applyScopeRestrictions() {
    400   if (ScopeRestrictionsDone)
    401     return;
    402 
    403   // Declare a callback for the internalize pass that will ask for every
    404   // candidate GlobalValue if it can be internalized or not.
    405   Mangler Mang;
    406   SmallString<64> MangledName;
    407   auto mustPreserveGV = [&](const GlobalValue &GV) -> bool {
    408     // Unnamed globals can't be mangled, but they can't be preserved either.
    409     if (!GV.hasName())
    410       return false;
    411 
    412     // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
    413     // with the linker supplied name, which on Darwin includes a leading
    414     // underscore.
    415     MangledName.clear();
    416     MangledName.reserve(GV.getName().size() + 1);
    417     Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
    418     return MustPreserveSymbols.count(MangledName);
    419   };
    420 
    421   // Preserve linkonce value on linker request
    422   preserveDiscardableGVs(*MergedModule, mustPreserveGV);
    423 
    424   if (!ShouldInternalize)
    425     return;
    426 
    427   if (ShouldRestoreGlobalsLinkage) {
    428     // Record the linkage type of non-local symbols so they can be restored
    429     // prior
    430     // to module splitting.
    431     auto RecordLinkage = [&](const GlobalValue &GV) {
    432       if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() &&
    433           GV.hasName())
    434         ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage()));
    435     };
    436     for (auto &GV : *MergedModule)
    437       RecordLinkage(GV);
    438     for (auto &GV : MergedModule->globals())
    439       RecordLinkage(GV);
    440     for (auto &GV : MergedModule->aliases())
    441       RecordLinkage(GV);
    442   }
    443 
    444   // Update the llvm.compiler_used globals to force preserving libcalls and
    445   // symbols referenced from asm
    446   updateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs);
    447 
    448   internalizeModule(*MergedModule, mustPreserveGV);
    449 
    450   ScopeRestrictionsDone = true;
    451 }
    452 
    453 /// Restore original linkage for symbols that may have been internalized
    454 void LTOCodeGenerator::restoreLinkageForExternals() {
    455   if (!ShouldInternalize || !ShouldRestoreGlobalsLinkage)
    456     return;
    457 
    458   assert(ScopeRestrictionsDone &&
    459          "Cannot externalize without internalization!");
    460 
    461   if (ExternalSymbols.empty())
    462     return;
    463 
    464   auto externalize = [this](GlobalValue &GV) {
    465     if (!GV.hasLocalLinkage() || !GV.hasName())
    466       return;
    467 
    468     auto I = ExternalSymbols.find(GV.getName());
    469     if (I == ExternalSymbols.end())
    470       return;
    471 
    472     GV.setLinkage(I->second);
    473   };
    474 
    475   llvm::for_each(MergedModule->functions(), externalize);
    476   llvm::for_each(MergedModule->globals(), externalize);
    477   llvm::for_each(MergedModule->aliases(), externalize);
    478 }
    479 
    480 void LTOCodeGenerator::verifyMergedModuleOnce() {
    481   // Only run on the first call.
    482   if (HasVerifiedInput)
    483     return;
    484   HasVerifiedInput = true;
    485 
    486   bool BrokenDebugInfo = false;
    487   if (verifyModule(*MergedModule, &dbgs(), &BrokenDebugInfo))
    488     report_fatal_error("Broken module found, compilation aborted!");
    489   if (BrokenDebugInfo) {
    490     emitWarning("Invalid debug info found, debug info will be stripped");
    491     StripDebugInfo(*MergedModule);
    492   }
    493 }
    494 
    495 void LTOCodeGenerator::finishOptimizationRemarks() {
    496   if (DiagnosticOutputFile) {
    497     DiagnosticOutputFile->keep();
    498     // FIXME: LTOCodeGenerator dtor is not invoked on Darwin
    499     DiagnosticOutputFile->os().flush();
    500   }
    501 }
    502 
    503 /// Optimize merged modules using various IPO passes
    504 bool LTOCodeGenerator::optimize() {
    505   if (!this->determineTarget())
    506     return false;
    507 
    508   auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
    509       Context, RemarksFilename, RemarksPasses, RemarksFormat,
    510       RemarksWithHotness, RemarksHotnessThreshold);
    511   if (!DiagFileOrErr) {
    512     errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
    513     report_fatal_error("Can't get an output file for the remarks");
    514   }
    515   DiagnosticOutputFile = std::move(*DiagFileOrErr);
    516 
    517   // Setup output file to emit statistics.
    518   auto StatsFileOrErr = lto::setupStatsFile(LTOStatsFile);
    519   if (!StatsFileOrErr) {
    520     errs() << "Error: " << toString(StatsFileOrErr.takeError()) << "\n";
    521     report_fatal_error("Can't get an output file for the statistics");
    522   }
    523   StatsFile = std::move(StatsFileOrErr.get());
    524 
    525   // Currently there is no support for enabling whole program visibility via a
    526   // linker option in the old LTO API, but this call allows it to be specified
    527   // via the internal option. Must be done before WPD invoked via the optimizer
    528   // pipeline run below.
    529   updateVCallVisibilityInModule(*MergedModule,
    530                                 /* WholeProgramVisibilityEnabledInLTO */ false,
    531                                 // FIXME: This needs linker information via a
    532                                 // TBD new interface.
    533                                 /* DynamicExportSymbols */ {});
    534 
    535   // We always run the verifier once on the merged module, the `DisableVerify`
    536   // parameter only applies to subsequent verify.
    537   verifyMergedModuleOnce();
    538 
    539   // Mark which symbols can not be internalized
    540   this->applyScopeRestrictions();
    541 
    542   // Write LTOPostLink flag for passes that require all the modules.
    543   MergedModule->addModuleFlag(Module::Error, "LTOPostLink", 1);
    544 
    545   // Add an appropriate DataLayout instance for this module...
    546   MergedModule->setDataLayout(TargetMach->createDataLayout());
    547 
    548   ModuleSummaryIndex CombinedIndex(false);
    549   TargetMach = createTargetMachine();
    550   if (!opt(Config, TargetMach.get(), 0, *MergedModule, /*IsThinLTO=*/false,
    551            /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
    552            /*CmdArgs*/ std::vector<uint8_t>())) {
    553     emitError("LTO middle-end optimizations failed");
    554     return false;
    555   }
    556 
    557   return true;
    558 }
    559 
    560 bool LTOCodeGenerator::compileOptimized(lto::AddStreamFn AddStream,
    561                                         unsigned ParallelismLevel) {
    562   if (!this->determineTarget())
    563     return false;
    564 
    565   // We always run the verifier once on the merged module.  If it has already
    566   // been called in optimize(), this call will return early.
    567   verifyMergedModuleOnce();
    568 
    569   // Re-externalize globals that may have been internalized to increase scope
    570   // for splitting
    571   restoreLinkageForExternals();
    572 
    573   ModuleSummaryIndex CombinedIndex(false);
    574 
    575   Config.CodeGenOnly = true;
    576   Error Err = backend(Config, AddStream, ParallelismLevel, *MergedModule,
    577                       CombinedIndex);
    578   assert(!Err && "unexpected code-generation failure");
    579   (void)Err;
    580 
    581   // If statistics were requested, save them to the specified file or
    582   // print them out after codegen.
    583   if (StatsFile)
    584     PrintStatisticsJSON(StatsFile->os());
    585   else if (AreStatisticsEnabled())
    586     PrintStatistics();
    587 
    588   reportAndResetTimings();
    589 
    590   finishOptimizationRemarks();
    591 
    592   return true;
    593 }
    594 
    595 void LTOCodeGenerator::setCodeGenDebugOptions(ArrayRef<StringRef> Options) {
    596   for (StringRef Option : Options)
    597     CodegenOptions.push_back(Option.str());
    598 }
    599 
    600 void LTOCodeGenerator::parseCodeGenDebugOptions() {
    601   if (!CodegenOptions.empty())
    602     llvm::parseCommandLineOptions(CodegenOptions);
    603 }
    604 
    605 void llvm::parseCommandLineOptions(std::vector<std::string> &Options) {
    606   if (!Options.empty()) {
    607     // ParseCommandLineOptions() expects argv[0] to be program name.
    608     std::vector<const char *> CodegenArgv(1, "libLLVMLTO");
    609     for (std::string &Arg : Options)
    610       CodegenArgv.push_back(Arg.c_str());
    611     cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data());
    612   }
    613 }
    614 
    615 void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI) {
    616   // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
    617   lto_codegen_diagnostic_severity_t Severity;
    618   switch (DI.getSeverity()) {
    619   case DS_Error:
    620     Severity = LTO_DS_ERROR;
    621     break;
    622   case DS_Warning:
    623     Severity = LTO_DS_WARNING;
    624     break;
    625   case DS_Remark:
    626     Severity = LTO_DS_REMARK;
    627     break;
    628   case DS_Note:
    629     Severity = LTO_DS_NOTE;
    630     break;
    631   }
    632   // Create the string that will be reported to the external diagnostic handler.
    633   std::string MsgStorage;
    634   raw_string_ostream Stream(MsgStorage);
    635   DiagnosticPrinterRawOStream DP(Stream);
    636   DI.print(DP);
    637   Stream.flush();
    638 
    639   // If this method has been called it means someone has set up an external
    640   // diagnostic handler. Assert on that.
    641   assert(DiagHandler && "Invalid diagnostic handler");
    642   (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
    643 }
    644 
    645 namespace {
    646 struct LTODiagnosticHandler : public DiagnosticHandler {
    647   LTOCodeGenerator *CodeGenerator;
    648   LTODiagnosticHandler(LTOCodeGenerator *CodeGenPtr)
    649       : CodeGenerator(CodeGenPtr) {}
    650   bool handleDiagnostics(const DiagnosticInfo &DI) override {
    651     CodeGenerator->DiagnosticHandler(DI);
    652     return true;
    653   }
    654 };
    655 }
    656 
    657 void
    658 LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler,
    659                                        void *Ctxt) {
    660   this->DiagHandler = DiagHandler;
    661   this->DiagContext = Ctxt;
    662   if (!DiagHandler)
    663     return Context.setDiagnosticHandler(nullptr);
    664   // Register the LTOCodeGenerator stub in the LLVMContext to forward the
    665   // diagnostic to the external DiagHandler.
    666   Context.setDiagnosticHandler(std::make_unique<LTODiagnosticHandler>(this),
    667                                true);
    668 }
    669 
    670 namespace {
    671 class LTODiagnosticInfo : public DiagnosticInfo {
    672   const Twine &Msg;
    673 public:
    674   LTODiagnosticInfo(const Twine &DiagMsg, DiagnosticSeverity Severity=DS_Error)
    675       : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
    676   void print(DiagnosticPrinter &DP) const override { DP << Msg; }
    677 };
    678 }
    679 
    680 void LTOCodeGenerator::emitError(const std::string &ErrMsg) {
    681   if (DiagHandler)
    682     (*DiagHandler)(LTO_DS_ERROR, ErrMsg.c_str(), DiagContext);
    683   else
    684     Context.diagnose(LTODiagnosticInfo(ErrMsg));
    685 }
    686 
    687 void LTOCodeGenerator::emitWarning(const std::string &ErrMsg) {
    688   if (DiagHandler)
    689     (*DiagHandler)(LTO_DS_WARNING, ErrMsg.c_str(), DiagContext);
    690   else
    691     Context.diagnose(LTODiagnosticInfo(ErrMsg, DS_Warning));
    692 }
    693