Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Transforms/Utils/SymbolRewriter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- SymbolRewriter.cpp - Symbol Rewriter ---------------------*- C++ -*-===//
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
// SymbolRewriter is a LLVM pass which can rewrite symbols transparently within
11
// existing code.  It is implemented as a compiler pass and is configured via a
12
// YAML configuration file.
13
//
14
// The YAML configuration file format is as follows:
15
//
16
// RewriteMapFile := RewriteDescriptors
17
// RewriteDescriptors := RewriteDescriptor | RewriteDescriptors
18
// RewriteDescriptor := RewriteDescriptorType ':' '{' RewriteDescriptorFields '}'
19
// RewriteDescriptorFields := RewriteDescriptorField | RewriteDescriptorFields
20
// RewriteDescriptorField := FieldIdentifier ':' FieldValue ','
21
// RewriteDescriptorType := Identifier
22
// FieldIdentifier := Identifier
23
// FieldValue := Identifier
24
// Identifier := [0-9a-zA-Z]+
25
//
26
// Currently, the following descriptor types are supported:
27
//
28
// - function:          (function rewriting)
29
//      + Source        (original name of the function)
30
//      + Target        (explicit transformation)
31
//      + Transform     (pattern transformation)
32
//      + Naked         (boolean, whether the function is undecorated)
33
// - global variable:   (external linkage global variable rewriting)
34
//      + Source        (original name of externally visible variable)
35
//      + Target        (explicit transformation)
36
//      + Transform     (pattern transformation)
37
// - global alias:      (global alias rewriting)
38
//      + Source        (original name of the aliased name)
39
//      + Target        (explicit transformation)
40
//      + Transform     (pattern transformation)
41
//
42
// Note that source and exactly one of [Target, Transform] must be provided
43
//
44
// New rewrite descriptors can be created.  Addding a new rewrite descriptor
45
// involves:
46
//
47
//  a) extended the rewrite descriptor kind enumeration
48
//     (<anonymous>::RewriteDescriptor::RewriteDescriptorType)
49
//  b) implementing the new descriptor
50
//     (c.f. <anonymous>::ExplicitRewriteFunctionDescriptor)
51
//  c) extending the rewrite map parser
52
//     (<anonymous>::RewriteMapParser::parseEntry)
53
//
54
//  Specify to rewrite the symbols using the `-rewrite-symbols` option, and
55
//  specify the map file to use for the rewriting via the `-rewrite-map-file`
56
//  option.
57
//
58
//===----------------------------------------------------------------------===//
59
60
#define DEBUG_TYPE "symbol-rewriter"
61
#include "llvm/Transforms/Utils/SymbolRewriter.h"
62
#include "llvm/ADT/SmallString.h"
63
#include "llvm/IR/LegacyPassManager.h"
64
#include "llvm/Pass.h"
65
#include "llvm/Support/CommandLine.h"
66
#include "llvm/Support/Debug.h"
67
#include "llvm/Support/MemoryBuffer.h"
68
#include "llvm/Support/Regex.h"
69
#include "llvm/Support/SourceMgr.h"
70
#include "llvm/Support/YAMLParser.h"
71
#include "llvm/Support/raw_ostream.h"
72
73
using namespace llvm;
74
using namespace SymbolRewriter;
75
76
static cl::list<std::string> RewriteMapFiles("rewrite-map-file",
77
                                             cl::desc("Symbol Rewrite Map"),
78
                                             cl::value_desc("filename"));
