Coverage Report

Created: 2017-10-03 07:32

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