Add TargetRegistry::lookupTarget.
[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     /// Name - The target name.
72     const char *Name;
73
74     /// ShortDesc - A short description of the target.
75     const char *ShortDesc;
76
77     /// HasJIT - Whether this target supports the JIT.
78     bool HasJIT;
79
80     /// TargetMachineCtorFn - Construction function for this target's
81     /// TargetMachine, if registered.
82     TargetMachineCtorTy TargetMachineCtorFn;
83
84     /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
85     /// if registered.
86     AsmPrinterCtorTy AsmPrinterCtorFn;
87
88     /// AsmParserCtorFn - Construction function for this target's AsmParser,
89     /// if registered.
90     AsmParserCtorTy AsmParserCtorFn;
91
92   public:
93     // getNext - Return the next registered target.
94     const Target *getNext() const { return Next; }
95
96     /// getName - Get the target name.
97     const char *getName() const { return Name; }
98
99     /// getShortDescription - Get a short description of the target.
100     const char *getShortDescription() const { return ShortDesc; }
101
102     bool hasJIT() const { return HasJIT; }
103
104     /// hasTargetMachine - Check if this target supports code generation.
105     bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
106
107     /// hasAsmPrinter - Check if this target supports .s printing.
108     bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
109
110     /// hasAsmParser - Check if this target supports .s parsing.
111     bool hasAsmParser() const { return AsmParserCtorFn != 0; }
112
113     /// createTargetMachine - Create a target specific machine implementation.
114     TargetMachine *createTargetMachine(const Module &M,
115                                        const std::string &Features) const {
116       if (!TargetMachineCtorFn)
117         return 0;
118       return TargetMachineCtorFn(*this, M, Features);
119     }
120
121     /// createAsmPrinter - Create a target specific assembly printer pass.
122     FunctionPass *createAsmPrinter(formatted_raw_ostream &OS,
123                                    TargetMachine &M,
124                                    bool Verbose) const {
125       if (!AsmPrinterCtorFn)
126         return 0;
127       return AsmPrinterCtorFn(OS, M, Verbose);
128     }
129
130     /// createAsmParser - Create a target specific assembly parser.
131     TargetAsmParser *createAsmParser() const {
132       if (!AsmParserCtorFn)
133         return 0;
134       return AsmParserCtorFn(*this);
135     }
136   };
137
138   /// TargetRegistry - Generic interface to target specific features.
139   //
140   // FIXME: Provide Target* iterator.
141   struct TargetRegistry {
142     class iterator {
143       const Target *Current;
144       explicit iterator(Target *T) : Current(T) {}
145       friend struct TargetRegistry;
146     public:
147       iterator(const iterator &I) : Current(I.Current) {}
148       iterator() : Current(0) {}
149
150       bool operator==(const iterator &x) const {
151         return Current == x.Current;
152       }
153       bool operator!=(const iterator &x) const {
154         return !operator==(x);
155       }
156
157       // Iterator traversal: forward iteration only
158       iterator &operator++() {          // Preincrement
159         assert(Current && "Cannot increment end iterator!");
160         Current = Current->getNext();
161         return *this;
162       }
163       iterator operator++(int) {        // Postincrement
164         iterator tmp = *this; 
165         ++*this; 
166         return tmp;
167       }
168
169       const Target &operator*() const {
170         assert(Current && "Cannot dereference end iterator!");
171         return *Current;
172       }
173
174       const Target *operator->() const {
175         return &operator*();
176       }
177     };
178
179     /// @name Registry Access
180     /// @{
181
182     static iterator begin();
183
184     static iterator end() { return iterator(); }
185
186     /// lookupTarget - Lookup a target based on a target triple.
187     ///
188     /// \param Triple - The triple to use for finding a target.
189     /// \param FallbackToHost - If true and no target is found for the given
190     /// \arg Triple, then the host's triple will be used.
191     /// \param RequireJIT - Require the target to support JIT compilation.
192     /// \param Error - On failure, an error string describing why no target was
193     /// found.
194     static const Target *lookupTarget(const std::string &Triple,
195                                       bool FallbackToHost,
196                                       bool RequireJIT,
197                                       std::string &Error);
198
199     /// getClosestTargetForJIT - Pick the best target that is compatible with
200     /// the current host.  If no close target can be found, this returns null
201     /// and sets the Error string to a reason.
202     ///
203     /// Mainted for compatibility through 2.6.
204     static const Target *getClosestTargetForJIT(std::string &Error) {
205       return lookupTarget("", true, true, Error);
206     }
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 HasJIT - Whether the target supports JIT code
228     /// generation.
229     static void RegisterTarget(Target &T,
230                                const char *Name,
231                                const char *ShortDesc,
232                                Target::TripleMatchQualityFnTy TQualityFn,
233                                Target::ModuleMatchQualityFnTy MQualityFn,
234                                bool HasJIT = false);
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 const bool HasJIT = ...;
296   ///
297   ///     static unsigned getJITMatchQuality() { ... }
298   ///     static unsigned getTripleMatchQuality(const std::string &) { ... }
299   ///     static unsigned getModuleMatchQuality(const Module &) { ... }
300   ///   };
301   /// }
302   ///
303   /// extern "C" void LLVMInitializeFooTargetInfo() {
304   ///   RegisterTarget<FooAsmPrinter> X(TheFooTarget, "foo", "Foo description");
305   /// }
306   template<class TargetInfoImpl>
307   struct RegisterTarget {
308     RegisterTarget(Target &T, const char *Name, const char *Desc) {
309       TargetRegistry::RegisterTarget(T, Name, Desc,
310                                      &TargetInfoImpl::getTripleMatchQuality,
311                                      &TargetInfoImpl::getModuleMatchQuality,
312                                      TargetInfoImpl::HasJIT);
313     }
314   };
315
316   /// RegisterTargetMachine - Helper template for registering a target machine
317   /// implementation, for use in the target machine initialization
318   /// function. Usage:
319   ///
320   /// extern "C" void LLVMInitializeFooTarget() {
321   ///   extern Target TheFooTarget;
322   ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
323   /// }
324   template<class TargetMachineImpl>
325   struct RegisterTargetMachine {
326     RegisterTargetMachine(Target &T) {
327       TargetRegistry::RegisterTargetMachine(T, &Allocator);
328     }
329
330   private:
331     static TargetMachine *Allocator(const Target &T, const Module &M,
332                                     const std::string &FS) {
333       return new TargetMachineImpl(T, M, FS);
334     }
335   };
336
337   /// RegisterAsmPrinter - Helper template for registering a target specific
338   /// assembly printer, for use in the target machine initialization
339   /// function. Usage:
340   ///
341   /// extern "C" void LLVMInitializeFooAsmPrinter() {
342   ///   extern Target TheFooTarget;
343   ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
344   /// }
345   template<class AsmPrinterImpl>
346   struct RegisterAsmPrinter {
347     RegisterAsmPrinter(Target &T) {
348       TargetRegistry::RegisterAsmPrinter(T, &Allocator);
349     }
350
351   private:
352     static FunctionPass *Allocator(formatted_raw_ostream &OS,
353                                    TargetMachine &TM,
354                                    bool Verbose) {
355       return new AsmPrinterImpl(OS, TM, TM.getTargetAsmInfo(), Verbose);
356     }
357   };
358
359   /// RegisterAsmParser - Helper template for registering a target specific asm
360   /// parser, for use in the target machine initialization function. Usage:
361   ///
362   /// extern "C" void LLVMInitializeFooAsmPrinter() {
363   ///   extern Target TheFooTarget;
364   ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
365   /// }
366   template<class AsmParserImpl>
367   struct RegisterAsmParser {
368     RegisterAsmParser(Target &T) {
369       TargetRegistry::RegisterAsmParser(T, &Allocator);
370     }
371
372   private:
373     static TargetAsmParser *Allocator(const Target &T) {
374       return new AsmParserImpl(T);
375     }
376   };
377
378 }
379
380 #endif