79
80
static void rewriteComdat(Module &M, GlobalObject *GO,
81
                          const std::string &Source,
82
24
                          const std::string &Target) {
83
24
  if (Comdat *
CD24
= GO->getComdat()) {
84
8
    auto &Comdats = M.getComdatSymbolTable();
85
8
86
8
    Comdat *C = M.getOrInsertComdat(Target);
87
8
    C->setSelectionKind(CD->getSelectionKind());
88
8
    GO->setComdat(C);
89
8
90
8
    Comdats.erase(Comdats.find(Source));
91
8
  }
92
24
}
93
94
namespace {
95
template <RewriteDescriptor::Type DT, typename ValueType,
96
          ValueType *(llvm::Module::*Get)(StringRef) const>
97
class ExplicitRewriteDescriptor : public RewriteDescriptor {
98
public:
99
  const std::string Source;
100
  const std::string Target;
101
102
  ExplicitRewriteDescriptor(StringRef S, StringRef T, const bool Naked)
103
      : RewriteDescriptor(DT), Source(Naked ? StringRef("\01" + S.str()) : S),
104
18
        Target(T) {}
SymbolRewriter.cpp:(anonymous namespace)::ExplicitRewriteDescriptor<(llvm::SymbolRewriter::RewriteDescriptor::Type)1, llvm::Function, &(llvm::Module::getFunction(llvm::StringRef) const)>::ExplicitRewriteDescriptor(llvm::StringRef, llvm::StringRef, bool)
Line
Count
Source
104
12
        Target(T) {}
SymbolRewriter.cpp:(anonymous namespace)::ExplicitRewriteDescriptor<(llvm::SymbolRewriter::RewriteDescriptor::Type)2, llvm::GlobalVariable, &(llvm::Module::getGlobalVariable(llvm::StringRef) const)>::ExplicitRewriteDescriptor(llvm::StringRef, llvm::StringRef, bool)
Line
Count
Source
104
4
        Target(T) {}
SymbolRewriter.cpp:(anonymous namespace)::ExplicitRewriteDescriptor<(llvm::SymbolRewriter::RewriteDescriptor::Type)3, llvm::GlobalAlias, &(llvm::Module::getNamedAlias(llvm::StringRef) const)>::ExplicitRewriteDescriptor(llvm::StringRef, llvm::StringRef, bool)
Line
Count
Source
104
2
        Target(T) {}
105
106
  bool performOnModule(Module &M) override;
107
108
  static bool classof(const RewriteDescriptor *RD) {
109
    return RD->getType() == DT;
110
  }
111
};
112
113
template <RewriteDescriptor::Type DT, typename ValueType,
114
          ValueType *(llvm::Module::*Get)(StringRef) const>
115
18
bool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) {
116
18
  bool Changed = false;
117
18
  if (ValueType *
S18
= (M.*Get)(Source)) {
118
14
    if (GlobalObject *GO = dyn_cast<GlobalObject>(S))
119
12
      rewriteComdat(M, GO, Source, Target);
120
14
121
14
    if (Value *T = (M.*Get)(Target))
122
0
      S->setValueName(T->getValueName());
123
14
    else
124
14
      S->setName(Target);
125
14
126
14
    Changed = true;
127
14
  }
128
18
  return Changed;
129
18
}
SymbolRewriter.cpp:(anonymous namespace)::ExplicitRewriteDescriptor<(llvm::SymbolRewriter::RewriteDescriptor::Type)1, llvm::Function, &(llvm::Module::getFunction(llvm::StringRef) const)>::performOnModule(llvm::Module&)
Line
Count
Source
115
12
bool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) {
116
12
  bool Changed = false;
117
12
  if (ValueType *
S12
= (M.*Get)(Source)) {
118
8
    if (GlobalObject *GO = dyn_cast<GlobalObject>(S))
119
8
      rewriteComdat(M, GO, Source, Target);
120
8
121
8
    if (Value *T = (M.*Get)(Target))
122
0
      S->setValueName(T->getValueName());
123
8
    else
124
8
      S->setName(Target);
125
8
126
8
    Changed = true;
127
8
  }
128
12
  return Changed;
129
12
}
SymbolRewriter.cpp:(anonymous namespace)::ExplicitRewriteDescriptor<(llvm::SymbolRewriter::RewriteDescriptor::Type)2, llvm::GlobalVariable, &(llvm::Module::getGlobalVariable(llvm::StringRef) const)>::performOnModule(llvm::Module&)
Line
Count
Source
115
4
bool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) {
116
4
  bool Changed = false;
117
4
  if (ValueType *
S4
= (M.*Get)(Source)) {
118
4
    if (GlobalObject *GO = dyn_cast<GlobalObject>(S))
119
4
      rewriteComdat(M, GO, Source, Target);
120
4
121
4
    if (Value *T = (M.*Get)(Target))
122
0
      S->setValueName(T->getValueName());
123
4
    else
124
4
      S->setName(Target);
125
4
126
4
    Changed = true;
127
4
  }
128
4
  return Changed;
129
4
}
SymbolRewriter.cpp:(anonymous namespace)::ExplicitRewriteDescriptor<(llvm::SymbolRewriter::RewriteDescriptor::Type)3, llvm::GlobalAlias, &(llvm::Module::getNamedAlias(llvm::StringRef) const)>::performOnModule(llvm::Module&)
Line
Count
Source
115
2
bool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) {
116
2
  bool Changed = false;
117
2
  if (ValueType *
S2
= (M.*Get)(Source)) {
118
2
    if (GlobalObject *GO = dyn_cast<GlobalObject>(S))
119
0
      rewriteComdat(M, GO, Source, Target);
120
2
121
2
    if (Value *T = (M.*Get)(Target))
122
0
      S->setValueName(T->getValueName());
123
2
    else
124
2
      S->setName(Target);
125
2
126
2
    Changed = true;
127
2
  }
128
2
  return Changed;
129
2
}
130
131
template <RewriteDescriptor::Type DT, typename ValueType,
132
          ValueType *(llvm::Module::*Get)(StringRef) const,
