PassNameParser.h revision bd448e3ca993226084d7f53445388fcd8e46b996
1f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//===- llvm/Support/PassNameParser.h ----------------------------*- C++ -*-===//
2f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
3f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//                     The LLVM Compiler Infrastructure
4f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
584e66db653835cee524fc51185ed614f1d6ac628Chris Lattner// This file is distributed under the University of Illinois Open Source
684e66db653835cee524fc51185ed614f1d6ac628Chris Lattner// License. See LICENSE.TXT for details.
7f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
8f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//===----------------------------------------------------------------------===//
9f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
10f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// This file the PassNameParser and FilteredPassNameParser<> classes, which are
11f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// used to add command line arguments to a utility for all of the passes that
12f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// have been registered into the system.
13f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
14f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// The PassNameParser class adds ALL passes linked into the system (that are
15f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// creatable) as command line arguments to the tool (when instantiated with the
16f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// appropriate command line option template).  The FilteredPassNameParser<>
17f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// template is used for the same purposes as PassNameParser, except that it only
18f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// includes passes that have a PassType that are compatible with the filter
19f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// (which is the template argument).
20f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
21f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//===----------------------------------------------------------------------===//
22f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
23f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#ifndef LLVM_SUPPORT_PASS_NAME_PARSER_H
24f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#define LLVM_SUPPORT_PASS_NAME_PARSER_H
25f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
26f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include "llvm/Support/CommandLine.h"
27675d56222b6b98d2c22a17aaf69a036e57d5426aEdwin Török#include "llvm/Support/ErrorHandling.h"
28f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include "llvm/Pass.h"
29f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include <algorithm>
30d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene#include <cstring>
31f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
32f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohmannamespace llvm {
33f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
34f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//===----------------------------------------------------------------------===//
35f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// PassNameParser class - Make use of the pass registration mechanism to
36f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// automatically add a command line argument to opt for each pass.
37f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
38f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohmanclass PassNameParser : public PassRegistrationListener,
39f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman                       public cl::parser<const PassInfo*> {
40f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  cl::Option *Opt;
41f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohmanpublic:
42f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  PassNameParser() : Opt(0) {}
43f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
44f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  void initialize(cl::Option &O) {
45f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    Opt = &O;
46f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    cl::parser<const PassInfo*>::initialize(O);
47f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
48f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    // Add all of the passes to the map that got initialized before 'this' did.
49f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    enumeratePasses();
50f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  }
51f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
52f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  // ignorablePassImpl - Can be overriden in subclasses to refine the list of
53f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  // which passes we want to include.
54f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  //
55f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  virtual bool ignorablePassImpl(const PassInfo *P) const { return false; }
56f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
57f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  inline bool ignorablePass(const PassInfo *P) const {
58f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    // Ignore non-selectable and non-constructible passes!  Ignore
59f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    // non-optimizations.
60f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    return P->getPassArgument() == 0 || *P->getPassArgument() == 0 ||
61f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman           P->getNormalCtor() == 0 || ignorablePassImpl(P);
62f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  }
63f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
64f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  // Implement the PassRegistrationListener callbacks used to populate our map
65f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  //
66f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  virtual void passRegistered(const PassInfo *P) {
67f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    if (ignorablePass(P) || !Opt) return;
68f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    if (findOption(P->getPassArgument()) != getNumOptions()) {
69f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman      cerr << "Two passes with the same argument (-"
70f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman           << P->getPassArgument() << ") attempted to be registered!\n";
71bd448e3ca993226084d7f53445388fcd8e46b996Edwin Török      llvm_unreachable(0);
72f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    }
73f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    addLiteralOption(P->getPassArgument(), P, P->getPassName());
74f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  }
75f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }
76f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
77f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  // ValLessThan - Provide a sorting comparator for Values elements...
78f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  typedef std::pair<const char*,
79f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman                    std::pair<const PassInfo*, const char*> > ValType;
80f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  static bool ValLessThan(const ValType &VT1, const ValType &VT2) {
81f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    return std::string(VT1.first) < std::string(VT2.first);
82f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  }
83f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
84f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  // printOptionInfo - Print out information about this option.  Override the
85f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  // default implementation to sort the table before we print...
865fb79208352fa2f29bbd5f9b9c46deb77170a04eBill Wendling  virtual void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const {
87f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    PassNameParser *PNP = const_cast<PassNameParser*>(this);
88f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    std::sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
89f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
90f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  }
91f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman};
92f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
93f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///===----------------------------------------------------------------------===//
94f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// FilteredPassNameParser class - Make use of the pass registration
95f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// mechanism to automatically add a command line argument to opt for
96f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// each pass that satisfies a filter criteria.  Filter should return
97f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// true for passes to be registered as command-line options.
98f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///
99d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greenetemplate<typename Filter>
100d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greeneclass FilteredPassNameParser : public PassNameParser {
101d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greeneprivate:
102d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene  Filter filter;
103f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
104d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greenepublic:
105d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene  bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); }
106d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene};
107d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene
108f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///===----------------------------------------------------------------------===//
109f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// PassArgFilter - A filter for use with PassNameFilterParser that only
110f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// accepts a Pass whose Arg matches certain strings.
111f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///
112f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// Use like this:
113f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///
114f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// extern const char AllowedPassArgs[] = "-anders_aa -dse";
115f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///
116f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// static cl::list<
117f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///   const PassInfo*,
118f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///   bool,
119f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///   FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > >
120f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// PassList(cl::desc("Passes available:"));
121f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///
122f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// Only the -anders_aa and -dse options will be available to the user.
123f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///
124d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greenetemplate<const char *Args>
125d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greeneclass PassArgFilter {
126d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greenepublic:
127d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene  bool operator()(const PassInfo &P) const {
128d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene    return(std::strstr(Args, P.getPassArgument()));
129d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene  }
130d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene};
131d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene
132d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene} // End llvm namespace
133c24a3f87f866e96b2a9ad691c78113651eaa77d1Dan Gohman
134f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#endif
135