Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Transforms/Utils/ModuleUtils.cpp
Line
Count
Source (jump to first uncovered line)
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
13
#include "llvm/Transforms/Utils/ModuleUtils.h"
14
#include "llvm/IR/DerivedTypes.h"
15
#include "llvm/IR/Function.h"
16
#include "llvm/IR/IRBuilder.h"
17
#include "llvm/IR/Module.h"
18
#include "llvm/Support/raw_ostream.h"
19
20
using namespace llvm;
21
22
static void appendToGlobalArray(const char *Array, Module &M, Function *F,
23
556
                                int Priority, Constant *Data) {
24
556
  IRBuilder<> IRB(M.getContext());
25
556
  FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false);
26
556
27
556
  // Get the current set of static global constructors and add the new ctor
28
556
  // to the list.
29
556
  SmallVector<Constant *, 16> CurrentCtors;
30
556
  StructType *EltTy = StructType::get(
31
556
      IRB.getInt32Ty(), PointerType::getUnqual(FnTy), IRB.getInt8PtrTy());
32
556
  if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) {
33
47
    if (Constant *Init = GVCtor->getInitializer()) {
34
47
      unsigned n = Init->getNumOperands();
35
47
      CurrentCtors.reserve(n + 1);
36
130
      for (unsigned i = 0; i != n; 
++i83
)
37
83
        CurrentCtors.push_back(cast<Constant>(Init->getOperand(i)));
38
47
    }
39
47
    GVCtor->eraseFromParent();
40
47
  }
41
556
42
556
  // Build a 3 field global_ctor entry.  We don't take a comdat key.
43
556
  Constant *CSVals[3];
44
556
  CSVals[0] = IRB.getInt32(Priority);
45
556
  CSVals[1] = F;
46
556
  CSVals[2] = Data ? 
ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy())184
47
556
                   : 
Constant::getNullValue(IRB.getInt8PtrTy())372
;
48
556
  Constant *RuntimeCtorInit =
49
556
      ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements()));
50
556
51
556
  CurrentCtors.push_back(RuntimeCtorInit);
52
556
53
556
  // Create a new initializer.
54
556
  ArrayType *AT = ArrayType::get(EltTy, CurrentCtors.size());
55
556
  Constant *NewInit = ConstantArray::get(AT, CurrentCtors);
56
556
57
556
  // Create the new global variable and replace all uses of
58
556
  // the old global variable with the new one.
59
556
  (void)new GlobalVariable(M, NewInit->getType(), false,
60
556
                           GlobalValue::AppendingLinkage, NewInit, Array);
61
556
}
62
63
490
void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data) {
64
490
  appendToGlobalArray("llvm.global_ctors", M, F, Priority, Data);
65
490
}
66
67
66
void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data) {
68
66
  appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data);
69
66
}
70
71
342
static void appendToUsedList(Module &M, StringRef Name, ArrayRef<GlobalValue *> Values) {
72
342
  GlobalVariable *GV = M.getGlobalVariable(Name);
73
342
  SmallPtrSet<Constant *, 16> InitAsSet;
74
342
  SmallVector<Constant *, 16> Init;
75
342
  if (GV) {
76
84
    ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer());
77
164
    for (auto &Op : CA->operands()) {
78
164
      Constant *C = cast_or_null<Constant>(Op);
79
164
      if (InitAsSet.insert(C).second)
80
164
        Init.push_back(C);
81
164
    }
82
84
    GV->eraseFromParent();
83
84
  }
84
342
85
342
  Type *Int8PtrTy = llvm::Type::getInt8PtrTy(M.getContext());
86
1.16k
  for (auto *V : Values) {
87
1.16k
    Constant *C = ConstantExpr::getBitCast(V, Int8PtrTy);
88
1.16k
    if (InitAsSet.insert(C).second)
89
1.16k
      Init.push_back(C);
90
1.16k
  }
91
342
92
342
  if (Init.empty())
93
9
    return;
94
333
95
333
  ArrayType *ATy = ArrayType::get(Int8PtrTy, Init.size());
96
333
  GV = new llvm::GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage,
97
333
                                ConstantArray::get(ATy, Init), Name);
98
333
  GV->setSection("llvm.metadata");