133
          iterator_range<typename iplist<ValueType>::iterator>
134
          (llvm::Module::*Iterator)()>
135
class PatternRewriteDescriptor : public RewriteDescriptor {
136
public:
137
  const std::string Pattern;
138
  const std::string Transform;
139
140
  PatternRewriteDescriptor(StringRef P, StringRef T)
141
8
    : RewriteDescriptor(DT), Pattern(P), Transform(T) { }
SymbolRewriter.cpp:(anonymous namespace)::PatternRewriteDescriptor<(llvm::SymbolRewriter::RewriteDescriptor::Type)1, llvm::Function, &(llvm::Module::getFunction(llvm::StringRef) const), &(llvm::Module::functions())>::PatternRewriteDescriptor(llvm::StringRef, llvm::StringRef)
Line
Count
Source
141
4
    : RewriteDescriptor(DT), Pattern(P), Transform(T) { }
SymbolRewriter.cpp:(anonymous namespace)::PatternRewriteDescriptor<(llvm::SymbolRewriter::RewriteDescriptor::Type)2, llvm::GlobalVariable, &(llvm::Module::getGlobalVariable(llvm::StringRef) const), &(llvm::Module::globals())>::PatternRewriteDescriptor(llvm::StringRef, llvm::StringRef)
Line
Count
Source
141
4
    : RewriteDescriptor(DT), Pattern(P), Transform(T) { }
Unexecuted instantiation: SymbolRewriter.cpp:(anonymous namespace)::PatternRewriteDescriptor<(llvm::SymbolRewriter::RewriteDescriptor::Type)3, llvm::GlobalAlias, &(llvm::Module::getNamedAlias(llvm::StringRef) const), &(llvm::Module::aliases())>::PatternRewriteDescriptor(llvm::StringRef, llvm::StringRef)
142
143
  bool performOnModule(Module &M) override;
144
145
  static bool classof(const RewriteDescriptor *RD) {
146
    return RD->getType() == DT;
147
  }
148
};
149
150
template <RewriteDescriptor::Type DT, typename ValueType,
151
          ValueType *(llvm::Module::*Get)(StringRef) const,
152
          iterator_range<typename iplist<ValueType>::iterator>
153
          (llvm::Module::*Iterator)()>
