summaryrefslogtreecommitdiff
path: root/include/llvm/Support/PassNameParser.h
blob: 961638c43f49a3ecbffaf6cef297b02b463c49e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//===- llvm/Support/PassNameParser.h ----------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file the PassNameParser and FilteredPassNameParser<> classes, which are
// used to add command line arguments to a utility for all of the passes that
// have been registered into the system.
//
// The PassNameParser class adds ALL passes linked into the system (that are
// creatable) as command line arguments to the tool (when instantiated with the
// appropriate command line option template).  The FilteredPassNameParser<>
// template is used for the same purposes as PassNameParser, except that it only
// includes passes that have a PassType that are compatible with the filter
// (which is the template argument).
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_PASS_NAME_PARSER_H
#define LLVM_SUPPORT_PASS_NAME_PARSER_H

#include "llvm/Support/CommandLine.h"
#include "llvm/Pass.h"
#include <algorithm>
#include <cstring>

namespace llvm {

//===----------------------------------------------------------------------===//
// PassNameParser class - Make use of the pass registration mechanism to
// automatically add a command line argument to opt for each pass.
//
class PassNameParser : public PassRegistrationListener,
                       public cl::parser<const PassInfo*> {
  cl::Option *Opt;
public:
  PassNameParser() : Opt(0) {}

  void initialize(cl::Option &O) {
    Opt = &O;
    cl::parser<const PassInfo*>::initialize(O);

    // Add all of the passes to the map that got initialized before 'this' did.
    enumeratePasses();
  }

  // ignorablePassImpl - Can be overriden in subclasses to refine the list of
  // which passes we want to include.
  //
  virtual bool ignorablePassImpl(const PassInfo *P) const { return false; }

  inline bool ignorablePass(const PassInfo *P) const {
    // Ignore non-selectable and non-constructible passes!  Ignore
    // non-optimizations.
    return P->getPassArgument() == 0 || *P->getPassArgument() == 0 ||
           P->getNormalCtor() == 0 || ignorablePassImpl(P);
  }

  // Implement the PassRegistrationListener callbacks used to populate our map
  //
  virtual void passRegistered(const PassInfo *P) {
    if (ignorablePass(P) || !Opt) return;
    if (findOption(P->getPassArgument()) != getNumOptions()) {
      cerr << "Two passes with the same argument (-"
           << P->getPassArgument() << ") attempted to be registered!\n";
      abort();
    }
    addLiteralOption(P->getPassArgument(), P, P->getPassName());
  }
  virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }

  // ValLessThan - Provide a sorting comparator for Values elements...
  typedef std::pair<const char*,
                    std::pair<const PassInfo*, const char*> > ValType;
  static bool ValLessThan(const ValType &VT1, const ValType &VT2) {
    return std::string(VT1.first) < std::string(VT2.first);
  }

  // printOptionInfo - Print out information about this option.  Override the
  // default implementation to sort the table before we print...
  virtual void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const {
    PassNameParser *PNP = const_cast<PassNameParser*>(this);
    std::sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
    cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
  }
};

///===----------------------------------------------------------------------===//
/// FilteredPassNameParser class - Make use of the pass registration
/// mechanism to automatically add a command line argument to opt for
/// each pass that satisfies a filter criteria.  Filter should return
/// true for passes to be registered as command-line options.
///
template<typename Filter>
class FilteredPassNameParser : public PassNameParser {
private:
  Filter filter;

public:
  bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); }
};

///===----------------------------------------------------------------------===//
/// PassArgFilter - A filter for use with PassNameFilterParser that only
/// accepts a Pass whose Arg matches certain strings.
///
/// Use like this:
///
/// extern const char AllowedPassArgs[] = "-anders_aa -dse";
///
/// static cl::list<
///   const PassInfo*,
///   bool,
///   FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > >
/// PassList(cl::desc("Passes available:"));
///
/// Only the -anders_aa and -dse options will be available to the user.
///
template<const char *Args>
class PassArgFilter {
public:
  bool operator()(const PassInfo &P) const {
    return(std::strstr(Args, P.getPassArgument()));
  }
};

} // End llvm namespace
#endif