1 //===-- llvm/CodeGen/MachinePassRegistry.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 mechanics for machine function pass registries.  A
11 // function pass registry (MachinePassRegistry) is auto filled by the static
12 // constructors of MachinePassRegistryNode.  Further there is a command line
13 // parser (RegisterPassParser) which listens to each registry for additions
14 // and deletions, so that the appropriate command option is updated.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_CODEGEN_MACHINEPASSREGISTRY_H
19 #define LLVM_CODEGEN_MACHINEPASSREGISTRY_H
20 
21 #include "llvm/CodeGen/Passes.h"
22 #include "llvm/Support/CommandLine.h"
23 
24 namespace llvm {
25 
26 typedef void *(*MachinePassCtor)();
27 
28 
29 //===----------------------------------------------------------------------===//
30 ///
31 /// MachinePassRegistryListener - Listener to adds and removals of nodes in
32 /// registration list.
33 ///
34 //===----------------------------------------------------------------------===//
35 class MachinePassRegistryListener {
36   virtual void anchor();
37 public:
MachinePassRegistryListener()38   MachinePassRegistryListener() {}
~MachinePassRegistryListener()39   virtual ~MachinePassRegistryListener() {}
40   virtual void NotifyAdd(const char *N, MachinePassCtor C, const char *D) = 0;
41   virtual void NotifyRemove(const char *N) = 0;
42 };
43 
44 
45 //===----------------------------------------------------------------------===//
46 ///
47 /// MachinePassRegistryNode - Machine pass node stored in registration list.
48 ///
49 //===----------------------------------------------------------------------===//
50 class MachinePassRegistryNode {
51 
52 private:
53 
54   MachinePassRegistryNode *Next;        // Next function pass in list.
55   const char *Name;                     // Name of function pass.
56   const char *Description;              // Description string.
57   MachinePassCtor Ctor;                 // Function pass creator.
58 
59 public:
60 
MachinePassRegistryNode(const char * N,const char * D,MachinePassCtor C)61   MachinePassRegistryNode(const char *N, const char *D, MachinePassCtor C)
62   : Next(nullptr)
63   , Name(N)
64   , Description(D)
65   , Ctor(C)
66   {}
67 
68   // Accessors
getNext()69   MachinePassRegistryNode *getNext()      const { return Next; }
getNextAddress()70   MachinePassRegistryNode **getNextAddress()    { return &Next; }
getName()71   const char *getName()                   const { return Name; }
getDescription()72   const char *getDescription()            const { return Description; }
getCtor()73   MachinePassCtor getCtor()               const { return Ctor; }
setNext(MachinePassRegistryNode * N)74   void setNext(MachinePassRegistryNode *N)      { Next = N; }
75 
76 };
77 
78 
79 //===----------------------------------------------------------------------===//
80 ///
81 /// MachinePassRegistry - Track the registration of machine passes.
82 ///
83 //===----------------------------------------------------------------------===//
84 class MachinePassRegistry {
85 
86 private:
87 
88   MachinePassRegistryNode *List;        // List of registry nodes.
89   MachinePassCtor Default;              // Default function pass creator.
90   MachinePassRegistryListener* Listener;// Listener for list adds are removes.
91 
92 public:
93 
94   // NO CONSTRUCTOR - we don't want static constructor ordering to mess
95   // with the registry.
96 
97   // Accessors.
98   //
getList()99   MachinePassRegistryNode *getList()                    { return List; }
getDefault()100   MachinePassCtor getDefault()                          { return Default; }
setDefault(MachinePassCtor C)101   void setDefault(MachinePassCtor C)                    { Default = C; }
102   void setDefault(StringRef Name);
setListener(MachinePassRegistryListener * L)103   void setListener(MachinePassRegistryListener *L)      { Listener = L; }
104 
105   /// Add - Adds a function pass to the registration list.
106   ///
107   void Add(MachinePassRegistryNode *Node);
108 
109   /// Remove - Removes a function pass from the registration list.
110   ///
111   void Remove(MachinePassRegistryNode *Node);
112 
113 };
114 
115 
116 //===----------------------------------------------------------------------===//
117 ///
118 /// RegisterPassParser class - Handle the addition of new machine passes.
119 ///
120 //===----------------------------------------------------------------------===//
121 template<class RegistryClass>
122 class RegisterPassParser : public MachinePassRegistryListener,
123                    public cl::parser<typename RegistryClass::FunctionPassCtor> {
124 public:
RegisterPassParser(cl::Option & O)125   RegisterPassParser(cl::Option &O)
126       : cl::parser<typename RegistryClass::FunctionPassCtor>(O) {}
~RegisterPassParser()127   ~RegisterPassParser() override { RegistryClass::setListener(nullptr); }
128 
initialize()129   void initialize() {
130     cl::parser<typename RegistryClass::FunctionPassCtor>::initialize();
131 
132     // Add existing passes to option.
133     for (RegistryClass *Node = RegistryClass::getList();
134          Node; Node = Node->getNext()) {
135       this->addLiteralOption(Node->getName(),
136                       (typename RegistryClass::FunctionPassCtor)Node->getCtor(),
137                              Node->getDescription());
138     }
139 
140     // Make sure we listen for list changes.
141     RegistryClass::setListener(this);
142   }
143 
144   // Implement the MachinePassRegistryListener callbacks.
145   //
NotifyAdd(const char * N,MachinePassCtor C,const char * D)146   void NotifyAdd(const char *N, MachinePassCtor C, const char *D) override {
147     this->addLiteralOption(N, (typename RegistryClass::FunctionPassCtor)C, D);
148   }
NotifyRemove(const char * N)149   void NotifyRemove(const char *N) override {
150     this->removeLiteralOption(N);
151   }
152 };
153 
154 
155 } // end namespace llvm
156 
157 #endif
158