154
bool PatternRewriteDescriptor<DT, ValueType, Get, Iterator>::
155
8
performOnModule(Module &M) {
156
8
  bool Changed = false;
157
64
  for (auto &C : (M.*Iterator)()) {
158
64
    std::string Error;
159
64
160
64
    std::string Name = Regex(Pattern).sub(Transform, C.getName(), &Error);
161
64
    if (!Error.empty())
162
0
      report_fatal_error("unable to transforn " + C.getName() + " in " +
163
0
                         M.getModuleIdentifier() + ": " + Error);
164
64
165
64
    
if (64
C.getName() == Name64
)
166
52
      continue;
167
12
168
12
    
if (GlobalObject *12
GO12
= dyn_cast<GlobalObject>(&C))
169
12
      rewriteComdat(M, GO, C.getName(), Name);
170
12
171
12
    if (Value *V = (M.*Get)(Name))
172
0
      C.setValueName(V->getValueName());
173
12
    else
174
12
      C.setName(Name);
175
64
176
64
    Changed = true;
177
64
  }
178
8
  return Changed;
179
8
}
SymbolRewriter.cpp:(anonymous namespace)::PatternRewriteDescriptor<(llvm::SymbolRewriter::RewriteDescriptor::Type)1, llvm::Function, &(llvm::Module::getFunction(llvm::StringRef) const), &(llvm::Module::functions())>::performOnModule(llvm::Module&)
Line
Count
Source
155
4
performOnModule(Module &M) {
156
4
  bool Changed = false;
157
44
  for (auto &C : (M.*Iterator)()) {
158
44
    std::string Error;
159
44
160
44
    std::string Name = Regex(Pattern).sub(Transform, C.getName(), &Error);
161
44
    if (!Error.empty())
162
0
      report_fatal_error("unable to transforn " + C.getName() + " in " +
163
0
                         M.getModuleIdentifier() + ": " + Error);
164
44
165
44
    
if (44
C.getName() == Name44
)
166
38
      continue;
167
6
168
6
    
if (GlobalObject *6
GO6
= dyn_cast<GlobalObject>(&C))
169
6
      rewriteComdat(M, GO, C.getName(), Name);
170
6
171
6
    if (Value *V = (M.*Get)(Name))
172
0
      C.setValueName(V->getValueName());
173
6
    else
174
6
      C.setName(Name);
175
44
176
44
    Changed = true;
177
44
  }
178
4
  return Changed;
179
4
}
SymbolRewriter.cpp:(anonymous namespace)::PatternRewriteDescriptor<(llvm::SymbolRewriter::RewriteDescriptor::Type)2, llvm::GlobalVariable, &(llvm::Module::getGlobalVariable(llvm::StringRef) const), &(llvm::Module::globals())>::performOnModule(llvm::Module&)
Line
Count
Source
155
4
performOnModule(Module &M) {
156
4
  bool Changed = false;
157
20
  for (auto &C : (M.*Iterator)()) {
158
20
    std::string Error;
159
20
160
20
    std::string Name = Regex(Pattern).sub(Transform, C.getName(), &Error);
161
20
    if (!Error.empty())
162
0
      report_fatal_error("unable to transforn " + C.getName() + " in " +
163
0
                         M.getModuleIdentifier() + ": " + Error);
164
20
165
20
    
if (20
C.getName() == Name20
)
166
14
      continue;
167
6
168
6
    
if (GlobalObject *6
GO6
= dyn_cast<GlobalObject>(&C))
169
6
      rewriteComdat(M, GO, C.getName(), Name);
170
6
171
6
    if (Value *V = (M.*Get)(Name))
172
0
      C.setValueName(V->getValueName());
173
6
    else
174
6
      C.setName(Name);
175
20
176
20
    Changed = true;
177
20
  }
178
4
  return Changed;
179
4
}
Unexecuted instantiation: SymbolRewriter.cpp:(anonymous namespace)::PatternRewriteDescriptor<(llvm::SymbolRewriter::RewriteDescriptor::Type)3, llvm::GlobalAlias, &(llvm::Module::getNamedAlias(llvm::StringRef) const), &(llvm::Module::aliases())>::performOnModule(llvm::Module&)
180
181
/// Represents a rewrite for an explicitly named (function) symbol.  Both the
182
/// source function name and target function name of the transformation are
183
/// explicitly spelt out.
184
typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function,
185
                                  llvm::Function, &llvm::Module::getFunction>
