36static bool allowPromotionAlias(
const std::string &
Name) {
40 for (
const char &
C :
Name) {
41 if (isAlnum(
C) ||
C ==
'_' ||
C ==
'.')
54 if (!ExportGV.hasLocalLinkage())
57 auto Name = ExportGV.getName();
59 if (!PromoteExtra.
count(&ExportGV)) {
70 std::string OldName =
Name.str();
71 std::string NewName = (
Name + ModuleId).str();
73 if (
const auto *
C = ExportGV.getComdat())
74 if (
C->getName() ==
Name)
77 ExportGV.setName(NewName);
86 if (isa<Function>(&ExportGV) && allowPromotionAlias(OldName)) {
90 ".lto_set_conditional " + OldName +
"," + NewName +
"\n";
95 if (!RenamedComdats.
empty())
97 if (
auto *
C = GO.getComdat()) {
98 auto Replacement = RenamedComdats.
find(
C);
99 if (Replacement != RenamedComdats.
end())
100 GO.setComdat(Replacement->second);
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();
129 for (
const Use &U : TypeTestFunc->
uses()) {
130 auto CI = cast<CallInst>(
U.getUser());
131 ExternalizeTypeId(CI, 1);
137 for (
const Use &U : PublicTypeTestFunc->
uses()) {
138 auto CI = cast<CallInst>(
U.getUser());
139 ExternalizeTypeId(CI, 1);
145 for (
const Use &U : TypeCheckedLoadFunc->
uses()) {
146 auto CI = cast<CallInst>(
U.getUser());
147 ExternalizeTypeId(CI, 2);
153 GO.getMetadata(LLVMContext::MD_type, MDs);
155 GO.eraseMetadata(LLVMContext::MD_type);
156 for (
auto *MD : MDs) {
157 auto I = LocalToGlobal.
find(MD->getOperand(1));
158 if (
I == LocalToGlobal.
end()) {
159 GO.addMetadata(LLVMContext::MD_type, *MD);
163 LLVMContext::MD_type,
164 *
MDNode::get(
M.getContext(), {MD->getOperand(0), I->second}));
171void simplifyExternals(
Module &M) {
176 if (
F.isDeclaration() &&
F.use_empty()) {
181 if (!
F.isDeclaration() ||
F.getFunctionType() == EmptyFT ||
183 F.getName().startswith(
"llvm."))
188 F.getAddressSpace(),
"", &M);
193 F.getAttributes().getFnAttrs()));
203 assert(
I.getResolverFunction() &&
"ifunc misses its resolver function");
207 if (GV.isDeclaration() && GV.use_empty()) {
208 GV.eraseFromParent();
217 std::vector<GlobalValue *>
V;
219 if (!ShouldKeepDefinition(&GV))
224 GV->eraseFromParent();
228 if (
auto *
F = dyn_cast<Function>(
C))
230 if (isa<GlobalValue>(
C))
232 for (
Value *Op :
C->operands())
233 forEachVirtualFunction(cast<Constant>(Op), Fn);
238static void cloneUsedGlobalVariables(
const Module &SrcM,
Module &DestM,
244 for (
auto *V : Used) {
246 if (GV && !GV->isDeclaration())
259void splitAndWriteThinLTOBitcode(
263 if (ModuleId.empty()) {
280 promoteTypeIds(M, ModuleId);
289 if (
MDNode *MD = GO->getMetadata(LLVMContext::MD_associated))
290 if (
auto *AssocVM = dyn_cast_or_null<ValueAsMetadata>(MD->getOperand(0)))
291 if (
auto *AssocGO = dyn_cast<GlobalObject>(AssocVM->getValue()))
292 if (AssocGO->hasMetadata(LLVMContext::MD_type))
294 return GO->hasMetadata(LLVMContext::MD_type);
314 if (HasTypeMetadata(&GV)) {
315 if (
const auto *
C = GV.getComdat())
317 forEachVirtualFunction(GV.getInitializer(), [&](
Function *
F) {
318 auto *RT = dyn_cast<IntegerType>(F->getReturnType());
319 if (!RT || RT->getBitWidth() > 64 || F->arg_empty() ||
320 !F->arg_begin()->use_empty())
322 for (auto &Arg : drop_begin(F->args())) {
323 auto *ArgT = dyn_cast<IntegerType>(Arg.getType());
324 if (!ArgT || ArgT->getBitWidth() > 64)
327 if (!
F->isDeclaration() &&
329 .doesNotAccessMemory())
335 std::unique_ptr<Module> MergedM(
340 if (
auto *
F = dyn_cast<Function>(GV))
341 return EligibleVirtualFns.
count(
F);
344 return HasTypeMetadata(GVar);
348 MergedM->setModuleInlineAsm(
"");
352 cloneUsedGlobalVariables(M, *MergedM,
false);
353 cloneUsedGlobalVariables(M, *MergedM,
true);
356 if (!
F.isDeclaration()) {
361 F.setComdat(
nullptr);
366 if ((!
F.hasLocalLinkage() ||
F.hasAddressTaken()) && HasTypeMetadata(&
F))
373 if (HasTypeMetadata(GVar))
381 promoteInternals(*MergedM, M, ModuleId, CfiFunctions);
382 promoteInternals(M, *MergedM, ModuleId, CfiFunctions);
384 auto &Ctx = MergedM->getContext();
386 for (
auto *V : CfiFunctions) {
389 F.getMetadata(LLVMContext::MD_type, Types);
396 else if (
F.hasExternalWeakLinkage())
406 if(!CfiFunctionMDs.
empty()) {
407 NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata(
"cfi.functions");
408 for (
auto *MD : CfiFunctionMDs)
413 for (
auto &
A :
M.aliases()) {
414 if (!isa<Function>(
A.getAliasee()))
417 auto *
F = cast<Function>(
A.getAliasee());
431 if (!FunctionAliases.
empty()) {
432 NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata(
"aliases");
433 for (
auto *MD : FunctionAliases)
440 if (!
F ||
F->use_empty())
444 Ctx, {MDString::get(Ctx, Name), MDString::get(Ctx, Alias)}));
447 if (!Symvers.
empty()) {
448 NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata(
"symvers");
449 for (
auto *MD : Symvers)
453 simplifyExternals(*MergedM);
472 W.writeModule(M,
false, &
Index,
474 W.writeModule(*MergedM,
false, &MergedMIndex);
486 W2.writeThinLinkBitcode(M,
Index, ModHash);
487 W2.writeModule(*MergedM,
false,
491 *ThinLinkOS << Buffer;
496bool enableSplitLTOUnit(
Module &M) {
497 bool EnableSplitLTOUnit =
false;
498 if (
auto *MD = mdconst::extract_or_null<ConstantInt>(
499 M.getModuleFlag(
"EnableSplitLTOUnit")))
500 EnableSplitLTOUnit = MD->getZExtValue();
501 return EnableSplitLTOUnit;
505bool hasTypeMetadata(
Module &M) {
506 for (
auto &GO :
M.global_objects()) {
507 if (GO.hasMetadata(LLVMContext::MD_type))
516 std::unique_ptr<ModuleSummaryIndex> NewIndex =
nullptr;
519 if (hasTypeMetadata(M)) {
520 if (enableSplitLTOUnit(M))
521 return splitAndWriteThinLTOBitcode(
OS, ThinLinkOS, AARGetter, M);
524 if (!ModuleId.empty()) {
525 promoteTypeIds(M, ModuleId);
535 NewIndex = std::make_unique<ModuleSummaryIndex>(
537 Index = NewIndex.get();
552 if (ThinLinkOS &&
Index)
562 writeThinLTOBitcode(
OS, ThinLinkOS,
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.
This is the interface to build a ModuleSummaryIndex for a module.
Module.h This file contains the declarations for the Module class.
FunctionAnalysisManager FAM
This header defines various interfaces for pass management in LLVM.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
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.
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 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.
StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
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 a range to a container.
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 ...