SimplifyCFG: don't remove unreachable default switch destinations
[oota-llvm.git] / lib / Transforms / Utils / SymbolRewriter.cpp
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/CodeGen/Passes.h"
62 #include "llvm/Pass.h"
63 #include "llvm/PassManager.h"
64 #include "llvm/Support/CommandLine.h"
65 #include "llvm/Support/Debug.h"
66 #include "llvm/Support/MemoryBuffer.h"
67 #include "llvm/Support/Regex.h"
68 #include "llvm/Support/SourceMgr.h"
69 #include "llvm/Support/YAMLParser.h"
70 #include "llvm/Support/raw_ostream.h"
71 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
72 #include "llvm/Transforms/Utils/SymbolRewriter.h"
73
74 using namespace llvm;
75
76 static cl::list<std::string> RewriteMapFiles("rewrite-map-file",
77                                              cl::desc("Symbol Rewrite Map"),
78                                              cl::value_desc("filename"));
79
80 namespace llvm {
81 namespace SymbolRewriter {
82 template <RewriteDescriptor::Type DT, typename ValueType,
83           ValueType *(llvm::Module::*Get)(StringRef) const>
84 class ExplicitRewriteDescriptor : public RewriteDescriptor {
85 public:
86   const std::string Source;
87   const std::string Target;
88
89   ExplicitRewriteDescriptor(StringRef S, StringRef T, const bool Naked)
90       : RewriteDescriptor(DT), Source(Naked ? StringRef("\01" + S.str()) : S),
91         Target(T) {}
92
93   bool performOnModule(Module &M) override;
94
95   static bool classof(const RewriteDescriptor *RD) {
96     return RD->getType() == DT;
97   }
98 };
99
100 template <RewriteDescriptor::Type DT, typename ValueType,
101           ValueType *(llvm::Module::*Get)(StringRef) const>
102 bool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) {
103   bool Changed = false;
104   if (ValueType *S = (M.*Get)(Source)) {
105     if (Value *T = (M.*Get)(Target))
106       S->setValueName(T->getValueName());
107     else
108       S->setName(Target);
109     Changed = true;
110   }
111   return Changed;
112 }
113
114 template <RewriteDescriptor::Type DT, typename ValueType,
115           ValueType *(llvm::Module::*Get)(StringRef) const,
116           iterator_range<typename iplist<ValueType>::iterator>
117           (llvm::Module::*Iterator)()>
118 class PatternRewriteDescriptor : public RewriteDescriptor {
119 public:
120   const std::string Pattern;
121   const std::string Transform;
122
123   PatternRewriteDescriptor(StringRef P, StringRef T)
124     : RewriteDescriptor(DT), Pattern(P), Transform(T) { }
125
126   bool performOnModule(Module &M) override;
127
128   static bool classof(const RewriteDescriptor *RD) {
129     return RD->getType() == DT;
130   }
131 };
132
133 template <RewriteDescriptor::Type DT, typename ValueType,
134           ValueType *(llvm::Module::*Get)(StringRef) const,
135           iterator_range<typename iplist<ValueType>::iterator>
136           (llvm::Module::*Iterator)()>
137 bool PatternRewriteDescriptor<DT, ValueType, Get, Iterator>::
138 performOnModule(Module &M) {
139   bool Changed = false;
140   for (auto &C : (M.*Iterator)()) {
141     std::string Error;
142
143     std::string Name = Regex(Pattern).sub(Transform, C.getName(), &Error);
144     if (!Error.empty())
145       report_fatal_error("unable to transforn " + C.getName() + " in " +
146                          M.getModuleIdentifier() + ": " + Error);
147
148     if (Value *V = (M.*Get)(Name))
149       C.setValueName(V->getValueName());
150     else
151       C.setName(Name);
152
153     Changed = true;
154   }
155   return Changed;
156 }
157
158 /// Represents a rewrite for an explicitly named (function) symbol.  Both the
159 /// source function name and target function name of the transformation are
160 /// explicitly spelt out.
161 typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function,
162                                   llvm::Function, &llvm::Module::getFunction>
163     ExplicitRewriteFunctionDescriptor;
164
165 /// Represents a rewrite for an explicitly named (global variable) symbol.  Both
166 /// the source variable name and target variable name are spelt out.  This
167 /// applies only to module level variables.
168 typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
169                                   llvm::GlobalVariable,
170                                   &llvm::Module::getGlobalVariable>
171     ExplicitRewriteGlobalVariableDescriptor;
172
173 /// Represents a rewrite for an explicitly named global alias.  Both the source
174 /// and target name are explicitly spelt out.
175 typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias,
176                                   llvm::GlobalAlias,
177                                   &llvm::Module::getNamedAlias>
178     ExplicitRewriteNamedAliasDescriptor;
179
180 /// Represents a rewrite for a regular expression based pattern for functions.
181 /// A pattern for the function name is provided and a transformation for that
182 /// pattern to determine the target function name create the rewrite rule.
183 typedef PatternRewriteDescriptor<RewriteDescriptor::Type::Function,
184                                  llvm::Function, &llvm::Module::getFunction,
185                                  &llvm::Module::functions>
186     PatternRewriteFunctionDescriptor;
187
188 /// Represents a rewrite for a global variable based upon a matching pattern.
189 /// Each global variable matching the provided pattern will be transformed as
190 /// described in the transformation pattern for the target.  Applies only to
191 /// module level variables.
192 typedef PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
193                                  llvm::GlobalVariable,
194                                  &llvm::Module::getGlobalVariable,
195                                  &llvm::Module::globals>
196     PatternRewriteGlobalVariableDescriptor;
197
198 /// PatternRewriteNamedAliasDescriptor - represents a rewrite for global
199 /// aliases which match a given pattern.  The provided transformation will be
200 /// applied to each of the matching names.
201 typedef PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias,
202                                  llvm::GlobalAlias,
203                                  &llvm::Module::getNamedAlias,
204                                  &llvm::Module::aliases>
205     PatternRewriteNamedAliasDescriptor;
206
207 bool RewriteMapParser::parse(const std::string &MapFile,
208                              RewriteDescriptorList *DL) {
209   ErrorOr<std::unique_ptr<MemoryBuffer>> Mapping =
210       MemoryBuffer::getFile(MapFile);
211
212   if (!Mapping)
213     report_fatal_error("unable to read rewrite map '" + MapFile + "': " +
214                        Mapping.getError().message());
215
216   if (!parse(*Mapping, DL))
217     report_fatal_error("unable to parse rewrite map '" + MapFile + "'");
218
219   return true;
220 }
221
222 bool RewriteMapParser::parse(std::unique_ptr<MemoryBuffer> &MapFile,
223                              RewriteDescriptorList *DL) {
224   SourceMgr SM;
225   yaml::Stream YS(MapFile->getBuffer(), SM);
226
227   for (auto &Document : YS) {
228     yaml::MappingNode *DescriptorList;
229
230     // ignore empty documents
231     if (isa<yaml::NullNode>(Document.getRoot()))
232       continue;
233
234     DescriptorList = dyn_cast<yaml::MappingNode>(Document.getRoot());
235     if (!DescriptorList) {
236       YS.printError(Document.getRoot(), "DescriptorList node must be a map");
237       return false;
238     }
239
240     for (auto &Descriptor : *DescriptorList)
241       if (!parseEntry(YS, Descriptor, DL))
242         return false;
243   }
244
245   return true;
246 }
247
248 bool RewriteMapParser::parseEntry(yaml::Stream &YS, yaml::KeyValueNode &Entry,
249                                   RewriteDescriptorList *DL) {
250   yaml::ScalarNode *Key;
251   yaml::MappingNode *Value;
252   SmallString<32> KeyStorage;
253   StringRef RewriteType;
254
255   Key = dyn_cast<yaml::ScalarNode>(Entry.getKey());
256   if (!Key) {
257     YS.printError(Entry.getKey(), "rewrite type must be a scalar");
258     return false;
259   }
260
261   Value = dyn_cast<yaml::MappingNode>(Entry.getValue());
262   if (!Value) {
263     YS.printError(Entry.getValue(), "rewrite descriptor must be a map");
264     return false;
265   }
266
267   RewriteType = Key->getValue(KeyStorage);
268   if (RewriteType.equals("function"))
269     return parseRewriteFunctionDescriptor(YS, Key, Value, DL);
270   else if (RewriteType.equals("global variable"))
271     return parseRewriteGlobalVariableDescriptor(YS, Key, Value, DL);
272   else if (RewriteType.equals("global alias"))
273     return parseRewriteGlobalAliasDescriptor(YS, Key, Value, DL);
274
275   YS.printError(Entry.getKey(), "unknown rewrite type");
276   return false;
277 }
278
279 bool RewriteMapParser::
280 parseRewriteFunctionDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
281                                yaml::MappingNode *Descriptor,
282                                RewriteDescriptorList *DL) {
283   bool Naked = false;
284   std::string Source;
285   std::string Target;
286   std::string Transform;
287
288   for (auto &Field : *Descriptor) {
289     yaml::ScalarNode *Key;
290     yaml::ScalarNode *Value;
291     SmallString<32> KeyStorage;
292     SmallString<32> ValueStorage;
293     StringRef KeyValue;
294
295     Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
296     if (!Key) {
297       YS.printError(Field.getKey(), "descriptor key must be a scalar");
298       return false;
299     }
300
301     Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
302     if (!Value) {
303       YS.printError(Field.getValue(), "descriptor value must be a scalar");
304       return false;
305     }
306
307     KeyValue = Key->getValue(KeyStorage);
308     if (KeyValue.equals("source")) {
309       std::string Error;
310
311       Source = Value->getValue(ValueStorage);
312       if (!Regex(Source).isValid(Error)) {
313         YS.printError(Field.getKey(), "invalid regex: " + Error);
314         return false;
315       }
316     } else if (KeyValue.equals("target")) {
317       Target = Value->getValue(ValueStorage);
318     } else if (KeyValue.equals("transform")) {
319       Transform = Value->getValue(ValueStorage);
320     } else if (KeyValue.equals("naked")) {
321       std::string Undecorated;
322
323       Undecorated = Value->getValue(ValueStorage);
324       Naked = StringRef(Undecorated).lower() == "true" || Undecorated == "1";
325     } else {
326       YS.printError(Field.getKey(), "unknown key for function");
327       return false;
328     }
329   }
330
331   if (Transform.empty() == Target.empty()) {
332     YS.printError(Descriptor,
333                   "exactly one of transform or target must be specified");
334     return false;
335   }
336
337   // TODO see if there is a more elegant solution to selecting the rewrite
338   // descriptor type
339   if (!Target.empty())
340     DL->push_back(new ExplicitRewriteFunctionDescriptor(Source, Target, Naked));
341   else
342     DL->push_back(new PatternRewriteFunctionDescriptor(Source, Transform));
343
344   return true;
345 }
346
347 bool RewriteMapParser::
348 parseRewriteGlobalVariableDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
349                                      yaml::MappingNode *Descriptor,
350                                      RewriteDescriptorList *DL) {
351   std::string Source;
352   std::string Target;
353   std::string Transform;
354
355   for (auto &Field : *Descriptor) {
356     yaml::ScalarNode *Key;
357     yaml::ScalarNode *Value;
358     SmallString<32> KeyStorage;
359     SmallString<32> ValueStorage;
360     StringRef KeyValue;
361
362     Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
363     if (!Key) {
364       YS.printError(Field.getKey(), "descriptor Key must be a scalar");
365       return false;
366     }
367
368     Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
369     if (!Value) {
370       YS.printError(Field.getValue(), "descriptor value must be a scalar");
371       return false;
372     }
373
374     KeyValue = Key->getValue(KeyStorage);
375     if (KeyValue.equals("source")) {
376       std::string Error;
377
378       Source = Value->getValue(ValueStorage);
379       if (!Regex(Source).isValid(Error)) {
380         YS.printError(Field.getKey(), "invalid regex: " + Error);
381         return false;
382       }
383     } else if (KeyValue.equals("target")) {
384       Target = Value->getValue(ValueStorage);
385     } else if (KeyValue.equals("transform")) {
386       Transform = Value->getValue(ValueStorage);
387     } else {
388       YS.printError(Field.getKey(), "unknown Key for Global Variable");
389       return false;
390     }
391   }
392
393   if (Transform.empty() == Target.empty()) {
394     YS.printError(Descriptor,
395                   "exactly one of transform or target must be specified");
396     return false;
397   }
398
399   if (!Target.empty())
400     DL->push_back(new ExplicitRewriteGlobalVariableDescriptor(Source, Target,
401                                                               /*Naked*/false));
402   else
403     DL->push_back(new PatternRewriteGlobalVariableDescriptor(Source,
404                                                              Transform));
405
406   return true;
407 }
408
409 bool RewriteMapParser::
410 parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
411                                   yaml::MappingNode *Descriptor,
412                                   RewriteDescriptorList *DL) {
413   std::string Source;
414   std::string Target;
415   std::string Transform;
416
417   for (auto &Field : *Descriptor) {
418     yaml::ScalarNode *Key;
419     yaml::ScalarNode *Value;
420     SmallString<32> KeyStorage;
421     SmallString<32> ValueStorage;
422     StringRef KeyValue;
423
424     Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
425     if (!Key) {
426       YS.printError(Field.getKey(), "descriptor key must be a scalar");
427       return false;
428     }
429
430     Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
431     if (!Value) {
432       YS.printError(Field.getValue(), "descriptor value must be a scalar");
433       return false;
434     }
435
436     KeyValue = Key->getValue(KeyStorage);
437     if (KeyValue.equals("source")) {
438       std::string Error;
439
440       Source = Value->getValue(ValueStorage);
441       if (!Regex(Source).isValid(Error)) {
442         YS.printError(Field.getKey(), "invalid regex: " + Error);
443         return false;
444       }
445     } else if (KeyValue.equals("target")) {
446       Target = Value->getValue(ValueStorage);
447     } else if (KeyValue.equals("transform")) {
448       Transform = Value->getValue(ValueStorage);
449     } else {
450       YS.printError(Field.getKey(), "unknown key for Global Alias");
451       return false;
452     }
453   }
454
455   if (Transform.empty() == Target.empty()) {
456     YS.printError(Descriptor,
457                   "exactly one of transform or target must be specified");
458     return false;
459   }
460
461   if (!Target.empty())
462     DL->push_back(new ExplicitRewriteNamedAliasDescriptor(Source, Target,
463                                                           /*Naked*/false));
464   else
465     DL->push_back(new PatternRewriteNamedAliasDescriptor(Source, Transform));
466
467   return true;
468 }
469 }
470 }
471
472 namespace {
473 class RewriteSymbols : public ModulePass {
474 public:
475   static char ID; // Pass identification, replacement for typeid
476
477   RewriteSymbols();
478   RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL);
479
480   bool runOnModule(Module &M) override;
481
482 private:
483   void loadAndParseMapFiles();
484
485   SymbolRewriter::RewriteDescriptorList Descriptors;
486 };
487
488 char RewriteSymbols::ID = 0;
489
490 RewriteSymbols::RewriteSymbols() : ModulePass(ID) {
491   initializeRewriteSymbolsPass(*PassRegistry::getPassRegistry());
492   loadAndParseMapFiles();
493 }
494
495 RewriteSymbols::RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL)
496     : ModulePass(ID) {
497   Descriptors.splice(Descriptors.begin(), DL);
498 }
499
500 bool RewriteSymbols::runOnModule(Module &M) {
501   bool Changed;
502
503   Changed = false;
504   for (auto &Descriptor : Descriptors)
505     Changed |= Descriptor.performOnModule(M);
506
507   return Changed;
508 }
509
510 void RewriteSymbols::loadAndParseMapFiles() {
511   const std::vector<std::string> MapFiles(RewriteMapFiles);
512   SymbolRewriter::RewriteMapParser parser;
513
514   for (const auto &MapFile : MapFiles)
515     parser.parse(MapFile, &Descriptors);
516 }
517 }
518
519 INITIALIZE_PASS(RewriteSymbols, "rewrite-symbols", "Rewrite Symbols", false,
520                 false)
521
522 ModulePass *llvm::createRewriteSymbolsPass() { return new RewriteSymbols(); }
523
524 ModulePass *
525 llvm::createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &DL) {
526   return new RewriteSymbols(DL);
527 }