6d692df27b85fc003f54db498e51f2974947e2df
[oota-llvm.git] / include / llvm / Target / TargetRegistry.h
1 //===-- Target/TargetRegistry.h - Target Registration -----------*- 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 exposes the TargetRegistry interface, which tools can use to access
11 // the appropriate target specific classes (TargetMachine, AsmPrinter, etc.)
12 // which have been registered.
13 //
14 // Target specific class implementations should register themselves using the
15 // appropriate TargetRegistry interfaces.
16 //
17 //===----------------------------------------------------------------------===//
18
19 #ifndef LLVM_TARGET_TARGETREGISTRY_H
20 #define LLVM_TARGET_TARGETREGISTRY_H
21
22 // FIXME: We shouldn't need this header, but we need it until there is a
23 // different interface to get the TargetAsmInfo.
24 #include "llvm/Target/TargetMachine.h"
25 #include <string>
26 #include <cassert>
27
28 namespace llvm {
29   class FunctionPass;
30   class Module;
31   class TargetAsmParser;
32   class TargetMachine;
33   class formatted_raw_ostream;
34
35   /// Target - Wrapper for Target specific information.
36   ///
37   /// For registration purposes, this is a POD type so that targets can be
38   /// registered without the use of static constructors.
39   ///
40   /// Targets should implement a single global instance of this class (which
41   /// will be zero initialized), and pass that instance to the TargetRegistry as
42   /// part of their initialization.
43   class Target {
44   private:
45     typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
46     typedef unsigned (*ModuleMatchQualityFnTy)(const Module &M);
47     typedef unsigned (*JITMatchQualityFnTy)();
48
49     typedef TargetMachine *(*TargetMachineCtorTy)(const Target &,
50                                                   const Module &, 
51                                                   const std::string &);
52     typedef FunctionPass *(*AsmPrinterCtorTy)(formatted_raw_ostream &,
53                                               TargetMachine &,
54                                               bool);
55     typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &);
56
57     friend struct TargetRegistry;
58
59     /// Next - The next registered target in the linked list, maintained by the
60     /// TargetRegistry.
61     Target *Next;
62
63     /// TripleMatchQualityFn - The target function for rating the match quality
64     /// of a triple.
65     TripleMatchQualityFnTy TripleMatchQualityFn;
66
67     /// ModuleMatchQualityFn - The target function for rating the match quality
68     /// of a module.
69     ModuleMatchQualityFnTy ModuleMatchQualityFn;
70
71     /// JITMatchQualityFn - The target function for rating the match quality
72     /// with the host.
73     JITMatchQualityFnTy JITMatchQualityFn;
74
75     /// Name - The target name.
76     const char *Name;
77
78     /// ShortDesc - A short description of the target.
79     const char *ShortDesc;
80
81     /// TargetMachineCtorFn - Construction function for this target's
82     /// TargetMachine, if registered.
83     TargetMachineCtorTy TargetMachineCtorFn;
84
85     /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
86     /// if registered.
87     AsmPrinterCtorTy AsmPrinterCtorFn;
88
89     /// AsmParserCtorFn - Construction function for this target's AsmParser,
90     /// if registered.
91     AsmParserCtorTy AsmParserCtorFn;
92
93   public:
94     // getNext - Return the next registered target.
95     const Target *getNext() const { return Next; }
96
97     /// getName - Get the target name.
98     const char *getName() const { return Name; }
99
100     /// getShortDescription - Get a short description of the target.
101     const char *getShortDescription() const { return ShortDesc; }
102
103     /// getJITMatchQuality - Get the quality of this targets match for use as a
104     /// JIT.
105     unsigned getJITMatchQuality() const { return JITMatchQualityFn(); }
106
107     /// hasTargetMachine - Check if this target supports code generation.
108     bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
109
110     /// hasAsmPrinter - Check if this target supports .s printing.
111     bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
112
113     /// hasAsmParser - Check if this target supports .s parsing.
114     bool hasAsmParser() const { return AsmParserCtorFn != 0; }
115
116     /// createTargetMachine - Create a target specific machine implementation.
117     TargetMachine *createTargetMachine(const Module &M,
118                                        const std::string &Features) const {
119       if (!TargetMachineCtorFn)
120         return 0;
121       return TargetMachineCtorFn(*this, M, Features);
122     }
123
124     /// createAsmPrinter - Create a target specific assembly printer pass.
125     FunctionPass *createAsmPrinter(formatted_raw_ostream &OS,
126                                    TargetMachine &M,
127                                    bool Verbose) const {
128       if (!AsmPrinterCtorFn)
129         return 0;
130       return AsmPrinterCtorFn(OS, M, Verbose);
131     }
132
133     /// createAsmParser - Create a target specific assembly parser.
134     TargetAsmParser *createAsmParser() const {
135       if (!AsmParserCtorFn)
136         return 0;
137       return AsmParserCtorFn(*this);
138     }
139   };
140
141   /// TargetRegistry - Generic interface to target specific features.
142   //
143   // FIXME: Provide Target* iterator.
144   struct TargetRegistry {
145     class iterator {
146       const Target *Current;
147       explicit iterator(Target *T) : Current(T) {}
148       friend struct TargetRegistry;
149     public:
150       iterator(const iterator &I) : Current(I.Current) {}
151       iterator() : Current(0) {}
152
153       bool operator==(const iterator &x) const {
154         return Current == x.Current;
155       }
156       bool operator!=(const iterator &x) const {
157         return !operator==(x);
158       }
159
160       // Iterator traversal: forward iteration only
161       iterator &operator++() {          // Preincrement
162         assert(Current && "Cannot increment end iterator!");
163         Current = Current->getNext();
164         return *this;
165       }
166       iterator operator++(int) {        // Postincrement
167         iterator tmp = *this; 
168         ++*this; 
169         return tmp;
170       }
171
172       const Target &operator*() const {
173         assert(Current && "Cannot dereference end iterator!");
174         return *Current;
175       }
176
177       const Target *operator->() const {
178         return &operator*();
179       }
180     };
181
182     /// @name Registry Access
183     /// @{
184
185     static iterator begin();
186
187     static iterator end() { return iterator(); }
188
189     /// getClosestStaticTargetForTriple - Given a target triple, pick the most
190     /// capable target for that triple.
191     static const Target *getClosestStaticTargetForTriple(const std::string &TT,
192                                                          std::string &Error);
193
194     /// getClosestStaticTargetForModule - Given an LLVM module, pick the best
195     /// target that is compatible with the module.  If no close target can be
196     /// found, this returns null and sets the Error string to a reason.
197     static const Target *getClosestStaticTargetForModule(const Module &M,
198                                                         std::string &Error);
199
200     /// getClosestTargetForJIT - Pick the best target that is compatible with
201     /// the current host.  If no close target can be found, this returns null
202     /// and sets the Error string to a reason.
203     //
204     // FIXME: Do we still need this interface, clients can always look for the
205     // match for the host triple.
206     static const Target *getClosestTargetForJIT(std::string &Error);
207
208     /// @}
209     /// @name Target Registration
210     /// @{
211
212     /// RegisterTarget - Register the given target. Attempts to register a
213     /// target which has already been registered will be ignored.
214     /// 
215     /// Clients are responsible for ensuring that registration doesn't occur
216     /// while another thread is attempting to access the registry. Typically
217     /// this is done by initializing all targets at program startup.
218     ///
219     /// @param T - The target being registered.
220     /// @param Name - The target name. This should be a static string.
221     /// @param ShortDesc - A short target description. This should be a static
222     /// string. 
223     /// @param TQualityFn - The triple match quality computation function for
224     /// this target.
225     /// @param MQualityFn - The module match quality computation function for
226     /// this target.
227     /// @param JITMatchQualityFn - The JIT match quality computation function
228     /// for this target.
229     static void RegisterTarget(Target &T,
230                                const char *Name,
231                                const char *ShortDesc,
232                                Target::TripleMatchQualityFnTy TQualityFn,
233                                Target::ModuleMatchQualityFnTy MQualityFn,
234                                Target::JITMatchQualityFnTy JITQualityFn);
235                                
236     /// RegisterTargetMachine - Register a TargetMachine implementation for the
237     /// given target.
238     /// 
239     /// Clients are responsible for ensuring that registration doesn't occur
240     /// while another thread is attempting to access the registry. Typically
241     /// this is done by initializing all targets at program startup.
242     /// 
243     /// @param T - The target being registered.
244     /// @param Fn - A function to construct a TargetMachine for the target.
245     static void RegisterTargetMachine(Target &T, 
246                                       Target::TargetMachineCtorTy Fn) {
247       // Ignore duplicate registration.
248       if (!T.TargetMachineCtorFn)
249         T.TargetMachineCtorFn = Fn;
250     }
251
252     /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
253     /// target.
254     /// 
255     /// Clients are responsible for ensuring that registration doesn't occur
256     /// while another thread is attempting to access the registry. Typically
257     /// this is done by initializing all targets at program startup.
258     ///
259     /// @param T - The target being registered.
260     /// @param Fn - A function to construct an AsmPrinter for the target.
261     static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
262       // Ignore duplicate registration.
263       if (!T.AsmPrinterCtorFn)
264         T.AsmPrinterCtorFn = Fn;
265     }
266
267     /// RegisterAsmParser - Register a TargetAsmParser implementation for the
268     /// given target.
269     /// 
270     /// Clients are responsible for ensuring that registration doesn't occur
271     /// while another thread is attempting to access the registry. Typically
272     /// this is done by initializing all targets at program startup.
273     ///
274     /// @param T - The target being registered.
275     /// @param Fn - A function to construct an AsmPrinter for the target.
276     static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) {
277       if (!T.AsmParserCtorFn)
278         T.AsmParserCtorFn = Fn;
279     }
280
281     /// @}
282   };
283
284
285   //===--------------------------------------------------------------------===//
286
287   /// RegisterTarget - Helper template for registering a target, for use in the
288   /// target's initialization function. Usage:
289   ///
290   ///
291   /// Target TheFooTarget; // The global target instance.
292   ///
293   /// namespace {
294   ///   struct FooInfo {
295   ///     static unsigned getJITMatchQuality() { ... }
296   ///     static unsigned getTripleMatchQuality(const std::string &) { ... }
297   ///     static unsigned getModuleMatchQuality(const Module &) { ... }
298   ///   };
299   /// }
300   ///
301   /// extern "C" void LLVMInitializeFooTargetInfo() {
302   ///   RegisterTarget<FooAsmPrinter> X(TheFooTarget, "foo", "Foo description");
303   /// }
304   template<class TargetInfoImpl>
305   struct RegisterTarget {
306     RegisterTarget(Target &T, const char *Name, const char *Desc) {
307       TargetRegistry::RegisterTarget(T, Name, Desc,
308                                      &TargetInfoImpl::getTripleMatchQuality,
309                                      &TargetInfoImpl::getModuleMatchQuality,
310                                      &TargetInfoImpl::getJITMatchQuality);
311     }
312   };
313
314   /// RegisterTargetMachine - Helper template for registering a target machine
315   /// implementation, for use in the target machine initialization
316   /// function. Usage:
317   ///
318   /// extern "C" void LLVMInitializeFooTarget() {
319   ///   extern Target TheFooTarget;
320   ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
321   /// }
322   template<class TargetMachineImpl>
323   struct RegisterTargetMachine {
324     RegisterTargetMachine(Target &T) {
325       TargetRegistry::RegisterTargetMachine(T, &Allocator);
326     }
327
328   private:
329     static TargetMachine *Allocator(const Target &T, const Module &M,
330                                     const std::string &FS) {
331       return new TargetMachineImpl(T, M, FS);
332     }
333   };
334
335   /// RegisterAsmPrinter - Helper template for registering a target specific
336   /// assembly printer, for use in the target machine initialization
337   /// function. Usage:
338   ///
339   /// extern "C" void LLVMInitializeFooAsmPrinter() {
340   ///   extern Target TheFooTarget;
341   ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
342   /// }
343   template<class AsmPrinterImpl>
344   struct RegisterAsmPrinter {
345     RegisterAsmPrinter(Target &T) {
346       TargetRegistry::RegisterAsmPrinter(T, &Allocator);
347     }
348
349   private:
350     static FunctionPass *Allocator(formatted_raw_ostream &OS,
351                                    TargetMachine &TM,
352                                    bool Verbose) {
353       return new AsmPrinterImpl(OS, TM, TM.getTargetAsmInfo(), Verbose);
354     }
355   };
356
357   /// RegisterAsmParser - Helper template for registering a target specific asm
358   /// parser, for use in the target machine initialization function. Usage:
359   ///
360   /// extern "C" void LLVMInitializeFooAsmPrinter() {
361   ///   extern Target TheFooTarget;
362   ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
363   /// }
364   template<class AsmParserImpl>
365   struct RegisterAsmParser {
366     RegisterAsmParser(Target &T) {
367       TargetRegistry::RegisterAsmParser(T, &Allocator);
368     }
369
370   private:
371     static TargetAsmParser *Allocator(const Target &T) {
372       return new AsmParserImpl(T);
373     }
374   };
375
376 }
377
378 #endif