xref: /llvm-project/llvm/include/llvm/Transforms/Utils/ModuleUtils.h (revision 048cf8857e081fb80d5ac8b24a79f999d632141b)
1 //===-- ModuleUtils.h - Functions to manipulate Modules ---------*- C++ -*-===//
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 family of functions perform manipulations on Modules.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
14 #define LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
15 
16 #include "llvm/ADT/STLFunctionalExtras.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/IR/GlobalIFunc.h"
19 #include "llvm/Support/Alignment.h"
20 #include "llvm/Support/MemoryBufferRef.h"
21 #include <utility> // for std::pair
22 
23 namespace llvm {
24 template <typename T> class SmallVectorImpl;
25 
26 template <typename T> class ArrayRef;
27 class Module;
28 class Function;
29 class FunctionCallee;
30 class GlobalIFunc;
31 class GlobalValue;
32 class Constant;
33 class ConstantStruct;
34 class Value;
35 class Type;
36 
37 /// Append F to the list of global ctors of module M with the given Priority.
38 /// This wraps the function in the appropriate structure and stores it along
39 /// side other global constructors. For details see
40 /// https://llvm.org/docs/LangRef.html#the-llvm-global-ctors-global-variable
41 void appendToGlobalCtors(Module &M, Function *F, int Priority,
42                          Constant *Data = nullptr);
43 
44 /// Same as appendToGlobalCtors(), but for global dtors.
45 void appendToGlobalDtors(Module &M, Function *F, int Priority,
46                          Constant *Data = nullptr);
47 
48 /// Apply 'Fn' to the list of global ctors of module M and replace contructor
49 /// record with the one returned by `Fn`. If `nullptr` was returned, the
50 /// corresponding constructor will be removed from the array. For details see
51 /// https://llvm.org/docs/LangRef.html#the-llvm-global-ctors-global-variable
52 using GlobalCtorTransformFn = llvm::function_ref<Constant *(Constant *)>;
53 void transformGlobalCtors(Module &M, const GlobalCtorTransformFn &Fn);
54 void transformGlobalDtors(Module &M, const GlobalCtorTransformFn &Fn);
55 
56 /// Sets the KCFI type for the function. Used for compiler-generated functions
57 /// that are indirectly called in instrumented code.
58 void setKCFIType(Module &M, Function &F, StringRef MangledType);
59 
60 FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName,
61                                             ArrayRef<Type *> InitArgTypes,
62                                             bool Weak = false);
63 
64 /// Creates sanitizer constructor function.
65 /// \return Returns pointer to constructor.
66 Function *createSanitizerCtor(Module &M, StringRef CtorName);
67 
68 /// Creates sanitizer constructor function, and calls sanitizer's init
69 /// function from it.
70 /// \return Returns pair of pointers to constructor, and init functions
71 /// respectively.
72 std::pair<Function *, FunctionCallee> createSanitizerCtorAndInitFunctions(
73     Module &M, StringRef CtorName, StringRef InitName,
74     ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
75     StringRef VersionCheckName = StringRef(), bool Weak = false);
76 
77 /// Creates sanitizer constructor function lazily. If a constructor and init
78 /// function already exist, this function returns it. Otherwise it calls \c
79 /// createSanitizerCtorAndInitFunctions. The FunctionsCreatedCallback is invoked
80 /// in that case, passing the new Ctor and Init function.
81 ///
82 /// \return Returns pair of pointers to constructor, and init functions
83 /// respectively.
84 std::pair<Function *, FunctionCallee> getOrCreateSanitizerCtorAndInitFunctions(
85     Module &M, StringRef CtorName, StringRef InitName,
86     ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
87     function_ref<void(Function *, FunctionCallee)> FunctionsCreatedCallback,
88     StringRef VersionCheckName = StringRef(), bool Weak = false);
89 
90 /// Rename all the anon globals in the module using a hash computed from
91 /// the list of public globals in the module.
92 bool nameUnamedGlobals(Module &M);
93 
94 /// Adds global values to the llvm.used list.
95 void appendToUsed(Module &M, ArrayRef<GlobalValue *> Values);
96 
97 /// Adds global values to the llvm.compiler.used list.
98 void appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values);
99 
100 /// Removes global values from the llvm.used and llvm.compiler.used arrays. \p
101 /// ShouldRemove should return true for any initializer field that should not be
102 /// included in the replacement global.
103 void removeFromUsedLists(Module &M,
104                          function_ref<bool(Constant *)> ShouldRemove);
105 
106 /// Filter out potentially dead comdat functions where other entries keep the
107 /// entire comdat group alive.
108 ///
109 /// This is designed for cases where functions appear to become dead but remain
110 /// alive due to other live entries in their comdat group.
111 ///
112 /// The \p DeadComdatFunctions container should only have pointers to
113 /// `Function`s which are members of a comdat group and are believed to be
114 /// dead.
115 ///
116 /// After this routine finishes, the only remaining `Function`s in \p
117 /// DeadComdatFunctions are those where every member of the comdat is listed
118 /// and thus removing them is safe (provided *all* are removed).
119 void filterDeadComdatFunctions(
120     SmallVectorImpl<Function *> &DeadComdatFunctions);
121 
122 /// Produce a unique identifier for this module by taking the MD5 sum of
123 /// the names of the module's strong external symbols that are not comdat
124 /// members.
125 ///
126 /// This identifier is normally guaranteed to be unique, or the program would
127 /// fail to link due to multiply defined symbols.
128 ///
129 /// If the module has no strong external symbols (such a module may still have a
130 /// semantic effect if it performs global initialization), we cannot produce a
131 /// unique identifier for this module, so we return the empty string.
132 std::string getUniqueModuleId(Module *M);
133 
134 /// Embed the memory buffer \p Buf into the module \p M as a global using the
135 /// specified section name. Also provide a metadata entry to identify it in the
136 /// module using the same section name.
137 void embedBufferInModule(Module &M, MemoryBufferRef Buf, StringRef SectionName,
138                          Align Alignment = Align(1));
139 
140 /// Lower all calls to ifuncs by replacing uses with indirect calls loaded out
141 /// of a global table initialized in a global constructor. This will introduce
142 /// one constructor function and adds it to llvm.global_ctors. The constructor
143 /// will call the resolver function once for each ifunc.
144 ///
145 /// Leaves any unhandled constant initializer uses as-is.
146 ///
147 /// If \p IFuncsToLower is empty, all ifuncs in the module will be lowered.
148 /// If \p IFuncsToLower is non-empty, only the selected ifuncs will be lowered.
149 ///
150 /// The processed ifuncs without remaining users will be removed from the
151 /// module.
152 bool lowerGlobalIFuncUsersAsGlobalCtor(
153     Module &M, ArrayRef<GlobalIFunc *> IFuncsToLower = {});
154 
155 } // End llvm namespace
156 
157 #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
158