Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
35266 views
1
//===- ThinLTOBitcodeWriter.cpp - Bitcode writing pass for ThinLTO --------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
10
#include "llvm/Analysis/BasicAliasAnalysis.h"
11
#include "llvm/Analysis/ModuleSummaryAnalysis.h"
12
#include "llvm/Analysis/ProfileSummaryInfo.h"
13
#include "llvm/Analysis/TypeMetadataUtils.h"
14
#include "llvm/Bitcode/BitcodeWriter.h"
15
#include "llvm/IR/Constants.h"
16
#include "llvm/IR/DebugInfo.h"
17
#include "llvm/IR/Instructions.h"
18
#include "llvm/IR/Intrinsics.h"
19
#include "llvm/IR/Module.h"
20
#include "llvm/IR/PassManager.h"
21
#include "llvm/Object/ModuleSymbolTable.h"
22
#include "llvm/Support/raw_ostream.h"
23
#include "llvm/Transforms/IPO.h"
24
#include "llvm/Transforms/IPO/FunctionAttrs.h"
25
#include "llvm/Transforms/IPO/FunctionImport.h"
26
#include "llvm/Transforms/IPO/LowerTypeTests.h"
27
#include "llvm/Transforms/Utils/Cloning.h"
28
#include "llvm/Transforms/Utils/ModuleUtils.h"
29
using namespace llvm;
30
31
namespace {
32
33
// Determine if a promotion alias should be created for a symbol name.
34
static bool allowPromotionAlias(const std::string &Name) {
35
// Promotion aliases are used only in inline assembly. It's safe to
36
// simply skip unusual names. Subset of MCAsmInfo::isAcceptableChar()
37
// and MCAsmInfoXCOFF::isAcceptableChar().
38
for (const char &C : Name) {
39
if (isAlnum(C) || C == '_' || C == '.')
40
continue;
41
return false;
42
}
43
return true;
44
}
45
46
// Promote each local-linkage entity defined by ExportM and used by ImportM by
47
// changing visibility and appending the given ModuleId.
48
void promoteInternals(Module &ExportM, Module &ImportM, StringRef ModuleId,
49
SetVector<GlobalValue *> &PromoteExtra) {
50
DenseMap<const Comdat *, Comdat *> RenamedComdats;
51
for (auto &ExportGV : ExportM.global_values()) {
52
if (!ExportGV.hasLocalLinkage())
53
continue;
54
55
auto Name = ExportGV.getName();
56
GlobalValue *ImportGV = nullptr;
57
if (!PromoteExtra.count(&ExportGV)) {
58
ImportGV = ImportM.getNamedValue(Name);
59
if (!ImportGV)
60
continue;
61
ImportGV->removeDeadConstantUsers();
62
if (ImportGV->use_empty()) {
63
ImportGV->eraseFromParent();
64
continue;
65
}
66
}
67
68
std::string OldName = Name.str();
69
std::string NewName = (Name + ModuleId).str();
70
71
if (const auto *C = ExportGV.getComdat())
72
if (C->getName() == Name)
73
RenamedComdats.try_emplace(C, ExportM.getOrInsertComdat(NewName));
74
75
ExportGV.setName(NewName);
76
ExportGV.setLinkage(GlobalValue::ExternalLinkage);
77
ExportGV.setVisibility(GlobalValue::HiddenVisibility);
78
79
if (ImportGV) {
80
ImportGV->setName(NewName);
81
ImportGV->setVisibility(GlobalValue::HiddenVisibility);
82
}
83
84
if (isa<Function>(&ExportGV) && allowPromotionAlias(OldName)) {
85
// Create a local alias with the original name to avoid breaking
86
// references from inline assembly.
87
std::string Alias =
88
".lto_set_conditional " + OldName + "," + NewName + "\n";
89
ExportM.appendModuleInlineAsm(Alias);
90
}
91
}
92
93
if (!RenamedComdats.empty())
94
for (auto &GO : ExportM.global_objects())
95
if (auto *C = GO.getComdat()) {
96
auto Replacement = RenamedComdats.find(C);
97
if (Replacement != RenamedComdats.end())
98
GO.setComdat(Replacement->second);
99
}
100
}
101
102
// Promote all internal (i.e. distinct) type ids used by the module by replacing
103
// them with external type ids formed using the module id.
104
//
105
// Note that this needs to be done before we clone the module because each clone
106
// will receive its own set of distinct metadata nodes.
107
void promoteTypeIds(Module &M, StringRef ModuleId) {
108
DenseMap<Metadata *, Metadata *> LocalToGlobal;
109
auto ExternalizeTypeId = [&](CallInst *CI, unsigned ArgNo) {
110
Metadata *MD =
111
cast<MetadataAsValue>(CI->getArgOperand(ArgNo))->getMetadata();
112
113
if (isa<MDNode>(MD) && cast<MDNode>(MD)->isDistinct()) {
114
Metadata *&GlobalMD = LocalToGlobal[MD];
115
if (!GlobalMD) {
116
std::string NewName = (Twine(LocalToGlobal.size()) + ModuleId).str();
117
GlobalMD = MDString::get(M.getContext(), NewName);
118
}
119
120
CI->setArgOperand(ArgNo,
121
MetadataAsValue::get(M.getContext(), GlobalMD));
122
}
123
};
124
125
if (Function *TypeTestFunc =
126
M.getFunction(Intrinsic::getName(Intrinsic::type_test))) {
127
for (const Use &U : TypeTestFunc->uses()) {
128
auto CI = cast<CallInst>(U.getUser());
129
ExternalizeTypeId(CI, 1);
130
}
131
}
132
133
if (Function *PublicTypeTestFunc =
134
M.getFunction(Intrinsic::getName(Intrinsic::public_type_test))) {
135
for (const Use &U : PublicTypeTestFunc->uses()) {
136
auto CI = cast<CallInst>(U.getUser());
137
ExternalizeTypeId(CI, 1);
138
}
139
}
140
141
if (Function *TypeCheckedLoadFunc =
142
M.getFunction(Intrinsic::getName(Intrinsic::type_checked_load))) {
143
for (const Use &U : TypeCheckedLoadFunc->uses()) {
144
auto CI = cast<CallInst>(U.getUser());
145
ExternalizeTypeId(CI, 2);
146
}
147
}
148
149
if (Function *TypeCheckedLoadRelativeFunc = M.getFunction(
150
Intrinsic::getName(Intrinsic::type_checked_load_relative))) {
151
for (const Use &U : TypeCheckedLoadRelativeFunc->uses()) {
152
auto CI = cast<CallInst>(U.getUser());
153
ExternalizeTypeId(CI, 2);
154
}
155
}
156
157
for (GlobalObject &GO : M.global_objects()) {
158
SmallVector<MDNode *, 1> MDs;
159
GO.getMetadata(LLVMContext::MD_type, MDs);
160
161
GO.eraseMetadata(LLVMContext::MD_type);
162
for (auto *MD : MDs) {
163
auto I = LocalToGlobal.find(MD->getOperand(1));
164
if (I == LocalToGlobal.end()) {
165
GO.addMetadata(LLVMContext::MD_type, *MD);
166
continue;
167
}
168
GO.addMetadata(
169
LLVMContext::MD_type,
170
*MDNode::get(M.getContext(), {MD->getOperand(0), I->second}));
171
}
172
}
173
}
174
175
// Drop unused globals, and drop type information from function declarations.
176
// FIXME: If we made functions typeless then there would be no need to do this.
177
void simplifyExternals(Module &M) {
178
FunctionType *EmptyFT =
179
FunctionType::get(Type::getVoidTy(M.getContext()), false);
180
181
for (Function &F : llvm::make_early_inc_range(M)) {
182
if (F.isDeclaration() && F.use_empty()) {
183
F.eraseFromParent();
184
continue;
185
}
186
187
if (!F.isDeclaration() || F.getFunctionType() == EmptyFT ||
188
// Changing the type of an intrinsic may invalidate the IR.
189
F.getName().starts_with("llvm."))
190
continue;
191
192
Function *NewF =
193
Function::Create(EmptyFT, GlobalValue::ExternalLinkage,
194
F.getAddressSpace(), "", &M);
195
NewF->copyAttributesFrom(&F);
196
// Only copy function attribtues.
197
NewF->setAttributes(AttributeList::get(M.getContext(),
198
AttributeList::FunctionIndex,
199
F.getAttributes().getFnAttrs()));
200
NewF->takeName(&F);
201
F.replaceAllUsesWith(NewF);
202
F.eraseFromParent();
203
}
204
205
for (GlobalIFunc &I : llvm::make_early_inc_range(M.ifuncs())) {
206
if (I.use_empty())
207
I.eraseFromParent();
208
else
209
assert(I.getResolverFunction() && "ifunc misses its resolver function");
210
}
211
212
for (GlobalVariable &GV : llvm::make_early_inc_range(M.globals())) {
213
if (GV.isDeclaration() && GV.use_empty()) {
214
GV.eraseFromParent();
215
continue;
216
}
217
}
218
}
219
220
static void
221
filterModule(Module *M,
222
function_ref<bool(const GlobalValue *)> ShouldKeepDefinition) {
223
std::vector<GlobalValue *> V;
224
for (GlobalValue &GV : M->global_values())
225
if (!ShouldKeepDefinition(&GV))
226
V.push_back(&GV);
227
228
for (GlobalValue *GV : V)
229
if (!convertToDeclaration(*GV))
230
GV->eraseFromParent();
231
}
232
233
void forEachVirtualFunction(Constant *C, function_ref<void(Function *)> Fn) {
234
if (auto *F = dyn_cast<Function>(C))
235
return Fn(F);
236
if (isa<GlobalValue>(C))
237
return;
238
for (Value *Op : C->operands())
239
forEachVirtualFunction(cast<Constant>(Op), Fn);
240
}
241
242
// Clone any @llvm[.compiler].used over to the new module and append
243
// values whose defs were cloned into that module.
244
static void cloneUsedGlobalVariables(const Module &SrcM, Module &DestM,
245
bool CompilerUsed) {
246
SmallVector<GlobalValue *, 4> Used, NewUsed;
247
// First collect those in the llvm[.compiler].used set.
248
collectUsedGlobalVariables(SrcM, Used, CompilerUsed);
249
// Next build a set of the equivalent values defined in DestM.
250
for (auto *V : Used) {
251
auto *GV = DestM.getNamedValue(V->getName());
252
if (GV && !GV->isDeclaration())
253
NewUsed.push_back(GV);
254
}
255
// Finally, add them to a llvm[.compiler].used variable in DestM.
256
if (CompilerUsed)
257
appendToCompilerUsed(DestM, NewUsed);
258
else
259
appendToUsed(DestM, NewUsed);
260
}
261
262
#ifndef NDEBUG
263
static bool enableUnifiedLTO(Module &M) {
264
bool UnifiedLTO = false;
265
if (auto *MD =
266
mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("UnifiedLTO")))
267
UnifiedLTO = MD->getZExtValue();
268
return UnifiedLTO;
269
}
270
#endif
271
272
// If it's possible to split M into regular and thin LTO parts, do so and write
273
// a multi-module bitcode file with the two parts to OS. Otherwise, write only a
274
// regular LTO bitcode file to OS.
275
void splitAndWriteThinLTOBitcode(
276
raw_ostream &OS, raw_ostream *ThinLinkOS,
277
function_ref<AAResults &(Function &)> AARGetter, Module &M) {
278
std::string ModuleId = getUniqueModuleId(&M);
279
if (ModuleId.empty()) {
280
assert(!enableUnifiedLTO(M));
281
// We couldn't generate a module ID for this module, write it out as a
282
// regular LTO module with an index for summary-based dead stripping.
283
ProfileSummaryInfo PSI(M);
284
M.addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
285
ModuleSummaryIndex Index = buildModuleSummaryIndex(M, nullptr, &PSI);
286
WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false, &Index,
287
/*UnifiedLTO=*/false);
288
289
if (ThinLinkOS)
290
// We don't have a ThinLTO part, but still write the module to the
291
// ThinLinkOS if requested so that the expected output file is produced.
292
WriteBitcodeToFile(M, *ThinLinkOS, /*ShouldPreserveUseListOrder=*/false,
293
&Index, /*UnifiedLTO=*/false);
294
295
return;
296
}
297
298
promoteTypeIds(M, ModuleId);
299
300
// Returns whether a global or its associated global has attached type
301
// metadata. The former may participate in CFI or whole-program
302
// devirtualization, so they need to appear in the merged module instead of
303
// the thin LTO module. Similarly, globals that are associated with globals
304
// with type metadata need to appear in the merged module because they will
305
// reference the global's section directly.
306
auto HasTypeMetadata = [](const GlobalObject *GO) {
307
if (MDNode *MD = GO->getMetadata(LLVMContext::MD_associated))
308
if (auto *AssocVM = dyn_cast_or_null<ValueAsMetadata>(MD->getOperand(0)))
309
if (auto *AssocGO = dyn_cast<GlobalObject>(AssocVM->getValue()))
310
if (AssocGO->hasMetadata(LLVMContext::MD_type))
311
return true;
312
return GO->hasMetadata(LLVMContext::MD_type);
313
};
314
315
// Collect the set of virtual functions that are eligible for virtual constant
316
// propagation. Each eligible function must not access memory, must return
317
// an integer of width <=64 bits, must take at least one argument, must not
318
// use its first argument (assumed to be "this") and all arguments other than
319
// the first one must be of <=64 bit integer type.
320
//
321
// Note that we test whether this copy of the function is readnone, rather
322
// than testing function attributes, which must hold for any copy of the
323
// function, even a less optimized version substituted at link time. This is
324
// sound because the virtual constant propagation optimizations effectively
325
// inline all implementations of the virtual function into each call site,
326
// rather than using function attributes to perform local optimization.
327
DenseSet<const Function *> EligibleVirtualFns;
328
// If any member of a comdat lives in MergedM, put all members of that
329
// comdat in MergedM to keep the comdat together.
330
DenseSet<const Comdat *> MergedMComdats;
331
for (GlobalVariable &GV : M.globals())
332
if (!GV.isDeclaration() && HasTypeMetadata(&GV)) {
333
if (const auto *C = GV.getComdat())
334
MergedMComdats.insert(C);
335
forEachVirtualFunction(GV.getInitializer(), [&](Function *F) {
336
auto *RT = dyn_cast<IntegerType>(F->getReturnType());
337
if (!RT || RT->getBitWidth() > 64 || F->arg_empty() ||
338
!F->arg_begin()->use_empty())
339
return;
340
for (auto &Arg : drop_begin(F->args())) {
341
auto *ArgT = dyn_cast<IntegerType>(Arg.getType());
342
if (!ArgT || ArgT->getBitWidth() > 64)
343
return;
344
}
345
if (!F->isDeclaration() &&
346
computeFunctionBodyMemoryAccess(*F, AARGetter(*F))
347
.doesNotAccessMemory())
348
EligibleVirtualFns.insert(F);
349
});
350
}
351
352
ValueToValueMapTy VMap;
353
std::unique_ptr<Module> MergedM(
354
CloneModule(M, VMap, [&](const GlobalValue *GV) -> bool {
355
if (const auto *C = GV->getComdat())
356
if (MergedMComdats.count(C))
357
return true;
358
if (auto *F = dyn_cast<Function>(GV))
359
return EligibleVirtualFns.count(F);
360
if (auto *GVar =
361
dyn_cast_or_null<GlobalVariable>(GV->getAliaseeObject()))
362
return HasTypeMetadata(GVar);
363
return false;
364
}));
365
StripDebugInfo(*MergedM);
366
MergedM->setModuleInlineAsm("");
367
368
// Clone any llvm.*used globals to ensure the included values are
369
// not deleted.
370
cloneUsedGlobalVariables(M, *MergedM, /*CompilerUsed*/ false);
371
cloneUsedGlobalVariables(M, *MergedM, /*CompilerUsed*/ true);
372
373
for (Function &F : *MergedM)
374
if (!F.isDeclaration()) {
375
// Reset the linkage of all functions eligible for virtual constant
376
// propagation. The canonical definitions live in the thin LTO module so
377
// that they can be imported.
378
F.setLinkage(GlobalValue::AvailableExternallyLinkage);
379
F.setComdat(nullptr);
380
}
381
382
SetVector<GlobalValue *> CfiFunctions;
383
for (auto &F : M)
384
if ((!F.hasLocalLinkage() || F.hasAddressTaken()) && HasTypeMetadata(&F))
385
CfiFunctions.insert(&F);
386
387
// Remove all globals with type metadata, globals with comdats that live in
388
// MergedM, and aliases pointing to such globals from the thin LTO module.
389
filterModule(&M, [&](const GlobalValue *GV) {
390
if (auto *GVar = dyn_cast_or_null<GlobalVariable>(GV->getAliaseeObject()))
391
if (HasTypeMetadata(GVar))
392
return false;
393
if (const auto *C = GV->getComdat())
394
if (MergedMComdats.count(C))
395
return false;
396
return true;
397
});
398
399
promoteInternals(*MergedM, M, ModuleId, CfiFunctions);
400
promoteInternals(M, *MergedM, ModuleId, CfiFunctions);
401
402
auto &Ctx = MergedM->getContext();
403
SmallVector<MDNode *, 8> CfiFunctionMDs;
404
for (auto *V : CfiFunctions) {
405
Function &F = *cast<Function>(V);
406
SmallVector<MDNode *, 2> Types;
407
F.getMetadata(LLVMContext::MD_type, Types);
408
409
SmallVector<Metadata *, 4> Elts;
410
Elts.push_back(MDString::get(Ctx, F.getName()));
411
CfiFunctionLinkage Linkage;
412
if (lowertypetests::isJumpTableCanonical(&F))
413
Linkage = CFL_Definition;
414
else if (F.hasExternalWeakLinkage())
415
Linkage = CFL_WeakDeclaration;
416
else
417
Linkage = CFL_Declaration;
418
Elts.push_back(ConstantAsMetadata::get(
419
llvm::ConstantInt::get(Type::getInt8Ty(Ctx), Linkage)));
420
append_range(Elts, Types);
421
CfiFunctionMDs.push_back(MDTuple::get(Ctx, Elts));
422
}
423
424
if(!CfiFunctionMDs.empty()) {
425
NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("cfi.functions");
426
for (auto *MD : CfiFunctionMDs)
427
NMD->addOperand(MD);
428
}
429
430
SmallVector<MDNode *, 8> FunctionAliases;
431
for (auto &A : M.aliases()) {
432
if (!isa<Function>(A.getAliasee()))
433
continue;
434
435
auto *F = cast<Function>(A.getAliasee());
436
437
Metadata *Elts[] = {
438
MDString::get(Ctx, A.getName()),
439
MDString::get(Ctx, F->getName()),
440
ConstantAsMetadata::get(
441
ConstantInt::get(Type::getInt8Ty(Ctx), A.getVisibility())),
442
ConstantAsMetadata::get(
443
ConstantInt::get(Type::getInt8Ty(Ctx), A.isWeakForLinker())),
444
};
445
446
FunctionAliases.push_back(MDTuple::get(Ctx, Elts));
447
}
448
449
if (!FunctionAliases.empty()) {
450
NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("aliases");
451
for (auto *MD : FunctionAliases)
452
NMD->addOperand(MD);
453
}
454
455
SmallVector<MDNode *, 8> Symvers;
456
ModuleSymbolTable::CollectAsmSymvers(M, [&](StringRef Name, StringRef Alias) {
457
Function *F = M.getFunction(Name);
458
if (!F || F->use_empty())
459
return;
460
461
Symvers.push_back(MDTuple::get(
462
Ctx, {MDString::get(Ctx, Name), MDString::get(Ctx, Alias)}));
463
});
464
465
if (!Symvers.empty()) {
466
NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("symvers");
467
for (auto *MD : Symvers)
468
NMD->addOperand(MD);
469
}
470
471
simplifyExternals(*MergedM);
472
473
// FIXME: Try to re-use BSI and PFI from the original module here.
474
ProfileSummaryInfo PSI(M);
475
ModuleSummaryIndex Index = buildModuleSummaryIndex(M, nullptr, &PSI);
476
477
// Mark the merged module as requiring full LTO. We still want an index for
478
// it though, so that it can participate in summary-based dead stripping.
479
MergedM->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
480
ModuleSummaryIndex MergedMIndex =
481
buildModuleSummaryIndex(*MergedM, nullptr, &PSI);
482
483
SmallVector<char, 0> Buffer;
484
485
BitcodeWriter W(Buffer);
486
// Save the module hash produced for the full bitcode, which will
487
// be used in the backends, and use that in the minimized bitcode
488
// produced for the full link.
489
ModuleHash ModHash = {{0}};
490
W.writeModule(M, /*ShouldPreserveUseListOrder=*/false, &Index,
491
/*GenerateHash=*/true, &ModHash);
492
W.writeModule(*MergedM, /*ShouldPreserveUseListOrder=*/false, &MergedMIndex);
493
W.writeSymtab();
494
W.writeStrtab();
495
OS << Buffer;
496
497
// If a minimized bitcode module was requested for the thin link, only
498
// the information that is needed by thin link will be written in the
499
// given OS (the merged module will be written as usual).
500
if (ThinLinkOS) {
501
Buffer.clear();
502
BitcodeWriter W2(Buffer);
503
StripDebugInfo(M);
504
W2.writeThinLinkBitcode(M, Index, ModHash);
505
W2.writeModule(*MergedM, /*ShouldPreserveUseListOrder=*/false,
506
&MergedMIndex);
507
W2.writeSymtab();
508
W2.writeStrtab();
509
*ThinLinkOS << Buffer;
510
}
511
}
512
513
// Check if the LTO Unit splitting has been enabled.
514
bool enableSplitLTOUnit(Module &M) {
515
bool EnableSplitLTOUnit = false;
516
if (auto *MD = mdconst::extract_or_null<ConstantInt>(
517
M.getModuleFlag("EnableSplitLTOUnit")))
518
EnableSplitLTOUnit = MD->getZExtValue();
519
return EnableSplitLTOUnit;
520
}
521
522
// Returns whether this module needs to be split because it uses type metadata.
523
bool hasTypeMetadata(Module &M) {
524
for (auto &GO : M.global_objects()) {
525
if (GO.hasMetadata(LLVMContext::MD_type))
526
return true;
527
}
528
return false;
529
}
530
531
bool writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS,
532
function_ref<AAResults &(Function &)> AARGetter,
533
Module &M, const ModuleSummaryIndex *Index) {
534
std::unique_ptr<ModuleSummaryIndex> NewIndex = nullptr;
535
// See if this module has any type metadata. If so, we try to split it
536
// or at least promote type ids to enable WPD.
537
if (hasTypeMetadata(M)) {
538
if (enableSplitLTOUnit(M)) {
539
splitAndWriteThinLTOBitcode(OS, ThinLinkOS, AARGetter, M);
540
return true;
541
}
542
// Promote type ids as needed for index-based WPD.
543
std::string ModuleId = getUniqueModuleId(&M);
544
if (!ModuleId.empty()) {
545
promoteTypeIds(M, ModuleId);
546
// Need to rebuild the index so that it contains type metadata
547
// for the newly promoted type ids.
548
// FIXME: Probably should not bother building the index at all
549
// in the caller of writeThinLTOBitcode (which does so via the
550
// ModuleSummaryIndexAnalysis pass), since we have to rebuild it
551
// anyway whenever there is type metadata (here or in
552
// splitAndWriteThinLTOBitcode). Just always build it once via the
553
// buildModuleSummaryIndex when Module(s) are ready.
554
ProfileSummaryInfo PSI(M);
555
NewIndex = std::make_unique<ModuleSummaryIndex>(
556
buildModuleSummaryIndex(M, nullptr, &PSI));
557
Index = NewIndex.get();
558
}
559
}
560
561
// Write it out as an unsplit ThinLTO module.
562
563
// Save the module hash produced for the full bitcode, which will
564
// be used in the backends, and use that in the minimized bitcode
565
// produced for the full link.
566
ModuleHash ModHash = {{0}};
567
WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false, Index,
568
/*GenerateHash=*/true, &ModHash);
569
// If a minimized bitcode module was requested for the thin link, only
570
// the information that is needed by thin link will be written in the
571
// given OS.
572
if (ThinLinkOS && Index)
573
writeThinLinkBitcodeToFile(M, *ThinLinkOS, *Index, ModHash);
574
return false;
575
}
576
577
} // anonymous namespace
578
extern bool WriteNewDbgInfoFormatToBitcode;
579
PreservedAnalyses
580
llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
581
FunctionAnalysisManager &FAM =
582
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
583
584
ScopedDbgInfoFormatSetter FormatSetter(M, M.IsNewDbgInfoFormat &&
585
WriteNewDbgInfoFormatToBitcode);
586
if (M.IsNewDbgInfoFormat)
587
M.removeDebugIntrinsicDeclarations();
588
589
bool Changed = writeThinLTOBitcode(
590
OS, ThinLinkOS,
591
[&FAM](Function &F) -> AAResults & {
592
return FAM.getResult<AAManager>(F);
593
},
594
M, &AM.getResult<ModuleSummaryIndexAnalysis>(M));
595
596
return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
597
}
598
599