186
    ExplicitRewriteFunctionDescriptor;
187
188
/// Represents a rewrite for an explicitly named (global variable) symbol.  Both
189
/// the source variable name and target variable name are spelt out.  This
190
/// applies only to module level variables.
191
typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
192
                                  llvm::GlobalVariable,
193
                                  &llvm::Module::getGlobalVariable>
194
    ExplicitRewriteGlobalVariableDescriptor;
195
196
/// Represents a rewrite for an explicitly named global alias.  Both the source
197
/// and target name are explicitly spelt out.
198
typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias,
199
                                  llvm::GlobalAlias,
200
                                  &llvm::Module::getNamedAlias>
201
    ExplicitRewriteNamedAliasDescriptor;
202
203
/// Represents a rewrite for a regular expression based pattern for functions.
204
/// A pattern for the function name is provided and a transformation for that
205
/// pattern to determine the target function name create the rewrite rule.
206
typedef PatternRewriteDescriptor<RewriteDescriptor::Type::Function,
207
                                 llvm::Function, &llvm::Module::getFunction,
208
                                 &llvm::Module::functions>
209
    PatternRewriteFunctionDescriptor;
210
211
/// Represents a rewrite for a global variable based upon a matching pattern.
212
/// Each global variable matching the provided pattern will be transformed as
213
/// described in the transformation pattern for the target.  Applies only to
214
/// module level variables.
215
typedef PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
216
                                 llvm::GlobalVariable,
217
                                 &llvm::Module::getGlobalVariable,
218
                                 &llvm::Module::globals>
219
    PatternRewriteGlobalVariableDescriptor;
220
221
/// PatternRewriteNamedAliasDescriptor - represents a rewrite for global
222
/// aliases which match a given pattern.  The provided transformation will be
223
/// applied to each of the matching names.
224
typedef PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias,
225
                                 llvm::GlobalAlias,
226
                                 &llvm::Module::getNamedAlias,
227
                                 &llvm::Module::aliases>
228
    PatternRewriteNamedAliasDescriptor;
229
} // namespace
230
231
bool RewriteMapParser::parse(const std::string &MapFile,
232
2
                             RewriteDescriptorList *DL) {
233
2
  ErrorOr<std::unique_ptr<MemoryBuffer>> Mapping =
234
2
      MemoryBuffer::getFile(MapFile);
235
2
236
2
  if (!Mapping)
237
0
    report_fatal_error("unable to read rewrite map '" + MapFile + "': " +
238
0
                       Mapping.getError().message());
239
2
240
2
  
if (2
!parse(*Mapping, DL)2
)
241
0
    report_fatal_error("unable to parse rewrite map '" + MapFile + "'");
242
2
243
2
  return true;
244
2
}
245
246
bool RewriteMapParser::parse(std::unique_ptr<MemoryBuffer> &MapFile,
247
2
                             RewriteDescriptorList *DL) {
248
2
  SourceMgr SM;
249
2
  yaml::Stream YS(MapFile->getBuffer(), SM);
250
2
251
2
  for (auto &Document : YS) {
252
2
    yaml::MappingNode *DescriptorList;
253
2
254
2
    // ignore empty documents
255
2
    if (isa<yaml::NullNode>(Document.getRoot()))
256
0
      continue;
257
2
258
2
    DescriptorList = dyn_cast<yaml::MappingNode>(Document.getRoot());
259
2
    if (
!DescriptorList2
) {
260
0
      YS.printError(Document.getRoot(), "DescriptorList node must be a map");
261
0
      return false;
262
0
    }
263
2
264
2
    for (auto &Descriptor : *DescriptorList)
265
26
      
if (26
!parseEntry(YS, Descriptor, DL)26
)
266
0
        return false;
267
2
  }
268
2
269
2
  return true;
270
2
}
271
272
bool RewriteMapParser::parseEntry(yaml::Stream &YS, yaml::KeyValueNode &Entry,
273
26
                                  RewriteDescriptorList *DL) {
274
26
  yaml::ScalarNode *Key;
275
26
  yaml::MappingNode *Value;
276
26
  SmallString<32> KeyStorage;
277
26
  StringRef RewriteType;
278
26
279
26
  Key = dyn_cast<yaml::ScalarNode>(Entry.getKey());
280
26
  if (
!Key26
) {
281
0
    YS.printError(Entry.getKey(), "rewrite type must be a scalar");
282
0
    return false;
283
0
  }
284
26
285
26
  Value = dyn_cast<yaml::MappingNode>(Entry.getValue());
286
26
  if (
!Value26
) {
287
0
    YS.printError(Entry.getValue(), "rewrite descriptor must be a map");
288
0
    return false;
289
0
  }
290
26
291
26
  RewriteType = Key->getValue(KeyStorage);
292
26
  if (RewriteType.equals("function"))
293
16
    return parseRewriteFunctionDescriptor(YS, Key, Value, DL);
294
10
  else 
if (10
RewriteType.equals("global variable")10
)
295
8
    return parseRewriteGlobalVariableDescriptor(YS, Key, Value, DL);
296
2
  else 
if (2
RewriteType.equals("global alias")2
)
297
2
    return parseRewriteGlobalAliasDescriptor(YS, Key, Value, DL);
298
0
299
0
  YS.printError(Entry.getKey(), "unknown rewrite type");
300
0
  return false;
301
0
}
302
303
bool RewriteMapParser::
304
parseRewriteFunctionDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
305
                               yaml::MappingNode *Descriptor,