99
333
}
100
101
162
void llvm::appendToUsed(Module &M, ArrayRef<GlobalValue *> Values) {
102
162
  appendToUsedList(M, "llvm.used", Values);
103
162
}
104
105
180
void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) {
106
180
  appendToUsedList(M, "llvm.compiler.used", Values);
107
180
}
108
109
FunctionCallee
110
llvm::declareSanitizerInitFunction(Module &M, StringRef InitName,
111
801
                                   ArrayRef<Type *> InitArgTypes) {
112
801
  assert(!InitName.empty() && "Expected init function name");
113
801
  return M.getOrInsertFunction(
114
801
      InitName,
115
801
      FunctionType::get(Type::getVoidTy(M.getContext()), InitArgTypes, false),
116
801
      AttributeList());
117
801
}
118
119
std::pair<Function *, FunctionCallee> llvm::createSanitizerCtorAndInitFunctions(
120
    Module &M, StringRef CtorName, StringRef InitName,
121
    ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
122
423
    StringRef VersionCheckName) {
123
423
  assert(!InitName.empty() && "Expected init function name");
124
423
  assert(InitArgs.size() == InitArgTypes.size() &&
125
423
         "Sanitizer's init function expects different number of arguments");
126
423
  FunctionCallee InitFunction =
127
423
      declareSanitizerInitFunction(M, InitName, InitArgTypes);
128
423
  Function *Ctor = Function::Create(
129
423
      FunctionType::get(Type::getVoidTy(M.getContext()), false),
130
423
      GlobalValue::InternalLinkage, CtorName, &M);
131
423
  BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor);
132
423
  IRBuilder<> IRB(ReturnInst::Create(M.getContext(), CtorBB));
133
423
  IRB.CreateCall(InitFunction, InitArgs);
134
423
  if (!VersionCheckName.empty()) {
135
167
    FunctionCallee VersionCheckFunction = M.getOrInsertFunction(
136
167
        VersionCheckName, FunctionType::get(IRB.getVoidTy(), {}, false),
137
167
        AttributeList());
138
167
    IRB.CreateCall(VersionCheckFunction, {});
139
167
  }
140
423
  return std::make_pair(Ctor, InitFunction);
