MachinePassRegistry.h revision 9ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3b
1//===-- llvm/CodeGen/MachinePassRegistry.h ----------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file was developed by the James M. Laskey and is distributed under
6// the University of Illinois Open Source 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/CodeGen/ScheduleDAG.h"
23#include "llvm/Support/CommandLine.h"
24
25namespace llvm {
26
27
28//===----------------------------------------------------------------------===//
29///
30/// MachinePassRegistryListener - Listener to adds and removals of nodes in
31/// registration list.
32///
33//===----------------------------------------------------------------------===//
34class MachinePassRegistryListener {
35public:
36  MachinePassRegistryListener() {}
37  virtual ~MachinePassRegistryListener() {}
38  virtual void NotifyAdd(const char *N, const char *D) = 0;
39  virtual void NotifyRemove(const char *N, const char *D) = 0;
40};
41
42
43//===----------------------------------------------------------------------===//
44///
45/// MachinePassRegistryNode - Machine pass node stored in registration list.
46///
47//===----------------------------------------------------------------------===//
48template<typename FunctionPassCtor>
49class MachinePassRegistryNode {
50
51private:
52
53  MachinePassRegistryNode<FunctionPassCtor> *Next;// Next function pass in list.
54  const char *Name;                     // Name of function pass.
55  const char *Description;              // Description string.
56  FunctionPassCtor Ctor;                // Function pass creator.
57
58public:
59
60  MachinePassRegistryNode(const char *N, const char *D, FunctionPassCtor C)
61  : Next(NULL)
62  , Name(N)
63  , Description(D)
64  , Ctor(C)
65  {}
66
67  // Accessors
68  MachinePassRegistryNode<FunctionPassCtor> *getNext()
69                                          const { return Next; }
70  MachinePassRegistryNode<FunctionPassCtor> **getNextAddress()
71                                                { return &Next; }
72  const char *getName()                   const { return Name; }
73  const char *getDescription()            const { return Description; }
74  FunctionPassCtor getCtor()              const { return Ctor; }
75  void setNext(MachinePassRegistryNode<FunctionPassCtor> *N) { Next = N; }
76
77};
78
79
80//===----------------------------------------------------------------------===//
81///
82/// MachinePassRegistry - Track the registration of machine passes.
83///
84//===----------------------------------------------------------------------===//
85template<typename FunctionPassCtor>
86class MachinePassRegistry {
87
88private:
89
90  MachinePassRegistryNode<FunctionPassCtor> *List;
91                                        // List of registry nodes.
92  FunctionPassCtor Default;             // Default function pass creator.
93  MachinePassRegistryListener* Listener;// Listener for list adds are removes.
94
95public:
96
97  // NO CONSTRUCTOR - we don't want static constructor ordering to mess
98  // with the registry.
99
100  // Accessors.
101  //
102  MachinePassRegistryNode<FunctionPassCtor> *getList()  { return List; }
103  FunctionPassCtor getDefault()                         { return Default; }
104  void setDefault(FunctionPassCtor C)                   { Default = C; }
105  void setListener(MachinePassRegistryListener *L)      { Listener = L; }
106
107  /// Add - Adds a function pass to the registration list.
108  ///
109 void Add(MachinePassRegistryNode<FunctionPassCtor> *Node) {
110    Node->setNext(List);
111    List = Node;
112    if (Listener) Listener->NotifyAdd(Node->getName(), Node->getDescription());
113  }
114
115
116  /// Remove - Removes a function pass from the registration list.
117  ///
118  void Remove(MachinePassRegistryNode<FunctionPassCtor> *Node) {
119    for (MachinePassRegistryNode<FunctionPassCtor> **I = &List;
120         *I; I = (*I)->getNextAddress()) {
121      if (*I == Node) {
122        if (Listener) Listener->NotifyRemove(Node->getName(),
123                                             Node->getDescription());
124        *I = (*I)->getNext();
125        break;
126      }
127    }
128  }
129
130
131  /// FInd - Finds and returns a function pass in registration list, otherwise
132  /// returns NULL.
133  MachinePassRegistryNode<FunctionPassCtor> *Find(const char *Name) {
134    for (MachinePassRegistryNode<FunctionPassCtor> *I = List;
135         I; I = I->getNext()) {
136      if (std::string(Name) == std::string(I->getName())) return I;
137    }
138    return NULL;
139  }
140
141
142};
143
144
145//===----------------------------------------------------------------------===//
146///
147/// RegisterRegAlloc class - Track the registration of register allocators.
148///
149//===----------------------------------------------------------------------===//
150class RegisterRegAlloc : public MachinePassRegistryNode<FunctionPass *(*)()> {
151
152public:
153
154  typedef FunctionPass *(*FunctionPassCtor)();
155
156  static MachinePassRegistry<FunctionPassCtor> Registry;
157
158  RegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C)
159  : MachinePassRegistryNode<FunctionPassCtor>(N, D, C)
160  { Registry.Add(this); }
161  ~RegisterRegAlloc() { Registry.Remove(this); }
162
163
164  // Accessors.
165  //
166  RegisterRegAlloc *getNext() const {
167    return (RegisterRegAlloc *)
168           MachinePassRegistryNode<FunctionPassCtor>::getNext();
169  }
170  static RegisterRegAlloc *getList() {
171    return (RegisterRegAlloc *)Registry.getList();
172  }
173  static FunctionPassCtor getDefault() {
174    return Registry.getDefault();
175  }
176  static void setDefault(FunctionPassCtor C) {
177    Registry.setDefault(C);
178  }
179  static void setListener(MachinePassRegistryListener *L) {
180    Registry.setListener(L);
181  }
182
183
184  /// FirstCtor - Finds the first register allocator in registration
185  /// list and returns its creator function, otherwise return NULL.
186  static FunctionPassCtor FirstCtor() {
187    MachinePassRegistryNode<FunctionPassCtor> *Node = Registry.getList();
188    return Node ? Node->getCtor() : NULL;
189  }
190
191  /// FindCtor - Finds a register allocator in registration list and returns
192  /// its creator function, otherwise return NULL.
193  static FunctionPassCtor FindCtor(const char *N) {
194    MachinePassRegistryNode<FunctionPassCtor> *Node = Registry.Find(N);
195    return Node ? Node->getCtor() : NULL;
196  }
197
198};
199
200
201//===----------------------------------------------------------------------===//
202///
203/// RegisterScheduler class - Track the registration of instruction schedulers.
204///
205//===----------------------------------------------------------------------===//
206
207class SelectionDAGISel;
208class ScheduleDAG;
209class SelectionDAG;
210class MachineBasicBlock;
211
212class RegisterScheduler : public
213  MachinePassRegistryNode<
214       ScheduleDAG *(*)(SelectionDAGISel*, SelectionDAG*, MachineBasicBlock*)> {
215
216public:
217
218  typedef ScheduleDAG *(*FunctionPassCtor)(SelectionDAGISel*, SelectionDAG*,
219                                           MachineBasicBlock*);
220
221  static MachinePassRegistry<FunctionPassCtor> Registry;
222
223  RegisterScheduler(const char *N, const char *D, FunctionPassCtor C)
224  : MachinePassRegistryNode<FunctionPassCtor>(N, D, C)
225  { Registry.Add(this); }
226  ~RegisterScheduler() { Registry.Remove(this); }
227
228
229  // Accessors.
230  //
231  RegisterScheduler *getNext() const {
232    return (RegisterScheduler *)
233           MachinePassRegistryNode<FunctionPassCtor>::getNext();
234  }
235  static RegisterScheduler *getList() {
236    return (RegisterScheduler *)Registry.getList();
237  }
238  static FunctionPassCtor getDefault() {
239    return Registry.getDefault();
240  }
241  static void setDefault(FunctionPassCtor C) {
242    Registry.setDefault(C);
243  }
244  static void setListener(MachinePassRegistryListener *L) {
245    Registry.setListener(L);
246  }
247
248
249  /// FirstCtor - Finds the first instruction scheduler in registration
250  /// list and returns its creator function, otherwise return NULL.
251  static FunctionPassCtor FirstCtor() {
252    MachinePassRegistryNode<FunctionPassCtor> *Node = Registry.getList();
253    return Node ? Node->getCtor() : NULL;
254  }
255
256
257  /// FindCtor - Finds a instruction scheduler in registration list and returns
258  /// its creator function, otherwise return NULL.
259  static FunctionPassCtor FindCtor(const char *N) {
260    MachinePassRegistryNode<FunctionPassCtor> *Node = Registry.Find(N);
261    return Node ? Node->getCtor() : NULL;
262  }
263
264};
265
266
267//===----------------------------------------------------------------------===//
268///
269/// RegisterPassParser class - Handle the addition of new machine passes.
270///
271//===----------------------------------------------------------------------===//
272template<class RegistryClass>
273class RegisterPassParser : public MachinePassRegistryListener,
274                           public cl::parser<const char *> {
275public:
276  RegisterPassParser() {}
277  ~RegisterPassParser() { RegistryClass::setListener(NULL); }
278
279  void initialize(cl::Option &O) {
280    cl::parser<const char *>::initialize(O);
281
282    // Add existing passes to option.
283    for (RegistryClass *Node = RegistryClass::getList();
284         Node; Node = Node->getNext()) {
285      addLiteralOption(Node->getName(), Node->getName(),
286                       Node->getDescription());
287    }
288
289    // Make sure we listen for list changes.
290    RegistryClass::setListener(this);
291  }
292
293  // Implement the MachinePassRegistryListener callbacks.
294  //
295  virtual void NotifyAdd(const char *N, const char *D) {
296    addLiteralOption(N, N, D);
297  }
298  virtual void NotifyRemove(const char *N, const char *D) {
299    removeLiteralOption(N);
300  }
301
302  // ValLessThan - Provide a sorting comparator for Values elements...
303  typedef std::pair<const char*, std::pair<const char*, const char*> > ValType;
304  static bool ValLessThan(const ValType &VT1, const ValType &VT2) {
305    return std::string(VT1.first) < std::string(VT2.first);
306  }
307
308  // printOptionInfo - Print out information about this option.  Override the
309  // default implementation to sort the table before we print...
310  virtual void printOptionInfo(const cl::Option &O, unsigned GlobalWidth) const{
311    RegisterPassParser *PNP = const_cast<RegisterPassParser*>(this);
312    std::sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
313    cl::parser<const char *>::printOptionInfo(O, GlobalWidth);
314  }
315};
316
317
318} // end namespace llvm
319
320#endif
321