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