93991dc687324f0614dd973c53eb9f6efddf3f29
[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 #include "llvm/ADT/Triple.h"
23 // FIXME: We shouldn't need this header, but we need it until there is a
24 // different interface to get the TargetAsmInfo.
25 #include "llvm/Target/TargetMachine.h"
26 // FIXME: We shouldn't need this header, but we need it until there is a
27 // different interface to the target machines.
28 #include "llvm/Module.h"
29 #include <string>
30 #include <cassert>
31
32 namespace llvm {
33   class FunctionPass;
34   class MCAsmParser;
35   class Module;
36   class TargetAsmParser;
37   class TargetMachine;
38   class formatted_raw_ostream;
39
40   /// Target - Wrapper for Target specific information.
41   ///
42   /// For registration purposes, this is a POD type so that targets can be
43   /// registered without the use of static constructors.
44   ///
45   /// Targets should implement a single global instance of this class (which
46   /// will be zero initialized), and pass that instance to the TargetRegistry as
47   /// part of their initialization.
48   class Target {
49   private:
50     typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
51
52     typedef TargetMachine *(*TargetMachineCtorTy)(const Target &,
53                                                   const Module &, 
54                                                   const std::string &,
55                                                   const std::string &);
56     typedef FunctionPass *(*AsmPrinterCtorTy)(formatted_raw_ostream &,
57                                               TargetMachine &,
58                                               bool);
59     typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &,
60                                                 MCAsmParser &);
61
62     friend struct TargetRegistry;
63
64     /// Next - The next registered target in the linked list, maintained by the
65     /// TargetRegistry.
66     Target *Next;
67
68     /// TripleMatchQualityFn - The target function for rating the match quality
69     /// of a triple.
70     TripleMatchQualityFnTy TripleMatchQualityFn;
71
72     /// Name - The target name.
73     const char *Name;
74
75     /// ShortDesc - A short description of the target.
76     const char *ShortDesc;
77
78     /// HasJIT - Whether this target supports the JIT.
79     bool HasJIT;
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     bool hasJIT() const { return HasJIT; }
104
105     /// hasTargetMachine - Check if this target supports code generation.
106     bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
107
108     /// hasAsmPrinter - Check if this target supports .s printing.
109     bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
110
111     /// hasAsmParser - Check if this target supports .s parsing.
112     bool hasAsmParser() const { return AsmParserCtorFn != 0; }
113
114     /// createTargetMachine - Create a target specific machine implementation
115     /// for the module \arg M and \arg Triple.
116     ///
117     /// \arg M - This argument is used for some machines to access the target
118     /// data.
119     /// \arg Triple - This argument is used to determine the target machine
120     /// feature set; it should always be provided. Generally this should be
121     /// either the target triple from the module, or the target triple of the
122     /// host if that does not exist.
123     TargetMachine *createTargetMachine(const Module &M,
124                                        const std::string &Triple,
125                                        const std::string &Features) const {
126       if (!TargetMachineCtorFn)
127         return 0;
128       return TargetMachineCtorFn(*this, M, Triple, Features);
129     }
130
131     /// createAsmPrinter - Create a target specific assembly printer pass.
132     FunctionPass *createAsmPrinter(formatted_raw_ostream &OS,
133                                    TargetMachine &M,
134                                    bool Verbose) const {
135       if (!AsmPrinterCtorFn)
136         return 0;
137       return AsmPrinterCtorFn(OS, M, Verbose);
138     }
139
140     /// createAsmParser - Create a target specific assembly parser.
141     ///
142     /// \arg Parser - The target independent parser implementation to use for
143     /// parsing and lexing.
144     TargetAsmParser *createAsmParser(MCAsmParser &Parser) const {
145       if (!AsmParserCtorFn)
146         return 0;
147       return AsmParserCtorFn(*this, Parser);
148     }
149   };
150
151   /// TargetRegistry - Generic interface to target specific features.
152   //
153   // FIXME: Provide Target* iterator.
154   struct TargetRegistry {
155     class iterator {
156       const Target *Current;
157       explicit iterator(Target *T) : Current(T) {}
158       friend struct TargetRegistry;
159     public:
160       iterator(const iterator &I) : Current(I.Current) {}
161       iterator() : Current(0) {}
162
163       bool operator==(const iterator &x) const {
164         return Current == x.Current;
165       }
166       bool operator!=(const iterator &x) const {
167         return !operator==(x);
168       }
169
170       // Iterator traversal: forward iteration only
171       iterator &operator++() {          // Preincrement
172         assert(Current && "Cannot increment end iterator!");
173         Current = Current->getNext();
174         return *this;
175       }
176       iterator operator++(int) {        // Postincrement
177         iterator tmp = *this; 
178         ++*this; 
179         return tmp;
180       }
181
182       const Target &operator*() const {
183         assert(Current && "Cannot dereference end iterator!");
184         return *Current;
185       }
186
187       const Target *operator->() const {
188         return &operator*();
189       }
190     };
191
192     /// @name Registry Access
193     /// @{
194
195     static iterator begin();
196
197     static iterator end() { return iterator(); }
198
199     /// lookupTarget - Lookup a target based on a target triple.
200     ///
201     /// \param Triple - The triple to use for finding a target.
202     /// \param FallbackToHost - If true and no target is found for the given
203     /// \arg Triple, then the host's triple will be used.
204     /// \param RequireJIT - Require the target to support JIT compilation.
205     /// \param Error - On failure, an error string describing why no target was
206     /// found.
207     static const Target *lookupTarget(const std::string &Triple,
208                                       bool FallbackToHost,
209                                       bool RequireJIT,
210                                       std::string &Error);
211
212     /// getClosestTargetForJIT - Pick the best target that is compatible with
213     /// the current host.  If no close target can be found, this returns null
214     /// and sets the Error string to a reason.
215     ///
216     /// Mainted for compatibility through 2.6.
217     static const Target *getClosestTargetForJIT(std::string &Error) {
218       return lookupTarget("", true, true, Error);
219     }
220
221     /// @}
222     /// @name Target Registration
223     /// @{
224
225     /// RegisterTarget - Register the given target. Attempts to register a
226     /// target which has already been registered will be ignored.
227     /// 
228     /// Clients are responsible for ensuring that registration doesn't occur
229     /// while another thread is attempting to access the registry. Typically
230     /// this is done by initializing all targets at program startup.
231     ///
232     /// @param T - The target being registered.
233     /// @param Name - The target name. This should be a static string.
234     /// @param ShortDesc - A short target description. This should be a static
235     /// string. 
236     /// @param TQualityFn - The triple match quality computation function for
237     /// this target.
238     /// @param HasJIT - Whether the target supports JIT code
239     /// generation.
240     static void RegisterTarget(Target &T,
241                                const char *Name,
242                                const char *ShortDesc,
243                                Target::TripleMatchQualityFnTy TQualityFn,
244                                bool HasJIT = false);
245                                
246     /// RegisterTargetMachine - Register a TargetMachine implementation for the
247     /// given target.
248     /// 
249     /// Clients are responsible for ensuring that registration doesn't occur
250     /// while another thread is attempting to access the registry. Typically
251     /// this is done by initializing all targets at program startup.
252     /// 
253     /// @param T - The target being registered.
254     /// @param Fn - A function to construct a TargetMachine for the target.
255     static void RegisterTargetMachine(Target &T, 
256                                       Target::TargetMachineCtorTy Fn) {
257       // Ignore duplicate registration.
258       if (!T.TargetMachineCtorFn)
259         T.TargetMachineCtorFn = Fn;
260     }
261
262     /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
263     /// target.
264     /// 
265     /// Clients are responsible for ensuring that registration doesn't occur
266     /// while another thread is attempting to access the registry. Typically
267     /// this is done by initializing all targets at program startup.
268     ///
269     /// @param T - The target being registered.
270     /// @param Fn - A function to construct an AsmPrinter for the target.
271     static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
272       // Ignore duplicate registration.
273       if (!T.AsmPrinterCtorFn)
274         T.AsmPrinterCtorFn = Fn;
275     }
276
277     /// RegisterAsmParser - Register a TargetAsmParser implementation for the
278     /// given target.
279     /// 
280     /// Clients are responsible for ensuring that registration doesn't occur
281     /// while another thread is attempting to access the registry. Typically
282     /// this is done by initializing all targets at program startup.
283     ///
284     /// @param T - The target being registered.
285     /// @param Fn - A function to construct an AsmPrinter for the target.
286     static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) {
287       if (!T.AsmParserCtorFn)
288         T.AsmParserCtorFn = Fn;
289     }
290
291     /// @}
292   };
293
294
295   //===--------------------------------------------------------------------===//
296
297   /// RegisterTarget - Helper template for registering a target, for use in the
298   /// target's initialization function. Usage:
299   ///
300   ///
301   /// Target TheFooTarget; // The global target instance.
302   ///
303   /// extern "C" void LLVMInitializeFooTargetInfo() {
304   ///   RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
305   /// }
306   template<Triple::ArchType TargetArchType = Triple::InvalidArch,
307            bool HasJIT = false>
308   struct RegisterTarget {
309     RegisterTarget(Target &T, const char *Name, const char *Desc) {
310       TargetRegistry::RegisterTarget(T, Name, Desc,
311                                      &getTripleMatchQuality,
312                                      HasJIT);
313     }
314
315     static unsigned getTripleMatchQuality(const std::string &TT) {
316       if (Triple(TT.c_str()).getArch() == TargetArchType)
317         return 20;
318       return 0;
319     }
320   };
321
322   /// RegisterTargetMachine - Helper template for registering a target machine
323   /// implementation, for use in the target machine initialization
324   /// function. Usage:
325   ///
326   /// extern "C" void LLVMInitializeFooTarget() {
327   ///   extern Target TheFooTarget;
328   ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
329   /// }
330   template<class TargetMachineImpl>
331   struct RegisterTargetMachine {
332     RegisterTargetMachine(Target &T) {
333       TargetRegistry::RegisterTargetMachine(T, &Allocator);
334     }
335
336   private:
337     static TargetMachine *Allocator(const Target &T, const Module &M,
338                                     const std::string &TT,
339                                     const std::string &FS) {
340       return new TargetMachineImpl(T, TT, FS);
341     }
342   };
343
344   template<class TargetMachineImpl>
345   struct RegisterTargetMachineDeprecated {
346     RegisterTargetMachineDeprecated(Target &T) {
347       TargetRegistry::RegisterTargetMachine(T, &Allocator);
348     }
349
350   private:
351     static TargetMachine *Allocator(const Target &T, const Module &M,
352                                     const std::string &TT,
353                                     const std::string &FS) {
354       return new TargetMachineImpl(T, M, FS);
355     }
356   };
357
358   /// RegisterAsmPrinter - Helper template for registering a target specific
359   /// assembly printer, for use in the target machine initialization
360   /// function. Usage:
361   ///
362   /// extern "C" void LLVMInitializeFooAsmPrinter() {
363   ///   extern Target TheFooTarget;
364   ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
365   /// }
366   template<class AsmPrinterImpl>
367   struct RegisterAsmPrinter {
368     RegisterAsmPrinter(Target &T) {
369       TargetRegistry::RegisterAsmPrinter(T, &Allocator);
370     }
371
372   private:
373     static FunctionPass *Allocator(formatted_raw_ostream &OS,
374                                    TargetMachine &TM,
375                                    bool Verbose) {
376       return new AsmPrinterImpl(OS, TM, TM.getTargetAsmInfo(), Verbose);
377     }
378   };
379
380   /// RegisterAsmParser - Helper template for registering a target specific
381   /// assembly parser, for use in the target machine initialization
382   /// function. Usage:
383   ///
384   /// extern "C" void LLVMInitializeFooAsmParser() {
385   ///   extern Target TheFooTarget;
386   ///   RegisterAsmParser<FooAsmParser> X(TheFooTarget);
387   /// }
388   template<class AsmParserImpl>
389   struct RegisterAsmParser {
390     RegisterAsmParser(Target &T) {
391       TargetRegistry::RegisterAsmParser(T, &Allocator);
392     }
393
394   private:
395     static TargetAsmParser *Allocator(const Target &T, MCAsmParser &P) {
396       return new AsmParserImpl(T, P);
397     }
398   };
399
400 }
401
402 #endif