Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame^] | 1 | //===- LegacyPassNameParser.h -----------------------------------*- 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 | // This file contains the PassNameParser and FilteredPassNameParser<> classes, |
| 11 | // which are used to add command line arguments to a utility for all of the |
| 12 | // passes that have been registered into the system. |
| 13 | // |
| 14 | // The PassNameParser class adds ALL passes linked into the system (that are |
| 15 | // creatable) as command line arguments to the tool (when instantiated with the |
| 16 | // appropriate command line option template). The FilteredPassNameParser<> |
| 17 | // template is used for the same purposes as PassNameParser, except that it only |
| 18 | // includes passes that have a PassType that are compatible with the filter |
| 19 | // (which is the template argument). |
| 20 | // |
| 21 | // Note that this is part of the legacy pass manager infrastructure and will be |
| 22 | // (eventually) going away. |
| 23 | // |
| 24 | //===----------------------------------------------------------------------===// |
| 25 | |
| 26 | #ifndef LLVM_IR_LEGACYPASSNAMEPARSER_H |
| 27 | #define LLVM_IR_LEGACYPASSNAMEPARSER_H |
| 28 | |
| 29 | #include "llvm/ADT/STLExtras.h" |
| 30 | #include "llvm/Pass.h" |
| 31 | #include "llvm/Support/CommandLine.h" |
| 32 | #include "llvm/Support/ErrorHandling.h" |
| 33 | #include "llvm/Support/raw_ostream.h" |
| 34 | #include <cstring> |
| 35 | |
| 36 | namespace llvm { |
| 37 | |
| 38 | //===----------------------------------------------------------------------===// |
| 39 | // PassNameParser class - Make use of the pass registration mechanism to |
| 40 | // automatically add a command line argument to opt for each pass. |
| 41 | // |
| 42 | class PassNameParser : public PassRegistrationListener, |
| 43 | public cl::parser<const PassInfo*> { |
| 44 | public: |
| 45 | PassNameParser(cl::Option &O); |
| 46 | ~PassNameParser() override; |
| 47 | |
| 48 | void initialize() { |
| 49 | cl::parser<const PassInfo*>::initialize(); |
| 50 | |
| 51 | // Add all of the passes to the map that got initialized before 'this' did. |
| 52 | enumeratePasses(); |
| 53 | } |
| 54 | |
| 55 | // ignorablePassImpl - Can be overriden in subclasses to refine the list of |
| 56 | // which passes we want to include. |
| 57 | // |
| 58 | virtual bool ignorablePassImpl(const PassInfo *P) const { return false; } |
| 59 | |
| 60 | inline bool ignorablePass(const PassInfo *P) const { |
| 61 | // Ignore non-selectable and non-constructible passes! Ignore |
| 62 | // non-optimizations. |
| 63 | return P->getPassArgument().empty() || P->getNormalCtor() == nullptr || |
| 64 | ignorablePassImpl(P); |
| 65 | } |
| 66 | |
| 67 | // Implement the PassRegistrationListener callbacks used to populate our map |
| 68 | // |
| 69 | void passRegistered(const PassInfo *P) override { |
| 70 | if (ignorablePass(P)) return; |
| 71 | if (findOption(P->getPassArgument().data()) != getNumOptions()) { |
| 72 | errs() << "Two passes with the same argument (-" |
| 73 | << P->getPassArgument() << ") attempted to be registered!\n"; |
| 74 | llvm_unreachable(nullptr); |
| 75 | } |
| 76 | addLiteralOption(P->getPassArgument().data(), P, P->getPassName().data()); |
| 77 | } |
| 78 | void passEnumerate(const PassInfo *P) override { passRegistered(P); } |
| 79 | |
| 80 | // printOptionInfo - Print out information about this option. Override the |
| 81 | // default implementation to sort the table before we print... |
| 82 | void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const override { |
| 83 | PassNameParser *PNP = const_cast<PassNameParser*>(this); |
| 84 | array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValCompare); |
| 85 | cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth); |
| 86 | } |
| 87 | |
| 88 | private: |
| 89 | // ValCompare - Provide a sorting comparator for Values elements... |
| 90 | static int ValCompare(const PassNameParser::OptionInfo *VT1, |
| 91 | const PassNameParser::OptionInfo *VT2) { |
| 92 | return VT1->Name.compare(VT2->Name); |
| 93 | } |
| 94 | }; |
| 95 | |
| 96 | ///===----------------------------------------------------------------------===// |
| 97 | /// FilteredPassNameParser class - Make use of the pass registration |
| 98 | /// mechanism to automatically add a command line argument to opt for |
| 99 | /// each pass that satisfies a filter criteria. Filter should return |
| 100 | /// true for passes to be registered as command-line options. |
| 101 | /// |
| 102 | template<typename Filter> |
| 103 | class FilteredPassNameParser : public PassNameParser { |
| 104 | private: |
| 105 | Filter filter; |
| 106 | |
| 107 | public: |
| 108 | bool ignorablePassImpl(const PassInfo *P) const override { |
| 109 | return !filter(*P); |
| 110 | } |
| 111 | }; |
| 112 | |
| 113 | ///===----------------------------------------------------------------------===// |
| 114 | /// PassArgFilter - A filter for use with PassNameFilterParser that only |
| 115 | /// accepts a Pass whose Arg matches certain strings. |
| 116 | /// |
| 117 | /// Use like this: |
| 118 | /// |
| 119 | /// extern const char AllowedPassArgs[] = "-anders_aa -dse"; |
| 120 | /// |
| 121 | /// static cl::list< |
| 122 | /// const PassInfo*, |
| 123 | /// bool, |
| 124 | /// FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > > |
| 125 | /// PassList(cl::desc("Passes available:")); |
| 126 | /// |
| 127 | /// Only the -anders_aa and -dse options will be available to the user. |
| 128 | /// |
| 129 | template<const char *Args> |
| 130 | class PassArgFilter { |
| 131 | public: |
| 132 | bool operator()(const PassInfo &P) const { |
| 133 | return StringRef(Args).contains(P.getPassArgument()); |
| 134 | } |
| 135 | }; |
| 136 | |
| 137 | } // End llvm namespace |
| 138 | |
| 139 | #endif |