306
16
                               RewriteDescriptorList *DL) {
307
16
  bool Naked = false;
308
16
  std::string Source;
309
16
  std::string Target;
310
16
  std::string Transform;
311
16
312
34
  for (auto &Field : *Descriptor) {
313
34
    yaml::ScalarNode *Key;
314
34
    yaml::ScalarNode *Value;
315
34
    SmallString<32> KeyStorage;
316
34
    SmallString<32> ValueStorage;
317
34
    StringRef KeyValue;
318
34
319
34
    Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
320
34
    if (
!Key34
) {
321
0
      YS.printError(Field.getKey(), "descriptor key must be a scalar");
322
0
      return false;
323
0
    }
324
34
325
34
    Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
326
34
    if (
!Value34
) {
327
0
      YS.printError(Field.getValue(), "descriptor value must be a scalar");
328
0
      return false;
329
0
    }
330
34
331
34
    KeyValue = Key->getValue(KeyStorage);
332
34
    if (
KeyValue.equals("source")34
) {
333
16
      std::string Error;
334
16
335
16
      Source = Value->getValue(ValueStorage);
336
16
      if (
!Regex(Source).isValid(Error)16
) {
337
0
        YS.printError(Field.getKey(), "invalid regex: " + Error);
338
0
        return false;
339
0
      }
340
18
    } else 
if (18
KeyValue.equals("target")18
) {
341
12
      Target = Value->getValue(ValueStorage);
342
18
    } else 
if (6
KeyValue.equals("transform")6
) {
343
4
      Transform = Value->getValue(ValueStorage);
344
6
    } else 
if (2
KeyValue.equals("naked")2
) {
345
2
      std::string Undecorated;
346
2
347
2
      Undecorated = Value->getValue(ValueStorage);
348
0
      Naked = StringRef(Undecorated).lower() == "true" || Undecorated == "1";
349
0
    } else {
350
0
      YS.printError(Field.getKey(), "unknown key for function");
351
0
      return false;
352
0
    }
353
16
  }
354
16
355
16
  
if (16
Transform.empty() == Target.empty()16
) {
356
0
    YS.printError(Descriptor,
357
0
                  "exactly one of transform or target must be specified");
358
0
    return false;
359
0
  }
360
16
361
16
  // TODO see if there is a more elegant solution to selecting the rewrite
362
16
  // descriptor type
363
16
  
if (16
!Target.empty()16
)
364
12
    DL->push_back(llvm::make_unique<ExplicitRewriteFunctionDescriptor>(
365
12
        Source, Target, Naked));
366
16
  else
367
4
    DL->push_back(
368
4
        llvm::make_unique<PatternRewriteFunctionDescriptor>(Source, Transform));
369
16
370
16
  return true;
371
16
}
372
373
bool RewriteMapParser::
374
parseRewriteGlobalVariableDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
375
                                     yaml::MappingNode *Descriptor,
