LLVM 19.0.0git
UpdateCompilerUsed.cpp
Go to the documentation of this file.
1//==-LTOInternalize.cpp - LLVM Link Time Optimizer Internalization Utility -==//
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// This file defines a helper to run the internalization part of LTO.
10//
11//===----------------------------------------------------------------------===//
12
17#include "llvm/IR/Mangler.h"
20
21using namespace llvm;
22
23namespace {
24
25// Helper class that collects AsmUsed and user supplied libcalls.
26class PreserveLibCallsAndAsmUsed {
27public:
28 PreserveLibCallsAndAsmUsed(const StringSet<> &AsmUndefinedRefs,
29 const TargetMachine &TM,
30 std::vector<GlobalValue *> &LLVMUsed)
31 : AsmUndefinedRefs(AsmUndefinedRefs), TM(TM), LLVMUsed(LLVMUsed) {}
32
33 void findInModule(Module &TheModule) {
34 initializeLibCalls(TheModule);
35 for (Function &F : TheModule)
36 findLibCallsAndAsm(F);
37 for (GlobalVariable &GV : TheModule.globals())
38 findLibCallsAndAsm(GV);
39 for (GlobalAlias &GA : TheModule.aliases())
40 findLibCallsAndAsm(GA);
41 }
42
43private:
44 // Inputs
45 const StringSet<> &AsmUndefinedRefs;
46 const TargetMachine &TM;
47
48 // Temps
50 StringSet<> Libcalls;
51
52 // Output
53 std::vector<GlobalValue *> &LLVMUsed;
54
55 // Collect names of runtime library functions. User-defined functions with the
56 // same names are added to llvm.compiler.used to prevent them from being
57 // deleted by optimizations.
58 void initializeLibCalls(const Module &TheModule) {
59 TargetLibraryInfoImpl TLII(Triple(TM.getTargetTriple()));
60 TargetLibraryInfo TLI(TLII);
61
62 // TargetLibraryInfo has info on C runtime library calls on the current
63 // target.
64 for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);
65 I != E; ++I) {
66 LibFunc F = static_cast<LibFunc>(I);
67 if (TLI.has(F))
68 Libcalls.insert(TLI.getName(F));
69 }
70
72
73 for (const Function &F : TheModule) {
75 TM.getSubtargetImpl(F)->getTargetLowering();
76
77 if (Lowering && TLSet.insert(Lowering).second)
78 // TargetLowering has info on library calls that CodeGen expects to be
79 // available, both from the C runtime and compiler-rt.
80 for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);
81 I != E; ++I)
82 if (const char *Name =
83 Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))
84 Libcalls.insert(Name);
85 }
86 }
87
88 void findLibCallsAndAsm(GlobalValue &GV) {
89 // There are no restrictions to apply to declarations.
90 if (GV.isDeclaration())
91 return;
92
93 // There is nothing more restrictive than private linkage.
94 if (GV.hasPrivateLinkage())
95 return;
96
97 // Conservatively append user-supplied runtime library functions (supplied
98 // either directly, or via a function alias) to llvm.compiler.used. These
99 // could be internalized and deleted by optimizations like -globalopt,
100 // causing problems when later optimizations add new library calls (e.g.,
101 // llvm.memset => memset and printf => puts).
102 // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
103 GlobalValue *FuncAliasee = nullptr;
104 if (isa<GlobalAlias>(GV)) {
105 auto *A = cast<GlobalAlias>(&GV);
106 FuncAliasee = dyn_cast<Function>(A->getAliasee());
107 }
108 if ((isa<Function>(GV) || FuncAliasee) && Libcalls.count(GV.getName())) {
109 LLVMUsed.push_back(&GV);
110 return;
111 }
112
113 SmallString<64> Buffer;
114 TM.getNameWithPrefix(Buffer, &GV, Mangler);
115 if (AsmUndefinedRefs.count(Buffer))
116 LLVMUsed.push_back(&GV);
117 }
118};
119
120} // namespace anonymous
121
123 const StringSet<> &AsmUndefinedRefs) {
124 std::vector<GlobalValue *> UsedValues;
125 PreserveLibCallsAndAsmUsed(AsmUndefinedRefs, TM, UsedValues)
126 .findInModule(TheModule);
127
128 if (UsedValues.empty())
129 return;
130
131 appendToCompilerUsed(TheModule, UsedValues);
132}
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::string Name
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
const char LLVMTargetMachineRef TM
pre isel intrinsic Pre ISel Intrinsic Lowering
This file describes how to lower LLVM code to machine code.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:274
bool hasPrivateLinkage() const
Definition: GlobalValue.h:526
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:342
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:427
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Definition: StringMap.h:277
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:23
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:38
Implementation of the target library information.
Provides information about what library functions are available for the current target.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void updateCompilerUsed(Module &TheModule, const TargetMachine &TM, const StringSet<> &AsmUndefinedRefs)
Find all globals in TheModule that are referenced in AsmUndefinedRefs, as well as the user-supplied f...
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.