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 20 namespace llvm { 21 22 // Simple helper to load a module from bitcode 23 std::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 43 static 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<bool(StringRef, GlobalValue::GUID)> isExported, 49 function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> 50 recordNewLinkage) { 51 auto HasMultipleCopies = GVSummaryList.size() > 1; 52 53 for (auto &S : GVSummaryList) { 54 if (GlobalInvolvedWithAlias.count(S.get())) 55 continue; 56 GlobalValue::LinkageTypes OriginalLinkage = S->linkage(); 57 if (!GlobalValue::isWeakForLinker(OriginalLinkage)) 58 continue; 59 // We need to emit only one of these, the first module will keep it, 60 // but turned into a weak, while the others will drop it when possible. 61 if (!HasMultipleCopies) { 62 // Exported Linkonce needs to be promoted to not be discarded. 63 if (GlobalValue::isLinkOnceLinkage(OriginalLinkage) && 64 isExported(S->modulePath(), GUID)) 65 S->setLinkage(GlobalValue::getWeakLinkage( 66 GlobalValue::isLinkOnceODRLinkage(OriginalLinkage))); 67 } else if (isPrevailing(GUID, S.get())) { 68 if (GlobalValue::isLinkOnceLinkage(OriginalLinkage)) 69 S->setLinkage(GlobalValue::getWeakLinkage( 70 GlobalValue::isLinkOnceODRLinkage(OriginalLinkage))); 71 } 72 // Alias can't be turned into available_externally. 73 else if (!isa<AliasSummary>(S.get()) && 74 (GlobalValue::isLinkOnceODRLinkage(OriginalLinkage) || 75 GlobalValue::isWeakODRLinkage(OriginalLinkage))) 76 S->setLinkage(GlobalValue::AvailableExternallyLinkage); 77 if (S->linkage() != OriginalLinkage) 78 recordNewLinkage(S->modulePath(), GUID, S->linkage()); 79 } 80 } 81 82 // Resolve Weak and LinkOnce values in the \p Index. 83 // 84 // We'd like to drop these functions if they are no longer referenced in the 85 // current module. However there is a chance that another module is still 86 // referencing them because of the import. We make sure we always emit at least 87 // one copy. 88 void thinLTOResolveWeakForLinkerInIndex( 89 ModuleSummaryIndex &Index, 90 function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 91 isPrevailing, 92 function_ref<bool(StringRef, GlobalValue::GUID)> isExported, 93 function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> 94 recordNewLinkage) { 95 if (Index.modulePaths().size() == 1) 96 // Nothing to do if we don't have multiple modules 97 return; 98 99 // We won't optimize the globals that are referenced by an alias for now 100 // Ideally we should turn the alias into a global and duplicate the definition 101 // when needed. 102 DenseSet<GlobalValueSummary *> GlobalInvolvedWithAlias; 103 for (auto &I : Index) 104 for (auto &S : I.second) 105 if (auto AS = dyn_cast<AliasSummary>(S.get())) 106 GlobalInvolvedWithAlias.insert(&AS->getAliasee()); 107 108 for (auto &I : Index) 109 thinLTOResolveWeakForLinkerGUID(I.second, I.first, GlobalInvolvedWithAlias, 110 isPrevailing, isExported, recordNewLinkage); 111 } 112 113 static void thinLTOInternalizeAndPromoteGUID( 114 GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID, 115 function_ref<bool(StringRef, GlobalValue::GUID)> isExported) { 116 for (auto &S : GVSummaryList) { 117 if (isExported(S->modulePath(), GUID)) { 118 if (GlobalValue::isLocalLinkage(S->linkage())) 119 S->setLinkage(GlobalValue::ExternalLinkage); 120 } else if (!GlobalValue::isLocalLinkage(S->linkage())) 121 S->setLinkage(GlobalValue::InternalLinkage); 122 } 123 } 124 125 // Update the linkages in the given \p Index to mark exported values 126 // as external and non-exported values as internal. 127 void thinLTOInternalizeAndPromoteInIndex( 128 ModuleSummaryIndex &Index, 129 function_ref<bool(StringRef, GlobalValue::GUID)> isExported) { 130 for (auto &I : Index) 131 thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported); 132 } 133 } 134