376
8
                                     RewriteDescriptorList *DL) {
377
8
  std::string Source;
378
8
  std::string Target;
379
8
  std::string Transform;
380
8
381
16
  for (auto &Field : *Descriptor) {
382
16
    yaml::ScalarNode *Key;
383
16
    yaml::ScalarNode *Value;
384
16
    SmallString<32> KeyStorage;
385
16
    SmallString<32> ValueStorage;
386
16
    StringRef KeyValue;
387
16
388
16
    Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
389
16
    if (
!Key16
) {
390
0
      YS.printError(Field.getKey(), "descriptor Key must be a scalar");
391
0
      return false;
392
0
    }
393
16
394
16
    Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
395
16
    if (
!Value16
) {
396
0
      YS.printError(Field.getValue(), "descriptor value must be a scalar");
397
0
      return false;
398
0
    }
399
16
400
16
    KeyValue = Key->getValue(KeyStorage);
401
16
    if (
KeyValue.equals("source")16
) {
402
8
      std::string Error;
403
8
404
8
      Source = Value->getValue(ValueStorage);
405
8
      if (
!Regex(Source).isValid(Error)8
) {
406
0
        YS.printError(Field.getKey(), "invalid regex: " + Error);
407
0
        return false;
408
0
      }
409
8
    } else 
if (8
KeyValue.equals("target")8
) {
410
4
      Target = Value->getValue(ValueStorage);
411
8
    } else 
if (4
KeyValue.equals("transform")4
) {
412
4
      Transform = Value->getValue(ValueStorage);
413
4
    } else {
414
0
      YS.printError(Field.getKey(), "unknown Key for Global Variable");
415
0
      return false;
416
0
    }
417
8
  }
418
8
419
8
  
if (8
Transform.empty() == Target.empty()8
) {
420
0
    YS.printError(Descriptor,
421
0
                  "exactly one of transform or target must be specified");
422
0
    return false;
423
0
  }
424
8
425
8
  
if (8
!Target.empty()8
)
426
4
    DL->push_back(llvm::make_unique<ExplicitRewriteGlobalVariableDescriptor>(
427
4
        Source, Target,
428
4
        /*Naked*/ false));
429
8
  else
430
4
    DL->push_back(llvm::make_unique<PatternRewriteGlobalVariableDescriptor>(
431
4
        Source, Transform));
432
8
433
8
  return true;
434
8
}
435
436
bool RewriteMapParser::
437
parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
438
                                  yaml::MappingNode *Descriptor,
