brintos

brintos / llvm-project-archived public Read only

0
0
Text · 105.6 KiB · a02af59 Raw
2633 lines · cpp
1//===-LTO.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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements functions and classes used to support LTO.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/LTO/LTO.h"14#include "llvm/ADT/ArrayRef.h"15#include "llvm/ADT/ScopeExit.h"16#include "llvm/ADT/SmallSet.h"17#include "llvm/ADT/StableHashing.h"18#include "llvm/ADT/Statistic.h"19#include "llvm/ADT/StringExtras.h"20#include "llvm/Analysis/OptimizationRemarkEmitter.h"21#include "llvm/Analysis/StackSafetyAnalysis.h"22#include "llvm/Analysis/TargetLibraryInfo.h"23#include "llvm/Analysis/TargetTransformInfo.h"24#include "llvm/Bitcode/BitcodeReader.h"25#include "llvm/Bitcode/BitcodeWriter.h"26#include "llvm/CGData/CodeGenData.h"27#include "llvm/CodeGen/Analysis.h"28#include "llvm/Config/llvm-config.h"29#include "llvm/IR/AutoUpgrade.h"30#include "llvm/IR/DiagnosticPrinter.h"31#include "llvm/IR/Intrinsics.h"32#include "llvm/IR/LLVMRemarkStreamer.h"33#include "llvm/IR/LegacyPassManager.h"34#include "llvm/IR/Mangler.h"35#include "llvm/IR/Metadata.h"36#include "llvm/IR/RuntimeLibcalls.h"37#include "llvm/LTO/LTOBackend.h"38#include "llvm/Linker/IRMover.h"39#include "llvm/MC/TargetRegistry.h"40#include "llvm/Object/IRObjectFile.h"41#include "llvm/Support/Caching.h"42#include "llvm/Support/CommandLine.h"43#include "llvm/Support/Compiler.h"44#include "llvm/Support/Error.h"45#include "llvm/Support/FileSystem.h"46#include "llvm/Support/JSON.h"47#include "llvm/Support/MemoryBuffer.h"48#include "llvm/Support/Path.h"49#include "llvm/Support/Process.h"50#include "llvm/Support/SHA1.h"51#include "llvm/Support/SourceMgr.h"52#include "llvm/Support/ThreadPool.h"53#include "llvm/Support/Threading.h"54#include "llvm/Support/TimeProfiler.h"55#include "llvm/Support/ToolOutputFile.h"56#include "llvm/Support/VCSRevision.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/MemProfContextDisambiguation.h"61#include "llvm/Transforms/IPO/WholeProgramDevirt.h"62#include "llvm/Transforms/Utils/FunctionImportUtils.h"63#include "llvm/Transforms/Utils/SplitModule.h"64 65#include <optional>66#include <set>67 68using namespace llvm;69using namespace lto;70using namespace object;71 72#define DEBUG_TYPE "lto"73 74static cl::opt<bool>75    DumpThinCGSCCs("dump-thin-cg-sccs", cl::init(false), cl::Hidden,76                   cl::desc("Dump the SCCs in the ThinLTO index's callgraph"));77 78namespace llvm {79extern cl::opt<bool> CodeGenDataThinLTOTwoRounds;80extern cl::opt<bool> ForceImportAll;81} // end namespace llvm82 83namespace llvm {84/// Enable global value internalization in LTO.85cl::opt<bool> EnableLTOInternalization(86    "enable-lto-internalization", cl::init(true), cl::Hidden,87    cl::desc("Enable global value internalization in LTO"));88 89static cl::opt<bool>90    LTOKeepSymbolCopies("lto-keep-symbol-copies", cl::init(false), cl::Hidden,91                        cl::desc("Keep copies of symbols in LTO indexing"));92 93/// Indicate we are linking with an allocator that supports hot/cold operator94/// new interfaces.95extern cl::opt<bool> SupportsHotColdNew;96 97/// Enable MemProf context disambiguation for thin link.98extern cl::opt<bool> EnableMemProfContextDisambiguation;99} // namespace llvm100 101// Computes a unique hash for the Module considering the current list of102// export/import and other global analysis results.103// Returns the hash in its hexadecimal representation.104std::string llvm::computeLTOCacheKey(105    const Config &Conf, const ModuleSummaryIndex &Index, StringRef ModuleID,106    const FunctionImporter::ImportMapTy &ImportList,107    const FunctionImporter::ExportSetTy &ExportList,108    const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,109    const GVSummaryMapTy &DefinedGlobals,110    const DenseSet<GlobalValue::GUID> &CfiFunctionDefs,111    const DenseSet<GlobalValue::GUID> &CfiFunctionDecls) {112  // Compute the unique hash for this entry.113  // This is based on the current compiler version, the module itself, the114  // export list, the hash for every single module in the import list, the115  // list of ResolvedODR for the module, and the list of preserved symbols.116  SHA1 Hasher;117 118  // Start with the compiler revision119  Hasher.update(LLVM_VERSION_STRING);120#ifdef LLVM_REVISION121  Hasher.update(LLVM_REVISION);122#endif123 124  // Include the parts of the LTO configuration that affect code generation.125  auto AddString = [&](StringRef Str) {126    Hasher.update(Str);127    Hasher.update(ArrayRef<uint8_t>{0});128  };129  auto AddUnsigned = [&](unsigned I) {130    uint8_t Data[4];131    support::endian::write32le(Data, I);132    Hasher.update(Data);133  };134  auto AddUint64 = [&](uint64_t I) {135    uint8_t Data[8];136    support::endian::write64le(Data, I);137    Hasher.update(Data);138  };139  auto AddUint8 = [&](const uint8_t I) {140    Hasher.update(ArrayRef<uint8_t>(&I, 1));141  };142  AddString(Conf.CPU);143  // FIXME: Hash more of Options. For now all clients initialize Options from144  // command-line flags (which is unsupported in production), but may set145  // X86RelaxRelocations. The clang driver can also pass FunctionSections,146  // DataSections and DebuggerTuning via command line flags.147  AddUnsigned(Conf.Options.MCOptions.X86RelaxRelocations);148  AddUnsigned(Conf.Options.FunctionSections);149  AddUnsigned(Conf.Options.DataSections);150  AddUnsigned((unsigned)Conf.Options.DebuggerTuning);151  for (auto &A : Conf.MAttrs)152    AddString(A);153  if (Conf.RelocModel)154    AddUnsigned(*Conf.RelocModel);155  else156    AddUnsigned(-1);157  if (Conf.CodeModel)158    AddUnsigned(*Conf.CodeModel);159  else160    AddUnsigned(-1);161  for (const auto &S : Conf.MllvmArgs)162    AddString(S);163  AddUnsigned(static_cast<int>(Conf.CGOptLevel));164  AddUnsigned(static_cast<int>(Conf.CGFileType));165  AddUnsigned(Conf.OptLevel);166  AddUnsigned(Conf.Freestanding);167  AddString(Conf.OptPipeline);168  AddString(Conf.AAPipeline);169  AddString(Conf.OverrideTriple);170  AddString(Conf.DefaultTriple);171  AddString(Conf.DwoDir);172  AddUint8(Conf.Dtlto);173 174  // Include the hash for the current module175  auto ModHash = Index.getModuleHash(ModuleID);176  Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));177 178  // TODO: `ExportList` is determined by `ImportList`. Since `ImportList` is179  // used to compute cache key, we could omit hashing `ExportList` here.180  std::vector<uint64_t> ExportsGUID;181  ExportsGUID.reserve(ExportList.size());182  for (const auto &VI : ExportList)183    ExportsGUID.push_back(VI.getGUID());184 185  // Sort the export list elements GUIDs.186  llvm::sort(ExportsGUID);187  for (auto GUID : ExportsGUID)188    Hasher.update(ArrayRef<uint8_t>((uint8_t *)&GUID, sizeof(GUID)));189 190  // Order using module hash, to be both independent of module name and191  // module order.192  auto Comp = [&](const std::pair<StringRef, GlobalValue::GUID> &L,193                  const std::pair<StringRef, GlobalValue::GUID> &R) {194    return std::make_pair(Index.getModule(L.first)->second, L.second) <195           std::make_pair(Index.getModule(R.first)->second, R.second);196  };197  FunctionImporter::SortedImportList SortedImportList(ImportList, Comp);198 199  // Count the number of imports for each source module.200  DenseMap<StringRef, unsigned> ModuleToNumImports;201  for (const auto &[FromModule, GUID, Type] : SortedImportList)202    ++ModuleToNumImports[FromModule];203 204  std::optional<StringRef> LastModule;205  for (const auto &[FromModule, GUID, Type] : SortedImportList) {206    if (LastModule != FromModule) {207      // Include the hash for every module we import functions from. The set of208      // imported symbols for each module may affect code generation and is209      // sensitive to link order, so include that as well.210      LastModule = FromModule;211      auto ModHash = Index.getModule(FromModule)->second;212      Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));213      AddUint64(ModuleToNumImports[FromModule]);214    }215    AddUint64(GUID);216    AddUint8(Type);217  }218 219  // Include the hash for the resolved ODR.220  for (auto &Entry : ResolvedODR) {221    Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&Entry.first,222                                    sizeof(GlobalValue::GUID)));223    Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&Entry.second,224                                    sizeof(GlobalValue::LinkageTypes)));225  }226 227  // Members of CfiFunctionDefs and CfiFunctionDecls that are referenced or228  // defined in this module.229  std::set<GlobalValue::GUID> UsedCfiDefs;230  std::set<GlobalValue::GUID> UsedCfiDecls;231 232  // Typeids used in this module.233  std::set<GlobalValue::GUID> UsedTypeIds;234 235  auto AddUsedCfiGlobal = [&](GlobalValue::GUID ValueGUID) {236    if (CfiFunctionDefs.contains(ValueGUID))237      UsedCfiDefs.insert(ValueGUID);238    if (CfiFunctionDecls.contains(ValueGUID))239      UsedCfiDecls.insert(ValueGUID);240  };241 242  auto AddUsedThings = [&](GlobalValueSummary *GS) {243    if (!GS) return;244    AddUnsigned(GS->getVisibility());245    AddUnsigned(GS->isLive());246    AddUnsigned(GS->canAutoHide());247    for (const ValueInfo &VI : GS->refs()) {248      AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));249      AddUsedCfiGlobal(VI.getGUID());250    }251    if (auto *GVS = dyn_cast<GlobalVarSummary>(GS)) {252      AddUnsigned(GVS->maybeReadOnly());253      AddUnsigned(GVS->maybeWriteOnly());254    }255    if (auto *FS = dyn_cast<FunctionSummary>(GS)) {256      for (auto &TT : FS->type_tests())257        UsedTypeIds.insert(TT);258      for (auto &TT : FS->type_test_assume_vcalls())259        UsedTypeIds.insert(TT.GUID);260      for (auto &TT : FS->type_checked_load_vcalls())261        UsedTypeIds.insert(TT.GUID);262      for (auto &TT : FS->type_test_assume_const_vcalls())263        UsedTypeIds.insert(TT.VFunc.GUID);264      for (auto &TT : FS->type_checked_load_const_vcalls())265        UsedTypeIds.insert(TT.VFunc.GUID);266      for (auto &ET : FS->calls()) {267        AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));268        AddUsedCfiGlobal(ET.first.getGUID());269      }270    }271  };272 273  // Include the hash for the linkage type to reflect internalization and weak274  // resolution, and collect any used type identifier resolutions.275  for (auto &GS : DefinedGlobals) {276    GlobalValue::LinkageTypes Linkage = GS.second->linkage();277    Hasher.update(278        ArrayRef<uint8_t>((const uint8_t *)&Linkage, sizeof(Linkage)));279    AddUsedCfiGlobal(GS.first);280    AddUsedThings(GS.second);281  }282 283  // Imported functions may introduce new uses of type identifier resolutions,284  // so we need to collect their used resolutions as well.285  for (const auto &[FromModule, GUID, Type] : SortedImportList) {286    GlobalValueSummary *S = Index.findSummaryInModule(GUID, FromModule);287    AddUsedThings(S);288    // If this is an alias, we also care about any types/etc. that the aliasee289    // may reference.290    if (auto *AS = dyn_cast_or_null<AliasSummary>(S))291      AddUsedThings(AS->getBaseObject());292  }293 294  auto AddTypeIdSummary = [&](StringRef TId, const TypeIdSummary &S) {295    AddString(TId);296 297    AddUnsigned(S.TTRes.TheKind);298    AddUnsigned(S.TTRes.SizeM1BitWidth);299 300    AddUint64(S.TTRes.AlignLog2);301    AddUint64(S.TTRes.SizeM1);302    AddUint64(S.TTRes.BitMask);303    AddUint64(S.TTRes.InlineBits);304 305    AddUint64(S.WPDRes.size());306    for (auto &WPD : S.WPDRes) {307      AddUnsigned(WPD.first);308      AddUnsigned(WPD.second.TheKind);309      AddString(WPD.second.SingleImplName);310 311      AddUint64(WPD.second.ResByArg.size());312      for (auto &ByArg : WPD.second.ResByArg) {313        AddUint64(ByArg.first.size());314        for (uint64_t Arg : ByArg.first)315          AddUint64(Arg);316        AddUnsigned(ByArg.second.TheKind);317        AddUint64(ByArg.second.Info);318        AddUnsigned(ByArg.second.Byte);319        AddUnsigned(ByArg.second.Bit);320      }321    }322  };323 324  // Include the hash for all type identifiers used by this module.325  for (GlobalValue::GUID TId : UsedTypeIds) {326    auto TidIter = Index.typeIds().equal_range(TId);327    for (const auto &I : make_range(TidIter))328      AddTypeIdSummary(I.second.first, I.second.second);329  }330 331  AddUnsigned(UsedCfiDefs.size());332  for (auto &V : UsedCfiDefs)333    AddUint64(V);334 335  AddUnsigned(UsedCfiDecls.size());336  for (auto &V : UsedCfiDecls)337    AddUint64(V);338 339  if (!Conf.SampleProfile.empty()) {340    auto FileOrErr = MemoryBuffer::getFile(Conf.SampleProfile);341    if (FileOrErr) {342      Hasher.update(FileOrErr.get()->getBuffer());343 344      if (!Conf.ProfileRemapping.empty()) {345        FileOrErr = MemoryBuffer::getFile(Conf.ProfileRemapping);346        if (FileOrErr)347          Hasher.update(FileOrErr.get()->getBuffer());348      }349    }350  }351 352  return toHex(Hasher.result());353}354 355std::string llvm::recomputeLTOCacheKey(const std::string &Key,356                                       StringRef ExtraID) {357  SHA1 Hasher;358 359  auto AddString = [&](StringRef Str) {360    Hasher.update(Str);361    Hasher.update(ArrayRef<uint8_t>{0});362  };363  AddString(Key);364  AddString(ExtraID);365 366  return toHex(Hasher.result());367}368 369static void thinLTOResolvePrevailingGUID(370    const Config &C, ValueInfo VI,371    DenseSet<GlobalValueSummary *> &GlobalInvolvedWithAlias,372    function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>373        isPrevailing,374    function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)>375        recordNewLinkage,376    const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {377  GlobalValue::VisibilityTypes Visibility =378      C.VisibilityScheme == Config::ELF ? VI.getELFVisibility()379                                        : GlobalValue::DefaultVisibility;380  for (auto &S : VI.getSummaryList()) {381    GlobalValue::LinkageTypes OriginalLinkage = S->linkage();382    // Ignore local and appending linkage values since the linker383    // doesn't resolve them.384    if (GlobalValue::isLocalLinkage(OriginalLinkage) ||385        GlobalValue::isAppendingLinkage(S->linkage()))386      continue;387    // We need to emit only one of these. The prevailing module will keep it,388    // but turned into a weak, while the others will drop it when possible.389    // This is both a compile-time optimization and a correctness390    // transformation. This is necessary for correctness when we have exported391    // a reference - we need to convert the linkonce to weak to392    // ensure a copy is kept to satisfy the exported reference.393    // FIXME: We may want to split the compile time and correctness394    // aspects into separate routines.395    if (isPrevailing(VI.getGUID(), S.get())) {396      if (GlobalValue::isLinkOnceLinkage(OriginalLinkage)) {397        S->setLinkage(GlobalValue::getWeakLinkage(398            GlobalValue::isLinkOnceODRLinkage(OriginalLinkage)));399        // The kept copy is eligible for auto-hiding (hidden visibility) if all400        // copies were (i.e. they were all linkonce_odr global unnamed addr).401        // If any copy is not (e.g. it was originally weak_odr), then the symbol402        // must remain externally available (e.g. a weak_odr from an explicitly403        // instantiated template). Additionally, if it is in the404        // GUIDPreservedSymbols set, that means that it is visibile outside405        // the summary (e.g. in a native object or a bitcode file without406        // summary), and in that case we cannot hide it as it isn't possible to407        // check all copies.408        S->setCanAutoHide(VI.canAutoHide() &&409                          !GUIDPreservedSymbols.count(VI.getGUID()));410      }411      if (C.VisibilityScheme == Config::FromPrevailing)412        Visibility = S->getVisibility();413    }414    // Alias and aliasee can't be turned into available_externally.415    // When force-import-all is used, it indicates that object linking is not416    // supported by the target. In this case, we can't change the linkage as417    // well in case the global is converted to declaration.418    else if (!isa<AliasSummary>(S.get()) &&419             !GlobalInvolvedWithAlias.count(S.get()) && !ForceImportAll)420      S->setLinkage(GlobalValue::AvailableExternallyLinkage);421 422    // For ELF, set visibility to the computed visibility from summaries. We423    // don't track visibility from declarations so this may be more relaxed than424    // the most constraining one.425    if (C.VisibilityScheme == Config::ELF)426      S->setVisibility(Visibility);427 428    if (S->linkage() != OriginalLinkage)429      recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());430  }431 432  if (C.VisibilityScheme == Config::FromPrevailing) {433    for (auto &S : VI.getSummaryList()) {434      GlobalValue::LinkageTypes OriginalLinkage = S->linkage();435      if (GlobalValue::isLocalLinkage(OriginalLinkage) ||436          GlobalValue::isAppendingLinkage(S->linkage()))437        continue;438      S->setVisibility(Visibility);439    }440  }441}442 443/// Resolve linkage for prevailing symbols in the \p Index.444//445// We'd like to drop these functions if they are no longer referenced in the446// current module. However there is a chance that another module is still447// referencing them because of the import. We make sure we always emit at least448// one copy.449void llvm::thinLTOResolvePrevailingInIndex(450    const Config &C, ModuleSummaryIndex &Index,451    function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>452        isPrevailing,453    function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)>454        recordNewLinkage,455    const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {456  // We won't optimize the globals that are referenced by an alias for now457  // Ideally we should turn the alias into a global and duplicate the definition458  // when needed.459  DenseSet<GlobalValueSummary *> GlobalInvolvedWithAlias;460  for (auto &I : Index)461    for (auto &S : I.second.getSummaryList())462      if (auto AS = dyn_cast<AliasSummary>(S.get()))463        GlobalInvolvedWithAlias.insert(&AS->getAliasee());464 465  for (auto &I : Index)466    thinLTOResolvePrevailingGUID(C, Index.getValueInfo(I),467                                 GlobalInvolvedWithAlias, isPrevailing,468                                 recordNewLinkage, GUIDPreservedSymbols);469}470 471static void thinLTOInternalizeAndPromoteGUID(472    ValueInfo VI, function_ref<bool(StringRef, ValueInfo)> isExported,473    function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>474        isPrevailing) {475  // Before performing index-based internalization and promotion for this GUID,476  // the local flag should be consistent with the summary list linkage types.477  VI.verifyLocal();478 479  const bool SingleExternallyVisibleCopy =480      VI.getSummaryList().size() == 1 &&481      !GlobalValue::isLocalLinkage(VI.getSummaryList().front()->linkage());482 483  for (auto &S : VI.getSummaryList()) {484    // First see if we need to promote an internal value because it is not485    // exported.486    if (isExported(S->modulePath(), VI)) {487      if (GlobalValue::isLocalLinkage(S->linkage()))488        S->setLinkage(GlobalValue::ExternalLinkage);489      continue;490    }491 492    // Otherwise, see if we can internalize.493    if (!EnableLTOInternalization)494      continue;495 496    // Non-exported values with external linkage can be internalized.497    if (GlobalValue::isExternalLinkage(S->linkage())) {498      S->setLinkage(GlobalValue::InternalLinkage);499      continue;500    }501 502    // Non-exported function and variable definitions with a weak-for-linker503    // linkage can be internalized in certain cases. The minimum legality504    // requirements would be that they are not address taken to ensure that we505    // don't break pointer equality checks, and that variables are either read-506    // or write-only. For functions, this is the case if either all copies are507    // [local_]unnamed_addr, or we can propagate reference edge attributes508    // (which is how this is guaranteed for variables, when analyzing whether509    // they are read or write-only).510    //511    // However, we only get to this code for weak-for-linkage values in one of512    // two cases:513    // 1) The prevailing copy is not in IR (it is in native code).514    // 2) The prevailing copy in IR is not exported from its module.515    // Additionally, at least for the new LTO API, case 2 will only happen if516    // there is exactly one definition of the value (i.e. in exactly one517    // module), as duplicate defs are result in the value being marked exported.518    // Likely, users of the legacy LTO API are similar, however, currently there519    // are llvm-lto based tests of the legacy LTO API that do not mark520    // duplicate linkonce_odr copies as exported via the tool, so we need521    // to handle that case below by checking the number of copies.522    //523    // Generally, we only want to internalize a weak-for-linker value in case524    // 2, because in case 1 we cannot see how the value is used to know if it525    // is read or write-only. We also don't want to bloat the binary with526    // multiple internalized copies of non-prevailing linkonce/weak functions.527    // Note if we don't internalize, we will convert non-prevailing copies to528    // available_externally anyway, so that we drop them after inlining. The529    // only reason to internalize such a function is if we indeed have a single530    // copy, because internalizing it won't increase binary size, and enables531    // use of inliner heuristics that are more aggressive in the face of a532    // single call to a static (local). For variables, internalizing a read or533    // write only variable can enable more aggressive optimization. However, we534    // already perform this elsewhere in the ThinLTO backend handling for535    // read or write-only variables (processGlobalForThinLTO).536    //537    // Therefore, only internalize linkonce/weak if there is a single copy, that538    // is prevailing in this IR module. We can do so aggressively, without539    // requiring the address to be insignificant, or that a variable be read or540    // write-only.541    if (!GlobalValue::isWeakForLinker(S->linkage()) ||542        GlobalValue::isExternalWeakLinkage(S->linkage()))543      continue;544 545    // We may have a single summary copy that is externally visible but not546    // prevailing if the prevailing copy is in a native object.547    if (SingleExternallyVisibleCopy && isPrevailing(VI.getGUID(), S.get()))548      S->setLinkage(GlobalValue::InternalLinkage);549  }550}551 552// Update the linkages in the given \p Index to mark exported values553// as external and non-exported values as internal.554void llvm::thinLTOInternalizeAndPromoteInIndex(555    ModuleSummaryIndex &Index,556    function_ref<bool(StringRef, ValueInfo)> isExported,557    function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>558        isPrevailing) {559  assert(!Index.withInternalizeAndPromote());560  for (auto &I : Index)561    thinLTOInternalizeAndPromoteGUID(Index.getValueInfo(I), isExported,562                                     isPrevailing);563  Index.setWithInternalizeAndPromote();564}565 566// Requires a destructor for std::vector<InputModule>.567InputFile::~InputFile() = default;568 569Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) {570  std::unique_ptr<InputFile> File(new InputFile);571 572  Expected<IRSymtabFile> FOrErr = readIRSymtab(Object);573  if (!FOrErr)574    return FOrErr.takeError();575 576  File->TargetTriple = FOrErr->TheReader.getTargetTriple();577  File->SourceFileName = FOrErr->TheReader.getSourceFileName();578  File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();579  File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();580  File->ComdatTable = FOrErr->TheReader.getComdatTable();581 582  for (unsigned I = 0; I != FOrErr->Mods.size(); ++I) {583    size_t Begin = File->Symbols.size();584    for (const irsymtab::Reader::SymbolRef &Sym :585         FOrErr->TheReader.module_symbols(I))586      // Skip symbols that are irrelevant to LTO. Note that this condition needs587      // to match the one in Skip() in LTO::addRegularLTO().588      if (Sym.isGlobal() && !Sym.isFormatSpecific())589        File->Symbols.push_back(Sym);590    File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});591  }592 593  File->Mods = FOrErr->Mods;594  File->Strtab = std::move(FOrErr->Strtab);595  return std::move(File);596}597 598StringRef InputFile::getName() const {599  return Mods[0].getModuleIdentifier();600}601 602BitcodeModule &InputFile::getSingleBitcodeModule() {603  assert(Mods.size() == 1 && "Expect only one bitcode module");604  return Mods[0];605}606 607LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,608                                      const Config &Conf)609    : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),610      Ctx(Conf), CombinedModule(std::make_unique<Module>("ld-temp.o", Ctx)),611      Mover(std::make_unique<IRMover>(*CombinedModule)) {}612 613LTO::ThinLTOState::ThinLTOState(ThinBackend BackendParam)614    : Backend(std::move(BackendParam)), CombinedIndex(/*HaveGVs*/ false) {615  if (!Backend.isValid())616    Backend =617        createInProcessThinBackend(llvm::heavyweight_hardware_concurrency());618}619 620LTO::LTO(Config Conf, ThinBackend Backend,621         unsigned ParallelCodeGenParallelismLevel, LTOKind LTOMode)622    : Conf(std::move(Conf)),623      RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),624      ThinLTO(std::move(Backend)),625      GlobalResolutions(626          std::make_unique<DenseMap<StringRef, GlobalResolution>>()),627      LTOMode(LTOMode) {628  if (Conf.KeepSymbolNameCopies || LTOKeepSymbolCopies) {629    Alloc = std::make_unique<BumpPtrAllocator>();630    GlobalResolutionSymbolSaver = std::make_unique<llvm::StringSaver>(*Alloc);631  }632}633 634// Requires a destructor for MapVector<BitcodeModule>.635LTO::~LTO() = default;636 637// Add the symbols in the given module to the GlobalResolutions map, and resolve638// their partitions.639void LTO::addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms,640                               ArrayRef<SymbolResolution> Res,641                               unsigned Partition, bool InSummary) {642  llvm::TimeTraceScope timeScope("LTO add module to global resolution");643  auto *ResI = Res.begin();644  auto *ResE = Res.end();645  (void)ResE;646  for (const InputFile::Symbol &Sym : Syms) {647    assert(ResI != ResE);648    SymbolResolution Res = *ResI++;649 650    StringRef SymbolName = Sym.getName();651    // Keep copies of symbols if the client of LTO says so.652    if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains(SymbolName))653      SymbolName = GlobalResolutionSymbolSaver->save(SymbolName);654 655    auto &GlobalRes = (*GlobalResolutions)[SymbolName];656    GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr();657    if (Res.Prevailing) {658      assert(!GlobalRes.Prevailing &&659             "Multiple prevailing defs are not allowed");660      GlobalRes.Prevailing = true;661      GlobalRes.IRName = std::string(Sym.getIRName());662    } else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {663      // Sometimes it can be two copies of symbol in a module and prevailing664      // symbol can have no IR name. That might happen if symbol is defined in665      // module level inline asm block. In case we have multiple modules with666      // the same symbol we want to use IR name of the prevailing symbol.667      // Otherwise, if we haven't seen a prevailing symbol, set the name so that668      // we can later use it to check if there is any prevailing copy in IR.669      GlobalRes.IRName = std::string(Sym.getIRName());670    }671 672    // In rare occasion, the symbol used to initialize GlobalRes has a different673    // IRName from the inspected Symbol. This can happen on macOS + iOS, when a674    // symbol is referenced through its mangled name, say @"\01_symbol" while675    // the IRName is @symbol (the prefix underscore comes from MachO mangling).676    // In that case, we have the same actual Symbol that can get two different677    // GUID, leading to some invalid internalization. Workaround this by marking678    // the GlobalRes external.679 680    // FIXME: instead of this check, it would be desirable to compute GUIDs681    // based on mangled name, but this requires an access to the Target Triple682    // and would be relatively invasive on the codebase.683    if (GlobalRes.IRName != Sym.getIRName()) {684      GlobalRes.Partition = GlobalResolution::External;685      GlobalRes.VisibleOutsideSummary = true;686    }687 688    // Set the partition to external if we know it is re-defined by the linker689    // with -defsym or -wrap options, used elsewhere, e.g. it is visible to a690    // regular object, is referenced from llvm.compiler.used/llvm.used, or was691    // already recorded as being referenced from a different partition.692    if (Res.LinkerRedefined || Res.VisibleToRegularObj || Sym.isUsed() ||693        (GlobalRes.Partition != GlobalResolution::Unknown &&694         GlobalRes.Partition != Partition)) {695      GlobalRes.Partition = GlobalResolution::External;696    } else697      // First recorded reference, save the current partition.698      GlobalRes.Partition = Partition;699 700    // Flag as visible outside of summary if visible from a regular object or701    // from a module that does not have a summary.702    GlobalRes.VisibleOutsideSummary |=703        (Res.VisibleToRegularObj || Sym.isUsed() || !InSummary);704 705    GlobalRes.ExportDynamic |= Res.ExportDynamic;706  }707}708 709void LTO::releaseGlobalResolutionsMemory() {710  // Release GlobalResolutions dense-map itself.711  GlobalResolutions.reset();712  // Release the string saver memory.713  GlobalResolutionSymbolSaver.reset();714  Alloc.reset();715}716 717static void writeToResolutionFile(raw_ostream &OS, InputFile *Input,718                                  ArrayRef<SymbolResolution> Res) {719  StringRef Path = Input->getName();720  OS << Path << '\n';721  auto ResI = Res.begin();722  for (const InputFile::Symbol &Sym : Input->symbols()) {723    assert(ResI != Res.end());724    SymbolResolution Res = *ResI++;725 726    OS << "-r=" << Path << ',' << Sym.getName() << ',';727    if (Res.Prevailing)728      OS << 'p';729    if (Res.FinalDefinitionInLinkageUnit)730      OS << 'l';731    if (Res.VisibleToRegularObj)732      OS << 'x';733    if (Res.LinkerRedefined)734      OS << 'r';735    OS << '\n';736  }737  OS.flush();738  assert(ResI == Res.end());739}740 741Error LTO::add(std::unique_ptr<InputFile> Input,742               ArrayRef<SymbolResolution> Res) {743  llvm::TimeTraceScope timeScope("LTO add input", Input->getName());744  assert(!CalledGetMaxTasks);745 746  if (Conf.ResolutionFile)747    writeToResolutionFile(*Conf.ResolutionFile, Input.get(), Res);748 749  if (RegularLTO.CombinedModule->getTargetTriple().empty()) {750    Triple InputTriple(Input->getTargetTriple());751    RegularLTO.CombinedModule->setTargetTriple(InputTriple);752    if (InputTriple.isOSBinFormatELF())753      Conf.VisibilityScheme = Config::ELF;754  }755 756  ArrayRef<SymbolResolution> InputRes = Res;757  for (unsigned I = 0; I != Input->Mods.size(); ++I) {758    if (auto Err = addModule(*Input, InputRes, I, Res).moveInto(Res))759      return Err;760  }761 762  assert(Res.empty());763  return Error::success();764}765 766Expected<ArrayRef<SymbolResolution>>767LTO::addModule(InputFile &Input, ArrayRef<SymbolResolution> InputRes,768               unsigned ModI, ArrayRef<SymbolResolution> Res) {769  llvm::TimeTraceScope timeScope("LTO add module", Input.getName());770  Expected<BitcodeLTOInfo> LTOInfo = Input.Mods[ModI].getLTOInfo();771  if (!LTOInfo)772    return LTOInfo.takeError();773 774  if (EnableSplitLTOUnit) {775    // If only some modules were split, flag this in the index so that776    // we can skip or error on optimizations that need consistently split777    // modules (whole program devirt and lower type tests).778    if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)779      ThinLTO.CombinedIndex.setPartiallySplitLTOUnits();780  } else781    EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;782 783  BitcodeModule BM = Input.Mods[ModI];784 785  if ((LTOMode == LTOK_UnifiedRegular || LTOMode == LTOK_UnifiedThin) &&786      !LTOInfo->UnifiedLTO)787    return make_error<StringError>(788        "unified LTO compilation must use "789        "compatible bitcode modules (use -funified-lto)",790        inconvertibleErrorCode());791 792  if (LTOInfo->UnifiedLTO && LTOMode == LTOK_Default)793    LTOMode = LTOK_UnifiedThin;794 795  bool IsThinLTO = LTOInfo->IsThinLTO && (LTOMode != LTOK_UnifiedRegular);796 797  auto ModSyms = Input.module_symbols(ModI);798  addModuleToGlobalRes(ModSyms, Res,799                       IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,800                       LTOInfo->HasSummary);801 802  if (IsThinLTO)803    return addThinLTO(BM, ModSyms, Res);804 805  RegularLTO.EmptyCombinedModule = false;806  auto ModOrErr = addRegularLTO(Input, InputRes, BM, ModSyms, Res);807  if (!ModOrErr)808    return ModOrErr.takeError();809  Res = ModOrErr->second;810 811  if (!LTOInfo->HasSummary) {812    if (Error Err = linkRegularLTO(std::move(ModOrErr->first),813                                   /*LivenessFromIndex=*/false))814      return Err;815    return Res;816  }817 818  // Regular LTO module summaries are added to a dummy module that represents819  // the combined regular LTO module.820  if (Error Err = BM.readSummary(ThinLTO.CombinedIndex, ""))821    return Err;822  RegularLTO.ModsWithSummaries.push_back(std::move(ModOrErr->first));823  return Res;824}825 826// Checks whether the given global value is in a non-prevailing comdat827// (comdat containing values the linker indicated were not prevailing,828// which we then dropped to available_externally), and if so, removes829// it from the comdat. This is called for all global values to ensure the830// comdat is empty rather than leaving an incomplete comdat. It is needed for831// regular LTO modules, in case we are in a mixed-LTO mode (both regular832// and thin LTO modules) compilation. Since the regular LTO module will be833// linked first in the final native link, we want to make sure the linker834// doesn't select any of these incomplete comdats that would be left835// in the regular LTO module without this cleanup.836static void837handleNonPrevailingComdat(GlobalValue &GV,838                          std::set<const Comdat *> &NonPrevailingComdats) {839  Comdat *C = GV.getComdat();840  if (!C)841    return;842 843  if (!NonPrevailingComdats.count(C))844    return;845 846  // Additionally need to drop all global values from the comdat to847  // available_externally, to satisfy the COMDAT requirement that all members848  // are discarded as a unit. The non-local linkage global values avoid849  // duplicate definition linker errors.850  GV.setLinkage(GlobalValue::AvailableExternallyLinkage);851 852  if (auto GO = dyn_cast<GlobalObject>(&GV))853    GO->setComdat(nullptr);854}855 856// Add a regular LTO object to the link.857// The resulting module needs to be linked into the combined LTO module with858// linkRegularLTO.859Expected<860    std::pair<LTO::RegularLTOState::AddedModule, ArrayRef<SymbolResolution>>>861LTO::addRegularLTO(InputFile &Input, ArrayRef<SymbolResolution> InputRes,862                   BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,863                   ArrayRef<SymbolResolution> Res) {864  llvm::TimeTraceScope timeScope("LTO add regular LTO");865  RegularLTOState::AddedModule Mod;866  Expected<std::unique_ptr<Module>> MOrErr =867      BM.getLazyModule(RegularLTO.Ctx, /*ShouldLazyLoadMetadata*/ true,868                       /*IsImporting*/ false);869  if (!MOrErr)870    return MOrErr.takeError();871  Module &M = **MOrErr;872  Mod.M = std::move(*MOrErr);873 874  if (Error Err = M.materializeMetadata())875    return std::move(Err);876 877  if (LTOMode == LTOK_UnifiedRegular) {878    // cfi.functions metadata is intended to be used with ThinLTO and may879    // trigger invalid IR transformations if they are present when doing regular880    // LTO, so delete it.881    if (NamedMDNode *CfiFunctionsMD = M.getNamedMetadata("cfi.functions"))882      M.eraseNamedMetadata(CfiFunctionsMD);883  } else if (NamedMDNode *AliasesMD = M.getNamedMetadata("aliases")) {884    // Delete aliases entries for non-prevailing symbols on the ThinLTO side of885    // this input file.886    DenseSet<StringRef> Prevailing;887    for (auto [I, R] : zip(Input.symbols(), InputRes))888      if (R.Prevailing && !I.getIRName().empty())889        Prevailing.insert(I.getIRName());890    std::vector<MDNode *> AliasGroups;891    for (MDNode *AliasGroup : AliasesMD->operands()) {892      std::vector<Metadata *> Aliases;893      for (Metadata *Alias : AliasGroup->operands()) {894        if (isa<MDString>(Alias) &&895            Prevailing.count(cast<MDString>(Alias)->getString()))896          Aliases.push_back(Alias);897      }898      if (Aliases.size() > 1)899        AliasGroups.push_back(MDTuple::get(RegularLTO.Ctx, Aliases));900    }901    AliasesMD->clearOperands();902    for (MDNode *G : AliasGroups)903      AliasesMD->addOperand(G);904  }905 906  UpgradeDebugInfo(M);907 908  ModuleSymbolTable SymTab;909  SymTab.addModule(&M);910 911  for (GlobalVariable &GV : M.globals())912    if (GV.hasAppendingLinkage())913      Mod.Keep.push_back(&GV);914 915  DenseSet<GlobalObject *> AliasedGlobals;916  for (auto &GA : M.aliases())917    if (GlobalObject *GO = GA.getAliaseeObject())918      AliasedGlobals.insert(GO);919 920  // In this function we need IR GlobalValues matching the symbols in Syms921  // (which is not backed by a module), so we need to enumerate them in the same922  // order. The symbol enumeration order of a ModuleSymbolTable intentionally923  // matches the order of an irsymtab, but when we read the irsymtab in924  // InputFile::create we omit some symbols that are irrelevant to LTO. The925  // Skip() function skips the same symbols from the module as InputFile does926  // from the symbol table.927  auto MsymI = SymTab.symbols().begin(), MsymE = SymTab.symbols().end();928  auto Skip = [&]() {929    while (MsymI != MsymE) {930      auto Flags = SymTab.getSymbolFlags(*MsymI);931      if ((Flags & object::BasicSymbolRef::SF_Global) &&932          !(Flags & object::BasicSymbolRef::SF_FormatSpecific))933        return;934      ++MsymI;935    }936  };937  Skip();938 939  std::set<const Comdat *> NonPrevailingComdats;940  SmallSet<StringRef, 2> NonPrevailingAsmSymbols;941  for (const InputFile::Symbol &Sym : Syms) {942    assert(!Res.empty());943    const SymbolResolution &R = Res.consume_front();944 945    assert(MsymI != MsymE);946    ModuleSymbolTable::Symbol Msym = *MsymI++;947    Skip();948 949    if (GlobalValue *GV = dyn_cast_if_present<GlobalValue *>(Msym)) {950      if (R.Prevailing) {951        if (Sym.isUndefined())952          continue;953        Mod.Keep.push_back(GV);954        // For symbols re-defined with linker -wrap and -defsym options,955        // set the linkage to weak to inhibit IPO. The linkage will be956        // restored by the linker.957        if (R.LinkerRedefined)958          GV->setLinkage(GlobalValue::WeakAnyLinkage);959 960        GlobalValue::LinkageTypes OriginalLinkage = GV->getLinkage();961        if (GlobalValue::isLinkOnceLinkage(OriginalLinkage))962          GV->setLinkage(GlobalValue::getWeakLinkage(963              GlobalValue::isLinkOnceODRLinkage(OriginalLinkage)));964      } else if (isa<GlobalObject>(GV) &&965                 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||966                  GV->hasAvailableExternallyLinkage()) &&967                 !AliasedGlobals.count(cast<GlobalObject>(GV))) {968        // Any of the above three types of linkage indicates that the969        // chosen prevailing symbol will have the same semantics as this copy of970        // the symbol, so we may be able to link it with available_externally971        // linkage. We will decide later whether to do that when we link this972        // module (in linkRegularLTO), based on whether it is undefined.973        Mod.Keep.push_back(GV);974        GV->setLinkage(GlobalValue::AvailableExternallyLinkage);975        if (GV->hasComdat())976          NonPrevailingComdats.insert(GV->getComdat());977        cast<GlobalObject>(GV)->setComdat(nullptr);978      }979 980      // Set the 'local' flag based on the linker resolution for this symbol.981      if (R.FinalDefinitionInLinkageUnit) {982        GV->setDSOLocal(true);983        if (GV->hasDLLImportStorageClass())984          GV->setDLLStorageClass(GlobalValue::DLLStorageClassTypes::985                                 DefaultStorageClass);986      }987    } else if (auto *AS =988                   dyn_cast_if_present<ModuleSymbolTable::AsmSymbol *>(Msym)) {989      // Collect non-prevailing symbols.990      if (!R.Prevailing)991        NonPrevailingAsmSymbols.insert(AS->first);992    } else {993      llvm_unreachable("unknown symbol type");994    }995 996    // Common resolution: collect the maximum size/alignment over all commons.997    // We also record if we see an instance of a common as prevailing, so that998    // if none is prevailing we can ignore it later.999    if (Sym.isCommon()) {1000      // FIXME: We should figure out what to do about commons defined by asm.1001      // For now they aren't reported correctly by ModuleSymbolTable.1002      auto &CommonRes = RegularLTO.Commons[std::string(Sym.getIRName())];1003      CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());1004      if (uint32_t SymAlignValue = Sym.getCommonAlignment()) {1005        CommonRes.Alignment =1006            std::max(Align(SymAlignValue), CommonRes.Alignment);1007      }1008      CommonRes.Prevailing |= R.Prevailing;1009    }1010  }1011 1012  if (!M.getComdatSymbolTable().empty())1013    for (GlobalValue &GV : M.global_values())1014      handleNonPrevailingComdat(GV, NonPrevailingComdats);1015 1016  // Prepend ".lto_discard <sym>, <sym>*" directive to each module inline asm1017  // block.1018  if (!M.getModuleInlineAsm().empty()) {1019    std::string NewIA = ".lto_discard";1020    if (!NonPrevailingAsmSymbols.empty()) {1021      // Don't dicard a symbol if there is a live .symver for it.1022      ModuleSymbolTable::CollectAsmSymvers(1023          M, [&](StringRef Name, StringRef Alias) {1024            if (!NonPrevailingAsmSymbols.count(Alias))1025              NonPrevailingAsmSymbols.erase(Name);1026          });1027      NewIA += " " + llvm::join(NonPrevailingAsmSymbols, ", ");1028    }1029    NewIA += "\n";1030    M.setModuleInlineAsm(NewIA + M.getModuleInlineAsm());1031  }1032 1033  assert(MsymI == MsymE);1034  return std::make_pair(std::move(Mod), Res);1035}1036 1037Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod,1038                          bool LivenessFromIndex) {1039  llvm::TimeTraceScope timeScope("LTO link regular LTO");1040  std::vector<GlobalValue *> Keep;1041  for (GlobalValue *GV : Mod.Keep) {1042    if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID())) {1043      if (Function *F = dyn_cast<Function>(GV)) {1044        if (DiagnosticOutputFile) {1045          if (Error Err = F->materialize())1046            return Err;1047          OptimizationRemarkEmitter ORE(F, nullptr);1048          ORE.emit(OptimizationRemark(DEBUG_TYPE, "deadfunction", F)1049                   << ore::NV("Function", F)1050                   << " not added to the combined module ");1051        }1052      }1053      continue;1054    }1055 1056    if (!GV->hasAvailableExternallyLinkage()) {1057      Keep.push_back(GV);1058      continue;1059    }1060 1061    // Only link available_externally definitions if we don't already have a1062    // definition.1063    GlobalValue *CombinedGV =1064        RegularLTO.CombinedModule->getNamedValue(GV->getName());1065    if (CombinedGV && !CombinedGV->isDeclaration())1066      continue;1067 1068    Keep.push_back(GV);1069  }1070 1071  return RegularLTO.Mover->move(std::move(Mod.M), Keep, nullptr,1072                                /* IsPerformingImport */ false);1073}1074 1075// Add a ThinLTO module to the link.1076Expected<ArrayRef<SymbolResolution>>1077LTO::addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,1078                ArrayRef<SymbolResolution> Res) {1079  llvm::TimeTraceScope timeScope("LTO add thin LTO");1080  const auto BMID = BM.getModuleIdentifier();1081  ArrayRef<SymbolResolution> ResTmp = Res;1082  for (const InputFile::Symbol &Sym : Syms) {1083    assert(!ResTmp.empty());1084    const SymbolResolution &R = ResTmp.consume_front();1085 1086    if (!Sym.getIRName().empty() && R.Prevailing) {1087      auto GUID = GlobalValue::getGUIDAssumingExternalLinkage(1088          GlobalValue::getGlobalIdentifier(Sym.getIRName(),1089                                           GlobalValue::ExternalLinkage, ""));1090      ThinLTO.setPrevailingModuleForGUID(GUID, BMID);1091    }1092  }1093 1094  if (Error Err = BM.readSummary(1095          ThinLTO.CombinedIndex, BMID, [&](GlobalValue::GUID GUID) {1096            return ThinLTO.isPrevailingModuleForGUID(GUID, BMID);1097          }))1098    return Err;1099  LLVM_DEBUG(dbgs() << "Module " << BMID << "\n");1100 1101  for (const InputFile::Symbol &Sym : Syms) {1102    assert(!Res.empty());1103    const SymbolResolution &R = Res.consume_front();1104 1105    if (!Sym.getIRName().empty() &&1106        (R.Prevailing || R.FinalDefinitionInLinkageUnit)) {1107      auto GUID = GlobalValue::getGUIDAssumingExternalLinkage(1108          GlobalValue::getGlobalIdentifier(Sym.getIRName(),1109                                           GlobalValue::ExternalLinkage, ""));1110      if (R.Prevailing) {1111        assert(ThinLTO.isPrevailingModuleForGUID(GUID, BMID));1112 1113        // For linker redefined symbols (via --wrap or --defsym) we want to1114        // switch the linkage to `weak` to prevent IPOs from happening.1115        // Find the summary in the module for this very GV and record the new1116        // linkage so that we can switch it when we import the GV.1117        if (R.LinkerRedefined)1118          if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID))1119            S->setLinkage(GlobalValue::WeakAnyLinkage);1120      }1121 1122      // If the linker resolved the symbol to a local definition then mark it1123      // as local in the summary for the module we are adding.1124      if (R.FinalDefinitionInLinkageUnit) {1125        if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID)) {1126          S->setDSOLocal(true);1127        }1128      }1129    }1130  }1131 1132  if (!ThinLTO.ModuleMap.insert({BMID, BM}).second)1133    return make_error<StringError>(1134        "Expected at most one ThinLTO module per bitcode file",1135        inconvertibleErrorCode());1136 1137  if (!Conf.ThinLTOModulesToCompile.empty()) {1138    if (!ThinLTO.ModulesToCompile)1139      ThinLTO.ModulesToCompile = ModuleMapType();1140    // This is a fuzzy name matching where only modules with name containing the1141    // specified switch values are going to be compiled.1142    for (const std::string &Name : Conf.ThinLTOModulesToCompile) {1143      if (BMID.contains(Name)) {1144        ThinLTO.ModulesToCompile->insert({BMID, BM});1145        LLVM_DEBUG(dbgs() << "[ThinLTO] Selecting " << BMID << " to compile\n");1146        break;1147      }1148    }1149  }1150 1151  return Res;1152}1153 1154unsigned LTO::getMaxTasks() const {1155  CalledGetMaxTasks = true;1156  auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()1157                                              : ThinLTO.ModuleMap.size();1158  return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;1159}1160 1161// If only some of the modules were split, we cannot correctly handle1162// code that contains type tests or type checked loads.1163Error LTO::checkPartiallySplit() {1164  if (!ThinLTO.CombinedIndex.partiallySplitLTOUnits())1165    return Error::success();1166 1167  const Module *Combined = RegularLTO.CombinedModule.get();1168  Function *TypeTestFunc =1169      Intrinsic::getDeclarationIfExists(Combined, Intrinsic::type_test);1170  Function *TypeCheckedLoadFunc =1171      Intrinsic::getDeclarationIfExists(Combined, Intrinsic::type_checked_load);1172  Function *TypeCheckedLoadRelativeFunc = Intrinsic::getDeclarationIfExists(1173      Combined, Intrinsic::type_checked_load_relative);1174 1175  // First check if there are type tests / type checked loads in the1176  // merged regular LTO module IR.1177  if ((TypeTestFunc && !TypeTestFunc->use_empty()) ||1178      (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->use_empty()) ||1179      (TypeCheckedLoadRelativeFunc &&1180       !TypeCheckedLoadRelativeFunc->use_empty()))1181    return make_error<StringError>(1182        "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",1183        inconvertibleErrorCode());1184 1185  // Otherwise check if there are any recorded in the combined summary from the1186  // ThinLTO modules.1187  for (auto &P : ThinLTO.CombinedIndex) {1188    for (auto &S : P.second.getSummaryList()) {1189      auto *FS = dyn_cast<FunctionSummary>(S.get());1190      if (!FS)1191        continue;1192      if (!FS->type_test_assume_vcalls().empty() ||1193          !FS->type_checked_load_vcalls().empty() ||1194          !FS->type_test_assume_const_vcalls().empty() ||1195          !FS->type_checked_load_const_vcalls().empty() ||1196          !FS->type_tests().empty())1197        return make_error<StringError>(1198            "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",1199            inconvertibleErrorCode());1200    }1201  }1202  return Error::success();1203}1204 1205Error LTO::run(AddStreamFn AddStream, FileCache Cache) {1206  // Compute "dead" symbols, we don't want to import/export these!1207  DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;1208  DenseMap<GlobalValue::GUID, PrevailingType> GUIDPrevailingResolutions;1209  for (auto &Res : *GlobalResolutions) {1210    // Normally resolution have IR name of symbol. We can do nothing here1211    // otherwise. See comments in GlobalResolution struct for more details.1212    if (Res.second.IRName.empty())1213      continue;1214 1215    GlobalValue::GUID GUID = GlobalValue::getGUIDAssumingExternalLinkage(1216        GlobalValue::dropLLVMManglingEscape(Res.second.IRName));1217 1218    if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)1219      GUIDPreservedSymbols.insert(GUID);1220 1221    if (Res.second.ExportDynamic)1222      DynamicExportSymbols.insert(GUID);1223 1224    GUIDPrevailingResolutions[GUID] =1225        Res.second.Prevailing ? PrevailingType::Yes : PrevailingType::No;1226  }1227 1228  auto isPrevailing = [&](GlobalValue::GUID G) {1229    auto It = GUIDPrevailingResolutions.find(G);1230    if (It == GUIDPrevailingResolutions.end())1231      return PrevailingType::Unknown;1232    return It->second;1233  };1234  computeDeadSymbolsWithConstProp(ThinLTO.CombinedIndex, GUIDPreservedSymbols,1235                                  isPrevailing, Conf.OptLevel > 0);1236 1237  // Setup output file to emit statistics.1238  auto StatsFileOrErr = setupStatsFile(Conf.StatsFile);1239  if (!StatsFileOrErr)1240    return StatsFileOrErr.takeError();1241  std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());1242 1243  // TODO: Ideally this would be controlled automatically by detecting that we1244  // are linking with an allocator that supports these interfaces, rather than1245  // an internal option (which would still be needed for tests, however). For1246  // example, if the library exported a symbol like __malloc_hot_cold the linker1247  // could recognize that and set a flag in the lto::Config.1248  if (SupportsHotColdNew)1249    ThinLTO.CombinedIndex.setWithSupportsHotColdNew();1250 1251  Error Result = runRegularLTO(AddStream);1252  if (!Result)1253    // This will reset the GlobalResolutions optional once done with it to1254    // reduce peak memory before importing.1255    Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);1256 1257  if (StatsFile)1258    PrintStatisticsJSON(StatsFile->os());1259 1260  return Result;1261}1262 1263Error LTO::runRegularLTO(AddStreamFn AddStream) {1264  llvm::TimeTraceScope timeScope("Run regular LTO");1265  LLVMContext &CombinedCtx = RegularLTO.CombinedModule->getContext();1266  // Setup optimization remarks.1267  auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(1268      CombinedCtx, Conf.RemarksFilename, Conf.RemarksPasses, Conf.RemarksFormat,1269      Conf.RemarksWithHotness, Conf.RemarksHotnessThreshold);1270  LLVM_DEBUG(dbgs() << "Running regular LTO\n");1271  if (!DiagFileOrErr)1272    return DiagFileOrErr.takeError();1273  DiagnosticOutputFile = std::move(*DiagFileOrErr);1274 1275  // Finalize linking of regular LTO modules containing summaries now that1276  // we have computed liveness information.1277  {1278    llvm::TimeTraceScope timeScope("Link regular LTO");1279    for (auto &M : RegularLTO.ModsWithSummaries)1280      if (Error Err = linkRegularLTO(std::move(M), /*LivenessFromIndex=*/true))1281        return Err;1282  }1283 1284  // Ensure we don't have inconsistently split LTO units with type tests.1285  // FIXME: this checks both LTO and ThinLTO. It happens to work as we take1286  // this path both cases but eventually this should be split into two and1287  // do the ThinLTO checks in `runThinLTO`.1288  if (Error Err = checkPartiallySplit())1289    return Err;1290 1291  // Make sure commons have the right size/alignment: we kept the largest from1292  // all the prevailing when adding the inputs, and we apply it here.1293  const DataLayout &DL = RegularLTO.CombinedModule->getDataLayout();1294  for (auto &I : RegularLTO.Commons) {1295    if (!I.second.Prevailing)1296      // Don't do anything if no instance of this common was prevailing.1297      continue;1298    GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(I.first);1299    if (OldGV && DL.getTypeAllocSize(OldGV->getValueType()) == I.second.Size) {1300      // Don't create a new global if the type is already correct, just make1301      // sure the alignment is correct.1302      OldGV->setAlignment(I.second.Alignment);1303      continue;1304    }1305    ArrayType *Ty =1306        ArrayType::get(Type::getInt8Ty(RegularLTO.Ctx), I.second.Size);1307    auto *GV = new GlobalVariable(*RegularLTO.CombinedModule, Ty, false,1308                                  GlobalValue::CommonLinkage,1309                                  ConstantAggregateZero::get(Ty), "");1310    GV->setAlignment(I.second.Alignment);1311    if (OldGV) {1312      OldGV->replaceAllUsesWith(GV);1313      GV->takeName(OldGV);1314      OldGV->eraseFromParent();1315    } else {1316      GV->setName(I.first);1317    }1318  }1319 1320  bool WholeProgramVisibilityEnabledInLTO =1321      Conf.HasWholeProgramVisibility &&1322      // If validation is enabled, upgrade visibility only when all vtables1323      // have typeinfos.1324      (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);1325 1326  // This returns true when the name is local or not defined. Locals are1327  // expected to be handled separately.1328  auto IsVisibleToRegularObj = [&](StringRef name) {1329    auto It = GlobalResolutions->find(name);1330    return (It == GlobalResolutions->end() ||1331            It->second.VisibleOutsideSummary || !It->second.Prevailing);1332  };1333 1334  // If allowed, upgrade public vcall visibility metadata to linkage unit1335  // visibility before whole program devirtualization in the optimizer.1336  updateVCallVisibilityInModule(1337      *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,1338      DynamicExportSymbols, Conf.ValidateAllVtablesHaveTypeInfos,1339      IsVisibleToRegularObj);1340  updatePublicTypeTestCalls(*RegularLTO.CombinedModule,1341                            WholeProgramVisibilityEnabledInLTO);1342 1343  if (Conf.PreOptModuleHook &&1344      !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule))1345    return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));1346 1347  if (!Conf.CodeGenOnly) {1348    for (const auto &R : *GlobalResolutions) {1349      GlobalValue *GV =1350          RegularLTO.CombinedModule->getNamedValue(R.second.IRName);1351      if (!R.second.isPrevailingIRSymbol())1352        continue;1353      if (R.second.Partition != 0 &&1354          R.second.Partition != GlobalResolution::External)1355        continue;1356 1357      // Ignore symbols defined in other partitions.1358      // Also skip declarations, which are not allowed to have internal linkage.1359      if (!GV || GV->hasLocalLinkage() || GV->isDeclaration())1360        continue;1361 1362      // Symbols that are marked DLLImport or DLLExport should not be1363      // internalized, as they are either externally visible or referencing1364      // external symbols. Symbols that have AvailableExternally or Appending1365      // linkage might be used by future passes and should be kept as is.1366      // These linkages are seen in Unified regular LTO, because the process1367      // of creating split LTO units introduces symbols with that linkage into1368      // one of the created modules. Normally, only the ThinLTO backend would1369      // compile this module, but Unified Regular LTO processes both1370      // modules created by the splitting process as regular LTO modules.1371      if ((LTOMode == LTOKind::LTOK_UnifiedRegular) &&1372          ((GV->getDLLStorageClass() != GlobalValue::DefaultStorageClass) ||1373           GV->hasAvailableExternallyLinkage() || GV->hasAppendingLinkage()))1374        continue;1375 1376      GV->setUnnamedAddr(R.second.UnnamedAddr ? GlobalValue::UnnamedAddr::Global1377                                              : GlobalValue::UnnamedAddr::None);1378      if (EnableLTOInternalization && R.second.Partition == 0)1379        GV->setLinkage(GlobalValue::InternalLinkage);1380    }1381 1382    if (Conf.PostInternalizeModuleHook &&1383        !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule))1384      return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));1385  }1386 1387  if (!RegularLTO.EmptyCombinedModule || Conf.AlwaysEmitRegularLTOObj) {1388    if (Error Err =1389            backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,1390                    *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))1391      return Err;1392  }1393 1394  return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));1395}1396 1397SmallVector<const char *> LTO::getRuntimeLibcallSymbols(const Triple &TT) {1398  RTLIB::RuntimeLibcallsInfo Libcalls(TT);1399  SmallVector<const char *> LibcallSymbols;1400  LibcallSymbols.reserve(Libcalls.getNumAvailableLibcallImpls());1401 1402  for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {1403    if (Libcalls.isAvailable(Impl))1404      LibcallSymbols.push_back(Libcalls.getLibcallImplName(Impl).data());1405  }1406 1407  return LibcallSymbols;1408}1409 1410Error ThinBackendProc::emitFiles(1411    const FunctionImporter::ImportMapTy &ImportList, llvm::StringRef ModulePath,1412    const std::string &NewModulePath) const {1413  return emitFiles(ImportList, ModulePath, NewModulePath,1414                   NewModulePath + ".thinlto.bc",1415                   /*ImportsFiles=*/std::nullopt);1416}1417 1418Error ThinBackendProc::emitFiles(1419    const FunctionImporter::ImportMapTy &ImportList, llvm::StringRef ModulePath,1420    const std::string &NewModulePath, StringRef SummaryPath,1421    std::optional<std::reference_wrapper<ImportsFilesContainer>> ImportsFiles)1422    const {1423  ModuleToSummariesForIndexTy ModuleToSummariesForIndex;1424  GVSummaryPtrSet DeclarationSummaries;1425 1426  std::error_code EC;1427  gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries,1428                                   ImportList, ModuleToSummariesForIndex,1429                                   DeclarationSummaries);1430 1431  raw_fd_ostream OS(SummaryPath, EC, sys::fs::OpenFlags::OF_None);1432  if (EC)1433    return createFileError("cannot open " + Twine(SummaryPath), EC);1434 1435  writeIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex,1436                   &DeclarationSummaries);1437 1438  if (ShouldEmitImportsFiles) {1439    Error ImportsFilesError = EmitImportsFiles(1440        ModulePath, NewModulePath + ".imports", ModuleToSummariesForIndex);1441    if (ImportsFilesError)1442      return ImportsFilesError;1443  }1444 1445  // Optionally, store the imports files.1446  if (ImportsFiles)1447    processImportsFiles(1448        ModulePath, ModuleToSummariesForIndex,1449        [&](StringRef M) { ImportsFiles->get().push_back(M.str()); });1450 1451  return Error::success();1452}1453 1454namespace {1455/// Base class for ThinLTO backends that perform code generation and insert the1456/// generated files back into the link.1457class CGThinBackend : public ThinBackendProc {1458protected:1459  AddStreamFn AddStream;1460  DenseSet<GlobalValue::GUID> CfiFunctionDefs;1461  DenseSet<GlobalValue::GUID> CfiFunctionDecls;1462  bool ShouldEmitIndexFiles;1463 1464public:1465  CGThinBackend(1466      const Config &Conf, ModuleSummaryIndex &CombinedIndex,1467      const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1468      AddStreamFn AddStream, lto::IndexWriteCallback OnWrite,1469      bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles,1470      ThreadPoolStrategy ThinLTOParallelism)1471      : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,1472                        OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),1473        AddStream(std::move(AddStream)),1474        ShouldEmitIndexFiles(ShouldEmitIndexFiles) {1475    auto &Defs = CombinedIndex.cfiFunctionDefs();1476    CfiFunctionDefs.insert_range(Defs.guids());1477    auto &Decls = CombinedIndex.cfiFunctionDecls();1478    CfiFunctionDecls.insert_range(Decls.guids());1479  }1480};1481 1482/// This backend performs code generation by scheduling a job to run on1483/// an in-process thread when invoked for each task.1484class InProcessThinBackend : public CGThinBackend {1485protected:1486  FileCache Cache;1487 1488public:1489  InProcessThinBackend(1490      const Config &Conf, ModuleSummaryIndex &CombinedIndex,1491      ThreadPoolStrategy ThinLTOParallelism,1492      const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1493      AddStreamFn AddStream, FileCache Cache, lto::IndexWriteCallback OnWrite,1494      bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles)1495      : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,1496                      AddStream, OnWrite, ShouldEmitIndexFiles,1497                      ShouldEmitImportsFiles, ThinLTOParallelism),1498        Cache(std::move(Cache)) {}1499 1500  virtual Error runThinLTOBackendThread(1501      AddStreamFn AddStream, FileCache Cache, unsigned Task, BitcodeModule BM,1502      ModuleSummaryIndex &CombinedIndex,1503      const FunctionImporter::ImportMapTy &ImportList,1504      const FunctionImporter::ExportSetTy &ExportList,1505      const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,1506      const GVSummaryMapTy &DefinedGlobals,1507      MapVector<StringRef, BitcodeModule> &ModuleMap) {1508    auto ModuleID = BM.getModuleIdentifier();1509    llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (in-process)",1510                                   ModuleID);1511    auto RunThinBackend = [&](AddStreamFn AddStream) {1512      LTOLLVMContext BackendContext(Conf);1513      Expected<std::unique_ptr<Module>> MOrErr = BM.parseModule(BackendContext);1514      if (!MOrErr)1515        return MOrErr.takeError();1516 1517      return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,1518                         ImportList, DefinedGlobals, &ModuleMap,1519                         Conf.CodeGenOnly);1520    };1521    if (ShouldEmitIndexFiles) {1522      if (auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))1523        return E;1524    }1525 1526    if (!Cache.isValid() || !CombinedIndex.modulePaths().count(ModuleID) ||1527        all_of(CombinedIndex.getModuleHash(ModuleID),1528               [](uint32_t V) { return V == 0; }))1529      // Cache disabled or no entry for this module in the combined index or1530      // no module hash.1531      return RunThinBackend(AddStream);1532 1533    // The module may be cached, this helps handling it.1534    std::string Key = computeLTOCacheKey(1535        Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,1536        DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);1537    Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, Key, ModuleID);1538    if (Error Err = CacheAddStreamOrErr.takeError())1539      return Err;1540    AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;1541    if (CacheAddStream)1542      return RunThinBackend(CacheAddStream);1543 1544    return Error::success();1545  }1546 1547  Error start(1548      unsigned Task, BitcodeModule BM,1549      const FunctionImporter::ImportMapTy &ImportList,1550      const FunctionImporter::ExportSetTy &ExportList,1551      const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,1552      MapVector<StringRef, BitcodeModule> &ModuleMap) override {1553    StringRef ModulePath = BM.getModuleIdentifier();1554    assert(ModuleToDefinedGVSummaries.count(ModulePath));1555    const GVSummaryMapTy &DefinedGlobals =1556        ModuleToDefinedGVSummaries.find(ModulePath)->second;1557    BackendThreadPool.async(1558        [=](BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,1559            const FunctionImporter::ImportMapTy &ImportList,1560            const FunctionImporter::ExportSetTy &ExportList,1561            const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>1562                &ResolvedODR,1563            const GVSummaryMapTy &DefinedGlobals,1564            MapVector<StringRef, BitcodeModule> &ModuleMap) {1565          if (LLVM_ENABLE_THREADS && Conf.TimeTraceEnabled)1566            timeTraceProfilerInitialize(Conf.TimeTraceGranularity,1567                                        "thin backend");1568          Error E = runThinLTOBackendThread(1569              AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,1570              ResolvedODR, DefinedGlobals, ModuleMap);1571          if (E) {1572            std::unique_lock<std::mutex> L(ErrMu);1573            if (Err)1574              Err = joinErrors(std::move(*Err), std::move(E));1575            else1576              Err = std::move(E);1577          }1578          if (LLVM_ENABLE_THREADS && Conf.TimeTraceEnabled)1579            timeTraceProfilerFinishThread();1580        },1581        BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),1582        std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));1583 1584    if (OnWrite)1585      OnWrite(std::string(ModulePath));1586    return Error::success();1587  }1588};1589 1590/// This backend is utilized in the first round of a two-codegen round process.1591/// It first saves optimized bitcode files to disk before the codegen process1592/// begins. After codegen, it stores the resulting object files in a scratch1593/// buffer. Note the codegen data stored in the scratch buffer will be extracted1594/// and merged in the subsequent step.1595class FirstRoundThinBackend : public InProcessThinBackend {1596  AddStreamFn IRAddStream;1597  FileCache IRCache;1598 1599public:1600  FirstRoundThinBackend(1601      const Config &Conf, ModuleSummaryIndex &CombinedIndex,1602      ThreadPoolStrategy ThinLTOParallelism,1603      const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1604      AddStreamFn CGAddStream, FileCache CGCache, AddStreamFn IRAddStream,1605      FileCache IRCache)1606      : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,1607                             ModuleToDefinedGVSummaries, std::move(CGAddStream),1608                             std::move(CGCache), /*OnWrite=*/nullptr,1609                             /*ShouldEmitIndexFiles=*/false,1610                             /*ShouldEmitImportsFiles=*/false),1611        IRAddStream(std::move(IRAddStream)), IRCache(std::move(IRCache)) {}1612 1613  Error runThinLTOBackendThread(1614      AddStreamFn CGAddStream, FileCache CGCache, unsigned Task,1615      BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,1616      const FunctionImporter::ImportMapTy &ImportList,1617      const FunctionImporter::ExportSetTy &ExportList,1618      const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,1619      const GVSummaryMapTy &DefinedGlobals,1620      MapVector<StringRef, BitcodeModule> &ModuleMap) override {1621    auto ModuleID = BM.getModuleIdentifier();1622    llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (first round)",1623                                   ModuleID);1624    auto RunThinBackend = [&](AddStreamFn CGAddStream,1625                              AddStreamFn IRAddStream) {1626      LTOLLVMContext BackendContext(Conf);1627      Expected<std::unique_ptr<Module>> MOrErr = BM.parseModule(BackendContext);1628      if (!MOrErr)1629        return MOrErr.takeError();1630 1631      return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,1632                         ImportList, DefinedGlobals, &ModuleMap,1633                         Conf.CodeGenOnly, IRAddStream);1634    };1635    // Like InProcessThinBackend, we produce index files as needed for1636    // FirstRoundThinBackend. However, these files are not generated for1637    // SecondRoundThinBackend.1638    if (ShouldEmitIndexFiles) {1639      if (auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))1640        return E;1641    }1642 1643    assert((CGCache.isValid() == IRCache.isValid()) &&1644           "Both caches for CG and IR should have matching availability");1645    if (!CGCache.isValid() || !CombinedIndex.modulePaths().count(ModuleID) ||1646        all_of(CombinedIndex.getModuleHash(ModuleID),1647               [](uint32_t V) { return V == 0; }))1648      // Cache disabled or no entry for this module in the combined index or1649      // no module hash.1650      return RunThinBackend(CGAddStream, IRAddStream);1651 1652    // Get CGKey for caching object in CGCache.1653    std::string CGKey = computeLTOCacheKey(1654        Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,1655        DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);1656    Expected<AddStreamFn> CacheCGAddStreamOrErr =1657        CGCache(Task, CGKey, ModuleID);1658    if (Error Err = CacheCGAddStreamOrErr.takeError())1659      return Err;1660    AddStreamFn &CacheCGAddStream = *CacheCGAddStreamOrErr;1661 1662    // Get IRKey for caching (optimized) IR in IRCache with an extra ID.1663    std::string IRKey = recomputeLTOCacheKey(CGKey, /*ExtraID=*/"IR");1664    Expected<AddStreamFn> CacheIRAddStreamOrErr =1665        IRCache(Task, IRKey, ModuleID);1666    if (Error Err = CacheIRAddStreamOrErr.takeError())1667      return Err;1668    AddStreamFn &CacheIRAddStream = *CacheIRAddStreamOrErr;1669 1670    // Ideally, both CG and IR caching should be synchronized. However, in1671    // practice, their availability may differ due to different expiration1672    // times. Therefore, if either cache is missing, the backend process is1673    // triggered.1674    if (CacheCGAddStream || CacheIRAddStream) {1675      LLVM_DEBUG(dbgs() << "[FirstRound] Cache Miss for "1676                        << BM.getModuleIdentifier() << "\n");1677      return RunThinBackend(CacheCGAddStream ? CacheCGAddStream : CGAddStream,1678                            CacheIRAddStream ? CacheIRAddStream : IRAddStream);1679    }1680 1681    return Error::success();1682  }1683};1684 1685/// This backend operates in the second round of a two-codegen round process.1686/// It starts by reading the optimized bitcode files that were saved during the1687/// first round. The backend then executes the codegen only to further optimize1688/// the code, utilizing the codegen data merged from the first round. Finally,1689/// it writes the resulting object files as usual.1690class SecondRoundThinBackend : public InProcessThinBackend {1691  std::unique_ptr<SmallVector<StringRef>> IRFiles;1692  stable_hash CombinedCGDataHash;1693 1694public:1695  SecondRoundThinBackend(1696      const Config &Conf, ModuleSummaryIndex &CombinedIndex,1697      ThreadPoolStrategy ThinLTOParallelism,1698      const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1699      AddStreamFn AddStream, FileCache Cache,1700      std::unique_ptr<SmallVector<StringRef>> IRFiles,1701      stable_hash CombinedCGDataHash)1702      : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,1703                             ModuleToDefinedGVSummaries, std::move(AddStream),1704                             std::move(Cache),1705                             /*OnWrite=*/nullptr,1706                             /*ShouldEmitIndexFiles=*/false,1707                             /*ShouldEmitImportsFiles=*/false),1708        IRFiles(std::move(IRFiles)), CombinedCGDataHash(CombinedCGDataHash) {}1709 1710  Error runThinLTOBackendThread(1711      AddStreamFn AddStream, FileCache Cache, unsigned Task, BitcodeModule BM,1712      ModuleSummaryIndex &CombinedIndex,1713      const FunctionImporter::ImportMapTy &ImportList,1714      const FunctionImporter::ExportSetTy &ExportList,1715      const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,1716      const GVSummaryMapTy &DefinedGlobals,1717      MapVector<StringRef, BitcodeModule> &ModuleMap) override {1718    auto ModuleID = BM.getModuleIdentifier();1719    llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (second round)",1720                                   ModuleID);1721    auto RunThinBackend = [&](AddStreamFn AddStream) {1722      LTOLLVMContext BackendContext(Conf);1723      std::unique_ptr<Module> LoadedModule =1724          cgdata::loadModuleForTwoRounds(BM, Task, BackendContext, *IRFiles);1725 1726      return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,1727                         ImportList, DefinedGlobals, &ModuleMap,1728                         /*CodeGenOnly=*/true);1729    };1730    if (!Cache.isValid() || !CombinedIndex.modulePaths().count(ModuleID) ||1731        all_of(CombinedIndex.getModuleHash(ModuleID),1732               [](uint32_t V) { return V == 0; }))1733      // Cache disabled or no entry for this module in the combined index or1734      // no module hash.1735      return RunThinBackend(AddStream);1736 1737    // Get Key for caching the final object file in Cache with the combined1738    // CGData hash.1739    std::string Key = computeLTOCacheKey(1740        Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,1741        DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);1742    Key = recomputeLTOCacheKey(Key,1743                               /*ExtraID=*/std::to_string(CombinedCGDataHash));1744    Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, Key, ModuleID);1745    if (Error Err = CacheAddStreamOrErr.takeError())1746      return Err;1747    AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;1748 1749    if (CacheAddStream) {1750      LLVM_DEBUG(dbgs() << "[SecondRound] Cache Miss for "1751                        << BM.getModuleIdentifier() << "\n");1752      return RunThinBackend(CacheAddStream);1753    }1754 1755    return Error::success();1756  }1757};1758} // end anonymous namespace1759 1760ThinBackend lto::createInProcessThinBackend(ThreadPoolStrategy Parallelism,1761                                            lto::IndexWriteCallback OnWrite,1762                                            bool ShouldEmitIndexFiles,1763                                            bool ShouldEmitImportsFiles) {1764  auto Func =1765      [=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,1766          const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1767          AddStreamFn AddStream, FileCache Cache) {1768        return std::make_unique<InProcessThinBackend>(1769            Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,1770            AddStream, Cache, OnWrite, ShouldEmitIndexFiles,1771            ShouldEmitImportsFiles);1772      };1773  return ThinBackend(Func, Parallelism);1774}1775 1776StringLiteral lto::getThinLTODefaultCPU(const Triple &TheTriple) {1777  if (!TheTriple.isOSDarwin())1778    return "";1779  if (TheTriple.getArch() == Triple::x86_64)1780    return "core2";1781  if (TheTriple.getArch() == Triple::x86)1782    return "yonah";1783  if (TheTriple.isArm64e())1784    return "apple-a12";1785  if (TheTriple.getArch() == Triple::aarch64 ||1786      TheTriple.getArch() == Triple::aarch64_32)1787    return "cyclone";1788  return "";1789}1790 1791// Given the original \p Path to an output file, replace any path1792// prefix matching \p OldPrefix with \p NewPrefix. Also, create the1793// resulting directory if it does not yet exist.1794std::string lto::getThinLTOOutputFile(StringRef Path, StringRef OldPrefix,1795                                      StringRef NewPrefix) {1796  if (OldPrefix.empty() && NewPrefix.empty())1797    return std::string(Path);1798  SmallString<128> NewPath(Path);1799  llvm::sys::path::replace_path_prefix(NewPath, OldPrefix, NewPrefix);1800  StringRef ParentPath = llvm::sys::path::parent_path(NewPath.str());1801  if (!ParentPath.empty()) {1802    // Make sure the new directory exists, creating it if necessary.1803    if (std::error_code EC = llvm::sys::fs::create_directories(ParentPath))1804      llvm::errs() << "warning: could not create directory '" << ParentPath1805                   << "': " << EC.message() << '\n';1806  }1807  return std::string(NewPath);1808}1809 1810namespace {1811class WriteIndexesThinBackend : public ThinBackendProc {1812  std::string OldPrefix, NewPrefix, NativeObjectPrefix;1813  raw_fd_ostream *LinkedObjectsFile;1814 1815public:1816  WriteIndexesThinBackend(1817      const Config &Conf, ModuleSummaryIndex &CombinedIndex,1818      ThreadPoolStrategy ThinLTOParallelism,1819      const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1820      std::string OldPrefix, std::string NewPrefix,1821      std::string NativeObjectPrefix, bool ShouldEmitImportsFiles,1822      raw_fd_ostream *LinkedObjectsFile, lto::IndexWriteCallback OnWrite)1823      : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,1824                        OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),1825        OldPrefix(OldPrefix), NewPrefix(NewPrefix),1826        NativeObjectPrefix(NativeObjectPrefix),1827        LinkedObjectsFile(LinkedObjectsFile) {}1828 1829  Error start(1830      unsigned Task, BitcodeModule BM,1831      const FunctionImporter::ImportMapTy &ImportList,1832      const FunctionImporter::ExportSetTy &ExportList,1833      const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,1834      MapVector<StringRef, BitcodeModule> &ModuleMap) override {1835    StringRef ModulePath = BM.getModuleIdentifier();1836 1837    // The contents of this file may be used as input to a native link, and must1838    // therefore contain the processed modules in a determinstic order that1839    // match the order they are provided on the command line. For that reason,1840    // we cannot include this in the asynchronously executed lambda below.1841    if (LinkedObjectsFile) {1842      std::string ObjectPrefix =1843          NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;1844      std::string LinkedObjectsFilePath =1845          getThinLTOOutputFile(ModulePath, OldPrefix, ObjectPrefix);1846      *LinkedObjectsFile << LinkedObjectsFilePath << '\n';1847    }1848 1849    BackendThreadPool.async(1850        [this](const StringRef ModulePath,1851               const FunctionImporter::ImportMapTy &ImportList,1852               const std::string &OldPrefix, const std::string &NewPrefix) {1853          std::string NewModulePath =1854              getThinLTOOutputFile(ModulePath, OldPrefix, NewPrefix);1855          auto E = emitFiles(ImportList, ModulePath, NewModulePath);1856          if (E) {1857            std::unique_lock<std::mutex> L(ErrMu);1858            if (Err)1859              Err = joinErrors(std::move(*Err), std::move(E));1860            else1861              Err = std::move(E);1862            return;1863          }1864        },1865        ModulePath, ImportList, OldPrefix, NewPrefix);1866 1867    if (OnWrite)1868      OnWrite(std::string(ModulePath));1869    return Error::success();1870  }1871 1872  bool isSensitiveToInputOrder() override {1873    // The order which modules are written to LinkedObjectsFile should be1874    // deterministic and match the order they are passed on the command line.1875    return true;1876  }1877};1878} // end anonymous namespace1879 1880ThinBackend lto::createWriteIndexesThinBackend(1881    ThreadPoolStrategy Parallelism, std::string OldPrefix,1882    std::string NewPrefix, std::string NativeObjectPrefix,1883    bool ShouldEmitImportsFiles, raw_fd_ostream *LinkedObjectsFile,1884    IndexWriteCallback OnWrite) {1885  auto Func =1886      [=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,1887          const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1888          AddStreamFn AddStream, FileCache Cache) {1889        return std::make_unique<WriteIndexesThinBackend>(1890            Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,1891            OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,1892            LinkedObjectsFile, OnWrite);1893      };1894  return ThinBackend(Func, Parallelism);1895}1896 1897Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,1898                      const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {1899  llvm::TimeTraceScope timeScope("Run ThinLTO");1900  LLVM_DEBUG(dbgs() << "Running ThinLTO\n");1901  ThinLTO.CombinedIndex.releaseTemporaryMemory();1902  timeTraceProfilerBegin("ThinLink", StringRef(""));1903  auto TimeTraceScopeExit = llvm::make_scope_exit([]() {1904    if (llvm::timeTraceProfilerEnabled())1905      llvm::timeTraceProfilerEnd();1906  });1907  if (ThinLTO.ModuleMap.empty())1908    return Error::success();1909 1910  if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {1911    llvm::errs() << "warning: [ThinLTO] No module compiled\n";1912    return Error::success();1913  }1914 1915  if (Conf.CombinedIndexHook &&1916      !Conf.CombinedIndexHook(ThinLTO.CombinedIndex, GUIDPreservedSymbols))1917    return Error::success();1918 1919  // Collect for each module the list of function it defines (GUID ->1920  // Summary).1921  DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(1922      ThinLTO.ModuleMap.size());1923  ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(1924      ModuleToDefinedGVSummaries);1925  // Create entries for any modules that didn't have any GV summaries1926  // (either they didn't have any GVs to start with, or we suppressed1927  // generation of the summaries because they e.g. had inline assembly1928  // uses that couldn't be promoted/renamed on export). This is so1929  // InProcessThinBackend::start can still launch a backend thread, which1930  // is passed the map of summaries for the module, without any special1931  // handling for this case.1932  for (auto &Mod : ThinLTO.ModuleMap)1933    if (!ModuleToDefinedGVSummaries.count(Mod.first))1934      ModuleToDefinedGVSummaries.try_emplace(Mod.first);1935 1936  FunctionImporter::ImportListsTy ImportLists(ThinLTO.ModuleMap.size());1937  DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists(1938      ThinLTO.ModuleMap.size());1939  StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;1940 1941  if (DumpThinCGSCCs)1942    ThinLTO.CombinedIndex.dumpSCCs(outs());1943 1944  std::set<GlobalValue::GUID> ExportedGUIDs;1945 1946  bool WholeProgramVisibilityEnabledInLTO =1947      Conf.HasWholeProgramVisibility &&1948      // If validation is enabled, upgrade visibility only when all vtables1949      // have typeinfos.1950      (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);1951  if (hasWholeProgramVisibility(WholeProgramVisibilityEnabledInLTO))1952    ThinLTO.CombinedIndex.setWithWholeProgramVisibility();1953 1954  // If we're validating, get the vtable symbols that should not be1955  // upgraded because they correspond to typeIDs outside of index-based1956  // WPD info.1957  DenseSet<GlobalValue::GUID> VisibleToRegularObjSymbols;1958  if (WholeProgramVisibilityEnabledInLTO &&1959      Conf.ValidateAllVtablesHaveTypeInfos) {1960    // This returns true when the name is local or not defined. Locals are1961    // expected to be handled separately.1962    auto IsVisibleToRegularObj = [&](StringRef name) {1963      auto It = GlobalResolutions->find(name);1964      return (It == GlobalResolutions->end() ||1965              It->second.VisibleOutsideSummary || !It->second.Prevailing);1966    };1967 1968    getVisibleToRegularObjVtableGUIDs(ThinLTO.CombinedIndex,1969                                      VisibleToRegularObjSymbols,1970                                      IsVisibleToRegularObj);1971  }1972 1973  // If allowed, upgrade public vcall visibility to linkage unit visibility in1974  // the summaries before whole program devirtualization below.1975  updateVCallVisibilityInIndex(1976      ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,1977      DynamicExportSymbols, VisibleToRegularObjSymbols);1978 1979  // Perform index-based WPD. This will return immediately if there are1980  // no index entries in the typeIdMetadata map (e.g. if we are instead1981  // performing IR-based WPD in hybrid regular/thin LTO mode).1982  std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;1983  runWholeProgramDevirtOnIndex(ThinLTO.CombinedIndex, ExportedGUIDs,1984                               LocalWPDTargetsMap);1985 1986  auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {1987    return ThinLTO.isPrevailingModuleForGUID(GUID, S->modulePath());1988  };1989  if (EnableMemProfContextDisambiguation) {1990    MemProfContextDisambiguation ContextDisambiguation;1991    ContextDisambiguation.run(ThinLTO.CombinedIndex, isPrevailing);1992  }1993 1994  // Figure out which symbols need to be internalized. This also needs to happen1995  // at -O0 because summary-based DCE is implemented using internalization, and1996  // we must apply DCE consistently with the full LTO module in order to avoid1997  // undefined references during the final link.1998  for (auto &Res : *GlobalResolutions) {1999    // If the symbol does not have external references or it is not prevailing,2000    // then not need to mark it as exported from a ThinLTO partition.2001    if (Res.second.Partition != GlobalResolution::External ||2002        !Res.second.isPrevailingIRSymbol())2003      continue;2004    auto GUID = GlobalValue::getGUIDAssumingExternalLinkage(2005        GlobalValue::dropLLVMManglingEscape(Res.second.IRName));2006    // Mark exported unless index-based analysis determined it to be dead.2007    if (ThinLTO.CombinedIndex.isGUIDLive(GUID))2008      ExportedGUIDs.insert(GUID);2009  }2010 2011  // Reset the GlobalResolutions to deallocate the associated memory, as there2012  // are no further accesses. We specifically want to do this before computing2013  // cross module importing, which adds to peak memory via the computed import2014  // and export lists.2015  releaseGlobalResolutionsMemory();2016 2017  if (Conf.OptLevel > 0)2018    ComputeCrossModuleImport(ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,2019                             isPrevailing, ImportLists, ExportLists);2020 2021  // Any functions referenced by the jump table in the regular LTO object must2022  // be exported.2023  auto &Defs = ThinLTO.CombinedIndex.cfiFunctionDefs();2024  ExportedGUIDs.insert(Defs.guid_begin(), Defs.guid_end());2025  auto &Decls = ThinLTO.CombinedIndex.cfiFunctionDecls();2026  ExportedGUIDs.insert(Decls.guid_begin(), Decls.guid_end());2027 2028  auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {2029    const auto &ExportList = ExportLists.find(ModuleIdentifier);2030    return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||2031           ExportedGUIDs.count(VI.getGUID());2032  };2033 2034  // Update local devirtualized targets that were exported by cross-module2035  // importing or by other devirtualizations marked in the ExportedGUIDs set.2036  updateIndexWPDForExports(ThinLTO.CombinedIndex, isExported,2037                           LocalWPDTargetsMap);2038 2039  thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported,2040                                      isPrevailing);2041 2042  auto recordNewLinkage = [&](StringRef ModuleIdentifier,2043                              GlobalValue::GUID GUID,2044                              GlobalValue::LinkageTypes NewLinkage) {2045    ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;2046  };2047  thinLTOResolvePrevailingInIndex(Conf, ThinLTO.CombinedIndex, isPrevailing,2048                                  recordNewLinkage, GUIDPreservedSymbols);2049 2050  thinLTOPropagateFunctionAttrs(ThinLTO.CombinedIndex, isPrevailing);2051 2052  generateParamAccessSummary(ThinLTO.CombinedIndex);2053 2054  if (llvm::timeTraceProfilerEnabled())2055    llvm::timeTraceProfilerEnd();2056 2057  TimeTraceScopeExit.release();2058 2059  auto &ModuleMap =2060      ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;2061 2062  auto RunBackends = [&](ThinBackendProc *BackendProcess) -> Error {2063    auto ProcessOneModule = [&](int I) -> Error {2064      auto &Mod = *(ModuleMap.begin() + I);2065      // Tasks 0 through ParallelCodeGenParallelismLevel-1 are reserved for2066      // combined module and parallel code generation partitions.2067      return BackendProcess->start(2068          RegularLTO.ParallelCodeGenParallelismLevel + I, Mod.second,2069          ImportLists[Mod.first], ExportLists[Mod.first],2070          ResolvedODR[Mod.first], ThinLTO.ModuleMap);2071    };2072 2073    BackendProcess->setup(ModuleMap.size(),2074                          RegularLTO.ParallelCodeGenParallelismLevel,2075                          RegularLTO.CombinedModule->getTargetTriple());2076 2077    if (BackendProcess->getThreadCount() == 1 ||2078        BackendProcess->isSensitiveToInputOrder()) {2079      // Process the modules in the order they were provided on the2080      // command-line. It is important for this codepath to be used for2081      // WriteIndexesThinBackend, to ensure the emitted LinkedObjectsFile lists2082      // ThinLTO objects in the same order as the inputs, which otherwise would2083      // affect the final link order.2084      for (int I = 0, E = ModuleMap.size(); I != E; ++I)2085        if (Error E = ProcessOneModule(I))2086          return E;2087    } else {2088      // When executing in parallel, process largest bitsize modules first to2089      // improve parallelism, and avoid starving the thread pool near the end.2090      // This saves about 15 sec on a 36-core machine while link `clang.exe`2091      // (out of 100 sec).2092      std::vector<BitcodeModule *> ModulesVec;2093      ModulesVec.reserve(ModuleMap.size());2094      for (auto &Mod : ModuleMap)2095        ModulesVec.push_back(&Mod.second);2096      for (int I : generateModulesOrdering(ModulesVec))2097        if (Error E = ProcessOneModule(I))2098          return E;2099    }2100    return BackendProcess->wait();2101  };2102 2103  if (!CodeGenDataThinLTOTwoRounds) {2104    std::unique_ptr<ThinBackendProc> BackendProc =2105        ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,2106                        AddStream, Cache);2107    return RunBackends(BackendProc.get());2108  }2109 2110  // Perform two rounds of code generation for ThinLTO:2111  // 1. First round: Perform optimization and code generation, outputting to2112  // temporary scratch objects.2113  // 2. Merge code generation data extracted from the temporary scratch objects.2114  // 3. Second round: Execute code generation again using the merged data.2115  LLVM_DEBUG(dbgs() << "[TwoRounds] Initializing ThinLTO two-codegen rounds\n");2116 2117  unsigned MaxTasks = getMaxTasks();2118  auto Parallelism = ThinLTO.Backend.getParallelism();2119  // Set up two additional streams and caches for storing temporary scratch2120  // objects and optimized IRs, using the same cache directory as the original.2121  cgdata::StreamCacheData CG(MaxTasks, Cache, "CG"), IR(MaxTasks, Cache, "IR");2122 2123  // First round: Execute optimization and code generation, outputting to2124  // temporary scratch objects. Serialize the optimized IRs before initiating2125  // code generation.2126  LLVM_DEBUG(dbgs() << "[TwoRounds] Running the first round of codegen\n");2127  auto FirstRoundLTO = std::make_unique<FirstRoundThinBackend>(2128      Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,2129      CG.AddStream, CG.Cache, IR.AddStream, IR.Cache);2130  if (Error E = RunBackends(FirstRoundLTO.get()))2131    return E;2132 2133  LLVM_DEBUG(dbgs() << "[TwoRounds] Merging codegen data\n");2134  auto CombinedHashOrErr = cgdata::mergeCodeGenData(*CG.getResult());2135  if (Error E = CombinedHashOrErr.takeError())2136    return E;2137  auto CombinedHash = *CombinedHashOrErr;2138  LLVM_DEBUG(dbgs() << "[TwoRounds] CGData hash: " << CombinedHash << "\n");2139 2140  // Second round: Read the optimized IRs and execute code generation using the2141  // merged data.2142  LLVM_DEBUG(dbgs() << "[TwoRounds] Running the second round of codegen\n");2143  auto SecondRoundLTO = std::make_unique<SecondRoundThinBackend>(2144      Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,2145      AddStream, Cache, IR.getResult(), CombinedHash);2146  return RunBackends(SecondRoundLTO.get());2147}2148 2149Expected<LLVMRemarkFileHandle> lto::setupLLVMOptimizationRemarks(2150    LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,2151    StringRef RemarksFormat, bool RemarksWithHotness,2152    std::optional<uint64_t> RemarksHotnessThreshold, int Count) {2153  std::string Filename = std::string(RemarksFilename);2154  // For ThinLTO, file.opt.<format> becomes2155  // file.opt.<format>.thin.<num>.<format>.2156  if (!Filename.empty() && Count != -1)2157    Filename =2158        (Twine(Filename) + ".thin." + llvm::utostr(Count) + "." + RemarksFormat)2159            .str();2160 2161  auto ResultOrErr = llvm::setupLLVMOptimizationRemarks(2162      Context, Filename, RemarksPasses, RemarksFormat, RemarksWithHotness,2163      RemarksHotnessThreshold);2164  if (Error E = ResultOrErr.takeError())2165    return std::move(E);2166 2167  if (*ResultOrErr)2168    (*ResultOrErr)->keep();2169 2170  return ResultOrErr;2171}2172 2173Expected<std::unique_ptr<ToolOutputFile>>2174lto::setupStatsFile(StringRef StatsFilename) {2175  // Setup output file to emit statistics.2176  if (StatsFilename.empty())2177    return nullptr;2178 2179  llvm::EnableStatistics(false);2180  std::error_code EC;2181  auto StatsFile =2182      std::make_unique<ToolOutputFile>(StatsFilename, EC, sys::fs::OF_None);2183  if (EC)2184    return errorCodeToError(EC);2185 2186  StatsFile->keep();2187  return std::move(StatsFile);2188}2189 2190// Compute the ordering we will process the inputs: the rough heuristic here2191// is to sort them per size so that the largest module get schedule as soon as2192// possible. This is purely a compile-time optimization.2193std::vector<int> lto::generateModulesOrdering(ArrayRef<BitcodeModule *> R) {2194  auto Seq = llvm::seq<int>(0, R.size());2195  std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());2196  llvm::sort(ModulesOrdering, [&](int LeftIndex, int RightIndex) {2197    auto LSize = R[LeftIndex]->getBuffer().size();2198    auto RSize = R[RightIndex]->getBuffer().size();2199    return LSize > RSize;2200  });2201  return ModulesOrdering;2202}2203 2204namespace {2205/// This out-of-process backend does not perform code generation when invoked2206/// for each task. Instead, it generates the necessary information (e.g., the2207/// summary index shard, import list, etc.) to enable code generation to be2208/// performed externally, similar to WriteIndexesThinBackend. The backend's2209/// `wait` function then invokes an external distributor process to carry out2210/// the backend compilations.2211class OutOfProcessThinBackend : public CGThinBackend {2212  using SString = SmallString<128>;2213 2214  BumpPtrAllocator Alloc;2215  StringSaver Saver{Alloc};2216 2217  SString LinkerOutputFile;2218 2219  SString DistributorPath;2220  ArrayRef<StringRef> DistributorArgs;2221 2222  SString RemoteCompiler;2223  ArrayRef<StringRef> RemoteCompilerPrependArgs;2224  ArrayRef<StringRef> RemoteCompilerArgs;2225 2226  bool SaveTemps;2227 2228  SmallVector<StringRef, 0> CodegenOptions;2229  DenseSet<StringRef> CommonInputs;2230  // Number of the object files that have been already cached.2231  std::atomic<size_t> CachedJobs{0};2232  // Information specific to individual backend compilation job.2233  struct Job {2234    unsigned Task;2235    StringRef ModuleID;2236    StringRef NativeObjectPath;2237    StringRef SummaryIndexPath;2238    ImportsFilesContainer ImportsFiles;2239    std::string CacheKey;2240    AddStreamFn CacheAddStream;2241    bool Cached = false;2242  };2243  // The set of backend compilations jobs.2244  SmallVector<Job> Jobs;2245 2246  // A unique string to identify the current link.2247  SmallString<8> UID;2248 2249  // The offset to the first ThinLTO task.2250  unsigned ThinLTOTaskOffset;2251 2252  // The target triple to supply for backend compilations.2253  llvm::Triple Triple;2254 2255  // Cache2256  FileCache Cache;2257 2258public:2259  OutOfProcessThinBackend(2260      const Config &Conf, ModuleSummaryIndex &CombinedIndex,2261      ThreadPoolStrategy ThinLTOParallelism,2262      const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,2263      AddStreamFn AddStream, FileCache CacheFn, lto::IndexWriteCallback OnWrite,2264      bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles,2265      StringRef LinkerOutputFile, StringRef Distributor,2266      ArrayRef<StringRef> DistributorArgs, StringRef RemoteCompiler,2267      ArrayRef<StringRef> RemoteCompilerPrependArgs,2268      ArrayRef<StringRef> RemoteCompilerArgs, bool SaveTemps)2269      : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,2270                      AddStream, OnWrite, ShouldEmitIndexFiles,2271                      ShouldEmitImportsFiles, ThinLTOParallelism),2272        LinkerOutputFile(LinkerOutputFile), DistributorPath(Distributor),2273        DistributorArgs(DistributorArgs), RemoteCompiler(RemoteCompiler),2274        RemoteCompilerPrependArgs(RemoteCompilerPrependArgs),2275        RemoteCompilerArgs(RemoteCompilerArgs), SaveTemps(SaveTemps),2276        Cache(std::move(CacheFn)) {}2277 2278  void setup(unsigned ThinLTONumTasks, unsigned ThinLTOTaskOffset,2279             llvm::Triple Triple) override {2280    UID = itostr(sys::Process::getProcessId());2281    Jobs.resize((size_t)ThinLTONumTasks);2282    this->ThinLTOTaskOffset = ThinLTOTaskOffset;2283    this->Triple = Triple;2284    this->Conf.Dtlto = 1;2285  }2286 2287  virtual Error runThinLTOBackendThread(2288      Job &J, const FunctionImporter::ImportMapTy &ImportList,2289      const FunctionImporter::ExportSetTy &ExportList,2290      const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>2291          &ResolvedODR) {2292 2293    llvm::TimeTraceScope timeScope(2294        "Run ThinLTO backend thread (out-of-process)", J.ModuleID);2295 2296    if (auto E = emitFiles(ImportList, J.ModuleID, J.ModuleID.str(),2297                           J.SummaryIndexPath, J.ImportsFiles))2298      return E;2299 2300    if (!Cache.isValid() || !CombinedIndex.modulePaths().count(J.ModuleID) ||2301        all_of(CombinedIndex.getModuleHash(J.ModuleID),2302               [](uint32_t V) { return V == 0; }))2303      // Cache disabled or no entry for this module in the combined index or2304      // no module hash.2305      return Error::success();2306 2307    const GVSummaryMapTy &DefinedGlobals =2308        ModuleToDefinedGVSummaries.find(J.ModuleID)->second;2309 2310    // The module may be cached, this helps handling it.2311    J.CacheKey = computeLTOCacheKey(Conf, CombinedIndex, J.ModuleID, ImportList,2312                                    ExportList, ResolvedODR, DefinedGlobals,2313                                    CfiFunctionDefs, CfiFunctionDecls);2314 2315    // The module may be cached, this helps handling it.2316    auto CacheAddStreamExp = Cache(J.Task, J.CacheKey, J.ModuleID);2317    if (Error Err = CacheAddStreamExp.takeError())2318      return Err;2319    AddStreamFn &CacheAddStream = *CacheAddStreamExp;2320    // If CacheAddStream is null, we have a cache hit and at this point2321    // object file is already passed back to the linker.2322    if (!CacheAddStream) {2323      J.Cached = true; // Cache hit, mark the job as cached.2324      CachedJobs.fetch_add(1);2325    } else {2326      // If CacheAddStream is not null, we have a cache miss and we need to2327      // run the backend for codegen. Save cache 'add stream'2328      // function for a later use.2329      J.CacheAddStream = std::move(CacheAddStream);2330    }2331    return Error::success();2332  }2333 2334  Error start(2335      unsigned Task, BitcodeModule BM,2336      const FunctionImporter::ImportMapTy &ImportList,2337      const FunctionImporter::ExportSetTy &ExportList,2338      const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,2339      MapVector<StringRef, BitcodeModule> &ModuleMap) override {2340 2341    StringRef ModulePath = BM.getModuleIdentifier();2342 2343    SString ObjFilePath = sys::path::parent_path(LinkerOutputFile);2344    sys::path::append(ObjFilePath, sys::path::stem(ModulePath) + "." +2345                                       itostr(Task) + "." + UID + ".native.o");2346 2347    Job &J = Jobs[Task - ThinLTOTaskOffset];2348    J = {Task,2349         ModulePath,2350         Saver.save(ObjFilePath.str()),2351         Saver.save(ObjFilePath.str() + ".thinlto.bc"),2352         {}, // Filled in by emitFiles below.2353         "", /*CacheKey=*/2354         nullptr,2355         false};2356 2357    assert(ModuleToDefinedGVSummaries.count(ModulePath));2358 2359    // The BackendThreadPool is only used here to write the sharded index files2360    // (similar to WriteIndexesThinBackend).2361    BackendThreadPool.async(2362        [=](Job &J, const FunctionImporter::ImportMapTy &ImportList,2363            const FunctionImporter::ExportSetTy &ExportList,2364            const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>2365                &ResolvedODR) {2366          Error E =2367              runThinLTOBackendThread(J, ImportList, ExportList, ResolvedODR);2368          if (E) {2369            std::unique_lock<std::mutex> L(ErrMu);2370            if (Err)2371              Err = joinErrors(std::move(*Err), std::move(E));2372            else2373              Err = std::move(E);2374          }2375        },2376        std::ref(J), std::ref(ImportList), std::ref(ExportList),2377        std::ref(ResolvedODR));2378 2379    return Error::success();2380  }2381 2382  // Derive a set of Clang options that will be shared/common for all DTLTO2383  // backend compilations. We are intentionally minimal here as these options2384  // must remain synchronized with the behavior of Clang. DTLTO does not support2385  // all the features available with in-process LTO. More features are expected2386  // to be added over time. Users can specify Clang options directly if a2387  // feature is not supported. Note that explicitly specified options that imply2388  // additional input or output file dependencies must be communicated to the2389  // distribution system, potentially by setting extra options on the2390  // distributor program.2391  void buildCommonRemoteCompilerOptions() {2392    const lto::Config &C = Conf;2393    auto &Ops = CodegenOptions;2394 2395    Ops.push_back(Saver.save("-O" + Twine(C.OptLevel)));2396 2397    if (C.Options.EmitAddrsig)2398      Ops.push_back("-faddrsig");2399    if (C.Options.FunctionSections)2400      Ops.push_back("-ffunction-sections");2401    if (C.Options.DataSections)2402      Ops.push_back("-fdata-sections");2403 2404    if (C.RelocModel == Reloc::PIC_)2405      // Clang doesn't have -fpic for all triples.2406      if (!Triple.isOSBinFormatCOFF())2407        Ops.push_back("-fpic");2408 2409    // Turn on/off warnings about profile cfg mismatch (default on)2410    // --lto-pgo-warn-mismatch.2411    if (!C.PGOWarnMismatch) {2412      Ops.push_back("-mllvm");2413      Ops.push_back("-no-pgo-warn-mismatch");2414    }2415 2416    // Enable sample-based profile guided optimizations.2417    // Sample profile file path --lto-sample-profile=<value>.2418    if (!C.SampleProfile.empty()) {2419      Ops.push_back(2420          Saver.save("-fprofile-sample-use=" + Twine(C.SampleProfile)));2421      CommonInputs.insert(C.SampleProfile);2422    }2423 2424    // We don't know which of options will be used by Clang.2425    Ops.push_back("-Wno-unused-command-line-argument");2426 2427    // Forward any supplied options.2428    if (!RemoteCompilerArgs.empty())2429      for (auto &a : RemoteCompilerArgs)2430        Ops.push_back(a);2431  }2432 2433  // Generates a JSON file describing the backend compilations, for the2434  // distributor.2435  bool emitDistributorJson(StringRef DistributorJson) {2436    using json::Array;2437    std::error_code EC;2438    raw_fd_ostream OS(DistributorJson, EC);2439    if (EC)2440      return false;2441 2442    json::OStream JOS(OS);2443    JOS.object([&]() {2444      // Information common to all jobs.2445      JOS.attributeObject("common", [&]() {2446        JOS.attribute("linker_output", LinkerOutputFile);2447 2448        JOS.attributeArray("args", [&]() {2449          JOS.value(RemoteCompiler);2450 2451          // Forward any supplied prepend options.2452          if (!RemoteCompilerPrependArgs.empty())2453            for (auto &A : RemoteCompilerPrependArgs)2454              JOS.value(A);2455 2456          JOS.value("-c");2457 2458          JOS.value(Saver.save("--target=" + Triple.str()));2459 2460          for (const auto &A : CodegenOptions)2461            JOS.value(A);2462        });2463 2464        JOS.attribute("inputs", Array(CommonInputs));2465      });2466 2467      // Per-compilation-job information.2468      JOS.attributeArray("jobs", [&]() {2469        for (const auto &J : Jobs) {2470          assert(J.Task != 0);2471          if (J.Cached) {2472            assert(!Cache.getCacheDirectoryPath().empty());2473            continue;2474          }2475 2476          SmallVector<StringRef, 2> Inputs;2477          SmallVector<StringRef, 1> Outputs;2478 2479          JOS.object([&]() {2480            JOS.attributeArray("args", [&]() {2481              JOS.value(J.ModuleID);2482              Inputs.push_back(J.ModuleID);2483 2484              JOS.value(2485                  Saver.save("-fthinlto-index=" + Twine(J.SummaryIndexPath)));2486              Inputs.push_back(J.SummaryIndexPath);2487 2488              JOS.value("-o");2489              JOS.value(J.NativeObjectPath);2490              Outputs.push_back(J.NativeObjectPath);2491            });2492 2493            // Add the bitcode files from which imports will be made. These do2494            // not explicitly appear on the backend compilation command lines2495            // but are recorded in the summary index shards.2496            llvm::append_range(Inputs, J.ImportsFiles);2497            JOS.attribute("inputs", Array(Inputs));2498 2499            JOS.attribute("outputs", Array(Outputs));2500          });2501        }2502      });2503    });2504 2505    return true;2506  }2507 2508  void removeFile(StringRef FileName) {2509    std::error_code EC = sys::fs::remove(FileName, true);2510    if (EC && EC != std::make_error_code(std::errc::no_such_file_or_directory))2511      errs() << "warning: could not remove the file '" << FileName2512             << "': " << EC.message() << "\n";2513  }2514 2515  Error wait() override {2516    // Wait for the information on the required backend compilations to be2517    // gathered.2518    BackendThreadPool.wait();2519    if (Err)2520      return std::move(*Err);2521 2522    auto CleanPerJobFiles = llvm::make_scope_exit([&] {2523      if (!SaveTemps)2524        for (auto &Job : Jobs) {2525          removeFile(Job.NativeObjectPath);2526          if (!ShouldEmitIndexFiles)2527            removeFile(Job.SummaryIndexPath);2528        }2529    });2530 2531    const StringRef BCError = "DTLTO backend compilation: ";2532 2533    buildCommonRemoteCompilerOptions();2534 2535    SString JsonFile = sys::path::parent_path(LinkerOutputFile);2536    sys::path::append(JsonFile, sys::path::stem(LinkerOutputFile) + "." + UID +2537                                    ".dist-file.json");2538    if (!emitDistributorJson(JsonFile))2539      return make_error<StringError>(2540          BCError + "failed to generate distributor JSON script: " + JsonFile,2541          inconvertibleErrorCode());2542    auto CleanJson = llvm::make_scope_exit([&] {2543      if (!SaveTemps)2544        removeFile(JsonFile);2545    });2546 2547    // Checks if we have any jobs that don't have corresponding cache entries.2548    if (CachedJobs.load() < Jobs.size()) {2549      SmallVector<StringRef, 3> Args = {DistributorPath};2550      llvm::append_range(Args, DistributorArgs);2551      Args.push_back(JsonFile);2552      std::string ErrMsg;2553      if (sys::ExecuteAndWait(Args[0], Args,2554                              /*Env=*/std::nullopt, /*Redirects=*/{},2555                              /*SecondsToWait=*/0, /*MemoryLimit=*/0,2556                              &ErrMsg)) {2557        return make_error<StringError>(2558            BCError + "distributor execution failed" +2559                (!ErrMsg.empty() ? ": " + ErrMsg + Twine(".") : Twine(".")),2560            inconvertibleErrorCode());2561      }2562    }2563 2564    for (auto &Job : Jobs) {2565      if (!Job.CacheKey.empty() && Job.Cached) {2566        assert(Cache.isValid());2567        continue;2568      }2569      // Load the native object from a file into a memory buffer2570      // and store its contents in the output buffer.2571      auto ObjFileMbOrErr =2572          MemoryBuffer::getFile(Job.NativeObjectPath, /*IsText=*/false,2573                                /*RequiresNullTerminator=*/false);2574      if (std::error_code EC = ObjFileMbOrErr.getError())2575        return make_error<StringError>(2576            BCError + "cannot open native object file: " +2577                Job.NativeObjectPath + ": " + EC.message(),2578            inconvertibleErrorCode());2579 2580      MemoryBufferRef ObjFileMbRef = ObjFileMbOrErr->get()->getMemBufferRef();2581      if (Cache.isValid()) {2582        // Cache hits are taken care of earlier. At this point, we could only2583        // have cache misses.2584        assert(Job.CacheAddStream);2585        // Obtain a file stream for a storing a cache entry.2586        auto CachedFileStreamOrErr = Job.CacheAddStream(Job.Task, Job.ModuleID);2587        if (!CachedFileStreamOrErr)2588          return joinErrors(2589              CachedFileStreamOrErr.takeError(),2590              createStringError(inconvertibleErrorCode(),2591                                "Cannot get a cache file stream: %s",2592                                Job.NativeObjectPath.data()));2593        // Store a file buffer into the cache stream.2594        auto &CacheStream = *(CachedFileStreamOrErr->get());2595        *(CacheStream.OS) << ObjFileMbRef.getBuffer();2596        if (Error Err = CacheStream.commit())2597          return Err;2598      } else {2599        auto StreamOrErr = AddStream(Job.Task, Job.ModuleID);2600        if (Error Err = StreamOrErr.takeError())2601          report_fatal_error(std::move(Err));2602        auto &Stream = *StreamOrErr->get();2603        *Stream.OS << ObjFileMbRef.getBuffer();2604        if (Error Err = Stream.commit())2605          report_fatal_error(std::move(Err));2606      }2607    }2608    return Error::success();2609  }2610};2611} // end anonymous namespace2612 2613ThinBackend lto::createOutOfProcessThinBackend(2614    ThreadPoolStrategy Parallelism, lto::IndexWriteCallback OnWrite,2615    bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles,2616    StringRef LinkerOutputFile, StringRef Distributor,2617    ArrayRef<StringRef> DistributorArgs, StringRef RemoteCompiler,2618    ArrayRef<StringRef> RemoteCompilerPrependArgs,2619    ArrayRef<StringRef> RemoteCompilerArgs, bool SaveTemps) {2620  auto Func =2621      [=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,2622          const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,2623          AddStreamFn AddStream, FileCache Cache) {2624        return std::make_unique<OutOfProcessThinBackend>(2625            Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,2626            AddStream, Cache, OnWrite, ShouldEmitIndexFiles,2627            ShouldEmitImportsFiles, LinkerOutputFile, Distributor,2628            DistributorArgs, RemoteCompiler, RemoteCompilerPrependArgs,2629            RemoteCompilerArgs, SaveTemps);2630      };2631  return ThinBackend(Func, Parallelism);2632}2633