141
423
}
142
143
std::pair<Function *, FunctionCallee>
144
llvm::getOrCreateSanitizerCtorAndInitFunctions(
145
    Module &M, StringRef CtorName, StringRef InitName,
146
    ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
147
    function_ref<void(Function *, FunctionCallee)> FunctionsCreatedCallback,
148
596
    StringRef VersionCheckName) {
149
596
  assert(!CtorName.empty() && "Expected ctor function name");
150
596
151
596
  if (Function *Ctor = M.getFunction(CtorName))
152
372
    // FIXME: Sink this logic into the module, similar to the handling of
153
372
    // globals. This will make moving to a concurrent model much easier.
154
372
    if (Ctor->arg_size() == 0 ||
155
372
        
Ctor->getReturnType() == Type::getVoidTy(M.getContext())0
)
156
372
      return {Ctor, declareSanitizerInitFunction(M, InitName, InitArgTypes)};
157
224
158
224
  Function *Ctor;
159
224
  FunctionCallee InitFunction;
160
224
  std::tie(Ctor, InitFunction) = llvm::createSanitizerCtorAndInitFunctions(
161
224
      M, CtorName, InitName, InitArgTypes, InitArgs, VersionCheckName);
162
224
  FunctionsCreatedCallback(Ctor, InitFunction);
163
224
  return std::make_pair(Ctor, InitFunction);
164
224
}
165
166
0
Function *llvm::getOrCreateInitFunction(Module &M, StringRef Name) {
167
0
  assert(!Name.empty() && "Expected init function name");
168
0
  if (Function *F = M.getFunction(Name)) {
169
0
    if (F->arg_size() != 0 ||
170
0
        F->getReturnType() != Type::getVoidTy(M.getContext())) {
171
0
      std::string Err;
172
0
      raw_string_ostream Stream(Err);
173
0
      Stream << "Sanitizer interface function defined with wrong type: " << *F;
174
0
      report_fatal_error(Err);
175
0
    }
176
0
    return F;
177
0
  }
178
0
  Function *F =
179
0
      cast<Function>(M.getOrInsertFunction(Name, AttributeList(),
180
0
                                           Type::getVoidTy(M.getContext()))
181
0
                         .getCallee());
182
0
183
0
  appendToGlobalCtors(M, F, 0);
184
0
185
0
  return F;
186
0
}
187
188
void llvm::filterDeadComdatFunctions(
189
24
    Module &M, SmallVectorImpl<Function *> &DeadComdatFunctions) {
190
24
  // Build a map from the comdat to the number of entries in that comdat we
191
24
  // think are dead. If this fully covers the comdat group, then the entire
192
24
  // group is dead. If we find another entry in the comdat group though, we'll
193
24
  // have to preserve the whole group.
194
24
  SmallDenseMap<Comdat *, int, 16> ComdatEntriesCovered;
195
66
  for (Function *F : DeadComdatFunctions) {
196
66
    Comdat *C = F->getComdat();
197
66
    assert(C && "Expected all input GVs to be in a comdat!");
198
66
    ComdatEntriesCovered[C] += 1;
199
66
  }
200
24
201
457
  auto CheckComdat = [&](Comdat &C) {
202
457
    auto CI = ComdatEntriesCovered.find(&C);
203
457
    if (CI == ComdatEntriesCovered.end())
204
386
      return;
205
71
206
71
    // If this could have been covered by a dead entry, just subtract one to
207
71
    // account for it.
208
71
    if (CI->second > 0) {
209
66
      CI->second -= 1;
210
66
      return;
211
66
    }
212
5
213
5
    // If we've already accounted for all the entries that were dead, the
214
5
    // entire comdat is alive so remove it from the map.
215
5
    ComdatEntriesCovered.erase(CI);
216
5
  };
217
24
218
24
  auto CheckAllComdats = [&] {
219
24
    for (Function &F : M.functions())
220
1.34k
      if (Comdat *C = F.getComdat()) {
221
424
        CheckComdat(*C);
222
424
        if (ComdatEntriesCovered.empty())
223
1
          return;
224
424
      }
225
24
    
for (GlobalVariable &GV : M.globals())23
226
237
      if (Comdat *C = GV.getComdat()) {
227
33
        CheckComdat(*C);
228
33
        if (ComdatEntriesCovered.empty())
229
0
          return;
230
33
      }
231
23
    for (GlobalAlias &GA : M.aliases())
232
0
      if (Comdat *C = GA.getComdat()) {
233
0
        CheckComdat(*C);
234
0
        if (ComdatEntriesCovered.empty())
235
0
          return;
236
0
      }
237
23
  };
238
24
  CheckAllComdats();
239
24
240
24
  if (ComdatEntriesCovered.empty()) {
241
1
    DeadComdatFunctions.clear();
242
1
    return;
243
1
  }
244
23
245
23
  // Remove the entries that were not covering.
246
65
  
erase_if(DeadComdatFunctions, [&](GlobalValue *GV) 23
{
247
65
    return ComdatEntriesCovered.find(GV->getComdat()) ==
248
65
           ComdatEntriesCovered.end();
249
65
  });
250
23
}
251
252
157
std::string llvm::getUniqueModuleId(Module *M) {
253
157
  MD5 Md5;
254
157
  bool ExportsSymbols = false;
255
1.73k
  auto AddGlobal = [&](GlobalValue &GV) {
256
1.73k
    if (GV.isDeclaration() || 
GV.getName().startswith("llvm.")789
||
257
1.73k
        
!GV.hasExternalLinkage()763
||
GV.hasComdat()500
)
258
1.24k
      return;
259
495
    ExportsSymbols = true;
260
495
    Md5.update(GV.getName());
261
495
    Md5.update(ArrayRef<uint8_t>{0});
262
495
  };
263
157
264
157
  for (auto &F : *M)
265
1.36k
    AddGlobal(F);
266
157
  for (auto &GV : M->globals())
267
350
    AddGlobal(GV);
268
157
  for (auto &GA : M->aliases())
269
17
    AddGlobal(GA);
270
157
  for (auto &IF : M->ifuncs())
271
0
    AddGlobal(IF);
272
157
273
157
  if (!ExportsSymbols)
274
4
    return "";
275
153
276
153
  MD5::MD5Result R;
277
153
  Md5.final(R);
278
153
279
153
  SmallString<32> Str;
280
153
  MD5::stringifyResult(R, Str);
281
153
  return ("$" + Str).str();
282
153
}