439
2
                                  RewriteDescriptorList *DL) {
440
2
  std::string Source;
441
2
  std::string Target;
442
2
  std::string Transform;
443
2
444
4
  for (auto &Field : *Descriptor) {
445
4
    yaml::ScalarNode *Key;
446
4
    yaml::ScalarNode *Value;
447
4
    SmallString<32> KeyStorage;
448
4
    SmallString<32> ValueStorage;
449
4
    StringRef KeyValue;
450
4
451
4
    Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
452
4
    if (
!Key4
) {
453
0
      YS.printError(Field.getKey(), "descriptor key must be a scalar");
454
0
      return false;
455
0
    }
456
4
457
4
    Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
458
4
    if (
!Value4
) {
459
0
      YS.printError(Field.getValue(), "descriptor value must be a scalar");
460
0
      return false;
461
0
    }
462
4
463
4
    KeyValue = Key->getValue(KeyStorage);
464
4
    if (
KeyValue.equals("source")4
) {
465
2
      std::string Error;
466
2
467
2
      Source = Value->getValue(ValueStorage);
468
2
      if (
!Regex(Source).isValid(Error)2
) {
469
0
        YS.printError(Field.getKey(), "invalid regex: " + Error);
470
0
        return false;
471
0
      }
472
2
    } else 
if (2
KeyValue.equals("target")2
) {
473
2
      Target = Value->getValue(ValueStorage);
474
2
    } else 
if (0
KeyValue.equals("transform")0
) {
475
0
      Transform = Value->getValue(ValueStorage);
476
0
    } else {
477
0
      YS.printError(Field.getKey(), "unknown key for Global Alias");
478
0
      return false;
479
0
    }
480
2
  }
481
2
482
2
  
if (2
Transform.empty() == Target.empty()2
) {
483
0
    YS.printError(Descriptor,
484
0
                  "exactly one of transform or target must be specified");
485
0
    return false;
486
0
  }
487
2
488
2
  
if (2
!Target.empty()2
)
489
2
    DL->push_back(llvm::make_unique<ExplicitRewriteNamedAliasDescriptor>(
490
2
        Source, Target,
491
2
        /*Naked*/ false));
492
2
  else
493
0
    DL->push_back(llvm::make_unique<PatternRewriteNamedAliasDescriptor>(
494
0
        Source, Transform));
495
2
496
2
  return true;
497
2
}
498
499
namespace {
500
class RewriteSymbolsLegacyPass : public ModulePass {
501
public:
502
  static char ID; // Pass identification, replacement for typeid
503
504
  RewriteSymbolsLegacyPass();
505
  RewriteSymbolsLegacyPass(SymbolRewriter::RewriteDescriptorList &DL);
506
507
  bool runOnModule(Module &M) override;
508
509
private:
510
  RewriteSymbolPass Impl;
511
};
512
513
char RewriteSymbolsLegacyPass::ID = 0;
514
515
33.5k
RewriteSymbolsLegacyPass::RewriteSymbolsLegacyPass() : ModulePass(ID), Impl() {
516
33.5k
  initializeRewriteSymbolsLegacyPassPass(*PassRegistry::getPassRegistry());  
517
33.5k
}
518
519
RewriteSymbolsLegacyPass::RewriteSymbolsLegacyPass(
520
    SymbolRewriter::RewriteDescriptorList &DL)
521
0
    : ModulePass(ID), Impl(DL) {}
522
523
33.4k
bool RewriteSymbolsLegacyPass::runOnModule(Module &M) {
524
33.4k
  return Impl.runImpl(M);
525
33.4k
}
526
}
527
528
namespace llvm {
529
1
PreservedAnalyses RewriteSymbolPass::run(Module &M, ModuleAnalysisManager &AM) {
530
1
  if (!runImpl(M))
531
0
    return PreservedAnalyses::all();
532
1
533
1
  return PreservedAnalyses::none();
534
1
}
535
536
33.4k
bool RewriteSymbolPass::runImpl(Module &M) {
537
33.4k
  bool Changed;
538
33.4k
539
33.4k
  Changed = false;
540
33.4k
  for (auto &Descriptor : Descriptors)
541
26
    Changed |= Descriptor->performOnModule(M);
542
33.4k
543
33.4k
  return Changed;
544
33.4k
}
545
546
33.5k
void RewriteSymbolPass::loadAndParseMapFiles() {
547
33.5k
  const std::vector<std::string> MapFiles(RewriteMapFiles);
548
33.5k
  SymbolRewriter::RewriteMapParser Parser;
549
33.5k
550
33.5k
  for (const auto &MapFile : MapFiles)
551
2
    Parser.parse(MapFile, &Descriptors);
552
33.5k
}
553
}
554
555
INITIALIZE_PASS(RewriteSymbolsLegacyPass, "rewrite-symbols", "Rewrite Symbols",
556
                false, false)
557
558
33.5k
ModulePass *llvm::createRewriteSymbolsPass() {
559
33.5k
  return new RewriteSymbolsLegacyPass();
560
33.5k
}
561
562
ModulePass *
563
0
llvm::createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &DL) {
564
0
  return new RewriteSymbolsLegacyPass(DL);
565
0
}