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