1//===-LTO.cpp - LLVM Link Time Optimizer ----------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements functions and classes used to support LTO. 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/LTO/LTO.h" 15#include "llvm/Bitcode/ReaderWriter.h" 16#include "llvm/Support/MemoryBuffer.h" 17#include "llvm/Support/SourceMgr.h" 18#include "llvm/Support/raw_ostream.h" 19 20namespace llvm { 21 22// Simple helper to load a module from bitcode 23std::unique_ptr<Module> loadModuleFromBuffer(const MemoryBufferRef &Buffer, 24 LLVMContext &Context, bool Lazy) { 25 SMDiagnostic Err; 26 ErrorOr<std::unique_ptr<Module>> ModuleOrErr(nullptr); 27 if (Lazy) { 28 ModuleOrErr = 29 getLazyBitcodeModule(MemoryBuffer::getMemBuffer(Buffer, false), Context, 30 /* ShouldLazyLoadMetadata */ Lazy); 31 } else { 32 ModuleOrErr = parseBitcodeFile(Buffer, Context); 33 } 34 if (std::error_code EC = ModuleOrErr.getError()) { 35 Err = SMDiagnostic(Buffer.getBufferIdentifier(), SourceMgr::DK_Error, 36 EC.message()); 37 Err.print("ThinLTO", errs()); 38 report_fatal_error("Can't load module, abort."); 39 } 40 return std::move(ModuleOrErr.get()); 41} 42 43static void thinLTOResolveWeakForLinkerGUID( 44 GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID, 45 DenseSet<GlobalValueSummary *> &GlobalInvolvedWithAlias, 46 function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 47 isPrevailing, 48 function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> 49 recordNewLinkage) { 50 for (auto &S : GVSummaryList) { 51 if (GlobalInvolvedWithAlias.count(S.get())) 52 continue; 53 GlobalValue::LinkageTypes OriginalLinkage = S->linkage(); 54 if (!GlobalValue::isWeakForLinker(OriginalLinkage)) 55 continue; 56 // We need to emit only one of these. The prevailing module will keep it, 57 // but turned into a weak, while the others will drop it when possible. 58 if (isPrevailing(GUID, S.get())) { 59 if (GlobalValue::isLinkOnceLinkage(OriginalLinkage)) 60 S->setLinkage(GlobalValue::getWeakLinkage( 61 GlobalValue::isLinkOnceODRLinkage(OriginalLinkage))); 62 } 63 // Alias can't be turned into available_externally. 64 else if (!isa<AliasSummary>(S.get()) && 65 (GlobalValue::isLinkOnceODRLinkage(OriginalLinkage) || 66 GlobalValue::isWeakODRLinkage(OriginalLinkage))) 67 S->setLinkage(GlobalValue::AvailableExternallyLinkage); 68 if (S->linkage() != OriginalLinkage) 69 recordNewLinkage(S->modulePath(), GUID, S->linkage()); 70 } 71} 72 73// Resolve Weak and LinkOnce values in the \p Index. 74// 75// We'd like to drop these functions if they are no longer referenced in the 76// current module. However there is a chance that another module is still 77// referencing them because of the import. We make sure we always emit at least 78// one copy. 79void thinLTOResolveWeakForLinkerInIndex( 80 ModuleSummaryIndex &Index, 81 function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 82 isPrevailing, 83 function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> 84 recordNewLinkage) { 85 // We won't optimize the globals that are referenced by an alias for now 86 // Ideally we should turn the alias into a global and duplicate the definition 87 // when needed. 88 DenseSet<GlobalValueSummary *> GlobalInvolvedWithAlias; 89 for (auto &I : Index) 90 for (auto &S : I.second) 91 if (auto AS = dyn_cast<AliasSummary>(S.get())) 92 GlobalInvolvedWithAlias.insert(&AS->getAliasee()); 93 94 for (auto &I : Index) 95 thinLTOResolveWeakForLinkerGUID(I.second, I.first, GlobalInvolvedWithAlias, 96 isPrevailing, recordNewLinkage); 97} 98 99static void thinLTOInternalizeAndPromoteGUID( 100 GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID, 101 function_ref<bool(StringRef, GlobalValue::GUID)> isExported) { 102 for (auto &S : GVSummaryList) { 103 if (isExported(S->modulePath(), GUID)) { 104 if (GlobalValue::isLocalLinkage(S->linkage())) 105 S->setLinkage(GlobalValue::ExternalLinkage); 106 } else if (!GlobalValue::isLocalLinkage(S->linkage())) 107 S->setLinkage(GlobalValue::InternalLinkage); 108 } 109} 110 111// Update the linkages in the given \p Index to mark exported values 112// as external and non-exported values as internal. 113void thinLTOInternalizeAndPromoteInIndex( 114 ModuleSummaryIndex &Index, 115 function_ref<bool(StringRef, GlobalValue::GUID)> isExported) { 116 for (auto &I : Index) 117 thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported); 118} 119} 120