LLVM  12.0.0git
ModuleUtils.cpp
Go to the documentation of this file.
1 //===-- ModuleUtils.cpp - Functions to manipulate Modules -----------------===//
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 
16 #include "llvm/IR/DerivedTypes.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/IR/IRBuilder.h"
19 #include "llvm/IR/Module.h"
21 using namespace llvm;
22 
23 #define DEBUG_TYPE "moduleutils"
24 
25 static void appendToGlobalArray(const char *Array, Module &M, Function *F,
26  int Priority, Constant *Data) {
27  IRBuilder<> IRB(M.getContext());
28  FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false);
29 
30  // Get the current set of static global constructors and add the new ctor
31  // to the list.
32  SmallVector<Constant *, 16> CurrentCtors;
33  StructType *EltTy = StructType::get(
34  IRB.getInt32Ty(), PointerType::getUnqual(FnTy), IRB.getInt8PtrTy());
35  if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) {
36  if (Constant *Init = GVCtor->getInitializer()) {
37  unsigned n = Init->getNumOperands();
38  CurrentCtors.reserve(n + 1);
39  for (unsigned i = 0; i != n; ++i)
40  CurrentCtors.push_back(cast<Constant>(Init->getOperand(i)));
41  }
42  GVCtor->eraseFromParent();
43  }
44 
45  // Build a 3 field global_ctor entry. We don't take a comdat key.
46  Constant *CSVals[3];
47  CSVals[0] = IRB.getInt32(Priority);
48  CSVals[1] = F;
49  CSVals[2] = Data ? ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy())
50  : Constant::getNullValue(IRB.getInt8PtrTy());
51  Constant *RuntimeCtorInit =
52  ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements()));
53 
54  CurrentCtors.push_back(RuntimeCtorInit);
55 
56  // Create a new initializer.
57  ArrayType *AT = ArrayType::get(EltTy, CurrentCtors.size());
58  Constant *NewInit = ConstantArray::get(AT, CurrentCtors);
59 
60  // Create the new global variable and replace all uses of
61  // the old global variable with the new one.
62  (void)new GlobalVariable(M, NewInit->getType(), false,
63  GlobalValue::AppendingLinkage, NewInit, Array);
64 }
65 
67  appendToGlobalArray("llvm.global_ctors", M, F, Priority, Data);
68 }
69 
71  appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data);
72 }
73 
75  GlobalVariable *GV = M.getGlobalVariable(Name);
78  if (GV) {
79  auto *CA = cast<ConstantArray>(GV->getInitializer());
80  for (auto &Op : CA->operands()) {
81  Constant *C = cast_or_null<Constant>(Op);
82  if (InitAsSet.insert(C).second)
83  Init.push_back(C);
84  }
85  GV->eraseFromParent();
86  }
87 
88  Type *Int8PtrTy = llvm::Type::getInt8PtrTy(M.getContext());
89  for (auto *V : Values) {
90  Constant *C = ConstantExpr::getBitCast(V, Int8PtrTy);
91  if (InitAsSet.insert(C).second)
92  Init.push_back(C);
93  }
94 
95  if (Init.empty())
96  return;
97 
98  ArrayType *ATy = ArrayType::get(Int8PtrTy, Init.size());
100  ConstantArray::get(ATy, Init), Name);
101  GV->setSection("llvm.metadata");
102 }
103 
105  appendToUsedList(M, "llvm.used", Values);
106 }
107 
109  appendToUsedList(M, "llvm.compiler.used", Values);
110 }
111 
114  ArrayRef<Type *> InitArgTypes) {
115  assert(!InitName.empty() && "Expected init function name");
116  return M.getOrInsertFunction(
117  InitName,
118  FunctionType::get(Type::getVoidTy(M.getContext()), InitArgTypes, false),
119  AttributeList());
120 }
121 
123  Function *Ctor = Function::Create(
124  FunctionType::get(Type::getVoidTy(M.getContext()), false),
125  GlobalValue::InternalLinkage, CtorName, &M);
126  BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor);
127  ReturnInst::Create(M.getContext(), CtorBB);
128  return Ctor;
129 }
130 
131 std::pair<Function *, FunctionCallee> llvm::createSanitizerCtorAndInitFunctions(
132  Module &M, StringRef CtorName, StringRef InitName,
133  ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
134  StringRef VersionCheckName) {
135  assert(!InitName.empty() && "Expected init function name");
136  assert(InitArgs.size() == InitArgTypes.size() &&
137  "Sanitizer's init function expects different number of arguments");
138  FunctionCallee InitFunction =
139  declareSanitizerInitFunction(M, InitName, InitArgTypes);
140  Function *Ctor = createSanitizerCtor(M, CtorName);
141  IRBuilder<> IRB(Ctor->getEntryBlock().getTerminator());
142  IRB.CreateCall(InitFunction, InitArgs);
143  if (!VersionCheckName.empty()) {
144  FunctionCallee VersionCheckFunction = M.getOrInsertFunction(
145  VersionCheckName, FunctionType::get(IRB.getVoidTy(), {}, false),
146  AttributeList());
147  IRB.CreateCall(VersionCheckFunction, {});
148  }
149  return std::make_pair(Ctor, InitFunction);
150 }
151 
152 std::pair<Function *, FunctionCallee>
154  Module &M, StringRef CtorName, StringRef InitName,
155  ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
156  function_ref<void(Function *, FunctionCallee)> FunctionsCreatedCallback,
157  StringRef VersionCheckName) {
158  assert(!CtorName.empty() && "Expected ctor function name");
159 
160  if (Function *Ctor = M.getFunction(CtorName))
161  // FIXME: Sink this logic into the module, similar to the handling of
162  // globals. This will make moving to a concurrent model much easier.
163  if (Ctor->arg_size() == 0 ||
164  Ctor->getReturnType() == Type::getVoidTy(M.getContext()))
165  return {Ctor, declareSanitizerInitFunction(M, InitName, InitArgTypes)};
166 
167  Function *Ctor;
168  FunctionCallee InitFunction;
169  std::tie(Ctor, InitFunction) = llvm::createSanitizerCtorAndInitFunctions(
170  M, CtorName, InitName, InitArgTypes, InitArgs, VersionCheckName);
171  FunctionsCreatedCallback(Ctor, InitFunction);
172  return std::make_pair(Ctor, InitFunction);
173 }
174 
176  assert(!Name.empty() && "Expected init function name");
177  if (Function *F = M.getFunction(Name)) {
178  if (F->arg_size() != 0 ||
179  F->getReturnType() != Type::getVoidTy(M.getContext())) {
180  std::string Err;
181  raw_string_ostream Stream(Err);
182  Stream << "Sanitizer interface function defined with wrong type: " << *F;
183  report_fatal_error(Err);
184  }
185  return F;
186  }
187  Function *F =
188  cast<Function>(M.getOrInsertFunction(Name, AttributeList(),
189  Type::getVoidTy(M.getContext()))
190  .getCallee());
191 
192  appendToGlobalCtors(M, F, 0);
193 
194  return F;
195 }
196 
198  Module &M, SmallVectorImpl<Function *> &DeadComdatFunctions) {
199  // Build a map from the comdat to the number of entries in that comdat we
200  // think are dead. If this fully covers the comdat group, then the entire
201  // group is dead. If we find another entry in the comdat group though, we'll
202  // have to preserve the whole group.
203  SmallDenseMap<Comdat *, int, 16> ComdatEntriesCovered;
204  for (Function *F : DeadComdatFunctions) {
205  Comdat *C = F->getComdat();
206  assert(C && "Expected all input GVs to be in a comdat!");
207  ComdatEntriesCovered[C] += 1;
208  }
209 
210  auto CheckComdat = [&](Comdat &C) {
211  auto CI = ComdatEntriesCovered.find(&C);
212  if (CI == ComdatEntriesCovered.end())
213  return;
214 
215  // If this could have been covered by a dead entry, just subtract one to
216  // account for it.
217  if (CI->second > 0) {
218  CI->second -= 1;
219  return;
220  }
221 
222  // If we've already accounted for all the entries that were dead, the
223  // entire comdat is alive so remove it from the map.
224  ComdatEntriesCovered.erase(CI);
225  };
226 
227  auto CheckAllComdats = [&] {
228  for (Function &F : M.functions())
229  if (Comdat *C = F.getComdat()) {
230  CheckComdat(*C);
231  if (ComdatEntriesCovered.empty())
232  return;
233  }
234  for (GlobalVariable &GV : M.globals())
235  if (Comdat *C = GV.getComdat()) {
236  CheckComdat(*C);
237  if (ComdatEntriesCovered.empty())
238  return;
239  }
240  for (GlobalAlias &GA : M.aliases())
241  if (Comdat *C = GA.getComdat()) {
242  CheckComdat(*C);
243  if (ComdatEntriesCovered.empty())
244  return;
245  }
246  };
247  CheckAllComdats();
248 
249  if (ComdatEntriesCovered.empty()) {
250  DeadComdatFunctions.clear();
251  return;
252  }
253 
254  // Remove the entries that were not covering.
255  erase_if(DeadComdatFunctions, [&](GlobalValue *GV) {
256  return ComdatEntriesCovered.find(GV->getComdat()) ==
257  ComdatEntriesCovered.end();
258  });
259 }
260 
262  MD5 Md5;
263  bool ExportsSymbols = false;
264  auto AddGlobal = [&](GlobalValue &GV) {
265  if (GV.isDeclaration() || GV.getName().startswith("llvm.") ||
266  !GV.hasExternalLinkage() || GV.hasComdat())
267  return;
268  ExportsSymbols = true;
269  Md5.update(GV.getName());
270  Md5.update(ArrayRef<uint8_t>{0});
271  };
272 
273  for (auto &F : *M)
274  AddGlobal(F);
275  for (auto &GV : M->globals())
276  AddGlobal(GV);
277  for (auto &GA : M->aliases())
278  AddGlobal(GA);
279  for (auto &IF : M->ifuncs())
280  AddGlobal(IF);
281 
282  if (!ExportsSymbols)
283  return "";
284 
285  MD5::MD5Result R;
286  Md5.final(R);
287 
288  SmallString<32> Str;
289  MD5::stringifyResult(R, Str);
290  return ("$" + Str).str();
291 }
292 
294  CallInst *CI, const SmallVector<std::string, 8> &VariantMappings) {
295  if (VariantMappings.empty())
296  return;
297 
298  SmallString<256> Buffer;
299  llvm::raw_svector_ostream Out(Buffer);
300  for (const std::string &VariantMapping : VariantMappings)
301  Out << VariantMapping << ",";
302  // Get rid of the trailing ','.
303  assert(!Buffer.str().empty() && "Must have at least one char.");
304  Buffer.pop_back();
305 
306  Module *M = CI->getModule();
307 #ifndef NDEBUG
308  for (const std::string &VariantMapping : VariantMappings) {
309  LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << VariantMapping << "'\n");
310  Optional<VFInfo> VI = VFABI::tryDemangleForVFABI(VariantMapping, *M);
311  assert(VI.hasValue() && "Cannot add an invalid VFABI name.");
312  assert(M->getNamedValue(VI.getValue().VectorName) &&
313  "Cannot add variant to attribute: "
314  "vector function declaration is missing.");
315  }
316 #endif
317  CI->addAttribute(
319  Attribute::get(M->getContext(), MappingsAttrName, Buffer.str()));
320 }
uint64_t CallInst * C
void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
Definition: ModuleUtils.cpp:70
Special purpose, only applies to global arrays.
Definition: GlobalValue.h:54
Function * getOrCreateInitFunction(Module &M, StringRef Name)
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
This class represents lattice values for constants.
Definition: AllocatorList.h:23
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2427
std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef())
Creates sanitizer constructor function, and calls sanitizer's init function from it.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
static void stringifyResult(MD5Result &Result, SmallString< 32 > &Str)
Translates the bytes in Res to a hex string that is deposited into Str.
Definition: MD5.cpp:273
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:75
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:164
unsigned getNumElements() const
Random access to the elements.
Definition: DerivedTypes.h:326
This class represents a function call, abstracting a target machine's calling convention.
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:176
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:636
F(f)
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:148
void addAttribute(unsigned i, Attribute::AttrKind Kind)
adds the attribute to the list of attributes.
Definition: InstrTypes.h:1475
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:347
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:458
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
Definition: MD5.cpp:190
Class to represent struct types.
Definition: DerivedTypes.h:212
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes)
void filterDeadComdatFunctions(Module &M, SmallVectorImpl< Function * > &DeadComdatFunctions)
Filter out potentially dead comdat functions where other entries keep the entire comdat group alive.
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:156
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:292
Class to represent function types.
Definition: DerivedTypes.h:102
Class to represent array types.
Definition: DerivedTypes.h:356
static constexpr char const * MappingsAttrName
Definition: VectorUtils.h:200
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:321
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
std::pair< Function *, FunctionCallee > getOrCreateSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, function_ref< void(Function *, FunctionCallee)> FunctionsCreatedCallback, StringRef VersionCheckName=StringRef())
Creates sanitizer constructor function lazily.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2173
const BasicBlock & getEntryBlock() const
Definition: Function.h:731
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:137
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:46
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:156
This is an important base class in LLVM.
Definition: Constant.h:41
static void appendToGlobalArray(const char *Array, Module &M, Function *F, int Priority, Constant *Data)
Definition: ModuleUtils.cpp:25
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1230
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:364
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition: Globals.cpp:385
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:180
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:100
static Constant * get(StructType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1291
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...
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:249
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
Definition: Constants.cpp:1985
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:442
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the generic address space (address sp...
Definition: DerivedTypes.h:670
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition: Type.cpp:366
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1116
Module.h This file contains the declarations for the Module class.
void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
Definition: ModuleUtils.cpp:66
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:1667
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Definition: Instruction.cpp:65
const Comdat * getComdat() const
Definition: Globals.cpp:172
static void appendToUsedList(Module &M, StringRef Name, ArrayRef< GlobalValue * > Values)
Definition: ModuleUtils.cpp:74
Definition: MD5.h:41
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Definition: Type.cpp:581
Rename collisions when linking (static functions).
Definition: GlobalValue.h:55
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
Definition: Attributes.cpp:81
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:607
Function * createSanitizerCtor(Module &M, StringRef CtorName)
Creates sanitizer constructor function.
void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
Definition: MD5.cpp:235
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
Optional< VFInfo > tryDemangleForVFABI(StringRef MangledName, const Module &M)
Function to construct a VFInfo out of a mangled names in the following format:
#define LLVM_DEBUG(X)
Definition: Debug.h:122
void setVectorVariantNames(CallInst *CI, const SmallVector< std::string, 8 > &VariantMappings)
Overwrite the Vector Function ABI variants attribute with the names provide in VariantMappings.