LCOV - code coverage report
Current view: top level - lib/LTO - LTOCodeGenerator.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 240 327 73.4 %
Date: 2018-02-23 05:02:05 Functions: 31 42 73.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-LTOCodeGenerator.cpp - LLVM Link Time Optimizer ---------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file implements the Link Time Optimization library. This library is
      11             : // intended to be used by linker to optimize code at link time.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "llvm/LTO/legacy/LTOCodeGenerator.h"
      16             : 
      17             : #include "llvm/ADT/Statistic.h"
      18             : #include "llvm/ADT/StringExtras.h"
      19             : #include "llvm/Analysis/Passes.h"
      20             : #include "llvm/Analysis/TargetLibraryInfo.h"
      21             : #include "llvm/Analysis/TargetTransformInfo.h"
      22             : #include "llvm/Bitcode/BitcodeWriter.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/LegacyPassManager.h"
      34             : #include "llvm/IR/Mangler.h"
      35             : #include "llvm/IR/Module.h"
      36             : #include "llvm/IR/Verifier.h"
      37             : #include "llvm/InitializePasses.h"
      38             : #include "llvm/LTO/LTO.h"
      39             : #include "llvm/LTO/legacy/LTOModule.h"
      40             : #include "llvm/LTO/legacy/UpdateCompilerUsed.h"
      41             : #include "llvm/Linker/Linker.h"
      42             : #include "llvm/MC/MCAsmInfo.h"
      43             : #include "llvm/MC/MCContext.h"
      44             : #include "llvm/MC/SubtargetFeature.h"
      45             : #include "llvm/Support/CommandLine.h"
      46             : #include "llvm/Support/FileSystem.h"
      47             : #include "llvm/Support/Host.h"
      48             : #include "llvm/Support/MemoryBuffer.h"
      49             : #include "llvm/Support/Signals.h"
      50             : #include "llvm/Support/TargetRegistry.h"
      51             : #include "llvm/Support/TargetSelect.h"
      52             : #include "llvm/Support/ToolOutputFile.h"
      53             : #include "llvm/Support/YAMLTraits.h"
      54             : #include "llvm/Support/raw_ostream.h"
      55             : #include "llvm/Target/TargetOptions.h"
      56             : #include "llvm/Transforms/IPO.h"
      57             : #include "llvm/Transforms/IPO/Internalize.h"
      58             : #include "llvm/Transforms/IPO/PassManagerBuilder.h"
      59             : #include "llvm/Transforms/ObjCARC.h"
      60             : #include "llvm/Transforms/Utils/ModuleUtils.h"
      61             : #include <system_error>
      62             : using namespace llvm;
      63             : 
      64           0 : const char* LTOCodeGenerator::getVersionString() {
      65             : #ifdef LLVM_VERSION_INFO
      66             :   return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
      67             : #else
      68           0 :   return PACKAGE_NAME " version " PACKAGE_VERSION;
      69             : #endif
      70             : }
      71             : 
      72             : namespace llvm {
      73       81677 : cl::opt<bool> LTODiscardValueNames(
      74             :     "lto-discard-value-names",
      75       81677 :     cl::desc("Strip names from Value during LTO (other than GlobalValue)."),
      76             : #ifdef NDEBUG
      77      163354 :     cl::init(true),
      78             : #else
      79             :     cl::init(false),
      80             : #endif
      81      245031 :     cl::Hidden);
      82             : 
      83             : cl::opt<std::string>
      84       81677 :     LTORemarksFilename("lto-pass-remarks-output",
      85       81677 :                        cl::desc("Output filename for pass remarks"),
      86      163354 :                        cl::value_desc("filename"));
      87             : 
      88       81677 : cl::opt<bool> LTOPassRemarksWithHotness(
      89             :     "lto-pass-remarks-with-hotness",
      90       81677 :     cl::desc("With PGO, include profile count in optimization remarks"),
      91      245031 :     cl::Hidden);
      92             : }
      93             : 
      94          43 : LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
      95          43 :     : Context(Context), MergedModule(new Module("ld-temp.o", Context)),
      96         258 :       TheLinker(new Linker(*MergedModule)) {
      97          43 :   Context.setDiscardValueNames(LTODiscardValueNames);
      98          43 :   Context.enableDebugTypeODRUniquing();
      99          43 :   initializeLTOPasses();
     100          43 : }
     101             : 
     102         117 : LTOCodeGenerator::~LTOCodeGenerator() {}
     103             : 
     104             : // Initialize LTO passes. Please keep this function in sync with
     105             : // PassManagerBuilder::populateLTOPassManager(), and make sure all LTO
     106             : // passes are initialized.
     107          43 : void LTOCodeGenerator::initializeLTOPasses() {
     108          43 :   PassRegistry &R = *PassRegistry::getPassRegistry();
     109             : 
     110          43 :   initializeInternalizeLegacyPassPass(R);
     111          43 :   initializeIPSCCPLegacyPassPass(R);
     112          43 :   initializeGlobalOptLegacyPassPass(R);
     113          43 :   initializeConstantMergeLegacyPassPass(R);
     114          43 :   initializeDAHPass(R);
     115          43 :   initializeInstructionCombiningPassPass(R);
     116          43 :   initializeSimpleInlinerPass(R);
     117          43 :   initializePruneEHPass(R);
     118          43 :   initializeGlobalDCELegacyPassPass(R);
     119          43 :   initializeArgPromotionPass(R);
     120          43 :   initializeJumpThreadingPass(R);
     121          43 :   initializeSROALegacyPassPass(R);
     122          43 :   initializePostOrderFunctionAttrsLegacyPassPass(R);
     123          43 :   initializeReversePostOrderFunctionAttrsLegacyPassPass(R);
     124          43 :   initializeGlobalsAAWrapperPassPass(R);
     125          43 :   initializeLegacyLICMPassPass(R);
     126          43 :   initializeMergedLoadStoreMotionLegacyPassPass(R);
     127          43 :   initializeGVNLegacyPassPass(R);
     128          43 :   initializeMemCpyOptLegacyPassPass(R);
     129          43 :   initializeDCELegacyPassPass(R);
     130          43 :   initializeCFGSimplifyPassPass(R);
     131          43 : }
     132             : 
     133          45 : void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) {
     134             :   const std::vector<StringRef> &undefs = Mod->getAsmUndefinedRefs();
     135          94 :   for (int i = 0, e = undefs.size(); i != e; ++i)
     136          12 :     AsmUndefinedRefs[undefs[i]] = 1;
     137          45 : }
     138             : 
     139          44 : bool LTOCodeGenerator::addModule(LTOModule *Mod) {
     140             :   assert(&Mod->getModule().getContext() == &Context &&
     141             :          "Expected module in same context");
     142             : 
     143          88 :   bool ret = TheLinker->linkInModule(Mod->takeModule());
     144          44 :   setAsmUndefinedRefs(Mod);
     145             : 
     146             :   // We've just changed the input, so let's make sure we verify it.
     147          44 :   HasVerifiedInput = false;
     148             : 
     149          44 :   return !ret;
     150             : }
     151             : 
     152           1 : void LTOCodeGenerator::setModule(std::unique_ptr<LTOModule> Mod) {
     153             :   assert(&Mod->getModule().getContext() == &Context &&
     154             :          "Expected module in same context");
     155             : 
     156           1 :   AsmUndefinedRefs.clear();
     157             : 
     158           1 :   MergedModule = Mod->takeModule();
     159           1 :   TheLinker = make_unique<Linker>(*MergedModule);
     160           1 :   setAsmUndefinedRefs(&*Mod);
     161             : 
     162             :   // We've just changed the input, so let's make sure we verify it.
     163           1 :   HasVerifiedInput = false;
     164           1 : }
     165             : 
     166          43 : void LTOCodeGenerator::setTargetOptions(const TargetOptions &Options) {
     167          43 :   this->Options = Options;
     168          43 : }
     169             : 
     170          43 : void LTOCodeGenerator::setDebugInfo(lto_debug_model Debug) {
     171          43 :   switch (Debug) {
     172           0 :   case LTO_DEBUG_MODEL_NONE:
     173           0 :     EmitDwarfDebugInfo = false;
     174           0 :     return;
     175             : 
     176          43 :   case LTO_DEBUG_MODEL_DWARF:
     177          43 :     EmitDwarfDebugInfo = true;
     178          43 :     return;
     179             :   }
     180           0 :   llvm_unreachable("Unknown debug format!");
     181             : }
     182             : 
     183          40 : void LTOCodeGenerator::setOptLevel(unsigned Level) {
     184          40 :   OptLevel = Level;
     185          40 :   switch (OptLevel) {
     186           2 :   case 0:
     187           2 :     CGOptLevel = CodeGenOpt::None;
     188           2 :     return;
     189           0 :   case 1:
     190           0 :     CGOptLevel = CodeGenOpt::Less;
     191           0 :     return;
     192          38 :   case 2:
     193          38 :     CGOptLevel = CodeGenOpt::Default;
     194          38 :     return;
     195           0 :   case 3:
     196           0 :     CGOptLevel = CodeGenOpt::Aggressive;
     197           0 :     return;
     198             :   }
     199           0 :   llvm_unreachable("Unknown optimization level!");
     200             : }
     201             : 
     202           2 : bool LTOCodeGenerator::writeMergedModules(StringRef Path) {
     203           2 :   if (!determineTarget())
     204             :     return false;
     205             : 
     206             :   // We always run the verifier once on the merged module.
     207           2 :   verifyMergedModuleOnce();
     208             : 
     209             :   // mark which symbols can not be internalized
     210           2 :   applyScopeRestrictions();
     211             : 
     212             :   // create output file
     213             :   std::error_code EC;
     214           2 :   ToolOutputFile Out(Path, EC, sys::fs::F_None);
     215           2 :   if (EC) {
     216           0 :     std::string ErrMsg = "could not open bitcode file for writing: ";
     217           0 :     ErrMsg += Path.str() + ": " + EC.message();
     218           0 :     emitError(ErrMsg);
     219             :     return false;
     220             :   }
     221             : 
     222             :   // write bitcode to it
     223           4 :   WriteBitcodeToFile(*MergedModule, Out.os(), ShouldEmbedUselists);
     224           2 :   Out.os().close();
     225             : 
     226           2 :   if (Out.os().has_error()) {
     227           0 :     std::string ErrMsg = "could not write bitcode file: ";
     228           0 :     ErrMsg += Path.str() + ": " + Out.os().error().message();
     229           0 :     emitError(ErrMsg);
     230             :     Out.os().clear_error();
     231             :     return false;
     232             :   }
     233             : 
     234             :   Out.keep();
     235           2 :   return true;
     236             : }
     237             : 
     238           1 : bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) {
     239             :   // make unique temp output file to put generated code
     240             :   SmallString<128> Filename;
     241             :   int FD;
     242             : 
     243             :   StringRef Extension
     244           1 :       (FileType == TargetMachine::CGFT_AssemblyFile ? "s" : "o");
     245             : 
     246             :   std::error_code EC =
     247           1 :       sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename);
     248           1 :   if (EC) {
     249           0 :     emitError(EC.message());
     250           0 :     return false;
     251             :   }
     252             : 
     253             :   // generate object file
     254           2 :   ToolOutputFile objFile(Filename, FD);
     255             : 
     256           2 :   bool genResult = compileOptimized(&objFile.os());
     257           1 :   objFile.os().close();
     258           1 :   if (objFile.os().has_error()) {
     259           0 :     emitError((Twine("could not write object file: ") + Filename + ": " +
     260           0 :                objFile.os().error().message())
     261           0 :                   .str());
     262             :     objFile.os().clear_error();
     263           0 :     sys::fs::remove(Twine(Filename));
     264           0 :     return false;
     265             :   }
     266             : 
     267             :   objFile.keep();
     268           1 :   if (!genResult) {
     269           0 :     sys::fs::remove(Twine(Filename));
     270           0 :     return false;
     271             :   }
     272             : 
     273             :   NativeObjectPath = Filename.c_str();
     274           1 :   *Name = NativeObjectPath.c_str();
     275           1 :   return true;
     276             : }
     277             : 
     278             : std::unique_ptr<MemoryBuffer>
     279           0 : LTOCodeGenerator::compileOptimized() {
     280             :   const char *name;
     281           0 :   if (!compileOptimizedToFile(&name))
     282             :     return nullptr;
     283             : 
     284             :   // read .o file into memory buffer
     285             :   ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
     286           0 :       MemoryBuffer::getFile(name, -1, false);
     287           0 :   if (std::error_code EC = BufferOrErr.getError()) {
     288           0 :     emitError(EC.message());
     289           0 :     sys::fs::remove(NativeObjectPath);
     290             :     return nullptr;
     291             :   }
     292             : 
     293             :   // remove temp files
     294           0 :   sys::fs::remove(NativeObjectPath);
     295             : 
     296             :   return std::move(*BufferOrErr);
     297             : }
     298             : 
     299           1 : bool LTOCodeGenerator::compile_to_file(const char **Name, bool DisableVerify,
     300             :                                        bool DisableInline,
     301             :                                        bool DisableGVNLoadPRE,
     302             :                                        bool DisableVectorization) {
     303           1 :   if (!optimize(DisableVerify, DisableInline, DisableGVNLoadPRE,
     304             :                 DisableVectorization))
     305             :     return false;
     306             : 
     307           1 :   return compileOptimizedToFile(Name);
     308             : }
     309             : 
     310             : std::unique_ptr<MemoryBuffer>
     311           0 : LTOCodeGenerator::compile(bool DisableVerify, bool DisableInline,
     312             :                           bool DisableGVNLoadPRE, bool DisableVectorization) {
     313           0 :   if (!optimize(DisableVerify, DisableInline, DisableGVNLoadPRE,
     314             :                 DisableVectorization))
     315             :     return nullptr;
     316             : 
     317           0 :   return compileOptimized();
     318             : }
     319             : 
     320          82 : bool LTOCodeGenerator::determineTarget() {
     321          82 :   if (TargetMach)
     322             :     return true;
     323             : 
     324          40 :   TripleStr = MergedModule->getTargetTriple();
     325          40 :   if (TripleStr.empty()) {
     326           8 :     TripleStr = sys::getDefaultTargetTriple();
     327           4 :     MergedModule->setTargetTriple(TripleStr);
     328             :   }
     329          40 :   llvm::Triple Triple(TripleStr);
     330             : 
     331             :   // create target machine from info for merged modules
     332             :   std::string ErrMsg;
     333          40 :   MArch = TargetRegistry::lookupTarget(TripleStr, ErrMsg);
     334          40 :   if (!MArch) {
     335           0 :     emitError(ErrMsg);
     336           0 :     return false;
     337             :   }
     338             : 
     339             :   // Construct LTOModule, hand over ownership of module and target. Use MAttr as
     340             :   // the default set of features.
     341          40 :   SubtargetFeatures Features(MAttr);
     342          40 :   Features.getDefaultSubtargetFeatures(Triple);
     343          80 :   FeatureStr = Features.getString();
     344             :   // Set a default CPU for Darwin triples.
     345          40 :   if (MCpu.empty() && Triple.isOSDarwin()) {
     346          16 :     if (Triple.getArch() == llvm::Triple::x86_64)
     347          16 :       MCpu = "core2";
     348           0 :     else if (Triple.getArch() == llvm::Triple::x86)
     349           0 :       MCpu = "yonah";
     350           0 :     else if (Triple.getArch() == llvm::Triple::aarch64)
     351           0 :       MCpu = "cyclone";
     352             :   }
     353             : 
     354          80 :   TargetMach = createTargetMachine();
     355             :   return true;
     356             : }
     357             : 
     358          81 : std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() {
     359          81 :   return std::unique_ptr<TargetMachine>(MArch->createTargetMachine(
     360         324 :       TripleStr, MCpu, FeatureStr, Options, RelocModel, None, CGOptLevel));
     361             : }
     362             : 
     363             : // If a linkonce global is present in the MustPreserveSymbols, we need to make
     364             : // sure we honor this. To force the compiler to not drop it, we add it to the
     365             : // "llvm.compiler.used" global.
     366          40 : void LTOCodeGenerator::preserveDiscardableGVs(
     367             :     Module &TheModule,
     368             :     llvm::function_ref<bool(const GlobalValue &)> mustPreserveGV) {
     369             :   std::vector<GlobalValue *> Used;
     370         116 :   auto mayPreserveGlobal = [&](GlobalValue &GV) {
     371          36 :     if (!GV.isDiscardableIfUnused() || GV.isDeclaration() ||
     372          18 :         !mustPreserveGV(GV))
     373             :       return;
     374           5 :     if (GV.hasAvailableExternallyLinkage())
     375           0 :       return emitWarning(
     376           0 :           (Twine("Linker asked to preserve available_externally global: '") +
     377           0 :            GV.getName() + "'").str());
     378           5 :     if (GV.hasInternalLinkage())
     379           0 :       return emitWarning((Twine("Linker asked to preserve internal global: '") +
     380           0 :                    GV.getName() + "'").str());
     381          10 :     Used.push_back(&GV);
     382          40 :   };
     383         133 :   for (auto &GV : TheModule)
     384          93 :     mayPreserveGlobal(GV);
     385          63 :   for (auto &GV : TheModule.globals())
     386          23 :     mayPreserveGlobal(GV);
     387          40 :   for (auto &GV : TheModule.aliases())
     388           0 :     mayPreserveGlobal(GV);
     389             : 
     390          40 :   if (Used.empty())
     391             :     return;
     392             : 
     393           2 :   appendToCompilerUsed(TheModule, Used);
     394             : }
     395             : 
     396          42 : void LTOCodeGenerator::applyScopeRestrictions() {
     397          42 :   if (ScopeRestrictionsDone)
     398           2 :     return;
     399             : 
     400             :   // Declare a callback for the internalize pass that will ask for every
     401             :   // candidate GlobalValue if it can be internalized or not.
     402             :   Mangler Mang;
     403             :   SmallString<64> MangledName;
     404         109 :   auto mustPreserveGV = [&](const GlobalValue &GV) -> bool {
     405             :     // Unnamed globals can't be mangled, but they can't be preserved either.
     406         109 :     if (!GV.hasName())
     407             :       return false;
     408             : 
     409             :     // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
     410             :     // with the linker supplied name, which on Darwin includes a leading
     411             :     // underscore.
     412         324 :     MangledName.clear();
     413         324 :     MangledName.reserve(GV.getName().size() + 1);
     414         216 :     Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
     415         216 :     return MustPreserveSymbols.count(MangledName);
     416          40 :   };
     417             : 
     418             :   // Preserve linkonce value on linker request
     419          40 :   preserveDiscardableGVs(*MergedModule, mustPreserveGV);
     420             : 
     421          40 :   if (!ShouldInternalize)
     422             :     return;
     423             : 
     424          40 :   if (ShouldRestoreGlobalsLinkage) {
     425             :     // Record the linkage type of non-local symbols so they can be restored
     426             :     // prior
     427             :     // to module splitting.
     428           3 :     auto RecordLinkage = [&](const GlobalValue &GV) {
     429           6 :       if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() &&
     430             :           GV.hasName())
     431           6 :         ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage()));
     432           4 :     };
     433           4 :     for (auto &GV : *MergedModule)
     434           3 :       RecordLinkage(GV);
     435           1 :     for (auto &GV : MergedModule->globals())
     436           0 :       RecordLinkage(GV);
     437           1 :     for (auto &GV : MergedModule->aliases())
     438           0 :       RecordLinkage(GV);
     439             :   }
     440             : 
     441             :   // Update the llvm.compiler_used globals to force preserving libcalls and
     442             :   // symbols referenced from asm
     443          80 :   updateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs);
     444             : 
     445          80 :   internalizeModule(*MergedModule, mustPreserveGV);
     446             : 
     447          40 :   ScopeRestrictionsDone = true;
     448             : }
     449             : 
     450             : /// Restore original linkage for symbols that may have been internalized
     451          40 : void LTOCodeGenerator::restoreLinkageForExternals() {
     452          40 :   if (!ShouldInternalize || !ShouldRestoreGlobalsLinkage)
     453          39 :     return;
     454             : 
     455             :   assert(ScopeRestrictionsDone &&
     456             :          "Cannot externalize without internalization!");
     457             : 
     458           1 :   if (ExternalSymbols.empty())
     459             :     return;
     460             : 
     461           5 :   auto externalize = [this](GlobalValue &GV) {
     462           1 :     if (!GV.hasLocalLinkage() || !GV.hasName())
     463             :       return;
     464             : 
     465           1 :     auto I = ExternalSymbols.find(GV.getName());
     466           2 :     if (I == ExternalSymbols.end())
     467             :       return;
     468             : 
     469           1 :     GV.setLinkage(I->second);
     470           1 :   };
     471             : 
     472           1 :   llvm::for_each(MergedModule->functions(), externalize);
     473           1 :   llvm::for_each(MergedModule->globals(), externalize);
     474           1 :   llvm::for_each(MergedModule->aliases(), externalize);
     475             : }
     476             : 
     477          82 : void LTOCodeGenerator::verifyMergedModuleOnce() {
     478             :   // Only run on the first call.
     479          82 :   if (HasVerifiedInput)
     480          42 :     return;
     481          40 :   HasVerifiedInput = true;
     482             : 
     483          40 :   bool BrokenDebugInfo = false;
     484          80 :   if (verifyModule(*MergedModule, &dbgs(), &BrokenDebugInfo))
     485           0 :     report_fatal_error("Broken module found, compilation aborted!");
     486          40 :   if (BrokenDebugInfo) {
     487           0 :     emitWarning("Invalid debug info found, debug info will be stripped");
     488           0 :     StripDebugInfo(*MergedModule);
     489             :   }
     490             : }
     491             : 
     492          39 : void LTOCodeGenerator::finishOptimizationRemarks() {
     493          39 :   if (DiagnosticOutputFile) {
     494             :     DiagnosticOutputFile->keep();
     495             :     // FIXME: LTOCodeGenerator dtor is not invoked on Darwin
     496           2 :     DiagnosticOutputFile->os().flush();
     497             :   }
     498          39 : }
     499             : 
     500             : /// Optimize merged modules using various IPO passes
     501          40 : bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline,
     502             :                                 bool DisableGVNLoadPRE,
     503             :                                 bool DisableVectorization) {
     504          40 :   if (!this->determineTarget())
     505             :     return false;
     506             : 
     507             :   auto DiagFileOrErr = lto::setupOptimizationRemarks(
     508         120 :       Context, LTORemarksFilename, LTOPassRemarksWithHotness);
     509          40 :   if (!DiagFileOrErr) {
     510           0 :     errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
     511           0 :     report_fatal_error("Can't get an output file for the remarks");
     512             :   }
     513             :   DiagnosticOutputFile = std::move(*DiagFileOrErr);
     514             : 
     515             :   // We always run the verifier once on the merged module, the `DisableVerify`
     516             :   // parameter only applies to subsequent verify.
     517          40 :   verifyMergedModuleOnce();
     518             : 
     519             :   // Mark which symbols can not be internalized
     520          40 :   this->applyScopeRestrictions();
     521             : 
     522             :   // Instantiate the pass manager to organize the passes.
     523          80 :   legacy::PassManager passes;
     524             : 
     525             :   // Add an appropriate DataLayout instance for this module...
     526          40 :   MergedModule->setDataLayout(TargetMach->createDataLayout());
     527             : 
     528          40 :   passes.add(
     529          80 :       createTargetTransformInfoWrapperPass(TargetMach->getTargetIRAnalysis()));
     530             : 
     531          40 :   Triple TargetTriple(TargetMach->getTargetTriple());
     532          80 :   PassManagerBuilder PMB;
     533          40 :   PMB.DisableGVNLoadPRE = DisableGVNLoadPRE;
     534          40 :   PMB.LoopVectorize = !DisableVectorization;
     535          40 :   PMB.SLPVectorize = !DisableVectorization;
     536          40 :   if (!DisableInline)
     537          40 :     PMB.Inliner = createFunctionInliningPass();
     538          40 :   PMB.LibraryInfo = new TargetLibraryInfoImpl(TargetTriple);
     539          40 :   if (Freestanding)
     540           1 :     PMB.LibraryInfo->disableAllFunctions();
     541          40 :   PMB.OptLevel = OptLevel;
     542          40 :   PMB.VerifyInput = !DisableVerify;
     543          40 :   PMB.VerifyOutput = !DisableVerify;
     544             : 
     545          40 :   PMB.populateLTOPassManager(passes);
     546             : 
     547             :   // Run our queue of passes all at once now, efficiently.
     548          40 :   passes.run(*MergedModule);
     549             : 
     550             :   return true;
     551             : }
     552             : 
     553          40 : bool LTOCodeGenerator::compileOptimized(ArrayRef<raw_pwrite_stream *> Out) {
     554          40 :   if (!this->determineTarget())
     555             :     return false;
     556             : 
     557             :   // We always run the verifier once on the merged module.  If it has already
     558             :   // been called in optimize(), this call will return early.
     559          40 :   verifyMergedModuleOnce();
     560             : 
     561          79 :   legacy::PassManager preCodeGenPasses;
     562             : 
     563             :   // If the bitcode files contain ARC code and were compiled with optimization,
     564             :   // the ObjCARCContractPass must be run, so do it unconditionally here.
     565          40 :   preCodeGenPasses.add(createObjCARCContractPass());
     566          40 :   preCodeGenPasses.run(*MergedModule);
     567             : 
     568             :   // Re-externalize globals that may have been internalized to increase scope
     569             :   // for splitting
     570          40 :   restoreLinkageForExternals();
     571             : 
     572             :   // Do code generation. We need to preserve the module in case the client calls
     573             :   // writeMergedModules() after compilation, but we only need to allow this at
     574             :   // parallelism level 1. This is achieved by having splitCodeGen return the
     575             :   // original module at parallelism level 1 which we then assign back to
     576             :   // MergedModule.
     577         159 :   MergedModule = splitCodeGen(std::move(MergedModule), Out, {},
     578          41 :                               [&]() { return createTargetMachine(); }, FileType,
     579          80 :                               ShouldRestoreGlobalsLinkage);
     580             : 
     581             :   // If statistics were requested, print them out after codegen.
     582          39 :   if (llvm::AreStatisticsEnabled())
     583           0 :     llvm::PrintStatistics();
     584          39 :   reportAndResetTimings();
     585             : 
     586          39 :   finishOptimizationRemarks();
     587             : 
     588             :   return true;
     589             : }
     590             : 
     591             : /// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging
     592             : /// LTO problems.
     593           0 : void LTOCodeGenerator::setCodeGenDebugOptions(StringRef Options) {
     594           0 :   for (std::pair<StringRef, StringRef> o = getToken(Options); !o.first.empty();
     595           0 :        o = getToken(o.second))
     596           0 :     CodegenOptions.push_back(o.first);
     597           0 : }
     598             : 
     599           0 : void LTOCodeGenerator::parseCodeGenDebugOptions() {
     600             :   // if options were requested, set them
     601           0 :   if (!CodegenOptions.empty()) {
     602             :     // ParseCommandLineOptions() expects argv[0] to be program name.
     603           0 :     std::vector<const char *> CodegenArgv(1, "libLLVMLTO");
     604           0 :     for (std::string &Arg : CodegenOptions)
     605           0 :       CodegenArgv.push_back(Arg.c_str());
     606           0 :     cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data());
     607             :   }
     608           0 : }
     609             : 
     610             : 
     611           3 : void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI) {
     612             :   // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
     613             :   lto_codegen_diagnostic_severity_t Severity;
     614           3 :   switch (DI.getSeverity()) {
     615           1 :   case DS_Error:
     616             :     Severity = LTO_DS_ERROR;
     617           1 :     break;
     618           0 :   case DS_Warning:
     619             :     Severity = LTO_DS_WARNING;
     620           0 :     break;
     621           2 :   case DS_Remark:
     622             :     Severity = LTO_DS_REMARK;
     623           2 :     break;
     624           0 :   case DS_Note:
     625             :     Severity = LTO_DS_NOTE;
     626           0 :     break;
     627             :   }
     628             :   // Create the string that will be reported to the external diagnostic handler.
     629             :   std::string MsgStorage;
     630           3 :   raw_string_ostream Stream(MsgStorage);
     631             :   DiagnosticPrinterRawOStream DP(Stream);
     632           3 :   DI.print(DP);
     633             :   Stream.flush();
     634             : 
     635             :   // If this method has been called it means someone has set up an external
     636             :   // diagnostic handler. Assert on that.
     637             :   assert(DiagHandler && "Invalid diagnostic handler");
     638           6 :   (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
     639           3 : }
     640             : 
     641             : namespace {
     642           2 : struct LTODiagnosticHandler : public DiagnosticHandler {
     643             :   LTOCodeGenerator *CodeGenerator;
     644             :   LTODiagnosticHandler(LTOCodeGenerator *CodeGenPtr)
     645           6 :       : CodeGenerator(CodeGenPtr) {}
     646           3 :   bool handleDiagnostics(const DiagnosticInfo &DI) override {
     647           3 :     CodeGenerator->DiagnosticHandler(DI);
     648           3 :     return true;
     649             :   }
     650             : };
     651             : }
     652             : 
     653             : void
     654           3 : LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler,
     655             :                                        void *Ctxt) {
     656           3 :   this->DiagHandler = DiagHandler;
     657           3 :   this->DiagContext = Ctxt;
     658           3 :   if (!DiagHandler)
     659           0 :     return Context.setDiagnosticHandler(nullptr);
     660             :   // Register the LTOCodeGenerator stub in the LLVMContext to forward the
     661             :   // diagnostic to the external DiagHandler.
     662           9 :   Context.setDiagnosticHandler(llvm::make_unique<LTODiagnosticHandler>(this),
     663             :                                true);
     664             : }
     665             : 
     666             : namespace {
     667           0 : class LTODiagnosticInfo : public DiagnosticInfo {
     668             :   const Twine &Msg;
     669             : public:
     670             :   LTODiagnosticInfo(const Twine &DiagMsg, DiagnosticSeverity Severity=DS_Error)
     671           0 :       : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
     672           0 :   void print(DiagnosticPrinter &DP) const override { DP << Msg; }
     673             : };
     674             : }
     675             : 
     676           0 : void LTOCodeGenerator::emitError(const std::string &ErrMsg) {
     677           0 :   if (DiagHandler)
     678           0 :     (*DiagHandler)(LTO_DS_ERROR, ErrMsg.c_str(), DiagContext);
     679             :   else
     680           0 :     Context.diagnose(LTODiagnosticInfo(ErrMsg));
     681           0 : }
     682             : 
     683           0 : void LTOCodeGenerator::emitWarning(const std::string &ErrMsg) {
     684           0 :   if (DiagHandler)
     685           0 :     (*DiagHandler)(LTO_DS_WARNING, ErrMsg.c_str(), DiagContext);
     686             :   else
     687           0 :     Context.diagnose(LTODiagnosticInfo(ErrMsg, DS_Warning));
     688      245031 : }

Generated by: LCOV version 1.13