1 //===- ThinLTOBitcodeWriter.cpp - Bitcode writing pass for ThinLTO --------===//
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
7 //===----------------------------------------------------------------------===//
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/InitializePasses.h"
22 #include "llvm/Object/ModuleSymbolTable.h"
23 #include "llvm/Pass.h"
24 #include "llvm/Support/ScopedPrinter.h"
25 #include "llvm/Support/raw_ostream.h"
26 #include "llvm/Transforms/IPO.h"
27 #include "llvm/Transforms/IPO/FunctionAttrs.h"
28 #include "llvm/Transforms/IPO/FunctionImport.h"
29 #include "llvm/Transforms/IPO/LowerTypeTests.h"
30 #include "llvm/Transforms/Utils/Cloning.h"
31 #include "llvm/Transforms/Utils/ModuleUtils.h"
36 // Determine if a promotion alias should be created for a symbol name.
37 static bool allowPromotionAlias(const std::string
&Name
) {
38 // Promotion aliases are used only in inline assembly. It's safe to
39 // simply skip unusual names. Subset of MCAsmInfo::isAcceptableChar()
40 // and MCAsmInfoXCOFF::isAcceptableChar().
41 for (const char &C
: Name
) {
42 if (isAlnum(C
) || C
== '_' || C
== '.')
49 // Promote each local-linkage entity defined by ExportM and used by ImportM by
50 // changing visibility and appending the given ModuleId.
51 void promoteInternals(Module
&ExportM
, Module
&ImportM
, StringRef ModuleId
,
52 SetVector
<GlobalValue
*> &PromoteExtra
) {
53 DenseMap
<const Comdat
*, Comdat
*> RenamedComdats
;
54 for (auto &ExportGV
: ExportM
.global_values()) {
55 if (!ExportGV
.hasLocalLinkage())
58 auto Name
= ExportGV
.getName();
59 GlobalValue
*ImportGV
= nullptr;
60 if (!PromoteExtra
.count(&ExportGV
)) {
61 ImportGV
= ImportM
.getNamedValue(Name
);
64 ImportGV
->removeDeadConstantUsers();
65 if (ImportGV
->use_empty()) {
66 ImportGV
->eraseFromParent();
71 std::string OldName
= Name
.str();
72 std::string NewName
= (Name
+ ModuleId
).str();
74 if (const auto *C
= ExportGV
.getComdat())
75 if (C
->getName() == Name
)
76 RenamedComdats
.try_emplace(C
, ExportM
.getOrInsertComdat(NewName
));
78 ExportGV
.setName(NewName
);
79 ExportGV
.setLinkage(GlobalValue::ExternalLinkage
);
80 ExportGV
.setVisibility(GlobalValue::HiddenVisibility
);
83 ImportGV
->setName(NewName
);
84 ImportGV
->setVisibility(GlobalValue::HiddenVisibility
);
87 if (isa
<Function
>(&ExportGV
) && allowPromotionAlias(OldName
)) {
88 // Create a local alias with the original name to avoid breaking
89 // references from inline assembly.
90 std::string Alias
= ".set " + OldName
+ "," + NewName
+ "\n";
91 ExportM
.appendModuleInlineAsm(Alias
);
95 if (!RenamedComdats
.empty())
96 for (auto &GO
: ExportM
.global_objects())
97 if (auto *C
= GO
.getComdat()) {
98 auto Replacement
= RenamedComdats
.find(C
);
99 if (Replacement
!= RenamedComdats
.end())
100 GO
.setComdat(Replacement
->second
);
104 // Promote all internal (i.e. distinct) type ids used by the module by replacing
105 // them with external type ids formed using the module id.
107 // Note that this needs to be done before we clone the module because each clone
108 // will receive its own set of distinct metadata nodes.
109 void promoteTypeIds(Module
&M
, StringRef ModuleId
) {
110 DenseMap
<Metadata
*, Metadata
*> LocalToGlobal
;
111 auto ExternalizeTypeId
= [&](CallInst
*CI
, unsigned ArgNo
) {
113 cast
<MetadataAsValue
>(CI
->getArgOperand(ArgNo
))->getMetadata();
115 if (isa
<MDNode
>(MD
) && cast
<MDNode
>(MD
)->isDistinct()) {
116 Metadata
*&GlobalMD
= LocalToGlobal
[MD
];
118 std::string NewName
= (Twine(LocalToGlobal
.size()) + ModuleId
).str();
119 GlobalMD
= MDString::get(M
.getContext(), NewName
);
122 CI
->setArgOperand(ArgNo
,
123 MetadataAsValue::get(M
.getContext(), GlobalMD
));
127 if (Function
*TypeTestFunc
=
128 M
.getFunction(Intrinsic::getName(Intrinsic::type_test
))) {
129 for (const Use
&U
: TypeTestFunc
->uses()) {
130 auto CI
= cast
<CallInst
>(U
.getUser());
131 ExternalizeTypeId(CI
, 1);
135 if (Function
*TypeCheckedLoadFunc
=
136 M
.getFunction(Intrinsic::getName(Intrinsic::type_checked_load
))) {
137 for (const Use
&U
: TypeCheckedLoadFunc
->uses()) {
138 auto CI
= cast
<CallInst
>(U
.getUser());
139 ExternalizeTypeId(CI
, 2);
143 for (GlobalObject
&GO
: M
.global_objects()) {
144 SmallVector
<MDNode
*, 1> MDs
;
145 GO
.getMetadata(LLVMContext::MD_type
, MDs
);
147 GO
.eraseMetadata(LLVMContext::MD_type
);
148 for (auto MD
: MDs
) {
149 auto I
= LocalToGlobal
.find(MD
->getOperand(1));
150 if (I
== LocalToGlobal
.end()) {
151 GO
.addMetadata(LLVMContext::MD_type
, *MD
);
155 LLVMContext::MD_type
,
156 *MDNode::get(M
.getContext(), {MD
->getOperand(0), I
->second
}));
161 // Drop unused globals, and drop type information from function declarations.
162 // FIXME: If we made functions typeless then there would be no need to do this.
163 void simplifyExternals(Module
&M
) {
164 FunctionType
*EmptyFT
=
165 FunctionType::get(Type::getVoidTy(M
.getContext()), false);
167 for (auto I
= M
.begin(), E
= M
.end(); I
!= E
;) {
169 if (F
.isDeclaration() && F
.use_empty()) {
174 if (!F
.isDeclaration() || F
.getFunctionType() == EmptyFT
||
175 // Changing the type of an intrinsic may invalidate the IR.
176 F
.getName().startswith("llvm."))
180 Function::Create(EmptyFT
, GlobalValue::ExternalLinkage
,
181 F
.getAddressSpace(), "", &M
);
182 NewF
->copyAttributesFrom(&F
);
183 // Only copy function attribtues.
184 NewF
->setAttributes(AttributeList::get(M
.getContext(),
185 AttributeList::FunctionIndex
,
186 F
.getAttributes().getFnAttrs()));
188 F
.replaceAllUsesWith(ConstantExpr::getBitCast(NewF
, F
.getType()));
192 for (auto I
= M
.global_begin(), E
= M
.global_end(); I
!= E
;) {
193 GlobalVariable
&GV
= *I
++;
194 if (GV
.isDeclaration() && GV
.use_empty()) {
195 GV
.eraseFromParent();
202 filterModule(Module
*M
,
203 function_ref
<bool(const GlobalValue
*)> ShouldKeepDefinition
) {
204 std::vector
<GlobalValue
*> V
;
205 for (GlobalValue
&GV
: M
->global_values())
206 if (!ShouldKeepDefinition(&GV
))
209 for (GlobalValue
*GV
: V
)
210 if (!convertToDeclaration(*GV
))
211 GV
->eraseFromParent();
214 void forEachVirtualFunction(Constant
*C
, function_ref
<void(Function
*)> Fn
) {
215 if (auto *F
= dyn_cast
<Function
>(C
))
217 if (isa
<GlobalValue
>(C
))
219 for (Value
*Op
: C
->operands())
220 forEachVirtualFunction(cast
<Constant
>(Op
), Fn
);
223 // Clone any @llvm[.compiler].used over to the new module and append
224 // values whose defs were cloned into that module.
225 static void cloneUsedGlobalVariables(const Module
&SrcM
, Module
&DestM
,
227 SmallVector
<GlobalValue
*, 4> Used
, NewUsed
;
228 // First collect those in the llvm[.compiler].used set.
229 collectUsedGlobalVariables(SrcM
, Used
, CompilerUsed
);
230 // Next build a set of the equivalent values defined in DestM.
231 for (auto *V
: Used
) {
232 auto *GV
= DestM
.getNamedValue(V
->getName());
233 if (GV
&& !GV
->isDeclaration())
234 NewUsed
.push_back(GV
);
236 // Finally, add them to a llvm[.compiler].used variable in DestM.
238 appendToCompilerUsed(DestM
, NewUsed
);
240 appendToUsed(DestM
, NewUsed
);
243 // If it's possible to split M into regular and thin LTO parts, do so and write
244 // a multi-module bitcode file with the two parts to OS. Otherwise, write only a
245 // regular LTO bitcode file to OS.
246 void splitAndWriteThinLTOBitcode(
247 raw_ostream
&OS
, raw_ostream
*ThinLinkOS
,
248 function_ref
<AAResults
&(Function
&)> AARGetter
, Module
&M
) {
249 std::string ModuleId
= getUniqueModuleId(&M
);
250 if (ModuleId
.empty()) {
251 // We couldn't generate a module ID for this module, write it out as a
252 // regular LTO module with an index for summary-based dead stripping.
253 ProfileSummaryInfo
PSI(M
);
254 M
.addModuleFlag(Module::Error
, "ThinLTO", uint32_t(0));
255 ModuleSummaryIndex Index
= buildModuleSummaryIndex(M
, nullptr, &PSI
);
256 WriteBitcodeToFile(M
, OS
, /*ShouldPreserveUseListOrder=*/false, &Index
);
259 // We don't have a ThinLTO part, but still write the module to the
260 // ThinLinkOS if requested so that the expected output file is produced.
261 WriteBitcodeToFile(M
, *ThinLinkOS
, /*ShouldPreserveUseListOrder=*/false,
267 promoteTypeIds(M
, ModuleId
);
269 // Returns whether a global or its associated global has attached type
270 // metadata. The former may participate in CFI or whole-program
271 // devirtualization, so they need to appear in the merged module instead of
272 // the thin LTO module. Similarly, globals that are associated with globals
273 // with type metadata need to appear in the merged module because they will
274 // reference the global's section directly.
275 auto HasTypeMetadata
= [](const GlobalObject
*GO
) {
276 if (MDNode
*MD
= GO
->getMetadata(LLVMContext::MD_associated
))
277 if (auto *AssocVM
= dyn_cast_or_null
<ValueAsMetadata
>(MD
->getOperand(0)))
278 if (auto *AssocGO
= dyn_cast
<GlobalObject
>(AssocVM
->getValue()))
279 if (AssocGO
->hasMetadata(LLVMContext::MD_type
))
281 return GO
->hasMetadata(LLVMContext::MD_type
);
284 // Collect the set of virtual functions that are eligible for virtual constant
285 // propagation. Each eligible function must not access memory, must return
286 // an integer of width <=64 bits, must take at least one argument, must not
287 // use its first argument (assumed to be "this") and all arguments other than
288 // the first one must be of <=64 bit integer type.
290 // Note that we test whether this copy of the function is readnone, rather
291 // than testing function attributes, which must hold for any copy of the
292 // function, even a less optimized version substituted at link time. This is
293 // sound because the virtual constant propagation optimizations effectively
294 // inline all implementations of the virtual function into each call site,
295 // rather than using function attributes to perform local optimization.
296 DenseSet
<const Function
*> EligibleVirtualFns
;
297 // If any member of a comdat lives in MergedM, put all members of that
298 // comdat in MergedM to keep the comdat together.
299 DenseSet
<const Comdat
*> MergedMComdats
;
300 for (GlobalVariable
&GV
: M
.globals())
301 if (HasTypeMetadata(&GV
)) {
302 if (const auto *C
= GV
.getComdat())
303 MergedMComdats
.insert(C
);
304 forEachVirtualFunction(GV
.getInitializer(), [&](Function
*F
) {
305 auto *RT
= dyn_cast
<IntegerType
>(F
->getReturnType());
306 if (!RT
|| RT
->getBitWidth() > 64 || F
->arg_empty() ||
307 !F
->arg_begin()->use_empty())
309 for (auto &Arg
: drop_begin(F
->args())) {
310 auto *ArgT
= dyn_cast
<IntegerType
>(Arg
.getType());
311 if (!ArgT
|| ArgT
->getBitWidth() > 64)
314 if (!F
->isDeclaration() &&
315 computeFunctionBodyMemoryAccess(*F
, AARGetter(*F
)) == MAK_ReadNone
)
316 EligibleVirtualFns
.insert(F
);
320 ValueToValueMapTy VMap
;
321 std::unique_ptr
<Module
> MergedM(
322 CloneModule(M
, VMap
, [&](const GlobalValue
*GV
) -> bool {
323 if (const auto *C
= GV
->getComdat())
324 if (MergedMComdats
.count(C
))
326 if (auto *F
= dyn_cast
<Function
>(GV
))
327 return EligibleVirtualFns
.count(F
);
328 if (auto *GVar
= dyn_cast_or_null
<GlobalVariable
>(GV
->getBaseObject()))
329 return HasTypeMetadata(GVar
);
332 StripDebugInfo(*MergedM
);
333 MergedM
->setModuleInlineAsm("");
335 // Clone any llvm.*used globals to ensure the included values are
337 cloneUsedGlobalVariables(M
, *MergedM
, /*CompilerUsed*/ false);
338 cloneUsedGlobalVariables(M
, *MergedM
, /*CompilerUsed*/ true);
340 for (Function
&F
: *MergedM
)
341 if (!F
.isDeclaration()) {
342 // Reset the linkage of all functions eligible for virtual constant
343 // propagation. The canonical definitions live in the thin LTO module so
344 // that they can be imported.
345 F
.setLinkage(GlobalValue::AvailableExternallyLinkage
);
346 F
.setComdat(nullptr);
349 SetVector
<GlobalValue
*> CfiFunctions
;
351 if ((!F
.hasLocalLinkage() || F
.hasAddressTaken()) && HasTypeMetadata(&F
))
352 CfiFunctions
.insert(&F
);
354 // Remove all globals with type metadata, globals with comdats that live in
355 // MergedM, and aliases pointing to such globals from the thin LTO module.
356 filterModule(&M
, [&](const GlobalValue
*GV
) {
357 if (auto *GVar
= dyn_cast_or_null
<GlobalVariable
>(GV
->getBaseObject()))
358 if (HasTypeMetadata(GVar
))
360 if (const auto *C
= GV
->getComdat())
361 if (MergedMComdats
.count(C
))
366 promoteInternals(*MergedM
, M
, ModuleId
, CfiFunctions
);
367 promoteInternals(M
, *MergedM
, ModuleId
, CfiFunctions
);
369 auto &Ctx
= MergedM
->getContext();
370 SmallVector
<MDNode
*, 8> CfiFunctionMDs
;
371 for (auto V
: CfiFunctions
) {
372 Function
&F
= *cast
<Function
>(V
);
373 SmallVector
<MDNode
*, 2> Types
;
374 F
.getMetadata(LLVMContext::MD_type
, Types
);
376 SmallVector
<Metadata
*, 4> Elts
;
377 Elts
.push_back(MDString::get(Ctx
, F
.getName()));
378 CfiFunctionLinkage Linkage
;
379 if (lowertypetests::isJumpTableCanonical(&F
))
380 Linkage
= CFL_Definition
;
381 else if (F
.hasExternalWeakLinkage())
382 Linkage
= CFL_WeakDeclaration
;
384 Linkage
= CFL_Declaration
;
385 Elts
.push_back(ConstantAsMetadata::get(
386 llvm::ConstantInt::get(Type::getInt8Ty(Ctx
), Linkage
)));
387 append_range(Elts
, Types
);
388 CfiFunctionMDs
.push_back(MDTuple::get(Ctx
, Elts
));
391 if(!CfiFunctionMDs
.empty()) {
392 NamedMDNode
*NMD
= MergedM
->getOrInsertNamedMetadata("cfi.functions");
393 for (auto MD
: CfiFunctionMDs
)
397 SmallVector
<MDNode
*, 8> FunctionAliases
;
398 for (auto &A
: M
.aliases()) {
399 if (!isa
<Function
>(A
.getAliasee()))
402 auto *F
= cast
<Function
>(A
.getAliasee());
405 MDString::get(Ctx
, A
.getName()),
406 MDString::get(Ctx
, F
->getName()),
407 ConstantAsMetadata::get(
408 ConstantInt::get(Type::getInt8Ty(Ctx
), A
.getVisibility())),
409 ConstantAsMetadata::get(
410 ConstantInt::get(Type::getInt8Ty(Ctx
), A
.isWeakForLinker())),
413 FunctionAliases
.push_back(MDTuple::get(Ctx
, Elts
));
416 if (!FunctionAliases
.empty()) {
417 NamedMDNode
*NMD
= MergedM
->getOrInsertNamedMetadata("aliases");
418 for (auto MD
: FunctionAliases
)
422 SmallVector
<MDNode
*, 8> Symvers
;
423 ModuleSymbolTable::CollectAsmSymvers(M
, [&](StringRef Name
, StringRef Alias
) {
424 Function
*F
= M
.getFunction(Name
);
425 if (!F
|| F
->use_empty())
428 Symvers
.push_back(MDTuple::get(
429 Ctx
, {MDString::get(Ctx
, Name
), MDString::get(Ctx
, Alias
)}));
432 if (!Symvers
.empty()) {
433 NamedMDNode
*NMD
= MergedM
->getOrInsertNamedMetadata("symvers");
434 for (auto MD
: Symvers
)
438 simplifyExternals(*MergedM
);
440 // FIXME: Try to re-use BSI and PFI from the original module here.
441 ProfileSummaryInfo
PSI(M
);
442 ModuleSummaryIndex Index
= buildModuleSummaryIndex(M
, nullptr, &PSI
);
444 // Mark the merged module as requiring full LTO. We still want an index for
445 // it though, so that it can participate in summary-based dead stripping.
446 MergedM
->addModuleFlag(Module::Error
, "ThinLTO", uint32_t(0));
447 ModuleSummaryIndex MergedMIndex
=
448 buildModuleSummaryIndex(*MergedM
, nullptr, &PSI
);
450 SmallVector
<char, 0> Buffer
;
452 BitcodeWriter
W(Buffer
);
453 // Save the module hash produced for the full bitcode, which will
454 // be used in the backends, and use that in the minimized bitcode
455 // produced for the full link.
456 ModuleHash ModHash
= {{0}};
457 W
.writeModule(M
, /*ShouldPreserveUseListOrder=*/false, &Index
,
458 /*GenerateHash=*/true, &ModHash
);
459 W
.writeModule(*MergedM
, /*ShouldPreserveUseListOrder=*/false, &MergedMIndex
);
464 // If a minimized bitcode module was requested for the thin link, only
465 // the information that is needed by thin link will be written in the
466 // given OS (the merged module will be written as usual).
469 BitcodeWriter
W2(Buffer
);
471 W2
.writeThinLinkBitcode(M
, Index
, ModHash
);
472 W2
.writeModule(*MergedM
, /*ShouldPreserveUseListOrder=*/false,
476 *ThinLinkOS
<< Buffer
;
480 // Check if the LTO Unit splitting has been enabled.
481 bool enableSplitLTOUnit(Module
&M
) {
482 bool EnableSplitLTOUnit
= false;
483 if (auto *MD
= mdconst::extract_or_null
<ConstantInt
>(
484 M
.getModuleFlag("EnableSplitLTOUnit")))
485 EnableSplitLTOUnit
= MD
->getZExtValue();
486 return EnableSplitLTOUnit
;
489 // Returns whether this module needs to be split because it uses type metadata.
490 bool hasTypeMetadata(Module
&M
) {
491 for (auto &GO
: M
.global_objects()) {
492 if (GO
.hasMetadata(LLVMContext::MD_type
))
498 void writeThinLTOBitcode(raw_ostream
&OS
, raw_ostream
*ThinLinkOS
,
499 function_ref
<AAResults
&(Function
&)> AARGetter
,
500 Module
&M
, const ModuleSummaryIndex
*Index
) {
501 std::unique_ptr
<ModuleSummaryIndex
> NewIndex
= nullptr;
502 // See if this module has any type metadata. If so, we try to split it
503 // or at least promote type ids to enable WPD.
504 if (hasTypeMetadata(M
)) {
505 if (enableSplitLTOUnit(M
))
506 return splitAndWriteThinLTOBitcode(OS
, ThinLinkOS
, AARGetter
, M
);
507 // Promote type ids as needed for index-based WPD.
508 std::string ModuleId
= getUniqueModuleId(&M
);
509 if (!ModuleId
.empty()) {
510 promoteTypeIds(M
, ModuleId
);
511 // Need to rebuild the index so that it contains type metadata
512 // for the newly promoted type ids.
513 // FIXME: Probably should not bother building the index at all
514 // in the caller of writeThinLTOBitcode (which does so via the
515 // ModuleSummaryIndexAnalysis pass), since we have to rebuild it
516 // anyway whenever there is type metadata (here or in
517 // splitAndWriteThinLTOBitcode). Just always build it once via the
518 // buildModuleSummaryIndex when Module(s) are ready.
519 ProfileSummaryInfo
PSI(M
);
520 NewIndex
= std::make_unique
<ModuleSummaryIndex
>(
521 buildModuleSummaryIndex(M
, nullptr, &PSI
));
522 Index
= NewIndex
.get();
526 // Write it out as an unsplit ThinLTO module.
528 // Save the module hash produced for the full bitcode, which will
529 // be used in the backends, and use that in the minimized bitcode
530 // produced for the full link.
531 ModuleHash ModHash
= {{0}};
532 WriteBitcodeToFile(M
, OS
, /*ShouldPreserveUseListOrder=*/false, Index
,
533 /*GenerateHash=*/true, &ModHash
);
534 // If a minimized bitcode module was requested for the thin link, only
535 // the information that is needed by thin link will be written in the
537 if (ThinLinkOS
&& Index
)
538 WriteThinLinkBitcodeToFile(M
, *ThinLinkOS
, *Index
, ModHash
);
541 class WriteThinLTOBitcode
: public ModulePass
{
542 raw_ostream
&OS
; // raw_ostream to print on
543 // The output stream on which to emit a minimized module for use
544 // just in the thin link, if requested.
545 raw_ostream
*ThinLinkOS
;
548 static char ID
; // Pass identification, replacement for typeid
549 WriteThinLTOBitcode() : ModulePass(ID
), OS(dbgs()), ThinLinkOS(nullptr) {
550 initializeWriteThinLTOBitcodePass(*PassRegistry::getPassRegistry());
553 explicit WriteThinLTOBitcode(raw_ostream
&o
, raw_ostream
*ThinLinkOS
)
554 : ModulePass(ID
), OS(o
), ThinLinkOS(ThinLinkOS
) {
555 initializeWriteThinLTOBitcodePass(*PassRegistry::getPassRegistry());
558 StringRef
getPassName() const override
{ return "ThinLTO Bitcode Writer"; }
560 bool runOnModule(Module
&M
) override
{
561 const ModuleSummaryIndex
*Index
=
562 &(getAnalysis
<ModuleSummaryIndexWrapperPass
>().getIndex());
563 writeThinLTOBitcode(OS
, ThinLinkOS
, LegacyAARGetter(*this), M
, Index
);
566 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
567 AU
.setPreservesAll();
568 AU
.addRequired
<AssumptionCacheTracker
>();
569 AU
.addRequired
<ModuleSummaryIndexWrapperPass
>();
570 AU
.addRequired
<TargetLibraryInfoWrapperPass
>();
573 } // anonymous namespace
575 char WriteThinLTOBitcode::ID
= 0;
576 INITIALIZE_PASS_BEGIN(WriteThinLTOBitcode
, "write-thinlto-bitcode",
577 "Write ThinLTO Bitcode", false, true)
578 INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker
)
579 INITIALIZE_PASS_DEPENDENCY(ModuleSummaryIndexWrapperPass
)
580 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass
)
581 INITIALIZE_PASS_END(WriteThinLTOBitcode
, "write-thinlto-bitcode",
582 "Write ThinLTO Bitcode", false, true)
584 ModulePass
*llvm::createWriteThinLTOBitcodePass(raw_ostream
&Str
,
585 raw_ostream
*ThinLinkOS
) {
586 return new WriteThinLTOBitcode(Str
, ThinLinkOS
);
590 llvm::ThinLTOBitcodeWriterPass::run(Module
&M
, ModuleAnalysisManager
&AM
) {
591 FunctionAnalysisManager
&FAM
=
592 AM
.getResult
<FunctionAnalysisManagerModuleProxy
>(M
).getManager();
593 writeThinLTOBitcode(OS
, ThinLinkOS
,
594 [&FAM
](Function
&F
) -> AAResults
& {
595 return FAM
.getResult
<AAManager
>(F
);
597 M
, &AM
.getResult
<ModuleSummaryIndexAnalysis
>(M
));
598 return PreservedAnalyses::all();