blob: 11ffb59f604da30fa3454f5c8f260a72d374ce35 [file] [log] [blame]
Teresa Johnsondf6edc52016-05-23 22:54:06 +00001//===-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}
Teresa Johnson04c9a2d2016-05-25 14:03:11 +000042
43static void thinLTOResolveWeakForLinkerGUID(
44 GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID,
45 DenseSet<GlobalValueSummary *> &GlobalInvolvedWithAlias,
46 std::function<bool(GlobalValue::GUID, const GlobalValueSummary *)>
47 isPrevailing,
48 std::function<bool(StringRef, GlobalValue::GUID)> isExported,
49 std::function<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.
Teresa Johnson28c03b52016-05-26 14:16:52 +000063 if (GlobalValue::isLinkOnceLinkage(OriginalLinkage) &&
Teresa Johnson04c9a2d2016-05-25 14:03:11 +000064 isExported(S->modulePath(), GUID))
Teresa Johnson28c03b52016-05-26 14:16:52 +000065 S->setLinkage(GlobalValue::getWeakLinkage(
66 GlobalValue::isLinkOnceODRLinkage(OriginalLinkage)));
Teresa Johnson04c9a2d2016-05-25 14:03:11 +000067 } else if (isPrevailing(GUID, S.get())) {
Teresa Johnson28c03b52016-05-26 14:16:52 +000068 if (GlobalValue::isLinkOnceLinkage(OriginalLinkage))
69 S->setLinkage(GlobalValue::getWeakLinkage(
70 GlobalValue::isLinkOnceODRLinkage(OriginalLinkage)));
Teresa Johnson04c9a2d2016-05-25 14:03:11 +000071 }
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.
88void thinLTOResolveWeakForLinkerInIndex(
89 ModuleSummaryIndex &Index,
90 std::function<bool(GlobalValue::GUID, const GlobalValueSummary *)>
91 isPrevailing,
92 std::function<bool(StringRef, GlobalValue::GUID)> isExported,
93 std::function<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
113static void thinLTOInternalizeAndPromoteGUID(
114 GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID,
115 std::function<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.
127void thinLTOInternalizeAndPromoteInIndex(
128 ModuleSummaryIndex &Index,
129 std::function<bool(StringRef, GlobalValue::GUID)> isExported) {
130 for (auto &I : Index)
131 thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported);
132}
Teresa Johnsondf6edc52016-05-23 22:54:06 +0000133}