34static bool allowPromotionAlias(
const std::string &
Name) {
38 for (
const char &
C :
Name) {
39 if (isAlnum(
C) ||
C ==
'_' ||
C ==
'.')
52 if (!ExportGV.hasLocalLinkage())
55 auto Name = ExportGV.getName();
57 if (!PromoteExtra.
count(&ExportGV)) {
68 std::string OldName =
Name.str();
69 std::string NewName = (
Name + ModuleId).str();
71 if (
const auto *
C = ExportGV.getComdat())
72 if (
C->getName() ==
Name)
75 ExportGV.setName(NewName);
84 if (isa<Function>(&ExportGV) && allowPromotionAlias(OldName)) {
88 ".lto_set_conditional " + OldName +
"," + NewName +
"\n";
93 if (!RenamedComdats.
empty())
95 if (
auto *
C = GO.getComdat()) {
96 auto Replacement = RenamedComdats.
find(
C);
97 if (Replacement != RenamedComdats.
end())
98 GO.setComdat(Replacement->second);
109 auto ExternalizeTypeId = [&](
CallInst *CI,
unsigned ArgNo) {
111 cast<MetadataAsValue>(CI->
getArgOperand(ArgNo))->getMetadata();
113 if (isa<MDNode>(MD) && cast<MDNode>(MD)->isDistinct()) {
114 Metadata *&GlobalMD = LocalToGlobal[MD];
116 std::string NewName = (
Twine(LocalToGlobal.
size()) + ModuleId).str();
127 for (
const Use &U : TypeTestFunc->
uses()) {
128 auto CI = cast<CallInst>(
U.getUser());
129 ExternalizeTypeId(CI, 1);
135 for (
const Use &U : PublicTypeTestFunc->
uses()) {
136 auto CI = cast<CallInst>(
U.getUser());
137 ExternalizeTypeId(CI, 1);
143 for (
const Use &U : TypeCheckedLoadFunc->
uses()) {
144 auto CI = cast<CallInst>(
U.getUser());
145 ExternalizeTypeId(CI, 2);
150 &M, Intrinsic::type_checked_load_relative)) {
151 for (
const Use &U : TypeCheckedLoadRelativeFunc->
uses()) {
152 auto CI = cast<CallInst>(
U.getUser());
153 ExternalizeTypeId(CI, 2);
159 GO.getMetadata(LLVMContext::MD_type, MDs);
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);
169 LLVMContext::MD_type,
170 *
MDNode::get(
M.getContext(), {MD->getOperand(0), I->second}));
177void simplifyExternals(
Module &M) {
182 if (
F.isDeclaration() &&
F.use_empty()) {
187 if (!
F.isDeclaration() ||
F.getFunctionType() == EmptyFT ||
189 F.getName().starts_with(
"llvm."))
194 F.getAddressSpace(),
"", &M);
199 F.getAttributes().getFnAttrs()));
201 F.replaceAllUsesWith(NewF);
209 assert(
I.getResolverFunction() &&
"ifunc misses its resolver function");
213 if (GV.isDeclaration() && GV.use_empty()) {
214 GV.eraseFromParent();
223 std::vector<GlobalValue *>
V;
225 if (!ShouldKeepDefinition(&GV))
230 GV->eraseFromParent();
234 if (
auto *
F = dyn_cast<Function>(
C))
236 if (isa<GlobalValue>(
C))
239 forEachVirtualFunction(cast<Constant>(
Op), Fn);
244static void cloneUsedGlobalVariables(
const Module &SrcM,
Module &DestM,
250 for (
auto *V : Used) {
252 if (GV && !GV->isDeclaration())
263static bool enableUnifiedLTO(
Module &M) {
264 bool UnifiedLTO =
false;
266 mdconst::extract_or_null<ConstantInt>(
M.getModuleFlag(
"UnifiedLTO")))
267 UnifiedLTO = MD->getZExtValue();
275void splitAndWriteThinLTOBitcode(
279 if (ModuleId.empty()) {
280 assert(!enableUnifiedLTO(M));
298 promoteTypeIds(M, ModuleId);
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))
312 return GO->hasMetadata(LLVMContext::MD_type);
332 if (!GV.isDeclaration() && HasTypeMetadata(&GV)) {
333 if (
const auto *
C = GV.getComdat())
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())
340 for (auto &Arg : drop_begin(F->args())) {
341 auto *ArgT = dyn_cast<IntegerType>(Arg.getType());
342 if (!ArgT || ArgT->getBitWidth() > 64)
345 if (!
F->isDeclaration() &&
347 .doesNotAccessMemory())
353 std::unique_ptr<Module> MergedM(
358 if (
auto *
F = dyn_cast<Function>(GV))
359 return EligibleVirtualFns.
count(
F);
362 return HasTypeMetadata(GVar);
366 MergedM->setModuleInlineAsm(
"");
370 cloneUsedGlobalVariables(M, *MergedM,
false);
371 cloneUsedGlobalVariables(M, *MergedM,
true);
374 if (!
F.isDeclaration()) {
379 F.setComdat(
nullptr);
384 if ((!
F.hasLocalLinkage() ||
F.hasAddressTaken()) && HasTypeMetadata(&
F))
391 if (HasTypeMetadata(GVar))
399 promoteInternals(*MergedM, M, ModuleId, CfiFunctions);
400 promoteInternals(M, *MergedM, ModuleId, CfiFunctions);
402 auto &Ctx = MergedM->getContext();
404 for (
auto *V : CfiFunctions) {
407 F.getMetadata(LLVMContext::MD_type, Types);
414 else if (
F.hasExternalWeakLinkage())
424 if(!CfiFunctionMDs.
empty()) {
425 NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata(
"cfi.functions");
426 for (
auto *MD : CfiFunctionMDs)
431 for (
auto &
A :
M.aliases()) {
432 if (!isa<Function>(
A.getAliasee()))
435 auto *
F = cast<Function>(
A.getAliasee());
449 if (!FunctionAliases.
empty()) {
450 NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata(
"aliases");
451 for (
auto *MD : FunctionAliases)
458 if (!
F ||
F->use_empty())
462 Ctx, {MDString::get(Ctx, Name), MDString::get(Ctx, Alias)}));
465 if (!Symvers.
empty()) {
466 NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata(
"symvers");
467 for (
auto *MD : Symvers)
471 simplifyExternals(*MergedM);
490 W.writeModule(M,
false, &Index,
492 W.writeModule(*MergedM,
false, &MergedMIndex);
504 W2.writeThinLinkBitcode(M, Index, ModHash);
505 W2.writeModule(*MergedM,
false,
509 *ThinLinkOS << Buffer;
514bool 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;
523bool hasTypeMetadata(
Module &M) {
524 for (
auto &GO :
M.global_objects()) {
525 if (GO.hasMetadata(LLVMContext::MD_type))
534 std::unique_ptr<ModuleSummaryIndex> NewIndex =
nullptr;
537 if (hasTypeMetadata(M)) {
538 if (enableSplitLTOUnit(M)) {
539 splitAndWriteThinLTOBitcode(
OS, ThinLinkOS, AARGetter, M);
544 if (!ModuleId.empty()) {
545 promoteTypeIds(M, ModuleId);
555 NewIndex = std::make_unique<ModuleSummaryIndex>(
557 Index = NewIndex.get();
572 if (ThinLinkOS && Index)
586 if (M.IsNewDbgInfoFormat)
587 M.removeDebugIntrinsicDeclarations();
589 bool Changed = writeThinLTOBitcode(
This is the interface for LLVM's primary stateless and local alias analysis.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Provides passes for computing function attributes based on interprocedural analyses.
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
bool WriteNewDbgInfoFormatToBitcode
This is the interface to build a ModuleSummaryIndex for a module.
FunctionAnalysisManager FAM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool WriteNewDbgInfoFormatToBitcode
A manager for alias analyses.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
This class represents a function call, abstracting a target machine's calling convention.
This is an important base class in LLVM.
void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
This class represents an Operation in the Expression.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Implements a dense probed hash-table based set.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
const Comdat * getComdat() const
const GlobalObject * getAliaseeObject() const
void eraseFromParent()
This method unlinks 'this' from the containing module and deletes it.
@ HiddenVisibility
The GV is hidden.
void setVisibility(VisibilityTypes V)
@ ExternalLinkage
Externally visible function.
@ AvailableExternallyLinkage
Available for inspection, not emission.
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static MDString * get(LLVMContext &Context, StringRef Str)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Analysis pass to provide the ModuleSummaryIndex object.
Class to hold module path string table and global value map, and encapsulate methods for operating on...
static void CollectAsmSymvers(const Module &M, function_ref< void(StringRef, StringRef)> AsmSymver)
Parse inline ASM and collect the symvers directives that are defined in the current module.
A Module instance is used to store all the information related to an LLVM module.
@ Error
Emits an error if two values disagree, otherwise the resulting value is that of the operands.
iterator_range< global_object_iterator > global_objects()
GlobalValue * getNamedValue(StringRef Name) const
Return the global value in the module with the specified name, of arbitrary type.
Comdat * getOrInsertComdat(StringRef Name)
Return the Comdat in the module with the specified name.
void appendModuleInlineAsm(StringRef Asm)
Append to the module-scope inline assembly blocks.
iterator_range< global_value_iterator > global_values()
void addOperand(MDNode *M)
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Analysis providing profile information.
A vector that has set insertion semantics.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Type * getVoidTy(LLVMContext &C)
static IntegerType * getInt8Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
void setName(const Twine &Name)
Change the name of the value.
iterator_range< use_iterator > uses()
void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclarationIfExists(Module *M, ID id, ArrayRef< Type * > Tys, FunctionType *FT=nullptr)
This version supports overloaded intrinsics.
Linkage
Describes symbol linkage. This can be used to resolve definition clashes.
bool isJumpTableCanonical(Function *F)
This is an optimization pass for GlobalISel generic memory operations.
MemoryEffects computeFunctionBodyMemoryAccess(Function &F, AAResults &AAR)
Returns the memory access properties of this copy of the function.
void WriteBitcodeToFile(const Module &M, raw_ostream &Out, bool ShouldPreserveUseListOrder=false, const ModuleSummaryIndex *Index=nullptr, bool GenerateHash=false, ModuleHash *ModHash=nullptr)
Write the specified module to the specified raw output stream.
void writeThinLinkBitcodeToFile(const Module &M, raw_ostream &Out, const ModuleSummaryIndex &Index, const ModuleHash &ModHash)
Write the specified thin link bitcode file (i.e., the minimized bitcode file) to the given raw output...
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool convertToDeclaration(GlobalValue &GV)
Converts value GV to declaration, or replaces with a declaration if it is an alias.
ModuleSummaryIndex buildModuleSummaryIndex(const Module &M, std::function< BlockFrequencyInfo *(const Function &F)> GetBFICallback, ProfileSummaryInfo *PSI, std::function< const StackSafetyInfo *(const Function &F)> GetSSICallback=[](const Function &F) -> const StackSafetyInfo *{ return nullptr;})
Direct function to compute a ModuleSummaryIndex from a given module.
std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
bool StripDebugInfo(Module &M)
Strip debug info in the module if it exists.
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
std::array< uint32_t, 5 > ModuleHash
160 bits SHA1
std::unique_ptr< Module > CloneModule(const Module &M)
Return an exact copy of the specified module.
void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
CfiFunctionLinkage
The type of CFI jumptable needed for a function.
GlobalVariable * collectUsedGlobalVariables(const Module &M, SmallVectorImpl< GlobalValue * > &Vec, bool CompilerUsed)
Given "llvm.used" or "llvm.compiler.used" as a global name, collect the initializer elements of that ...