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
267bbe4f47853f4cfda1d1bd6c0af2c11fc01e1e1aBenjamin Kramer#include "llvm/Pass.h"
277bbe4f47853f4cfda1d1bd6c0af2c11fc01e1e1aBenjamin Kramer#include "llvm/ADT/STLExtras.h"
28f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include "llvm/Support/CommandLine.h"
29675d56222b6b98d2c22a17aaf69a036e57d5426aEdwin Török#include "llvm/Support/ErrorHandling.h"
304e4fe9d4baccaff88c839d9662b0b503f9d2edd0Douglas Gregor#include "llvm/Support/raw_ostream.h"
31d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene#include <cstring>
32f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
33f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohmannamespace llvm {
34f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
35f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//===----------------------------------------------------------------------===//
36f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// PassNameParser class - Make use of the pass registration mechanism to
37f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// automatically add a command line argument to opt for each pass.
38f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
39f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohmanclass PassNameParser : public PassRegistrationListener,
40f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman                       public cl::parser<const PassInfo*> {
41f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  cl::Option *Opt;
42f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohmanpublic:
43f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  PassNameParser() : Opt(0) {}
445f9a4f33e931303f39ffb532530e6d3bf4dfae03Chris Lattner  virtual ~PassNameParser();
457bbe4f47853f4cfda1d1bd6c0af2c11fc01e1e1aBenjamin Kramer
46f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  void initialize(cl::Option &O) {
47f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    Opt = &O;
48f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    cl::parser<const PassInfo*>::initialize(O);
49f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
50f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    // Add all of the passes to the map that got initialized before 'this' did.
51f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    enumeratePasses();
52f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  }
53f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
54f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  // ignorablePassImpl - Can be overriden in subclasses to refine the list of
55f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  // which passes we want to include.
56f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  //
57cb14cb861b75a0a643c16851af1c350ce7b38d4cOwen Anderson  virtual bool ignorablePassImpl(const PassInfo *P) const { return false; }
58f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
59cb14cb861b75a0a643c16851af1c350ce7b38d4cOwen Anderson  inline bool ignorablePass(const PassInfo *P) const {
60f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    // Ignore non-selectable and non-constructible passes!  Ignore
61f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    // non-optimizations.
62f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    return P->getPassArgument() == 0 || *P->getPassArgument() == 0 ||
63f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman           P->getNormalCtor() == 0 || ignorablePassImpl(P);
64f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  }
65f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
66f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  // Implement the PassRegistrationListener callbacks used to populate our map
67f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  //
68cb14cb861b75a0a643c16851af1c350ce7b38d4cOwen Anderson  virtual void passRegistered(const PassInfo *P) {
69f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    if (ignorablePass(P) || !Opt) return;
70f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    if (findOption(P->getPassArgument()) != getNumOptions()) {
71397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner      errs() << "Two passes with the same argument (-"
72f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman           << P->getPassArgument() << ") attempted to be registered!\n";
73bd448e3ca993226084d7f53445388fcd8e46b996Edwin Török      llvm_unreachable(0);
74f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    }
75f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    addLiteralOption(P->getPassArgument(), P, P->getPassName());
76f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  }
77cb14cb861b75a0a643c16851af1c350ce7b38d4cOwen Anderson  virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }
78f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
79f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  // printOptionInfo - Print out information about this option.  Override the
80f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  // default implementation to sort the table before we print...
815fb79208352fa2f29bbd5f9b9c46deb77170a04eBill Wendling  virtual void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const {
82f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    PassNameParser *PNP = const_cast<PassNameParser*>(this);
837bbe4f47853f4cfda1d1bd6c0af2c11fc01e1e1aBenjamin Kramer    array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
84f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
85f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  }
867bbe4f47853f4cfda1d1bd6c0af2c11fc01e1e1aBenjamin Kramer
877bbe4f47853f4cfda1d1bd6c0af2c11fc01e1e1aBenjamin Kramerprivate:
887bbe4f47853f4cfda1d1bd6c0af2c11fc01e1e1aBenjamin Kramer  // ValLessThan - Provide a sorting comparator for Values elements...
897bbe4f47853f4cfda1d1bd6c0af2c11fc01e1e1aBenjamin Kramer  static int ValLessThan(const void *VT1, const void *VT2) {
907bbe4f47853f4cfda1d1bd6c0af2c11fc01e1e1aBenjamin Kramer    typedef PassNameParser::OptionInfo ValType;
917bbe4f47853f4cfda1d1bd6c0af2c11fc01e1e1aBenjamin Kramer    return std::strcmp(static_cast<const ValType *>(VT1)->Name,
927bbe4f47853f4cfda1d1bd6c0af2c11fc01e1e1aBenjamin Kramer                       static_cast<const ValType *>(VT2)->Name);
937bbe4f47853f4cfda1d1bd6c0af2c11fc01e1e1aBenjamin Kramer  }
94f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman};
95f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
96f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///===----------------------------------------------------------------------===//
97f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// FilteredPassNameParser class - Make use of the pass registration
98f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// mechanism to automatically add a command line argument to opt for
99f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// each pass that satisfies a filter criteria.  Filter should return
100f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// true for passes to be registered as command-line options.
101f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///
102d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greenetemplate<typename Filter>
103d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greeneclass FilteredPassNameParser : public PassNameParser {
104d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greeneprivate:
105d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene  Filter filter;
106f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
107d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greenepublic:
108cb14cb861b75a0a643c16851af1c350ce7b38d4cOwen Anderson  bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); }
109d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene};
110d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene
111f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///===----------------------------------------------------------------------===//
112f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// PassArgFilter - A filter for use with PassNameFilterParser that only
113f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// accepts a Pass whose Arg matches certain strings.
114f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///
115f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// Use like this:
116f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///
117f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// extern const char AllowedPassArgs[] = "-anders_aa -dse";
118f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///
119f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// static cl::list<
120f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///   const PassInfo*,
121f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///   bool,
122f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///   FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > >
123f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// PassList(cl::desc("Passes available:"));
124f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///
125f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene/// Only the -anders_aa and -dse options will be available to the user.
126f1a75f634add670f6f74ef8242be659c0e82dd7bDavid Greene///
127d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greenetemplate<const char *Args>
128d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greeneclass PassArgFilter {
129d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greenepublic:
130d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene  bool operator()(const PassInfo &P) const {
131d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene    return(std::strstr(Args, P.getPassArgument()));
132d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene  }
133d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene};
134d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene
135d2ce5b45df1e2dd9ddb2a6aeef0b72f5c7603113David Greene} // End llvm namespace
136c24a3f87f866e96b2a9ad691c78113651eaa77d1Dan Gohman
137f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#endif
138