Path: blob/main/contrib/llvm-project/llvm/lib/LTO/LTO.cpp
35234 views
//===-LTO.cpp - LLVM Link Time Optimizer ----------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements functions and classes used to support LTO.9//10//===----------------------------------------------------------------------===//1112#include "llvm/LTO/LTO.h"13#include "llvm/ADT/ScopeExit.h"14#include "llvm/ADT/SmallSet.h"15#include "llvm/ADT/Statistic.h"16#include "llvm/ADT/StringExtras.h"17#include "llvm/Analysis/OptimizationRemarkEmitter.h"18#include "llvm/Analysis/StackSafetyAnalysis.h"19#include "llvm/Analysis/TargetLibraryInfo.h"20#include "llvm/Analysis/TargetTransformInfo.h"21#include "llvm/Bitcode/BitcodeReader.h"22#include "llvm/Bitcode/BitcodeWriter.h"23#include "llvm/CodeGen/Analysis.h"24#include "llvm/Config/llvm-config.h"25#include "llvm/IR/AutoUpgrade.h"26#include "llvm/IR/DiagnosticPrinter.h"27#include "llvm/IR/Intrinsics.h"28#include "llvm/IR/LLVMRemarkStreamer.h"29#include "llvm/IR/LegacyPassManager.h"30#include "llvm/IR/Mangler.h"31#include "llvm/IR/Metadata.h"32#include "llvm/IR/RuntimeLibcalls.h"33#include "llvm/LTO/LTOBackend.h"34#include "llvm/LTO/SummaryBasedOptimizations.h"35#include "llvm/Linker/IRMover.h"36#include "llvm/MC/TargetRegistry.h"37#include "llvm/Object/IRObjectFile.h"38#include "llvm/Support/CommandLine.h"39#include "llvm/Support/Error.h"40#include "llvm/Support/FileSystem.h"41#include "llvm/Support/ManagedStatic.h"42#include "llvm/Support/MemoryBuffer.h"43#include "llvm/Support/Path.h"44#include "llvm/Support/SHA1.h"45#include "llvm/Support/SourceMgr.h"46#include "llvm/Support/ThreadPool.h"47#include "llvm/Support/Threading.h"48#include "llvm/Support/TimeProfiler.h"49#include "llvm/Support/ToolOutputFile.h"50#include "llvm/Support/VCSRevision.h"51#include "llvm/Support/raw_ostream.h"52#include "llvm/Target/TargetOptions.h"53#include "llvm/Transforms/IPO.h"54#include "llvm/Transforms/IPO/MemProfContextDisambiguation.h"55#include "llvm/Transforms/IPO/WholeProgramDevirt.h"56#include "llvm/Transforms/Utils/FunctionImportUtils.h"57#include "llvm/Transforms/Utils/SplitModule.h"5859#include <optional>60#include <set>6162using namespace llvm;63using namespace lto;64using namespace object;6566#define DEBUG_TYPE "lto"6768extern cl::opt<bool> UseNewDbgInfoFormat;6970static cl::opt<bool>71DumpThinCGSCCs("dump-thin-cg-sccs", cl::init(false), cl::Hidden,72cl::desc("Dump the SCCs in the ThinLTO index's callgraph"));7374namespace llvm {75/// Enable global value internalization in LTO.76cl::opt<bool> EnableLTOInternalization(77"enable-lto-internalization", cl::init(true), cl::Hidden,78cl::desc("Enable global value internalization in LTO"));7980/// Indicate we are linking with an allocator that supports hot/cold operator81/// new interfaces.82extern cl::opt<bool> SupportsHotColdNew;8384/// Enable MemProf context disambiguation for thin link.85extern cl::opt<bool> EnableMemProfContextDisambiguation;86} // namespace llvm8788// Computes a unique hash for the Module considering the current list of89// export/import and other global analysis results.90// The hash is produced in \p Key.91void llvm::computeLTOCacheKey(92SmallString<40> &Key, const Config &Conf, const ModuleSummaryIndex &Index,93StringRef ModuleID, const FunctionImporter::ImportMapTy &ImportList,94const FunctionImporter::ExportSetTy &ExportList,95const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,96const GVSummaryMapTy &DefinedGlobals,97const std::set<GlobalValue::GUID> &CfiFunctionDefs,98const std::set<GlobalValue::GUID> &CfiFunctionDecls) {99// Compute the unique hash for this entry.100// This is based on the current compiler version, the module itself, the101// export list, the hash for every single module in the import list, the102// list of ResolvedODR for the module, and the list of preserved symbols.103SHA1 Hasher;104105// Start with the compiler revision106Hasher.update(LLVM_VERSION_STRING);107#ifdef LLVM_REVISION108Hasher.update(LLVM_REVISION);109#endif110111// Include the parts of the LTO configuration that affect code generation.112auto AddString = [&](StringRef Str) {113Hasher.update(Str);114Hasher.update(ArrayRef<uint8_t>{0});115};116auto AddUnsigned = [&](unsigned I) {117uint8_t Data[4];118support::endian::write32le(Data, I);119Hasher.update(Data);120};121auto AddUint64 = [&](uint64_t I) {122uint8_t Data[8];123support::endian::write64le(Data, I);124Hasher.update(Data);125};126auto AddUint8 = [&](const uint8_t I) {127Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&I, 1));128};129AddString(Conf.CPU);130// FIXME: Hash more of Options. For now all clients initialize Options from131// command-line flags (which is unsupported in production), but may set132// X86RelaxRelocations. The clang driver can also pass FunctionSections,133// DataSections and DebuggerTuning via command line flags.134AddUnsigned(Conf.Options.MCOptions.X86RelaxRelocations);135AddUnsigned(Conf.Options.FunctionSections);136AddUnsigned(Conf.Options.DataSections);137AddUnsigned((unsigned)Conf.Options.DebuggerTuning);138for (auto &A : Conf.MAttrs)139AddString(A);140if (Conf.RelocModel)141AddUnsigned(*Conf.RelocModel);142else143AddUnsigned(-1);144if (Conf.CodeModel)145AddUnsigned(*Conf.CodeModel);146else147AddUnsigned(-1);148for (const auto &S : Conf.MllvmArgs)149AddString(S);150AddUnsigned(static_cast<int>(Conf.CGOptLevel));151AddUnsigned(static_cast<int>(Conf.CGFileType));152AddUnsigned(Conf.OptLevel);153AddUnsigned(Conf.Freestanding);154AddString(Conf.OptPipeline);155AddString(Conf.AAPipeline);156AddString(Conf.OverrideTriple);157AddString(Conf.DefaultTriple);158AddString(Conf.DwoDir);159160// Include the hash for the current module161auto ModHash = Index.getModuleHash(ModuleID);162Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));163164// TODO: `ExportList` is determined by `ImportList`. Since `ImportList` is165// used to compute cache key, we could omit hashing `ExportList` here.166std::vector<uint64_t> ExportsGUID;167ExportsGUID.reserve(ExportList.size());168for (const auto &VI : ExportList)169ExportsGUID.push_back(VI.getGUID());170171// Sort the export list elements GUIDs.172llvm::sort(ExportsGUID);173for (auto GUID : ExportsGUID)174Hasher.update(ArrayRef<uint8_t>((uint8_t *)&GUID, sizeof(GUID)));175176// Include the hash for every module we import functions from. The set of177// imported symbols for each module may affect code generation and is178// sensitive to link order, so include that as well.179using ImportMapIteratorTy = FunctionImporter::ImportMapTy::const_iterator;180struct ImportModule {181ImportMapIteratorTy ModIt;182const ModuleSummaryIndex::ModuleInfo *ModInfo;183184StringRef getIdentifier() const { return ModIt->getFirst(); }185const FunctionImporter::FunctionsToImportTy &getFunctions() const {186return ModIt->second;187}188189const ModuleHash &getHash() const { return ModInfo->second; }190};191192std::vector<ImportModule> ImportModulesVector;193ImportModulesVector.reserve(ImportList.size());194195for (ImportMapIteratorTy It = ImportList.begin(); It != ImportList.end();196++It) {197ImportModulesVector.push_back({It, Index.getModule(It->getFirst())});198}199// Order using module hash, to be both independent of module name and200// module order.201llvm::sort(ImportModulesVector,202[](const ImportModule &Lhs, const ImportModule &Rhs) -> bool {203return Lhs.getHash() < Rhs.getHash();204});205std::vector<std::pair<uint64_t, uint8_t>> ImportedGUIDs;206for (const ImportModule &Entry : ImportModulesVector) {207auto ModHash = Entry.getHash();208Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));209210AddUint64(Entry.getFunctions().size());211212ImportedGUIDs.clear();213for (auto &[Fn, ImportType] : Entry.getFunctions())214ImportedGUIDs.push_back(std::make_pair(Fn, ImportType));215llvm::sort(ImportedGUIDs);216for (auto &[GUID, Type] : ImportedGUIDs) {217AddUint64(GUID);218AddUint8(Type);219}220}221222// Include the hash for the resolved ODR.223for (auto &Entry : ResolvedODR) {224Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&Entry.first,225sizeof(GlobalValue::GUID)));226Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&Entry.second,227sizeof(GlobalValue::LinkageTypes)));228}229230// Members of CfiFunctionDefs and CfiFunctionDecls that are referenced or231// defined in this module.232std::set<GlobalValue::GUID> UsedCfiDefs;233std::set<GlobalValue::GUID> UsedCfiDecls;234235// Typeids used in this module.236std::set<GlobalValue::GUID> UsedTypeIds;237238auto AddUsedCfiGlobal = [&](GlobalValue::GUID ValueGUID) {239if (CfiFunctionDefs.count(ValueGUID))240UsedCfiDefs.insert(ValueGUID);241if (CfiFunctionDecls.count(ValueGUID))242UsedCfiDecls.insert(ValueGUID);243};244245auto AddUsedThings = [&](GlobalValueSummary *GS) {246if (!GS) return;247AddUnsigned(GS->getVisibility());248AddUnsigned(GS->isLive());249AddUnsigned(GS->canAutoHide());250for (const ValueInfo &VI : GS->refs()) {251AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));252AddUsedCfiGlobal(VI.getGUID());253}254if (auto *GVS = dyn_cast<GlobalVarSummary>(GS)) {255AddUnsigned(GVS->maybeReadOnly());256AddUnsigned(GVS->maybeWriteOnly());257}258if (auto *FS = dyn_cast<FunctionSummary>(GS)) {259for (auto &TT : FS->type_tests())260UsedTypeIds.insert(TT);261for (auto &TT : FS->type_test_assume_vcalls())262UsedTypeIds.insert(TT.GUID);263for (auto &TT : FS->type_checked_load_vcalls())264UsedTypeIds.insert(TT.GUID);265for (auto &TT : FS->type_test_assume_const_vcalls())266UsedTypeIds.insert(TT.VFunc.GUID);267for (auto &TT : FS->type_checked_load_const_vcalls())268UsedTypeIds.insert(TT.VFunc.GUID);269for (auto &ET : FS->calls()) {270AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));271AddUsedCfiGlobal(ET.first.getGUID());272}273}274};275276// Include the hash for the linkage type to reflect internalization and weak277// resolution, and collect any used type identifier resolutions.278for (auto &GS : DefinedGlobals) {279GlobalValue::LinkageTypes Linkage = GS.second->linkage();280Hasher.update(281ArrayRef<uint8_t>((const uint8_t *)&Linkage, sizeof(Linkage)));282AddUsedCfiGlobal(GS.first);283AddUsedThings(GS.second);284}285286// Imported functions may introduce new uses of type identifier resolutions,287// so we need to collect their used resolutions as well.288for (const ImportModule &ImpM : ImportModulesVector)289for (auto &[GUID, UnusedImportType] : ImpM.getFunctions()) {290GlobalValueSummary *S =291Index.findSummaryInModule(GUID, ImpM.getIdentifier());292AddUsedThings(S);293// If this is an alias, we also care about any types/etc. that the aliasee294// may reference.295if (auto *AS = dyn_cast_or_null<AliasSummary>(S))296AddUsedThings(AS->getBaseObject());297}298299auto AddTypeIdSummary = [&](StringRef TId, const TypeIdSummary &S) {300AddString(TId);301302AddUnsigned(S.TTRes.TheKind);303AddUnsigned(S.TTRes.SizeM1BitWidth);304305AddUint64(S.TTRes.AlignLog2);306AddUint64(S.TTRes.SizeM1);307AddUint64(S.TTRes.BitMask);308AddUint64(S.TTRes.InlineBits);309310AddUint64(S.WPDRes.size());311for (auto &WPD : S.WPDRes) {312AddUnsigned(WPD.first);313AddUnsigned(WPD.second.TheKind);314AddString(WPD.second.SingleImplName);315316AddUint64(WPD.second.ResByArg.size());317for (auto &ByArg : WPD.second.ResByArg) {318AddUint64(ByArg.first.size());319for (uint64_t Arg : ByArg.first)320AddUint64(Arg);321AddUnsigned(ByArg.second.TheKind);322AddUint64(ByArg.second.Info);323AddUnsigned(ByArg.second.Byte);324AddUnsigned(ByArg.second.Bit);325}326}327};328329// Include the hash for all type identifiers used by this module.330for (GlobalValue::GUID TId : UsedTypeIds) {331auto TidIter = Index.typeIds().equal_range(TId);332for (auto It = TidIter.first; It != TidIter.second; ++It)333AddTypeIdSummary(It->second.first, It->second.second);334}335336AddUnsigned(UsedCfiDefs.size());337for (auto &V : UsedCfiDefs)338AddUint64(V);339340AddUnsigned(UsedCfiDecls.size());341for (auto &V : UsedCfiDecls)342AddUint64(V);343344if (!Conf.SampleProfile.empty()) {345auto FileOrErr = MemoryBuffer::getFile(Conf.SampleProfile);346if (FileOrErr) {347Hasher.update(FileOrErr.get()->getBuffer());348349if (!Conf.ProfileRemapping.empty()) {350FileOrErr = MemoryBuffer::getFile(Conf.ProfileRemapping);351if (FileOrErr)352Hasher.update(FileOrErr.get()->getBuffer());353}354}355}356357Key = toHex(Hasher.result());358}359360static void thinLTOResolvePrevailingGUID(361const Config &C, ValueInfo VI,362DenseSet<GlobalValueSummary *> &GlobalInvolvedWithAlias,363function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>364isPrevailing,365function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)>366recordNewLinkage,367const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {368GlobalValue::VisibilityTypes Visibility =369C.VisibilityScheme == Config::ELF ? VI.getELFVisibility()370: GlobalValue::DefaultVisibility;371for (auto &S : VI.getSummaryList()) {372GlobalValue::LinkageTypes OriginalLinkage = S->linkage();373// Ignore local and appending linkage values since the linker374// doesn't resolve them.375if (GlobalValue::isLocalLinkage(OriginalLinkage) ||376GlobalValue::isAppendingLinkage(S->linkage()))377continue;378// We need to emit only one of these. The prevailing module will keep it,379// but turned into a weak, while the others will drop it when possible.380// This is both a compile-time optimization and a correctness381// transformation. This is necessary for correctness when we have exported382// a reference - we need to convert the linkonce to weak to383// ensure a copy is kept to satisfy the exported reference.384// FIXME: We may want to split the compile time and correctness385// aspects into separate routines.386if (isPrevailing(VI.getGUID(), S.get())) {387if (GlobalValue::isLinkOnceLinkage(OriginalLinkage)) {388S->setLinkage(GlobalValue::getWeakLinkage(389GlobalValue::isLinkOnceODRLinkage(OriginalLinkage)));390// The kept copy is eligible for auto-hiding (hidden visibility) if all391// copies were (i.e. they were all linkonce_odr global unnamed addr).392// If any copy is not (e.g. it was originally weak_odr), then the symbol393// must remain externally available (e.g. a weak_odr from an explicitly394// instantiated template). Additionally, if it is in the395// GUIDPreservedSymbols set, that means that it is visibile outside396// the summary (e.g. in a native object or a bitcode file without397// summary), and in that case we cannot hide it as it isn't possible to398// check all copies.399S->setCanAutoHide(VI.canAutoHide() &&400!GUIDPreservedSymbols.count(VI.getGUID()));401}402if (C.VisibilityScheme == Config::FromPrevailing)403Visibility = S->getVisibility();404}405// Alias and aliasee can't be turned into available_externally.406else if (!isa<AliasSummary>(S.get()) &&407!GlobalInvolvedWithAlias.count(S.get()))408S->setLinkage(GlobalValue::AvailableExternallyLinkage);409410// For ELF, set visibility to the computed visibility from summaries. We411// don't track visibility from declarations so this may be more relaxed than412// the most constraining one.413if (C.VisibilityScheme == Config::ELF)414S->setVisibility(Visibility);415416if (S->linkage() != OriginalLinkage)417recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());418}419420if (C.VisibilityScheme == Config::FromPrevailing) {421for (auto &S : VI.getSummaryList()) {422GlobalValue::LinkageTypes OriginalLinkage = S->linkage();423if (GlobalValue::isLocalLinkage(OriginalLinkage) ||424GlobalValue::isAppendingLinkage(S->linkage()))425continue;426S->setVisibility(Visibility);427}428}429}430431/// Resolve linkage for prevailing symbols in the \p Index.432//433// We'd like to drop these functions if they are no longer referenced in the434// current module. However there is a chance that another module is still435// referencing them because of the import. We make sure we always emit at least436// one copy.437void llvm::thinLTOResolvePrevailingInIndex(438const Config &C, ModuleSummaryIndex &Index,439function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>440isPrevailing,441function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)>442recordNewLinkage,443const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {444// We won't optimize the globals that are referenced by an alias for now445// Ideally we should turn the alias into a global and duplicate the definition446// when needed.447DenseSet<GlobalValueSummary *> GlobalInvolvedWithAlias;448for (auto &I : Index)449for (auto &S : I.second.SummaryList)450if (auto AS = dyn_cast<AliasSummary>(S.get()))451GlobalInvolvedWithAlias.insert(&AS->getAliasee());452453for (auto &I : Index)454thinLTOResolvePrevailingGUID(C, Index.getValueInfo(I),455GlobalInvolvedWithAlias, isPrevailing,456recordNewLinkage, GUIDPreservedSymbols);457}458459static void thinLTOInternalizeAndPromoteGUID(460ValueInfo VI, function_ref<bool(StringRef, ValueInfo)> isExported,461function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>462isPrevailing) {463auto ExternallyVisibleCopies =464llvm::count_if(VI.getSummaryList(),465[](const std::unique_ptr<GlobalValueSummary> &Summary) {466return !GlobalValue::isLocalLinkage(Summary->linkage());467});468469for (auto &S : VI.getSummaryList()) {470// First see if we need to promote an internal value because it is not471// exported.472if (isExported(S->modulePath(), VI)) {473if (GlobalValue::isLocalLinkage(S->linkage()))474S->setLinkage(GlobalValue::ExternalLinkage);475continue;476}477478// Otherwise, see if we can internalize.479if (!EnableLTOInternalization)480continue;481482// Non-exported values with external linkage can be internalized.483if (GlobalValue::isExternalLinkage(S->linkage())) {484S->setLinkage(GlobalValue::InternalLinkage);485continue;486}487488// Non-exported function and variable definitions with a weak-for-linker489// linkage can be internalized in certain cases. The minimum legality490// requirements would be that they are not address taken to ensure that we491// don't break pointer equality checks, and that variables are either read-492// or write-only. For functions, this is the case if either all copies are493// [local_]unnamed_addr, or we can propagate reference edge attributes494// (which is how this is guaranteed for variables, when analyzing whether495// they are read or write-only).496//497// However, we only get to this code for weak-for-linkage values in one of498// two cases:499// 1) The prevailing copy is not in IR (it is in native code).500// 2) The prevailing copy in IR is not exported from its module.501// Additionally, at least for the new LTO API, case 2 will only happen if502// there is exactly one definition of the value (i.e. in exactly one503// module), as duplicate defs are result in the value being marked exported.504// Likely, users of the legacy LTO API are similar, however, currently there505// are llvm-lto based tests of the legacy LTO API that do not mark506// duplicate linkonce_odr copies as exported via the tool, so we need507// to handle that case below by checking the number of copies.508//509// Generally, we only want to internalize a weak-for-linker value in case510// 2, because in case 1 we cannot see how the value is used to know if it511// is read or write-only. We also don't want to bloat the binary with512// multiple internalized copies of non-prevailing linkonce/weak functions.513// Note if we don't internalize, we will convert non-prevailing copies to514// available_externally anyway, so that we drop them after inlining. The515// only reason to internalize such a function is if we indeed have a single516// copy, because internalizing it won't increase binary size, and enables517// use of inliner heuristics that are more aggressive in the face of a518// single call to a static (local). For variables, internalizing a read or519// write only variable can enable more aggressive optimization. However, we520// already perform this elsewhere in the ThinLTO backend handling for521// read or write-only variables (processGlobalForThinLTO).522//523// Therefore, only internalize linkonce/weak if there is a single copy, that524// is prevailing in this IR module. We can do so aggressively, without525// requiring the address to be insignificant, or that a variable be read or526// write-only.527if (!GlobalValue::isWeakForLinker(S->linkage()) ||528GlobalValue::isExternalWeakLinkage(S->linkage()))529continue;530531if (isPrevailing(VI.getGUID(), S.get()) && ExternallyVisibleCopies == 1)532S->setLinkage(GlobalValue::InternalLinkage);533}534}535536// Update the linkages in the given \p Index to mark exported values537// as external and non-exported values as internal.538void llvm::thinLTOInternalizeAndPromoteInIndex(539ModuleSummaryIndex &Index,540function_ref<bool(StringRef, ValueInfo)> isExported,541function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>542isPrevailing) {543for (auto &I : Index)544thinLTOInternalizeAndPromoteGUID(Index.getValueInfo(I), isExported,545isPrevailing);546}547548// Requires a destructor for std::vector<InputModule>.549InputFile::~InputFile() = default;550551Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) {552std::unique_ptr<InputFile> File(new InputFile);553554Expected<IRSymtabFile> FOrErr = readIRSymtab(Object);555if (!FOrErr)556return FOrErr.takeError();557558File->TargetTriple = FOrErr->TheReader.getTargetTriple();559File->SourceFileName = FOrErr->TheReader.getSourceFileName();560File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();561File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();562File->ComdatTable = FOrErr->TheReader.getComdatTable();563564for (unsigned I = 0; I != FOrErr->Mods.size(); ++I) {565size_t Begin = File->Symbols.size();566for (const irsymtab::Reader::SymbolRef &Sym :567FOrErr->TheReader.module_symbols(I))568// Skip symbols that are irrelevant to LTO. Note that this condition needs569// to match the one in Skip() in LTO::addRegularLTO().570if (Sym.isGlobal() && !Sym.isFormatSpecific())571File->Symbols.push_back(Sym);572File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});573}574575File->Mods = FOrErr->Mods;576File->Strtab = std::move(FOrErr->Strtab);577return std::move(File);578}579580StringRef InputFile::getName() const {581return Mods[0].getModuleIdentifier();582}583584BitcodeModule &InputFile::getSingleBitcodeModule() {585assert(Mods.size() == 1 && "Expect only one bitcode module");586return Mods[0];587}588589LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,590const Config &Conf)591: ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),592Ctx(Conf), CombinedModule(std::make_unique<Module>("ld-temp.o", Ctx)),593Mover(std::make_unique<IRMover>(*CombinedModule)) {594CombinedModule->IsNewDbgInfoFormat = UseNewDbgInfoFormat;595}596597LTO::ThinLTOState::ThinLTOState(ThinBackend Backend)598: Backend(Backend), CombinedIndex(/*HaveGVs*/ false) {599if (!Backend)600this->Backend =601createInProcessThinBackend(llvm::heavyweight_hardware_concurrency());602}603604LTO::LTO(Config Conf, ThinBackend Backend,605unsigned ParallelCodeGenParallelismLevel, LTOKind LTOMode)606: Conf(std::move(Conf)),607RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),608ThinLTO(std::move(Backend)),609GlobalResolutions(std::make_optional<StringMap<GlobalResolution>>()),610LTOMode(LTOMode) {}611612// Requires a destructor for MapVector<BitcodeModule>.613LTO::~LTO() = default;614615// Add the symbols in the given module to the GlobalResolutions map, and resolve616// their partitions.617void LTO::addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms,618ArrayRef<SymbolResolution> Res,619unsigned Partition, bool InSummary) {620auto *ResI = Res.begin();621auto *ResE = Res.end();622(void)ResE;623const Triple TT(RegularLTO.CombinedModule->getTargetTriple());624for (const InputFile::Symbol &Sym : Syms) {625assert(ResI != ResE);626SymbolResolution Res = *ResI++;627628auto &GlobalRes = (*GlobalResolutions)[Sym.getName()];629GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr();630if (Res.Prevailing) {631assert(!GlobalRes.Prevailing &&632"Multiple prevailing defs are not allowed");633GlobalRes.Prevailing = true;634GlobalRes.IRName = std::string(Sym.getIRName());635} else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {636// Sometimes it can be two copies of symbol in a module and prevailing637// symbol can have no IR name. That might happen if symbol is defined in638// module level inline asm block. In case we have multiple modules with639// the same symbol we want to use IR name of the prevailing symbol.640// Otherwise, if we haven't seen a prevailing symbol, set the name so that641// we can later use it to check if there is any prevailing copy in IR.642GlobalRes.IRName = std::string(Sym.getIRName());643}644645// In rare occasion, the symbol used to initialize GlobalRes has a different646// IRName from the inspected Symbol. This can happen on macOS + iOS, when a647// symbol is referenced through its mangled name, say @"\01_symbol" while648// the IRName is @symbol (the prefix underscore comes from MachO mangling).649// In that case, we have the same actual Symbol that can get two different650// GUID, leading to some invalid internalization. Workaround this by marking651// the GlobalRes external.652653// FIXME: instead of this check, it would be desirable to compute GUIDs654// based on mangled name, but this requires an access to the Target Triple655// and would be relatively invasive on the codebase.656if (GlobalRes.IRName != Sym.getIRName()) {657GlobalRes.Partition = GlobalResolution::External;658GlobalRes.VisibleOutsideSummary = true;659}660661// Set the partition to external if we know it is re-defined by the linker662// with -defsym or -wrap options, used elsewhere, e.g. it is visible to a663// regular object, is referenced from llvm.compiler.used/llvm.used, or was664// already recorded as being referenced from a different partition.665if (Res.LinkerRedefined || Res.VisibleToRegularObj || Sym.isUsed() ||666(GlobalRes.Partition != GlobalResolution::Unknown &&667GlobalRes.Partition != Partition)) {668GlobalRes.Partition = GlobalResolution::External;669} else670// First recorded reference, save the current partition.671GlobalRes.Partition = Partition;672673// Flag as visible outside of summary if visible from a regular object or674// from a module that does not have a summary.675GlobalRes.VisibleOutsideSummary |=676(Res.VisibleToRegularObj || Sym.isUsed() || !InSummary);677678GlobalRes.ExportDynamic |= Res.ExportDynamic;679}680}681682static void writeToResolutionFile(raw_ostream &OS, InputFile *Input,683ArrayRef<SymbolResolution> Res) {684StringRef Path = Input->getName();685OS << Path << '\n';686auto ResI = Res.begin();687for (const InputFile::Symbol &Sym : Input->symbols()) {688assert(ResI != Res.end());689SymbolResolution Res = *ResI++;690691OS << "-r=" << Path << ',' << Sym.getName() << ',';692if (Res.Prevailing)693OS << 'p';694if (Res.FinalDefinitionInLinkageUnit)695OS << 'l';696if (Res.VisibleToRegularObj)697OS << 'x';698if (Res.LinkerRedefined)699OS << 'r';700OS << '\n';701}702OS.flush();703assert(ResI == Res.end());704}705706Error LTO::add(std::unique_ptr<InputFile> Input,707ArrayRef<SymbolResolution> Res) {708assert(!CalledGetMaxTasks);709710if (Conf.ResolutionFile)711writeToResolutionFile(*Conf.ResolutionFile, Input.get(), Res);712713if (RegularLTO.CombinedModule->getTargetTriple().empty()) {714RegularLTO.CombinedModule->setTargetTriple(Input->getTargetTriple());715if (Triple(Input->getTargetTriple()).isOSBinFormatELF())716Conf.VisibilityScheme = Config::ELF;717}718719const SymbolResolution *ResI = Res.begin();720for (unsigned I = 0; I != Input->Mods.size(); ++I)721if (Error Err = addModule(*Input, I, ResI, Res.end()))722return Err;723724assert(ResI == Res.end());725return Error::success();726}727728Error LTO::addModule(InputFile &Input, unsigned ModI,729const SymbolResolution *&ResI,730const SymbolResolution *ResE) {731Expected<BitcodeLTOInfo> LTOInfo = Input.Mods[ModI].getLTOInfo();732if (!LTOInfo)733return LTOInfo.takeError();734735if (EnableSplitLTOUnit) {736// If only some modules were split, flag this in the index so that737// we can skip or error on optimizations that need consistently split738// modules (whole program devirt and lower type tests).739if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)740ThinLTO.CombinedIndex.setPartiallySplitLTOUnits();741} else742EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;743744BitcodeModule BM = Input.Mods[ModI];745746if ((LTOMode == LTOK_UnifiedRegular || LTOMode == LTOK_UnifiedThin) &&747!LTOInfo->UnifiedLTO)748return make_error<StringError>(749"unified LTO compilation must use "750"compatible bitcode modules (use -funified-lto)",751inconvertibleErrorCode());752753if (LTOInfo->UnifiedLTO && LTOMode == LTOK_Default)754LTOMode = LTOK_UnifiedThin;755756bool IsThinLTO = LTOInfo->IsThinLTO && (LTOMode != LTOK_UnifiedRegular);757758auto ModSyms = Input.module_symbols(ModI);759addModuleToGlobalRes(ModSyms, {ResI, ResE},760IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,761LTOInfo->HasSummary);762763if (IsThinLTO)764return addThinLTO(BM, ModSyms, ResI, ResE);765766RegularLTO.EmptyCombinedModule = false;767Expected<RegularLTOState::AddedModule> ModOrErr =768addRegularLTO(BM, ModSyms, ResI, ResE);769if (!ModOrErr)770return ModOrErr.takeError();771772if (!LTOInfo->HasSummary)773return linkRegularLTO(std::move(*ModOrErr), /*LivenessFromIndex=*/false);774775// Regular LTO module summaries are added to a dummy module that represents776// the combined regular LTO module.777if (Error Err = BM.readSummary(ThinLTO.CombinedIndex, ""))778return Err;779RegularLTO.ModsWithSummaries.push_back(std::move(*ModOrErr));780return Error::success();781}782783// Checks whether the given global value is in a non-prevailing comdat784// (comdat containing values the linker indicated were not prevailing,785// which we then dropped to available_externally), and if so, removes786// it from the comdat. This is called for all global values to ensure the787// comdat is empty rather than leaving an incomplete comdat. It is needed for788// regular LTO modules, in case we are in a mixed-LTO mode (both regular789// and thin LTO modules) compilation. Since the regular LTO module will be790// linked first in the final native link, we want to make sure the linker791// doesn't select any of these incomplete comdats that would be left792// in the regular LTO module without this cleanup.793static void794handleNonPrevailingComdat(GlobalValue &GV,795std::set<const Comdat *> &NonPrevailingComdats) {796Comdat *C = GV.getComdat();797if (!C)798return;799800if (!NonPrevailingComdats.count(C))801return;802803// Additionally need to drop all global values from the comdat to804// available_externally, to satisfy the COMDAT requirement that all members805// are discarded as a unit. The non-local linkage global values avoid806// duplicate definition linker errors.807GV.setLinkage(GlobalValue::AvailableExternallyLinkage);808809if (auto GO = dyn_cast<GlobalObject>(&GV))810GO->setComdat(nullptr);811}812813// Add a regular LTO object to the link.814// The resulting module needs to be linked into the combined LTO module with815// linkRegularLTO.816Expected<LTO::RegularLTOState::AddedModule>817LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,818const SymbolResolution *&ResI,819const SymbolResolution *ResE) {820RegularLTOState::AddedModule Mod;821Expected<std::unique_ptr<Module>> MOrErr =822BM.getLazyModule(RegularLTO.Ctx, /*ShouldLazyLoadMetadata*/ true,823/*IsImporting*/ false);824if (!MOrErr)825return MOrErr.takeError();826Module &M = **MOrErr;827Mod.M = std::move(*MOrErr);828829if (Error Err = M.materializeMetadata())830return std::move(Err);831832// If cfi.functions is present and we are in regular LTO mode, LowerTypeTests833// will rename local functions in the merged module as "<function name>.1".834// This causes linking errors, since other parts of the module expect the835// original function name.836if (LTOMode == LTOK_UnifiedRegular)837if (NamedMDNode *CfiFunctionsMD = M.getNamedMetadata("cfi.functions"))838M.eraseNamedMetadata(CfiFunctionsMD);839840UpgradeDebugInfo(M);841842ModuleSymbolTable SymTab;843SymTab.addModule(&M);844845for (GlobalVariable &GV : M.globals())846if (GV.hasAppendingLinkage())847Mod.Keep.push_back(&GV);848849DenseSet<GlobalObject *> AliasedGlobals;850for (auto &GA : M.aliases())851if (GlobalObject *GO = GA.getAliaseeObject())852AliasedGlobals.insert(GO);853854// In this function we need IR GlobalValues matching the symbols in Syms855// (which is not backed by a module), so we need to enumerate them in the same856// order. The symbol enumeration order of a ModuleSymbolTable intentionally857// matches the order of an irsymtab, but when we read the irsymtab in858// InputFile::create we omit some symbols that are irrelevant to LTO. The859// Skip() function skips the same symbols from the module as InputFile does860// from the symbol table.861auto MsymI = SymTab.symbols().begin(), MsymE = SymTab.symbols().end();862auto Skip = [&]() {863while (MsymI != MsymE) {864auto Flags = SymTab.getSymbolFlags(*MsymI);865if ((Flags & object::BasicSymbolRef::SF_Global) &&866!(Flags & object::BasicSymbolRef::SF_FormatSpecific))867return;868++MsymI;869}870};871Skip();872873std::set<const Comdat *> NonPrevailingComdats;874SmallSet<StringRef, 2> NonPrevailingAsmSymbols;875for (const InputFile::Symbol &Sym : Syms) {876assert(ResI != ResE);877SymbolResolution Res = *ResI++;878879assert(MsymI != MsymE);880ModuleSymbolTable::Symbol Msym = *MsymI++;881Skip();882883if (GlobalValue *GV = dyn_cast_if_present<GlobalValue *>(Msym)) {884if (Res.Prevailing) {885if (Sym.isUndefined())886continue;887Mod.Keep.push_back(GV);888// For symbols re-defined with linker -wrap and -defsym options,889// set the linkage to weak to inhibit IPO. The linkage will be890// restored by the linker.891if (Res.LinkerRedefined)892GV->setLinkage(GlobalValue::WeakAnyLinkage);893894GlobalValue::LinkageTypes OriginalLinkage = GV->getLinkage();895if (GlobalValue::isLinkOnceLinkage(OriginalLinkage))896GV->setLinkage(GlobalValue::getWeakLinkage(897GlobalValue::isLinkOnceODRLinkage(OriginalLinkage)));898} else if (isa<GlobalObject>(GV) &&899(GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||900GV->hasAvailableExternallyLinkage()) &&901!AliasedGlobals.count(cast<GlobalObject>(GV))) {902// Any of the above three types of linkage indicates that the903// chosen prevailing symbol will have the same semantics as this copy of904// the symbol, so we may be able to link it with available_externally905// linkage. We will decide later whether to do that when we link this906// module (in linkRegularLTO), based on whether it is undefined.907Mod.Keep.push_back(GV);908GV->setLinkage(GlobalValue::AvailableExternallyLinkage);909if (GV->hasComdat())910NonPrevailingComdats.insert(GV->getComdat());911cast<GlobalObject>(GV)->setComdat(nullptr);912}913914// Set the 'local' flag based on the linker resolution for this symbol.915if (Res.FinalDefinitionInLinkageUnit) {916GV->setDSOLocal(true);917if (GV->hasDLLImportStorageClass())918GV->setDLLStorageClass(GlobalValue::DLLStorageClassTypes::919DefaultStorageClass);920}921} else if (auto *AS =922dyn_cast_if_present<ModuleSymbolTable::AsmSymbol *>(Msym)) {923// Collect non-prevailing symbols.924if (!Res.Prevailing)925NonPrevailingAsmSymbols.insert(AS->first);926} else {927llvm_unreachable("unknown symbol type");928}929930// Common resolution: collect the maximum size/alignment over all commons.931// We also record if we see an instance of a common as prevailing, so that932// if none is prevailing we can ignore it later.933if (Sym.isCommon()) {934// FIXME: We should figure out what to do about commons defined by asm.935// For now they aren't reported correctly by ModuleSymbolTable.936auto &CommonRes = RegularLTO.Commons[std::string(Sym.getIRName())];937CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());938if (uint32_t SymAlignValue = Sym.getCommonAlignment()) {939CommonRes.Alignment =940std::max(Align(SymAlignValue), CommonRes.Alignment);941}942CommonRes.Prevailing |= Res.Prevailing;943}944}945946if (!M.getComdatSymbolTable().empty())947for (GlobalValue &GV : M.global_values())948handleNonPrevailingComdat(GV, NonPrevailingComdats);949950// Prepend ".lto_discard <sym>, <sym>*" directive to each module inline asm951// block.952if (!M.getModuleInlineAsm().empty()) {953std::string NewIA = ".lto_discard";954if (!NonPrevailingAsmSymbols.empty()) {955// Don't dicard a symbol if there is a live .symver for it.956ModuleSymbolTable::CollectAsmSymvers(957M, [&](StringRef Name, StringRef Alias) {958if (!NonPrevailingAsmSymbols.count(Alias))959NonPrevailingAsmSymbols.erase(Name);960});961NewIA += " " + llvm::join(NonPrevailingAsmSymbols, ", ");962}963NewIA += "\n";964M.setModuleInlineAsm(NewIA + M.getModuleInlineAsm());965}966967assert(MsymI == MsymE);968return std::move(Mod);969}970971Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod,972bool LivenessFromIndex) {973std::vector<GlobalValue *> Keep;974for (GlobalValue *GV : Mod.Keep) {975if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID())) {976if (Function *F = dyn_cast<Function>(GV)) {977if (DiagnosticOutputFile) {978if (Error Err = F->materialize())979return Err;980OptimizationRemarkEmitter ORE(F, nullptr);981ORE.emit(OptimizationRemark(DEBUG_TYPE, "deadfunction", F)982<< ore::NV("Function", F)983<< " not added to the combined module ");984}985}986continue;987}988989if (!GV->hasAvailableExternallyLinkage()) {990Keep.push_back(GV);991continue;992}993994// Only link available_externally definitions if we don't already have a995// definition.996GlobalValue *CombinedGV =997RegularLTO.CombinedModule->getNamedValue(GV->getName());998if (CombinedGV && !CombinedGV->isDeclaration())999continue;10001001Keep.push_back(GV);1002}10031004return RegularLTO.Mover->move(std::move(Mod.M), Keep, nullptr,1005/* IsPerformingImport */ false);1006}10071008// Add a ThinLTO module to the link.1009Error LTO::addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,1010const SymbolResolution *&ResI,1011const SymbolResolution *ResE) {1012const SymbolResolution *ResITmp = ResI;1013for (const InputFile::Symbol &Sym : Syms) {1014assert(ResITmp != ResE);1015SymbolResolution Res = *ResITmp++;10161017if (!Sym.getIRName().empty()) {1018auto GUID = GlobalValue::getGUID(GlobalValue::getGlobalIdentifier(1019Sym.getIRName(), GlobalValue::ExternalLinkage, ""));1020if (Res.Prevailing)1021ThinLTO.PrevailingModuleForGUID[GUID] = BM.getModuleIdentifier();1022}1023}10241025if (Error Err =1026BM.readSummary(ThinLTO.CombinedIndex, BM.getModuleIdentifier(),1027[&](GlobalValue::GUID GUID) {1028return ThinLTO.PrevailingModuleForGUID[GUID] ==1029BM.getModuleIdentifier();1030}))1031return Err;1032LLVM_DEBUG(dbgs() << "Module " << BM.getModuleIdentifier() << "\n");10331034for (const InputFile::Symbol &Sym : Syms) {1035assert(ResI != ResE);1036SymbolResolution Res = *ResI++;10371038if (!Sym.getIRName().empty()) {1039auto GUID = GlobalValue::getGUID(GlobalValue::getGlobalIdentifier(1040Sym.getIRName(), GlobalValue::ExternalLinkage, ""));1041if (Res.Prevailing) {1042assert(ThinLTO.PrevailingModuleForGUID[GUID] ==1043BM.getModuleIdentifier());10441045// For linker redefined symbols (via --wrap or --defsym) we want to1046// switch the linkage to `weak` to prevent IPOs from happening.1047// Find the summary in the module for this very GV and record the new1048// linkage so that we can switch it when we import the GV.1049if (Res.LinkerRedefined)1050if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(1051GUID, BM.getModuleIdentifier()))1052S->setLinkage(GlobalValue::WeakAnyLinkage);1053}10541055// If the linker resolved the symbol to a local definition then mark it1056// as local in the summary for the module we are adding.1057if (Res.FinalDefinitionInLinkageUnit) {1058if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(1059GUID, BM.getModuleIdentifier())) {1060S->setDSOLocal(true);1061}1062}1063}1064}10651066if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)1067return make_error<StringError>(1068"Expected at most one ThinLTO module per bitcode file",1069inconvertibleErrorCode());10701071if (!Conf.ThinLTOModulesToCompile.empty()) {1072if (!ThinLTO.ModulesToCompile)1073ThinLTO.ModulesToCompile = ModuleMapType();1074// This is a fuzzy name matching where only modules with name containing the1075// specified switch values are going to be compiled.1076for (const std::string &Name : Conf.ThinLTOModulesToCompile) {1077if (BM.getModuleIdentifier().contains(Name)) {1078ThinLTO.ModulesToCompile->insert({BM.getModuleIdentifier(), BM});1079llvm::errs() << "[ThinLTO] Selecting " << BM.getModuleIdentifier()1080<< " to compile\n";1081}1082}1083}10841085return Error::success();1086}10871088unsigned LTO::getMaxTasks() const {1089CalledGetMaxTasks = true;1090auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()1091: ThinLTO.ModuleMap.size();1092return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;1093}10941095// If only some of the modules were split, we cannot correctly handle1096// code that contains type tests or type checked loads.1097Error LTO::checkPartiallySplit() {1098if (!ThinLTO.CombinedIndex.partiallySplitLTOUnits())1099return Error::success();11001101Function *TypeTestFunc = RegularLTO.CombinedModule->getFunction(1102Intrinsic::getName(Intrinsic::type_test));1103Function *TypeCheckedLoadFunc = RegularLTO.CombinedModule->getFunction(1104Intrinsic::getName(Intrinsic::type_checked_load));1105Function *TypeCheckedLoadRelativeFunc =1106RegularLTO.CombinedModule->getFunction(1107Intrinsic::getName(Intrinsic::type_checked_load_relative));11081109// First check if there are type tests / type checked loads in the1110// merged regular LTO module IR.1111if ((TypeTestFunc && !TypeTestFunc->use_empty()) ||1112(TypeCheckedLoadFunc && !TypeCheckedLoadFunc->use_empty()) ||1113(TypeCheckedLoadRelativeFunc &&1114!TypeCheckedLoadRelativeFunc->use_empty()))1115return make_error<StringError>(1116"inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",1117inconvertibleErrorCode());11181119// Otherwise check if there are any recorded in the combined summary from the1120// ThinLTO modules.1121for (auto &P : ThinLTO.CombinedIndex) {1122for (auto &S : P.second.SummaryList) {1123auto *FS = dyn_cast<FunctionSummary>(S.get());1124if (!FS)1125continue;1126if (!FS->type_test_assume_vcalls().empty() ||1127!FS->type_checked_load_vcalls().empty() ||1128!FS->type_test_assume_const_vcalls().empty() ||1129!FS->type_checked_load_const_vcalls().empty() ||1130!FS->type_tests().empty())1131return make_error<StringError>(1132"inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",1133inconvertibleErrorCode());1134}1135}1136return Error::success();1137}11381139Error LTO::run(AddStreamFn AddStream, FileCache Cache) {1140// Compute "dead" symbols, we don't want to import/export these!1141DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;1142DenseMap<GlobalValue::GUID, PrevailingType> GUIDPrevailingResolutions;1143for (auto &Res : *GlobalResolutions) {1144// Normally resolution have IR name of symbol. We can do nothing here1145// otherwise. See comments in GlobalResolution struct for more details.1146if (Res.second.IRName.empty())1147continue;11481149GlobalValue::GUID GUID = GlobalValue::getGUID(1150GlobalValue::dropLLVMManglingEscape(Res.second.IRName));11511152if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)1153GUIDPreservedSymbols.insert(GUID);11541155if (Res.second.ExportDynamic)1156DynamicExportSymbols.insert(GUID);11571158GUIDPrevailingResolutions[GUID] =1159Res.second.Prevailing ? PrevailingType::Yes : PrevailingType::No;1160}11611162auto isPrevailing = [&](GlobalValue::GUID G) {1163auto It = GUIDPrevailingResolutions.find(G);1164if (It == GUIDPrevailingResolutions.end())1165return PrevailingType::Unknown;1166return It->second;1167};1168computeDeadSymbolsWithConstProp(ThinLTO.CombinedIndex, GUIDPreservedSymbols,1169isPrevailing, Conf.OptLevel > 0);11701171// Setup output file to emit statistics.1172auto StatsFileOrErr = setupStatsFile(Conf.StatsFile);1173if (!StatsFileOrErr)1174return StatsFileOrErr.takeError();1175std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());11761177// TODO: Ideally this would be controlled automatically by detecting that we1178// are linking with an allocator that supports these interfaces, rather than1179// an internal option (which would still be needed for tests, however). For1180// example, if the library exported a symbol like __malloc_hot_cold the linker1181// could recognize that and set a flag in the lto::Config.1182if (SupportsHotColdNew)1183ThinLTO.CombinedIndex.setWithSupportsHotColdNew();11841185Error Result = runRegularLTO(AddStream);1186if (!Result)1187// This will reset the GlobalResolutions optional once done with it to1188// reduce peak memory before importing.1189Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);11901191if (StatsFile)1192PrintStatisticsJSON(StatsFile->os());11931194return Result;1195}11961197void lto::updateMemProfAttributes(Module &Mod,1198const ModuleSummaryIndex &Index) {1199if (Index.withSupportsHotColdNew())1200return;12011202// The profile matcher applies hotness attributes directly for allocations,1203// and those will cause us to generate calls to the hot/cold interfaces1204// unconditionally. If supports-hot-cold-new was not enabled in the LTO1205// link then assume we don't want these calls (e.g. not linking with1206// the appropriate library, or otherwise trying to disable this behavior).1207for (auto &F : Mod) {1208for (auto &BB : F) {1209for (auto &I : BB) {1210auto *CI = dyn_cast<CallBase>(&I);1211if (!CI)1212continue;1213if (CI->hasFnAttr("memprof"))1214CI->removeFnAttr("memprof");1215// Strip off all memprof metadata as it is no longer needed.1216// Importantly, this avoids the addition of new memprof attributes1217// after inlining propagation.1218// TODO: If we support additional types of MemProf metadata beyond hot1219// and cold, we will need to update the metadata based on the allocator1220// APIs supported instead of completely stripping all.1221CI->setMetadata(LLVMContext::MD_memprof, nullptr);1222CI->setMetadata(LLVMContext::MD_callsite, nullptr);1223}1224}1225}1226}12271228Error LTO::runRegularLTO(AddStreamFn AddStream) {1229// Setup optimization remarks.1230auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(1231RegularLTO.CombinedModule->getContext(), Conf.RemarksFilename,1232Conf.RemarksPasses, Conf.RemarksFormat, Conf.RemarksWithHotness,1233Conf.RemarksHotnessThreshold);1234LLVM_DEBUG(dbgs() << "Running regular LTO\n");1235if (!DiagFileOrErr)1236return DiagFileOrErr.takeError();1237DiagnosticOutputFile = std::move(*DiagFileOrErr);12381239// Finalize linking of regular LTO modules containing summaries now that1240// we have computed liveness information.1241for (auto &M : RegularLTO.ModsWithSummaries)1242if (Error Err = linkRegularLTO(std::move(M),1243/*LivenessFromIndex=*/true))1244return Err;12451246// Ensure we don't have inconsistently split LTO units with type tests.1247// FIXME: this checks both LTO and ThinLTO. It happens to work as we take1248// this path both cases but eventually this should be split into two and1249// do the ThinLTO checks in `runThinLTO`.1250if (Error Err = checkPartiallySplit())1251return Err;12521253// Make sure commons have the right size/alignment: we kept the largest from1254// all the prevailing when adding the inputs, and we apply it here.1255const DataLayout &DL = RegularLTO.CombinedModule->getDataLayout();1256for (auto &I : RegularLTO.Commons) {1257if (!I.second.Prevailing)1258// Don't do anything if no instance of this common was prevailing.1259continue;1260GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(I.first);1261if (OldGV && DL.getTypeAllocSize(OldGV->getValueType()) == I.second.Size) {1262// Don't create a new global if the type is already correct, just make1263// sure the alignment is correct.1264OldGV->setAlignment(I.second.Alignment);1265continue;1266}1267ArrayType *Ty =1268ArrayType::get(Type::getInt8Ty(RegularLTO.Ctx), I.second.Size);1269auto *GV = new GlobalVariable(*RegularLTO.CombinedModule, Ty, false,1270GlobalValue::CommonLinkage,1271ConstantAggregateZero::get(Ty), "");1272GV->setAlignment(I.second.Alignment);1273if (OldGV) {1274OldGV->replaceAllUsesWith(GV);1275GV->takeName(OldGV);1276OldGV->eraseFromParent();1277} else {1278GV->setName(I.first);1279}1280}12811282updateMemProfAttributes(*RegularLTO.CombinedModule, ThinLTO.CombinedIndex);12831284bool WholeProgramVisibilityEnabledInLTO =1285Conf.HasWholeProgramVisibility &&1286// If validation is enabled, upgrade visibility only when all vtables1287// have typeinfos.1288(!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);12891290// This returns true when the name is local or not defined. Locals are1291// expected to be handled separately.1292auto IsVisibleToRegularObj = [&](StringRef name) {1293auto It = GlobalResolutions->find(name);1294return (It == GlobalResolutions->end() || It->second.VisibleOutsideSummary);1295};12961297// If allowed, upgrade public vcall visibility metadata to linkage unit1298// visibility before whole program devirtualization in the optimizer.1299updateVCallVisibilityInModule(1300*RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,1301DynamicExportSymbols, Conf.ValidateAllVtablesHaveTypeInfos,1302IsVisibleToRegularObj);1303updatePublicTypeTestCalls(*RegularLTO.CombinedModule,1304WholeProgramVisibilityEnabledInLTO);13051306if (Conf.PreOptModuleHook &&1307!Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule))1308return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));13091310if (!Conf.CodeGenOnly) {1311for (const auto &R : *GlobalResolutions) {1312GlobalValue *GV =1313RegularLTO.CombinedModule->getNamedValue(R.second.IRName);1314if (!R.second.isPrevailingIRSymbol())1315continue;1316if (R.second.Partition != 0 &&1317R.second.Partition != GlobalResolution::External)1318continue;13191320// Ignore symbols defined in other partitions.1321// Also skip declarations, which are not allowed to have internal linkage.1322if (!GV || GV->hasLocalLinkage() || GV->isDeclaration())1323continue;13241325// Symbols that are marked DLLImport or DLLExport should not be1326// internalized, as they are either externally visible or referencing1327// external symbols. Symbols that have AvailableExternally or Appending1328// linkage might be used by future passes and should be kept as is.1329// These linkages are seen in Unified regular LTO, because the process1330// of creating split LTO units introduces symbols with that linkage into1331// one of the created modules. Normally, only the ThinLTO backend would1332// compile this module, but Unified Regular LTO processes both1333// modules created by the splitting process as regular LTO modules.1334if ((LTOMode == LTOKind::LTOK_UnifiedRegular) &&1335((GV->getDLLStorageClass() != GlobalValue::DefaultStorageClass) ||1336GV->hasAvailableExternallyLinkage() || GV->hasAppendingLinkage()))1337continue;13381339GV->setUnnamedAddr(R.second.UnnamedAddr ? GlobalValue::UnnamedAddr::Global1340: GlobalValue::UnnamedAddr::None);1341if (EnableLTOInternalization && R.second.Partition == 0)1342GV->setLinkage(GlobalValue::InternalLinkage);1343}13441345if (Conf.PostInternalizeModuleHook &&1346!Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule))1347return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));1348}13491350if (!RegularLTO.EmptyCombinedModule || Conf.AlwaysEmitRegularLTOObj) {1351if (Error Err =1352backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,1353*RegularLTO.CombinedModule, ThinLTO.CombinedIndex))1354return Err;1355}13561357return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));1358}13591360SmallVector<const char *> LTO::getRuntimeLibcallSymbols(const Triple &TT) {1361RTLIB::RuntimeLibcallsInfo Libcalls(TT);1362SmallVector<const char *> LibcallSymbols;1363copy_if(Libcalls.getLibcallNames(), std::back_inserter(LibcallSymbols),1364[](const char *Name) { return Name; });1365return LibcallSymbols;1366}13671368/// This class defines the interface to the ThinLTO backend.1369class lto::ThinBackendProc {1370protected:1371const Config &Conf;1372ModuleSummaryIndex &CombinedIndex;1373const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries;1374lto::IndexWriteCallback OnWrite;1375bool ShouldEmitImportsFiles;13761377public:1378ThinBackendProc(1379const Config &Conf, ModuleSummaryIndex &CombinedIndex,1380const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1381lto::IndexWriteCallback OnWrite, bool ShouldEmitImportsFiles)1382: Conf(Conf), CombinedIndex(CombinedIndex),1383ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries),1384OnWrite(OnWrite), ShouldEmitImportsFiles(ShouldEmitImportsFiles) {}13851386virtual ~ThinBackendProc() = default;1387virtual Error start(1388unsigned Task, BitcodeModule BM,1389const FunctionImporter::ImportMapTy &ImportList,1390const FunctionImporter::ExportSetTy &ExportList,1391const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,1392MapVector<StringRef, BitcodeModule> &ModuleMap) = 0;1393virtual Error wait() = 0;1394virtual unsigned getThreadCount() = 0;13951396// Write sharded indices and (optionally) imports to disk1397Error emitFiles(const FunctionImporter::ImportMapTy &ImportList,1398llvm::StringRef ModulePath,1399const std::string &NewModulePath) {1400std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;1401GVSummaryPtrSet DeclarationSummaries;14021403std::error_code EC;1404gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries,1405ImportList, ModuleToSummariesForIndex,1406DeclarationSummaries);14071408raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC,1409sys::fs::OpenFlags::OF_None);1410if (EC)1411return errorCodeToError(EC);14121413writeIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex,1414&DeclarationSummaries);14151416if (ShouldEmitImportsFiles) {1417EC = EmitImportsFiles(ModulePath, NewModulePath + ".imports",1418ModuleToSummariesForIndex);1419if (EC)1420return errorCodeToError(EC);1421}1422return Error::success();1423}1424};14251426namespace {1427class InProcessThinBackend : public ThinBackendProc {1428DefaultThreadPool BackendThreadPool;1429AddStreamFn AddStream;1430FileCache Cache;1431std::set<GlobalValue::GUID> CfiFunctionDefs;1432std::set<GlobalValue::GUID> CfiFunctionDecls;14331434std::optional<Error> Err;1435std::mutex ErrMu;14361437bool ShouldEmitIndexFiles;14381439public:1440InProcessThinBackend(1441const Config &Conf, ModuleSummaryIndex &CombinedIndex,1442ThreadPoolStrategy ThinLTOParallelism,1443const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1444AddStreamFn AddStream, FileCache Cache, lto::IndexWriteCallback OnWrite,1445bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles)1446: ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,1447OnWrite, ShouldEmitImportsFiles),1448BackendThreadPool(ThinLTOParallelism), AddStream(std::move(AddStream)),1449Cache(std::move(Cache)), ShouldEmitIndexFiles(ShouldEmitIndexFiles) {1450for (auto &Name : CombinedIndex.cfiFunctionDefs())1451CfiFunctionDefs.insert(1452GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));1453for (auto &Name : CombinedIndex.cfiFunctionDecls())1454CfiFunctionDecls.insert(1455GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));1456}14571458Error runThinLTOBackendThread(1459AddStreamFn AddStream, FileCache Cache, unsigned Task, BitcodeModule BM,1460ModuleSummaryIndex &CombinedIndex,1461const FunctionImporter::ImportMapTy &ImportList,1462const FunctionImporter::ExportSetTy &ExportList,1463const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,1464const GVSummaryMapTy &DefinedGlobals,1465MapVector<StringRef, BitcodeModule> &ModuleMap) {1466auto RunThinBackend = [&](AddStreamFn AddStream) {1467LTOLLVMContext BackendContext(Conf);1468Expected<std::unique_ptr<Module>> MOrErr = BM.parseModule(BackendContext);1469if (!MOrErr)1470return MOrErr.takeError();14711472return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,1473ImportList, DefinedGlobals, &ModuleMap);1474};14751476auto ModuleID = BM.getModuleIdentifier();14771478if (ShouldEmitIndexFiles) {1479if (auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))1480return E;1481}14821483if (!Cache || !CombinedIndex.modulePaths().count(ModuleID) ||1484all_of(CombinedIndex.getModuleHash(ModuleID),1485[](uint32_t V) { return V == 0; }))1486// Cache disabled or no entry for this module in the combined index or1487// no module hash.1488return RunThinBackend(AddStream);14891490SmallString<40> Key;1491// The module may be cached, this helps handling it.1492computeLTOCacheKey(Key, Conf, CombinedIndex, ModuleID, ImportList,1493ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs,1494CfiFunctionDecls);1495Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, Key, ModuleID);1496if (Error Err = CacheAddStreamOrErr.takeError())1497return Err;1498AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;1499if (CacheAddStream)1500return RunThinBackend(CacheAddStream);15011502return Error::success();1503}15041505Error start(1506unsigned Task, BitcodeModule BM,1507const FunctionImporter::ImportMapTy &ImportList,1508const FunctionImporter::ExportSetTy &ExportList,1509const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,1510MapVector<StringRef, BitcodeModule> &ModuleMap) override {1511StringRef ModulePath = BM.getModuleIdentifier();1512assert(ModuleToDefinedGVSummaries.count(ModulePath));1513const GVSummaryMapTy &DefinedGlobals =1514ModuleToDefinedGVSummaries.find(ModulePath)->second;1515BackendThreadPool.async(1516[=](BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,1517const FunctionImporter::ImportMapTy &ImportList,1518const FunctionImporter::ExportSetTy &ExportList,1519const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>1520&ResolvedODR,1521const GVSummaryMapTy &DefinedGlobals,1522MapVector<StringRef, BitcodeModule> &ModuleMap) {1523if (LLVM_ENABLE_THREADS && Conf.TimeTraceEnabled)1524timeTraceProfilerInitialize(Conf.TimeTraceGranularity,1525"thin backend");1526Error E = runThinLTOBackendThread(1527AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,1528ResolvedODR, DefinedGlobals, ModuleMap);1529if (E) {1530std::unique_lock<std::mutex> L(ErrMu);1531if (Err)1532Err = joinErrors(std::move(*Err), std::move(E));1533else1534Err = std::move(E);1535}1536if (LLVM_ENABLE_THREADS && Conf.TimeTraceEnabled)1537timeTraceProfilerFinishThread();1538},1539BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),1540std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));15411542if (OnWrite)1543OnWrite(std::string(ModulePath));1544return Error::success();1545}15461547Error wait() override {1548BackendThreadPool.wait();1549if (Err)1550return std::move(*Err);1551else1552return Error::success();1553}15541555unsigned getThreadCount() override {1556return BackendThreadPool.getMaxConcurrency();1557}1558};1559} // end anonymous namespace15601561ThinBackend lto::createInProcessThinBackend(ThreadPoolStrategy Parallelism,1562lto::IndexWriteCallback OnWrite,1563bool ShouldEmitIndexFiles,1564bool ShouldEmitImportsFiles) {1565return1566[=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,1567const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1568AddStreamFn AddStream, FileCache Cache) {1569return std::make_unique<InProcessThinBackend>(1570Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,1571AddStream, Cache, OnWrite, ShouldEmitIndexFiles,1572ShouldEmitImportsFiles);1573};1574}15751576StringLiteral lto::getThinLTODefaultCPU(const Triple &TheTriple) {1577if (!TheTriple.isOSDarwin())1578return "";1579if (TheTriple.getArch() == Triple::x86_64)1580return "core2";1581if (TheTriple.getArch() == Triple::x86)1582return "yonah";1583if (TheTriple.isArm64e())1584return "apple-a12";1585if (TheTriple.getArch() == Triple::aarch64 ||1586TheTriple.getArch() == Triple::aarch64_32)1587return "cyclone";1588return "";1589}15901591// Given the original \p Path to an output file, replace any path1592// prefix matching \p OldPrefix with \p NewPrefix. Also, create the1593// resulting directory if it does not yet exist.1594std::string lto::getThinLTOOutputFile(StringRef Path, StringRef OldPrefix,1595StringRef NewPrefix) {1596if (OldPrefix.empty() && NewPrefix.empty())1597return std::string(Path);1598SmallString<128> NewPath(Path);1599llvm::sys::path::replace_path_prefix(NewPath, OldPrefix, NewPrefix);1600StringRef ParentPath = llvm::sys::path::parent_path(NewPath.str());1601if (!ParentPath.empty()) {1602// Make sure the new directory exists, creating it if necessary.1603if (std::error_code EC = llvm::sys::fs::create_directories(ParentPath))1604llvm::errs() << "warning: could not create directory '" << ParentPath1605<< "': " << EC.message() << '\n';1606}1607return std::string(NewPath);1608}16091610namespace {1611class WriteIndexesThinBackend : public ThinBackendProc {1612std::string OldPrefix, NewPrefix, NativeObjectPrefix;1613raw_fd_ostream *LinkedObjectsFile;16141615public:1616WriteIndexesThinBackend(1617const Config &Conf, ModuleSummaryIndex &CombinedIndex,1618const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1619std::string OldPrefix, std::string NewPrefix,1620std::string NativeObjectPrefix, bool ShouldEmitImportsFiles,1621raw_fd_ostream *LinkedObjectsFile, lto::IndexWriteCallback OnWrite)1622: ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,1623OnWrite, ShouldEmitImportsFiles),1624OldPrefix(OldPrefix), NewPrefix(NewPrefix),1625NativeObjectPrefix(NativeObjectPrefix),1626LinkedObjectsFile(LinkedObjectsFile) {}16271628Error start(1629unsigned Task, BitcodeModule BM,1630const FunctionImporter::ImportMapTy &ImportList,1631const FunctionImporter::ExportSetTy &ExportList,1632const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,1633MapVector<StringRef, BitcodeModule> &ModuleMap) override {1634StringRef ModulePath = BM.getModuleIdentifier();1635std::string NewModulePath =1636getThinLTOOutputFile(ModulePath, OldPrefix, NewPrefix);16371638if (LinkedObjectsFile) {1639std::string ObjectPrefix =1640NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;1641std::string LinkedObjectsFilePath =1642getThinLTOOutputFile(ModulePath, OldPrefix, ObjectPrefix);1643*LinkedObjectsFile << LinkedObjectsFilePath << '\n';1644}16451646if (auto E = emitFiles(ImportList, ModulePath, NewModulePath))1647return E;16481649if (OnWrite)1650OnWrite(std::string(ModulePath));1651return Error::success();1652}16531654Error wait() override { return Error::success(); }16551656// WriteIndexesThinBackend should always return 1 to prevent module1657// re-ordering and avoid non-determinism in the final link.1658unsigned getThreadCount() override { return 1; }1659};1660} // end anonymous namespace16611662ThinBackend lto::createWriteIndexesThinBackend(1663std::string OldPrefix, std::string NewPrefix,1664std::string NativeObjectPrefix, bool ShouldEmitImportsFiles,1665raw_fd_ostream *LinkedObjectsFile, IndexWriteCallback OnWrite) {1666return1667[=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,1668const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1669AddStreamFn AddStream, FileCache Cache) {1670return std::make_unique<WriteIndexesThinBackend>(1671Conf, CombinedIndex, ModuleToDefinedGVSummaries, OldPrefix,1672NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,1673LinkedObjectsFile, OnWrite);1674};1675}16761677Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,1678const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {1679LLVM_DEBUG(dbgs() << "Running ThinLTO\n");1680ThinLTO.CombinedIndex.releaseTemporaryMemory();1681timeTraceProfilerBegin("ThinLink", StringRef(""));1682auto TimeTraceScopeExit = llvm::make_scope_exit([]() {1683if (llvm::timeTraceProfilerEnabled())1684llvm::timeTraceProfilerEnd();1685});1686if (ThinLTO.ModuleMap.empty())1687return Error::success();16881689if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {1690llvm::errs() << "warning: [ThinLTO] No module compiled\n";1691return Error::success();1692}16931694if (Conf.CombinedIndexHook &&1695!Conf.CombinedIndexHook(ThinLTO.CombinedIndex, GUIDPreservedSymbols))1696return Error::success();16971698// Collect for each module the list of function it defines (GUID ->1699// Summary).1700DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(1701ThinLTO.ModuleMap.size());1702ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(1703ModuleToDefinedGVSummaries);1704// Create entries for any modules that didn't have any GV summaries1705// (either they didn't have any GVs to start with, or we suppressed1706// generation of the summaries because they e.g. had inline assembly1707// uses that couldn't be promoted/renamed on export). This is so1708// InProcessThinBackend::start can still launch a backend thread, which1709// is passed the map of summaries for the module, without any special1710// handling for this case.1711for (auto &Mod : ThinLTO.ModuleMap)1712if (!ModuleToDefinedGVSummaries.count(Mod.first))1713ModuleToDefinedGVSummaries.try_emplace(Mod.first);17141715// Synthesize entry counts for functions in the CombinedIndex.1716computeSyntheticCounts(ThinLTO.CombinedIndex);17171718DenseMap<StringRef, FunctionImporter::ImportMapTy> ImportLists(1719ThinLTO.ModuleMap.size());1720DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists(1721ThinLTO.ModuleMap.size());1722StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;17231724if (DumpThinCGSCCs)1725ThinLTO.CombinedIndex.dumpSCCs(outs());17261727std::set<GlobalValue::GUID> ExportedGUIDs;17281729bool WholeProgramVisibilityEnabledInLTO =1730Conf.HasWholeProgramVisibility &&1731// If validation is enabled, upgrade visibility only when all vtables1732// have typeinfos.1733(!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);1734if (hasWholeProgramVisibility(WholeProgramVisibilityEnabledInLTO))1735ThinLTO.CombinedIndex.setWithWholeProgramVisibility();17361737// If we're validating, get the vtable symbols that should not be1738// upgraded because they correspond to typeIDs outside of index-based1739// WPD info.1740DenseSet<GlobalValue::GUID> VisibleToRegularObjSymbols;1741if (WholeProgramVisibilityEnabledInLTO &&1742Conf.ValidateAllVtablesHaveTypeInfos) {1743// This returns true when the name is local or not defined. Locals are1744// expected to be handled separately.1745auto IsVisibleToRegularObj = [&](StringRef name) {1746auto It = GlobalResolutions->find(name);1747return (It == GlobalResolutions->end() ||1748It->second.VisibleOutsideSummary);1749};17501751getVisibleToRegularObjVtableGUIDs(ThinLTO.CombinedIndex,1752VisibleToRegularObjSymbols,1753IsVisibleToRegularObj);1754}17551756// If allowed, upgrade public vcall visibility to linkage unit visibility in1757// the summaries before whole program devirtualization below.1758updateVCallVisibilityInIndex(1759ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,1760DynamicExportSymbols, VisibleToRegularObjSymbols);17611762// Perform index-based WPD. This will return immediately if there are1763// no index entries in the typeIdMetadata map (e.g. if we are instead1764// performing IR-based WPD in hybrid regular/thin LTO mode).1765std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;1766runWholeProgramDevirtOnIndex(ThinLTO.CombinedIndex, ExportedGUIDs,1767LocalWPDTargetsMap);17681769auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {1770return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath();1771};1772if (EnableMemProfContextDisambiguation) {1773MemProfContextDisambiguation ContextDisambiguation;1774ContextDisambiguation.run(ThinLTO.CombinedIndex, isPrevailing);1775}17761777// Figure out which symbols need to be internalized. This also needs to happen1778// at -O0 because summary-based DCE is implemented using internalization, and1779// we must apply DCE consistently with the full LTO module in order to avoid1780// undefined references during the final link.1781for (auto &Res : *GlobalResolutions) {1782// If the symbol does not have external references or it is not prevailing,1783// then not need to mark it as exported from a ThinLTO partition.1784if (Res.second.Partition != GlobalResolution::External ||1785!Res.second.isPrevailingIRSymbol())1786continue;1787auto GUID = GlobalValue::getGUID(1788GlobalValue::dropLLVMManglingEscape(Res.second.IRName));1789// Mark exported unless index-based analysis determined it to be dead.1790if (ThinLTO.CombinedIndex.isGUIDLive(GUID))1791ExportedGUIDs.insert(GUID);1792}17931794// Reset the GlobalResolutions to deallocate the associated memory, as there1795// are no further accesses. We specifically want to do this before computing1796// cross module importing, which adds to peak memory via the computed import1797// and export lists.1798GlobalResolutions.reset();17991800if (Conf.OptLevel > 0)1801ComputeCrossModuleImport(ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,1802isPrevailing, ImportLists, ExportLists);18031804// Any functions referenced by the jump table in the regular LTO object must1805// be exported.1806for (auto &Def : ThinLTO.CombinedIndex.cfiFunctionDefs())1807ExportedGUIDs.insert(1808GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Def)));1809for (auto &Decl : ThinLTO.CombinedIndex.cfiFunctionDecls())1810ExportedGUIDs.insert(1811GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Decl)));18121813auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {1814const auto &ExportList = ExportLists.find(ModuleIdentifier);1815return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||1816ExportedGUIDs.count(VI.getGUID());1817};18181819// Update local devirtualized targets that were exported by cross-module1820// importing or by other devirtualizations marked in the ExportedGUIDs set.1821updateIndexWPDForExports(ThinLTO.CombinedIndex, isExported,1822LocalWPDTargetsMap);18231824thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported,1825isPrevailing);18261827auto recordNewLinkage = [&](StringRef ModuleIdentifier,1828GlobalValue::GUID GUID,1829GlobalValue::LinkageTypes NewLinkage) {1830ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;1831};1832thinLTOResolvePrevailingInIndex(Conf, ThinLTO.CombinedIndex, isPrevailing,1833recordNewLinkage, GUIDPreservedSymbols);18341835thinLTOPropagateFunctionAttrs(ThinLTO.CombinedIndex, isPrevailing);18361837generateParamAccessSummary(ThinLTO.CombinedIndex);18381839if (llvm::timeTraceProfilerEnabled())1840llvm::timeTraceProfilerEnd();18411842TimeTraceScopeExit.release();18431844std::unique_ptr<ThinBackendProc> BackendProc =1845ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,1846AddStream, Cache);18471848auto &ModuleMap =1849ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;18501851auto ProcessOneModule = [&](int I) -> Error {1852auto &Mod = *(ModuleMap.begin() + I);1853// Tasks 0 through ParallelCodeGenParallelismLevel-1 are reserved for1854// combined module and parallel code generation partitions.1855return BackendProc->start(RegularLTO.ParallelCodeGenParallelismLevel + I,1856Mod.second, ImportLists[Mod.first],1857ExportLists[Mod.first], ResolvedODR[Mod.first],1858ThinLTO.ModuleMap);1859};18601861if (BackendProc->getThreadCount() == 1) {1862// Process the modules in the order they were provided on the command-line.1863// It is important for this codepath to be used for WriteIndexesThinBackend,1864// to ensure the emitted LinkedObjectsFile lists ThinLTO objects in the same1865// order as the inputs, which otherwise would affect the final link order.1866for (int I = 0, E = ModuleMap.size(); I != E; ++I)1867if (Error E = ProcessOneModule(I))1868return E;1869} else {1870// When executing in parallel, process largest bitsize modules first to1871// improve parallelism, and avoid starving the thread pool near the end.1872// This saves about 15 sec on a 36-core machine while link `clang.exe` (out1873// of 100 sec).1874std::vector<BitcodeModule *> ModulesVec;1875ModulesVec.reserve(ModuleMap.size());1876for (auto &Mod : ModuleMap)1877ModulesVec.push_back(&Mod.second);1878for (int I : generateModulesOrdering(ModulesVec))1879if (Error E = ProcessOneModule(I))1880return E;1881}1882return BackendProc->wait();1883}18841885Expected<std::unique_ptr<ToolOutputFile>> lto::setupLLVMOptimizationRemarks(1886LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,1887StringRef RemarksFormat, bool RemarksWithHotness,1888std::optional<uint64_t> RemarksHotnessThreshold, int Count) {1889std::string Filename = std::string(RemarksFilename);1890// For ThinLTO, file.opt.<format> becomes1891// file.opt.<format>.thin.<num>.<format>.1892if (!Filename.empty() && Count != -1)1893Filename =1894(Twine(Filename) + ".thin." + llvm::utostr(Count) + "." + RemarksFormat)1895.str();18961897auto ResultOrErr = llvm::setupLLVMOptimizationRemarks(1898Context, Filename, RemarksPasses, RemarksFormat, RemarksWithHotness,1899RemarksHotnessThreshold);1900if (Error E = ResultOrErr.takeError())1901return std::move(E);19021903if (*ResultOrErr)1904(*ResultOrErr)->keep();19051906return ResultOrErr;1907}19081909Expected<std::unique_ptr<ToolOutputFile>>1910lto::setupStatsFile(StringRef StatsFilename) {1911// Setup output file to emit statistics.1912if (StatsFilename.empty())1913return nullptr;19141915llvm::EnableStatistics(false);1916std::error_code EC;1917auto StatsFile =1918std::make_unique<ToolOutputFile>(StatsFilename, EC, sys::fs::OF_None);1919if (EC)1920return errorCodeToError(EC);19211922StatsFile->keep();1923return std::move(StatsFile);1924}19251926// Compute the ordering we will process the inputs: the rough heuristic here1927// is to sort them per size so that the largest module get schedule as soon as1928// possible. This is purely a compile-time optimization.1929std::vector<int> lto::generateModulesOrdering(ArrayRef<BitcodeModule *> R) {1930auto Seq = llvm::seq<int>(0, R.size());1931std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());1932llvm::sort(ModulesOrdering, [&](int LeftIndex, int RightIndex) {1933auto LSize = R[LeftIndex]->getBuffer().size();1934auto RSize = R[RightIndex]->getBuffer().size();1935return LSize > RSize;1936});1937return ModulesOrdering;1938}193919401941