LLVM 22.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"
18#include "llvm/IR/Module.h"
21
22using namespace llvm;
23
24namespace {
25
26// Helper class that collects AsmUsed and user supplied libcalls.
27class PreserveLibCallsAndAsmUsed {
28public:
29 PreserveLibCallsAndAsmUsed(const StringSet<> &AsmUndefinedRefs,
30 const TargetMachine &TM,
31 std::vector<GlobalValue *> &LLVMUsed)
32 : AsmUndefinedRefs(AsmUndefinedRefs), TM(TM), LLVMUsed(LLVMUsed) {}
33
34 void findInModule(Module &TheModule) {
35 initializeLibCalls(TheModule);
36 for (Function &F : TheModule)
37 findLibCallsAndAsm(F);
38 for (GlobalVariable &GV : TheModule.globals())
39 findLibCallsAndAsm(GV);
40 for (GlobalAlias &GA : TheModule.aliases())
41 findLibCallsAndAsm(GA);
42 }
43
44private:
45 // Inputs
46 const StringSet<> &AsmUndefinedRefs;
47 const TargetMachine &TM;
48
49 // Temps
50 llvm::Mangler Mangler;
51 StringSet<> Libcalls;
52
53 // Output
54 std::vector<GlobalValue *> &LLVMUsed;
55
56 // Collect names of runtime library functions. User-defined functions with the
57 // same names are added to llvm.compiler.used to prevent them from being
58 // deleted by optimizations.
59 void initializeLibCalls(const Module &TheModule) {
60 TargetLibraryInfoImpl TLII(TM.getTargetTriple());
61 TargetLibraryInfo TLI(TLII);
62
63 // TargetLibraryInfo has info on C runtime library calls on the current
64 // target.
65 for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);
66 I != E; ++I) {
67 LibFunc F = static_cast<LibFunc>(I);
68 if (TLI.has(F))
69 Libcalls.insert(TLI.getName(F));
70 }
71
72 SmallPtrSet<const TargetLowering *, 1> TLSet;
73
74 for (const Function &F : TheModule) {
75 const TargetLowering *Lowering =
76 TM.getSubtargetImpl(F)->getTargetLowering();
77
78 if (Lowering && TLSet.insert(Lowering).second)
79 // TargetLowering has info on library calls that CodeGen expects to be
80 // available, both from the C runtime and compiler-rt.
81 for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);
82 I != E; ++I)
83 if (const char *Name =
84 Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))
85 Libcalls.insert(Name);
86 }
87 }
88
89 void findLibCallsAndAsm(GlobalValue &GV) {
90 // There are no restrictions to apply to declarations.
91 if (GV.isDeclaration())
92 return;
93
94 // There is nothing more restrictive than private linkage.
95 if (GV.hasPrivateLinkage())
96 return;
97
98 // Conservatively append user-supplied runtime library functions (supplied
99 // either directly, or via a function alias) to llvm.compiler.used. These
100 // could be internalized and deleted by optimizations like -globalopt,
101 // causing problems when later optimizations add new library calls (e.g.,
102 // llvm.memset => memset and printf => puts).
103 // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
104 GlobalValue *FuncAliasee = nullptr;
105 if (isa<GlobalAlias>(GV)) {
106 auto *A = cast<GlobalAlias>(&GV);
107 FuncAliasee = dyn_cast<Function>(A->getAliasee());
108 }
109 if ((isa<Function>(GV) || FuncAliasee) && Libcalls.count(GV.getName())) {
110 LLVMUsed.push_back(&GV);
111 return;
112 }
113
114 SmallString<64> Buffer;
115 TM.getNameWithPrefix(Buffer, &GV, Mangler);
116 if (AsmUndefinedRefs.count(Buffer))
117 LLVMUsed.push_back(&GV);
118 }
119};
120
121} // namespace anonymous
122
124 const StringSet<> &AsmUndefinedRefs) {
125 std::vector<GlobalValue *> UsedValues;
126 PreserveLibCallsAndAsmUsed(AsmUndefinedRefs, TM, UsedValues)
127 .findInModule(TheModule);
128
129 if (UsedValues.empty())
130 return;
131
132 appendToCompilerUsed(TheModule, UsedValues);
133}
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
Machine Check Debug Module
static void initializeLibCalls(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
This file describes how to lower LLVM code to machine code.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:316
bool hasPrivateLinkage() const
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition StringSet.h:25
Primary interface to the complete machine description for the target machine.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:322
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
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...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565