1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===- llvm/Support/PassNameParser.h ----------------------------*- C++ -*-===//
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//                     The LLVM Compiler Infrastructure
4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details.
7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file the PassNameParser and FilteredPassNameParser<> classes, which are
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// used to add command line arguments to a utility for all of the passes that
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// have been registered into the system.
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The PassNameParser class adds ALL passes linked into the system (that are
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// creatable) as command line arguments to the tool (when instantiated with the
16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// appropriate command line option template).  The FilteredPassNameParser<>
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// template is used for the same purposes as PassNameParser, except that it only
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// includes passes that have a PassType that are compatible with the filter
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// (which is the template argument).
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef LLVM_SUPPORT_PASS_NAME_PARSER_H
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define LLVM_SUPPORT_PASS_NAME_PARSER_H
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Pass.h"
27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/STLExtras.h"
28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/CommandLine.h"
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h"
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h"
31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <cstring>
32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace llvm {
34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// PassNameParser class - Make use of the pass registration mechanism to
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// automatically add a command line argument to opt for each pass.
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass PassNameParser : public PassRegistrationListener,
40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                       public cl::parser<const PassInfo*> {
41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  cl::Option *Opt;
42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  PassNameParser() : Opt(0) {}
44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual ~PassNameParser();
45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void initialize(cl::Option &O) {
47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Opt = &O;
48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    cl::parser<const PassInfo*>::initialize(O);
49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Add all of the passes to the map that got initialized before 'this' did.
51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    enumeratePasses();
52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // ignorablePassImpl - Can be overriden in subclasses to refine the list of
55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // which passes we want to include.
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual bool ignorablePassImpl(const PassInfo *P) const { return false; }
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  inline bool ignorablePass(const PassInfo *P) const {
60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Ignore non-selectable and non-constructible passes!  Ignore
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // non-optimizations.
62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return P->getPassArgument() == 0 || *P->getPassArgument() == 0 ||
63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           P->getNormalCtor() == 0 || ignorablePassImpl(P);
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Implement the PassRegistrationListener callbacks used to populate our map
67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual void passRegistered(const PassInfo *P) {
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ignorablePass(P) || !Opt) return;
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (findOption(P->getPassArgument()) != getNumOptions()) {
71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      errs() << "Two passes with the same argument (-"
72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           << P->getPassArgument() << ") attempted to be registered!\n";
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      llvm_unreachable(0);
74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    addLiteralOption(P->getPassArgument(), P, P->getPassName());
76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // printOptionInfo - Print out information about this option.  Override the
80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // default implementation to sort the table before we print...
81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const {
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    PassNameParser *PNP = const_cast<PassNameParser*>(this);
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate:
88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // ValLessThan - Provide a sorting comparator for Values elements...
89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static int ValLessThan(const void *VT1, const void *VT2) {
90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    typedef PassNameParser::OptionInfo ValType;
91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return std::strcmp(static_cast<const ValType *>(VT1)->Name,
92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                       static_cast<const ValType *>(VT2)->Name);
93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///===----------------------------------------------------------------------===//
97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// FilteredPassNameParser class - Make use of the pass registration
98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// mechanism to automatically add a command line argument to opt for
99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// each pass that satisfies a filter criteria.  Filter should return
100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// true for passes to be registered as command-line options.
101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename Filter>
103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass FilteredPassNameParser : public PassNameParser {
104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate:
105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Filter filter;
106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); }
109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///===----------------------------------------------------------------------===//
112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// PassArgFilter - A filter for use with PassNameFilterParser that only
113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// accepts a Pass whose Arg matches certain strings.
114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Use like this:
116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// extern const char AllowedPassArgs[] = "-anders_aa -dse";
118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// static cl::list<
120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///   const PassInfo*,
121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///   bool,
122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///   FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > >
123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// PassList(cl::desc("Passes available:"));
124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Only the -anders_aa and -dse options will be available to the user.
126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<const char *Args>
128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass PassArgFilter {
129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool operator()(const PassInfo &P) const {
131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return(std::strstr(Args, P.getPassArgument()));
132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} // End llvm namespace
136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif
138