64d6e12fea3e2ea3fc23a91bcf5e3e705cd85cf1
[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     /// getClosestStaticTargetForTriple - Given a target triple, pick the most
187     /// capable target for that triple.
188     static const Target *getClosestStaticTargetForTriple(const std::string &TT,
189                                                          std::string &Error);
190
191     /// getClosestStaticTargetForModule - Given an LLVM module, pick the best
192     /// target that is compatible with the module.  If no close target can be
193     /// found, this returns null and sets the Error string to a reason.
194     static const Target *getClosestStaticTargetForModule(const Module &M,
195                                                         std::string &Error);
196
197     /// getClosestTargetForJIT - Pick the best target that is compatible with
198     /// the current host.  If no close target can be found, this returns null
199     /// and sets the Error string to a reason.
200     //
201     // FIXME: Do we still need this interface, clients can always look for the
202     // match for the host triple.
203     static const Target *getClosestTargetForJIT(std::string &Error);
204
205     /// @}
206     /// @name Target Registration
207     /// @{
208
209     /// RegisterTarget - Register the given target. Attempts to register a
210     /// target which has already been registered will be ignored.
211     /// 
212     /// Clients are responsible for ensuring that registration doesn't occur
213     /// while another thread is attempting to access the registry. Typically
214     /// this is done by initializing all targets at program startup.
215     ///
216     /// @param T - The target being registered.
217     /// @param Name - The target name. This should be a static string.
218     /// @param ShortDesc - A short target description. This should be a static
219     /// string. 
220     /// @param TQualityFn - The triple match quality computation function for
221     /// this target.
222     /// @param MQualityFn - The module match quality computation function for
223     /// this target.
224     /// @param HasJIT - Whether the target supports JIT code
225     /// generation.
226     static void RegisterTarget(Target &T,
227                                const char *Name,
228                                const char *ShortDesc,
229                                Target::TripleMatchQualityFnTy TQualityFn,
230                                Target::ModuleMatchQualityFnTy MQualityFn,
231                                bool HasJIT = false);
232                                
233     /// RegisterTargetMachine - Register a TargetMachine implementation for the
234     /// given target.
235     /// 
236     /// Clients are responsible for ensuring that registration doesn't occur
237     /// while another thread is attempting to access the registry. Typically
238     /// this is done by initializing all targets at program startup.
239     /// 
240     /// @param T - The target being registered.
241     /// @param Fn - A function to construct a TargetMachine for the target.
242     static void RegisterTargetMachine(Target &T, 
243                                       Target::TargetMachineCtorTy Fn) {
244       // Ignore duplicate registration.
245       if (!T.TargetMachineCtorFn)
246         T.TargetMachineCtorFn = Fn;
247     }
248
249     /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
250     /// target.
251     /// 
252     /// Clients are responsible for ensuring that registration doesn't occur
253     /// while another thread is attempting to access the registry. Typically
254     /// this is done by initializing all targets at program startup.
255     ///
256     /// @param T - The target being registered.
257     /// @param Fn - A function to construct an AsmPrinter for the target.
258     static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
259       // Ignore duplicate registration.
260       if (!T.AsmPrinterCtorFn)
261         T.AsmPrinterCtorFn = Fn;
262     }
263
264     /// RegisterAsmParser - Register a TargetAsmParser implementation for the
265     /// given target.
266     /// 
267     /// Clients are responsible for ensuring that registration doesn't occur
268     /// while another thread is attempting to access the registry. Typically
269     /// this is done by initializing all targets at program startup.
270     ///
271     /// @param T - The target being registered.
272     /// @param Fn - A function to construct an AsmPrinter for the target.
273     static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) {
274       if (!T.AsmParserCtorFn)
275         T.AsmParserCtorFn = Fn;
276     }
277
278     /// @}
279   };
280
281
282   //===--------------------------------------------------------------------===//
283
284   /// RegisterTarget - Helper template for registering a target, for use in the
285   /// target's initialization function. Usage:
286   ///
287   ///
288   /// Target TheFooTarget; // The global target instance.
289   ///
290   /// namespace {
291   ///   struct FooInfo {
292   ///     static const bool HasJIT = ...;
293   ///
294   ///     static unsigned getJITMatchQuality() { ... }
295   ///     static unsigned getTripleMatchQuality(const std::string &) { ... }
296   ///     static unsigned getModuleMatchQuality(const Module &) { ... }
297   ///   };
298   /// }
299   ///
300   /// extern "C" void LLVMInitializeFooTargetInfo() {
301   ///   RegisterTarget<FooAsmPrinter> X(TheFooTarget, "foo", "Foo description");
302   /// }
303   template<class TargetInfoImpl>
304   struct RegisterTarget {
305     RegisterTarget(Target &T, const char *Name, const char *Desc) {
306       TargetRegistry::RegisterTarget(T, Name, Desc,
307                                      &TargetInfoImpl::getTripleMatchQuality,
308                                      &TargetInfoImpl::getModuleMatchQuality,
309                                      TargetInfoImpl::HasJIT);
310     }
311   };
312
313   /// RegisterTargetMachine - Helper template for registering a target machine
314   /// implementation, for use in the target machine initialization
315   /// function. Usage:
316   ///
317   /// extern "C" void LLVMInitializeFooTarget() {
318   ///   extern Target TheFooTarget;
319   ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
320   /// }
321   template<class TargetMachineImpl>
322   struct RegisterTargetMachine {
323     RegisterTargetMachine(Target &T) {
324       TargetRegistry::RegisterTargetMachine(T, &Allocator);
325     }
326
327   private:
328     static TargetMachine *Allocator(const Target &T, const Module &M,
329                                     const std::string &FS) {
330       return new TargetMachineImpl(T, M, FS);
331     }
332   };
333
334   /// RegisterAsmPrinter - Helper template for registering a target specific
335   /// assembly printer, for use in the target machine initialization
336   /// function. Usage:
337   ///
338   /// extern "C" void LLVMInitializeFooAsmPrinter() {
339   ///   extern Target TheFooTarget;
340   ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
341   /// }
342   template<class AsmPrinterImpl>
343   struct RegisterAsmPrinter {
344     RegisterAsmPrinter(Target &T) {
345       TargetRegistry::RegisterAsmPrinter(T, &Allocator);
346     }
347
348   private:
349     static FunctionPass *Allocator(formatted_raw_ostream &OS,
350                                    TargetMachine &TM,
351                                    bool Verbose) {
352       return new AsmPrinterImpl(OS, TM, TM.getTargetAsmInfo(), Verbose);
353     }
354   };
355
356   /// RegisterAsmParser - Helper template for registering a target specific asm
357   /// parser, for use in the target machine initialization function. Usage:
358   ///
359   /// extern "C" void LLVMInitializeFooAsmPrinter() {
360   ///   extern Target TheFooTarget;
361   ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
362   /// }
363   template<class AsmParserImpl>
364   struct RegisterAsmParser {
365     RegisterAsmParser(Target &T) {
366       TargetRegistry::RegisterAsmParser(T, &Allocator);
367     }
368
369   private:
370     static TargetAsmParser *Allocator(const Target &T) {
371       return new AsmParserImpl(T);
372     }
373   };
374
375 }
376
377 #endif