blob: b39e881a2e7195fd8f67a551c25724c4b84c635d [file] [log] [blame]
Peter Collingbourne1398a322016-12-16 00:26:30 +00001//===- ThinLTOBitcodeWriter.cpp - Bitcode writing pass for ThinLTO --------===//
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 pass prepares a module containing type metadata for ThinLTO by splitting
11// it into regular and thin LTO parts if possible, and writing both parts to
12// a multi-module bitcode file. Modules that do not contain type metadata are
13// written unmodified as a single module.
14//
15//===----------------------------------------------------------------------===//
16
Peter Collingbourne002c2d52017-02-14 03:42:38 +000017#include "llvm/Analysis/BasicAliasAnalysis.h"
Peter Collingbourne1398a322016-12-16 00:26:30 +000018#include "llvm/Analysis/ModuleSummaryAnalysis.h"
19#include "llvm/Analysis/TypeMetadataUtils.h"
20#include "llvm/Bitcode/BitcodeWriter.h"
21#include "llvm/IR/Constants.h"
Peter Collingbourne28ffd322017-02-08 20:44:00 +000022#include "llvm/IR/DebugInfo.h"
Peter Collingbourne1398a322016-12-16 00:26:30 +000023#include "llvm/IR/Intrinsics.h"
24#include "llvm/IR/Module.h"
25#include "llvm/IR/PassManager.h"
26#include "llvm/Pass.h"
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +000027#include "llvm/Support/FileSystem.h"
Peter Collingbourne1398a322016-12-16 00:26:30 +000028#include "llvm/Support/ScopedPrinter.h"
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +000029#include "llvm/Support/raw_ostream.h"
30#include "llvm/Transforms/IPO.h"
Peter Collingbourne002c2d52017-02-14 03:42:38 +000031#include "llvm/Transforms/IPO/FunctionAttrs.h"
Peter Collingbourne1398a322016-12-16 00:26:30 +000032#include "llvm/Transforms/Utils/Cloning.h"
Evgeniy Stepanov6c3a8cb2017-04-06 19:55:17 +000033#include "llvm/Transforms/Utils/ModuleUtils.h"
Peter Collingbourne1398a322016-12-16 00:26:30 +000034using namespace llvm;
35
36namespace {
37
Peter Collingbourne1398a322016-12-16 00:26:30 +000038// Promote each local-linkage entity defined by ExportM and used by ImportM by
39// changing visibility and appending the given ModuleId.
40void promoteInternals(Module &ExportM, Module &ImportM, StringRef ModuleId) {
Peter Collingbourne6b193962017-03-30 23:43:08 +000041 for (auto &ExportGV : ExportM.global_values()) {
Peter Collingbourne1398a322016-12-16 00:26:30 +000042 if (!ExportGV.hasLocalLinkage())
Peter Collingbourne6b193962017-03-30 23:43:08 +000043 continue;
Peter Collingbourne1398a322016-12-16 00:26:30 +000044
45 GlobalValue *ImportGV = ImportM.getNamedValue(ExportGV.getName());
46 if (!ImportGV || ImportGV->use_empty())
Peter Collingbourne6b193962017-03-30 23:43:08 +000047 continue;
Peter Collingbourne1398a322016-12-16 00:26:30 +000048
49 std::string NewName = (ExportGV.getName() + ModuleId).str();
50
51 ExportGV.setName(NewName);
52 ExportGV.setLinkage(GlobalValue::ExternalLinkage);
53 ExportGV.setVisibility(GlobalValue::HiddenVisibility);
54
55 ImportGV->setName(NewName);
56 ImportGV->setVisibility(GlobalValue::HiddenVisibility);
Peter Collingbourne6b193962017-03-30 23:43:08 +000057 }
Peter Collingbourne1398a322016-12-16 00:26:30 +000058}
59
60// Promote all internal (i.e. distinct) type ids used by the module by replacing
61// them with external type ids formed using the module id.
62//
63// Note that this needs to be done before we clone the module because each clone
64// will receive its own set of distinct metadata nodes.
65void promoteTypeIds(Module &M, StringRef ModuleId) {
66 DenseMap<Metadata *, Metadata *> LocalToGlobal;
67 auto ExternalizeTypeId = [&](CallInst *CI, unsigned ArgNo) {
68 Metadata *MD =
69 cast<MetadataAsValue>(CI->getArgOperand(ArgNo))->getMetadata();
70
71 if (isa<MDNode>(MD) && cast<MDNode>(MD)->isDistinct()) {
72 Metadata *&GlobalMD = LocalToGlobal[MD];
73 if (!GlobalMD) {
74 std::string NewName =
75 (to_string(LocalToGlobal.size()) + ModuleId).str();
76 GlobalMD = MDString::get(M.getContext(), NewName);
77 }
78
79 CI->setArgOperand(ArgNo,
80 MetadataAsValue::get(M.getContext(), GlobalMD));
81 }
82 };
83
84 if (Function *TypeTestFunc =
85 M.getFunction(Intrinsic::getName(Intrinsic::type_test))) {
86 for (const Use &U : TypeTestFunc->uses()) {
87 auto CI = cast<CallInst>(U.getUser());
88 ExternalizeTypeId(CI, 1);
89 }
90 }
91
92 if (Function *TypeCheckedLoadFunc =
93 M.getFunction(Intrinsic::getName(Intrinsic::type_checked_load))) {
94 for (const Use &U : TypeCheckedLoadFunc->uses()) {
95 auto CI = cast<CallInst>(U.getUser());
96 ExternalizeTypeId(CI, 2);
97 }
98 }
99
100 for (GlobalObject &GO : M.global_objects()) {
101 SmallVector<MDNode *, 1> MDs;
102 GO.getMetadata(LLVMContext::MD_type, MDs);
103
104 GO.eraseMetadata(LLVMContext::MD_type);
105 for (auto MD : MDs) {
106 auto I = LocalToGlobal.find(MD->getOperand(1));
107 if (I == LocalToGlobal.end()) {
108 GO.addMetadata(LLVMContext::MD_type, *MD);
109 continue;
110 }
111 GO.addMetadata(
112 LLVMContext::MD_type,
113 *MDNode::get(M.getContext(),
114 ArrayRef<Metadata *>{MD->getOperand(0), I->second}));
115 }
116 }
117}
118
119// Drop unused globals, and drop type information from function declarations.
120// FIXME: If we made functions typeless then there would be no need to do this.
121void simplifyExternals(Module &M) {
122 FunctionType *EmptyFT =
123 FunctionType::get(Type::getVoidTy(M.getContext()), false);
124
125 for (auto I = M.begin(), E = M.end(); I != E;) {
126 Function &F = *I++;
127 if (F.isDeclaration() && F.use_empty()) {
128 F.eraseFromParent();
129 continue;
130 }
131
132 if (!F.isDeclaration() || F.getFunctionType() == EmptyFT)
133 continue;
134
135 Function *NewF =
136 Function::Create(EmptyFT, GlobalValue::ExternalLinkage, "", &M);
137 NewF->setVisibility(F.getVisibility());
138 NewF->takeName(&F);
139 F.replaceAllUsesWith(ConstantExpr::getBitCast(NewF, F.getType()));
140 F.eraseFromParent();
141 }
142
143 for (auto I = M.global_begin(), E = M.global_end(); I != E;) {
144 GlobalVariable &GV = *I++;
145 if (GV.isDeclaration() && GV.use_empty()) {
146 GV.eraseFromParent();
147 continue;
148 }
149 }
150}
151
152void filterModule(
Benjamin Kramer061f4a52017-01-13 14:39:03 +0000153 Module *M, function_ref<bool(const GlobalValue *)> ShouldKeepDefinition) {
Bob Haarman6de81342017-04-05 00:42:07 +0000154 for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end();
155 I != E;) {
156 GlobalAlias *GA = &*I++;
157 if (ShouldKeepDefinition(GA))
158 continue;
159
160 GlobalObject *GO;
161 if (GA->getValueType()->isFunctionTy())
162 GO = Function::Create(cast<FunctionType>(GA->getValueType()),
163 GlobalValue::ExternalLinkage, "", M);
164 else
165 GO = new GlobalVariable(
166 *M, GA->getValueType(), false, GlobalValue::ExternalLinkage,
167 (Constant *)nullptr, "", (GlobalVariable *)nullptr,
168 GA->getThreadLocalMode(), GA->getType()->getAddressSpace());
169 GO->takeName(GA);
170 GA->replaceAllUsesWith(GO);
171 GA->eraseFromParent();
172 }
173
Peter Collingbourne1398a322016-12-16 00:26:30 +0000174 for (Function &F : *M) {
175 if (ShouldKeepDefinition(&F))
176 continue;
177
178 F.deleteBody();
Peter Collingbourne20a00932017-01-18 20:03:02 +0000179 F.setComdat(nullptr);
Peter Collingbourne1398a322016-12-16 00:26:30 +0000180 F.clearMetadata();
181 }
182
183 for (GlobalVariable &GV : M->globals()) {
184 if (ShouldKeepDefinition(&GV))
185 continue;
186
187 GV.setInitializer(nullptr);
188 GV.setLinkage(GlobalValue::ExternalLinkage);
Peter Collingbourne20a00932017-01-18 20:03:02 +0000189 GV.setComdat(nullptr);
Peter Collingbourne1398a322016-12-16 00:26:30 +0000190 GV.clearMetadata();
191 }
Peter Collingbourne1398a322016-12-16 00:26:30 +0000192}
193
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000194void forEachVirtualFunction(Constant *C, function_ref<void(Function *)> Fn) {
195 if (auto *F = dyn_cast<Function>(C))
196 return Fn(F);
Peter Collingbourne3baa72a2017-03-02 23:10:17 +0000197 if (isa<GlobalValue>(C))
198 return;
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000199 for (Value *Op : C->operands())
200 forEachVirtualFunction(cast<Constant>(Op), Fn);
201}
202
Peter Collingbourne1398a322016-12-16 00:26:30 +0000203// If it's possible to split M into regular and thin LTO parts, do so and write
204// a multi-module bitcode file with the two parts to OS. Otherwise, write only a
205// regular LTO bitcode file to OS.
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000206void splitAndWriteThinLTOBitcode(
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000207 raw_ostream &OS, raw_ostream *ThinLinkOS,
208 function_ref<AAResults &(Function &)> AARGetter, Module &M) {
Evgeniy Stepanov6c3a8cb2017-04-06 19:55:17 +0000209 std::string ModuleId = getUniqueModuleId(&M);
Peter Collingbourne1398a322016-12-16 00:26:30 +0000210 if (ModuleId.empty()) {
211 // We couldn't generate a module ID for this module, just write it out as a
212 // regular LTO module.
213 WriteBitcodeToFile(&M, OS);
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000214 if (ThinLinkOS)
215 // We don't have a ThinLTO part, but still write the module to the
216 // ThinLinkOS if requested so that the expected output file is produced.
217 WriteBitcodeToFile(&M, *ThinLinkOS);
Peter Collingbourne1398a322016-12-16 00:26:30 +0000218 return;
219 }
220
221 promoteTypeIds(M, ModuleId);
222
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000223 // Returns whether a global has attached type metadata. Such globals may
224 // participate in CFI or whole-program devirtualization, so they need to
225 // appear in the merged module instead of the thin LTO module.
226 auto HasTypeMetadata = [&](const GlobalObject *GO) {
Peter Collingbourne1398a322016-12-16 00:26:30 +0000227 SmallVector<MDNode *, 1> MDs;
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000228 GO->getMetadata(LLVMContext::MD_type, MDs);
Peter Collingbourne1398a322016-12-16 00:26:30 +0000229 return !MDs.empty();
230 };
231
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000232 // Collect the set of virtual functions that are eligible for virtual constant
233 // propagation. Each eligible function must not access memory, must return
234 // an integer of width <=64 bits, must take at least one argument, must not
235 // use its first argument (assumed to be "this") and all arguments other than
236 // the first one must be of <=64 bit integer type.
237 //
238 // Note that we test whether this copy of the function is readnone, rather
239 // than testing function attributes, which must hold for any copy of the
240 // function, even a less optimized version substituted at link time. This is
241 // sound because the virtual constant propagation optimizations effectively
242 // inline all implementations of the virtual function into each call site,
243 // rather than using function attributes to perform local optimization.
244 std::set<const Function *> EligibleVirtualFns;
245 for (GlobalVariable &GV : M.globals())
246 if (HasTypeMetadata(&GV))
247 forEachVirtualFunction(GV.getInitializer(), [&](Function *F) {
248 auto *RT = dyn_cast<IntegerType>(F->getReturnType());
249 if (!RT || RT->getBitWidth() > 64 || F->arg_empty() ||
250 !F->arg_begin()->use_empty())
251 return;
252 for (auto &Arg : make_range(std::next(F->arg_begin()), F->arg_end())) {
253 auto *ArgT = dyn_cast<IntegerType>(Arg.getType());
254 if (!ArgT || ArgT->getBitWidth() > 64)
255 return;
256 }
257 if (computeFunctionBodyMemoryAccess(*F, AARGetter(*F)) == MAK_ReadNone)
258 EligibleVirtualFns.insert(F);
259 });
260
Peter Collingbourne1398a322016-12-16 00:26:30 +0000261 ValueToValueMapTy VMap;
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000262 std::unique_ptr<Module> MergedM(
263 CloneModule(&M, VMap, [&](const GlobalValue *GV) -> bool {
264 if (auto *F = dyn_cast<Function>(GV))
265 return EligibleVirtualFns.count(F);
266 if (auto *GVar = dyn_cast_or_null<GlobalVariable>(GV->getBaseObject()))
267 return HasTypeMetadata(GVar);
268 return false;
269 }));
Peter Collingbourne28ffd322017-02-08 20:44:00 +0000270 StripDebugInfo(*MergedM);
Peter Collingbourne1398a322016-12-16 00:26:30 +0000271
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000272 for (Function &F : *MergedM)
273 if (!F.isDeclaration()) {
274 // Reset the linkage of all functions eligible for virtual constant
275 // propagation. The canonical definitions live in the thin LTO module so
276 // that they can be imported.
277 F.setLinkage(GlobalValue::AvailableExternallyLinkage);
278 F.setComdat(nullptr);
279 }
280
281 // Remove all globals with type metadata, as well as aliases pointing to them,
282 // from the thin LTO module.
283 filterModule(&M, [&](const GlobalValue *GV) {
284 if (auto *GVar = dyn_cast_or_null<GlobalVariable>(GV->getBaseObject()))
285 return !HasTypeMetadata(GVar);
286 return true;
287 });
Peter Collingbourne1398a322016-12-16 00:26:30 +0000288
289 promoteInternals(*MergedM, M, ModuleId);
290 promoteInternals(M, *MergedM, ModuleId);
291
292 simplifyExternals(*MergedM);
293
Peter Collingbourne1398a322016-12-16 00:26:30 +0000294
295 // FIXME: Try to re-use BSI and PFI from the original module here.
296 ModuleSummaryIndex Index = buildModuleSummaryIndex(M, nullptr, nullptr);
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000297
298 SmallVector<char, 0> Buffer;
299
300 BitcodeWriter W(Buffer);
301 // Save the module hash produced for the full bitcode, which will
302 // be used in the backends, and use that in the minimized bitcode
303 // produced for the full link.
304 ModuleHash ModHash = {{0}};
Peter Collingbourne1398a322016-12-16 00:26:30 +0000305 W.writeModule(&M, /*ShouldPreserveUseListOrder=*/false, &Index,
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000306 /*GenerateHash=*/true, &ModHash);
Peter Collingbourne1398a322016-12-16 00:26:30 +0000307 W.writeModule(MergedM.get());
Peter Collingbourne1398a322016-12-16 00:26:30 +0000308 OS << Buffer;
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000309
310 // If a minimized bitcode module was requested for the thin link,
311 // strip the debug info (the merged module was already stripped above)
312 // and write it to the given OS.
313 if (ThinLinkOS) {
314 Buffer.clear();
315 BitcodeWriter W2(Buffer);
316 StripDebugInfo(M);
317 W2.writeModule(&M, /*ShouldPreserveUseListOrder=*/false, &Index,
318 /*GenerateHash=*/false, &ModHash);
319 W2.writeModule(MergedM.get());
320 *ThinLinkOS << Buffer;
321 }
Peter Collingbourne1398a322016-12-16 00:26:30 +0000322}
323
324// Returns whether this module needs to be split because it uses type metadata.
325bool requiresSplit(Module &M) {
326 SmallVector<MDNode *, 1> MDs;
327 for (auto &GO : M.global_objects()) {
328 GO.getMetadata(LLVMContext::MD_type, MDs);
329 if (!MDs.empty())
330 return true;
331 }
332
333 return false;
334}
335
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000336void writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS,
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000337 function_ref<AAResults &(Function &)> AARGetter,
338 Module &M, const ModuleSummaryIndex *Index) {
Peter Collingbourne1398a322016-12-16 00:26:30 +0000339 // See if this module has any type metadata. If so, we need to split it.
340 if (requiresSplit(M))
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000341 return splitAndWriteThinLTOBitcode(OS, ThinLinkOS, AARGetter, M);
Peter Collingbourne1398a322016-12-16 00:26:30 +0000342
343 // Otherwise we can just write it out as a regular module.
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000344
345 // Save the module hash produced for the full bitcode, which will
346 // be used in the backends, and use that in the minimized bitcode
347 // produced for the full link.
348 ModuleHash ModHash = {{0}};
Peter Collingbourne1398a322016-12-16 00:26:30 +0000349 WriteBitcodeToFile(&M, OS, /*ShouldPreserveUseListOrder=*/false, Index,
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000350 /*GenerateHash=*/true, &ModHash);
351 // If a minimized bitcode module was requested for the thin link,
352 // strip the debug info and write it to the given OS.
353 if (ThinLinkOS) {
354 StripDebugInfo(M);
355 WriteBitcodeToFile(&M, *ThinLinkOS, /*ShouldPreserveUseListOrder=*/false,
356 Index,
357 /*GenerateHash=*/false, &ModHash);
358 }
Peter Collingbourne1398a322016-12-16 00:26:30 +0000359}
360
361class WriteThinLTOBitcode : public ModulePass {
362 raw_ostream &OS; // raw_ostream to print on
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000363 // The output stream on which to emit a minimized module for use
364 // just in the thin link, if requested.
365 raw_ostream *ThinLinkOS;
Peter Collingbourne1398a322016-12-16 00:26:30 +0000366
367public:
368 static char ID; // Pass identification, replacement for typeid
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000369 WriteThinLTOBitcode() : ModulePass(ID), OS(dbgs()), ThinLinkOS(nullptr) {
Peter Collingbourne1398a322016-12-16 00:26:30 +0000370 initializeWriteThinLTOBitcodePass(*PassRegistry::getPassRegistry());
371 }
372
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000373 explicit WriteThinLTOBitcode(raw_ostream &o, raw_ostream *ThinLinkOS)
374 : ModulePass(ID), OS(o), ThinLinkOS(ThinLinkOS) {
Peter Collingbourne1398a322016-12-16 00:26:30 +0000375 initializeWriteThinLTOBitcodePass(*PassRegistry::getPassRegistry());
376 }
377
378 StringRef getPassName() const override { return "ThinLTO Bitcode Writer"; }
379
380 bool runOnModule(Module &M) override {
381 const ModuleSummaryIndex *Index =
382 &(getAnalysis<ModuleSummaryIndexWrapperPass>().getIndex());
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000383 writeThinLTOBitcode(OS, ThinLinkOS, LegacyAARGetter(*this), M, Index);
Peter Collingbourne1398a322016-12-16 00:26:30 +0000384 return true;
385 }
386 void getAnalysisUsage(AnalysisUsage &AU) const override {
387 AU.setPreservesAll();
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000388 AU.addRequired<AssumptionCacheTracker>();
Peter Collingbourne1398a322016-12-16 00:26:30 +0000389 AU.addRequired<ModuleSummaryIndexWrapperPass>();
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000390 AU.addRequired<TargetLibraryInfoWrapperPass>();
Peter Collingbourne1398a322016-12-16 00:26:30 +0000391 }
392};
393} // anonymous namespace
394
395char WriteThinLTOBitcode::ID = 0;
396INITIALIZE_PASS_BEGIN(WriteThinLTOBitcode, "write-thinlto-bitcode",
397 "Write ThinLTO Bitcode", false, true)
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000398INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
Peter Collingbourne1398a322016-12-16 00:26:30 +0000399INITIALIZE_PASS_DEPENDENCY(ModuleSummaryIndexWrapperPass)
Peter Collingbourne002c2d52017-02-14 03:42:38 +0000400INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Peter Collingbourne1398a322016-12-16 00:26:30 +0000401INITIALIZE_PASS_END(WriteThinLTOBitcode, "write-thinlto-bitcode",
402 "Write ThinLTO Bitcode", false, true)
403
Teresa Johnson0c6a4ff2017-03-23 19:47:39 +0000404ModulePass *llvm::createWriteThinLTOBitcodePass(raw_ostream &Str,
405 raw_ostream *ThinLinkOS) {
406 return new WriteThinLTOBitcode(Str, ThinLinkOS);
Peter Collingbourne1398a322016-12-16 00:26:30 +0000407}