Remove now unused Module argument to createTargetMachine.
[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 #include <string>
27 #include <cassert>
28
29 namespace llvm {
30   class FunctionPass;
31   class MCAsmParser;
32   class Module;
33   class TargetAsmParser;
34   class TargetMachine;
35   class formatted_raw_ostream;
36
37   /// Target - Wrapper for Target specific information.
38   ///
39   /// For registration purposes, this is a POD type so that targets can be
40   /// registered without the use of static constructors.
41   ///
42   /// Targets should implement a single global instance of this class (which
43   /// will be zero initialized), and pass that instance to the TargetRegistry as
44   /// part of their initialization.
45   class Target {
46   private:
47     typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
48
49     typedef TargetMachine *(*TargetMachineCtorTy)(const Target &,
50                                                   const std::string &,
51                                                   const std::string &);
52     typedef FunctionPass *(*AsmPrinterCtorTy)(formatted_raw_ostream &,
53                                               TargetMachine &,
54                                               bool);
55     typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &,
56                                                 MCAsmParser &);
57
58     friend struct TargetRegistry;
59
60     /// Next - The next registered target in the linked list, maintained by the
61     /// TargetRegistry.
62     Target *Next;
63
64     /// TripleMatchQualityFn - The target function for rating the match quality
65     /// of a triple.
66     TripleMatchQualityFnTy TripleMatchQualityFn;
67
68     /// Name - The target name.
69     const char *Name;
70
71     /// ShortDesc - A short description of the target.
72     const char *ShortDesc;
73
74     /// HasJIT - Whether this target supports the JIT.
75     bool HasJIT;
76
77     /// TargetMachineCtorFn - Construction function for this target's
78     /// TargetMachine, if registered.
79     TargetMachineCtorTy TargetMachineCtorFn;
80
81     /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
82     /// if registered.
83     AsmPrinterCtorTy AsmPrinterCtorFn;
84
85     /// AsmParserCtorFn - Construction function for this target's AsmParser,
86     /// if registered.
87     AsmParserCtorTy AsmParserCtorFn;
88
89   public:
90     // getNext - Return the next registered target.
91     const Target *getNext() const { return Next; }
92
93     /// getName - Get the target name.
94     const char *getName() const { return Name; }
95
96     /// getShortDescription - Get a short description of the target.
97     const char *getShortDescription() const { return ShortDesc; }
98
99     bool hasJIT() const { return HasJIT; }
100
101     /// hasTargetMachine - Check if this target supports code generation.
102     bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
103
104     /// hasAsmPrinter - Check if this target supports .s printing.
105     bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
106
107     /// hasAsmParser - Check if this target supports .s parsing.
108     bool hasAsmParser() const { return AsmParserCtorFn != 0; }
109
110     /// createTargetMachine - Create a target specific machine implementation
111     /// for the module \arg M and \arg Triple.
112     ///
113     /// \arg M - This argument is used for some machines to access the target
114     /// data.
115     /// \arg Triple - This argument is used to determine the target machine
116     /// feature set; it should always be provided. Generally this should be
117     /// either the target triple from the module, or the target triple of the
118     /// host if that does not exist.
119     TargetMachine *createTargetMachine(const std::string &Triple,
120                                        const std::string &Features) const {
121       if (!TargetMachineCtorFn)
122         return 0;
123       return TargetMachineCtorFn(*this, Triple, Features);
124     }
125     TargetMachine *createTargetMachine(const Module &M,
126                                        const std::string &Triple,
127                                        const std::string &Features) const {
128       return createTargetMachine(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   struct TargetRegistry {
153     class iterator {
154       const Target *Current;
155       explicit iterator(Target *T) : Current(T) {}
156       friend struct TargetRegistry;
157     public:
158       iterator(const iterator &I) : Current(I.Current) {}
159       iterator() : Current(0) {}
160
161       bool operator==(const iterator &x) const {
162         return Current == x.Current;
163       }
164       bool operator!=(const iterator &x) const {
165         return !operator==(x);
166       }
167
168       // Iterator traversal: forward iteration only
169       iterator &operator++() {          // Preincrement
170         assert(Current && "Cannot increment end iterator!");
171         Current = Current->getNext();
172         return *this;
173       }
174       iterator operator++(int) {        // Postincrement
175         iterator tmp = *this; 
176         ++*this; 
177         return tmp;
178       }
179
180       const Target &operator*() const {
181         assert(Current && "Cannot dereference end iterator!");
182         return *Current;
183       }
184
185       const Target *operator->() const {
186         return &operator*();
187       }
188     };
189
190     /// @name Registry Access
191     /// @{
192
193     static iterator begin();
194
195     static iterator end() { return iterator(); }
196
197     /// lookupTarget - Lookup a target based on a target triple.
198     ///
199     /// \param Triple - The triple to use for finding a target.
200     /// \param Error - On failure, an error string describing why no target was
201     /// found.
202     static const Target *lookupTarget(const std::string &Triple,
203                                       std::string &Error);
204
205     /// getClosestTargetForJIT - Pick the best target that is compatible with
206     /// the current host.  If no close target can be found, this returns null
207     /// and sets the Error string to a reason.
208     ///
209     /// Mainted for compatibility through 2.6.
210     static const Target *getClosestTargetForJIT(std::string &Error);
211
212     /// @}
213     /// @name Target Registration
214     /// @{
215
216     /// RegisterTarget - Register the given target. Attempts to register a
217     /// target which has already been registered will be ignored.
218     /// 
219     /// Clients are responsible for ensuring that registration doesn't occur
220     /// while another thread is attempting to access the registry. Typically
221     /// this is done by initializing all targets at program startup.
222     ///
223     /// @param T - The target being registered.
224     /// @param Name - The target name. This should be a static string.
225     /// @param ShortDesc - A short target description. This should be a static
226     /// string. 
227     /// @param TQualityFn - The triple match quality computation function for
228     /// this target.
229     /// @param HasJIT - Whether the target supports JIT code
230     /// generation.
231     static void RegisterTarget(Target &T,
232                                const char *Name,
233                                const char *ShortDesc,
234                                Target::TripleMatchQualityFnTy TQualityFn,
235                                bool HasJIT = false);
236                                
237     /// RegisterTargetMachine - Register a TargetMachine implementation for the
238     /// given target.
239     /// 
240     /// Clients are responsible for ensuring that registration doesn't occur
241     /// while another thread is attempting to access the registry. Typically
242     /// this is done by initializing all targets at program startup.
243     /// 
244     /// @param T - The target being registered.
245     /// @param Fn - A function to construct a TargetMachine for the target.
246     static void RegisterTargetMachine(Target &T, 
247                                       Target::TargetMachineCtorTy Fn) {
248       // Ignore duplicate registration.
249       if (!T.TargetMachineCtorFn)
250         T.TargetMachineCtorFn = Fn;
251     }
252
253     /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
254     /// target.
255     /// 
256     /// Clients are responsible for ensuring that registration doesn't occur
257     /// while another thread is attempting to access the registry. Typically
258     /// this is done by initializing all targets at program startup.
259     ///
260     /// @param T - The target being registered.
261     /// @param Fn - A function to construct an AsmPrinter for the target.
262     static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
263       // Ignore duplicate registration.
264       if (!T.AsmPrinterCtorFn)
265         T.AsmPrinterCtorFn = Fn;
266     }
267
268     /// RegisterAsmParser - Register a TargetAsmParser implementation for the
269     /// given target.
270     /// 
271     /// Clients are responsible for ensuring that registration doesn't occur
272     /// while another thread is attempting to access the registry. Typically
273     /// this is done by initializing all targets at program startup.
274     ///
275     /// @param T - The target being registered.
276     /// @param Fn - A function to construct an AsmPrinter for the target.
277     static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) {
278       if (!T.AsmParserCtorFn)
279         T.AsmParserCtorFn = Fn;
280     }
281
282     /// @}
283   };
284
285
286   //===--------------------------------------------------------------------===//
287
288   /// RegisterTarget - Helper template for registering a target, for use in the
289   /// target's initialization function. Usage:
290   ///
291   ///
292   /// Target TheFooTarget; // The global target instance.
293   ///
294   /// extern "C" void LLVMInitializeFooTargetInfo() {
295   ///   RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
296   /// }
297   template<Triple::ArchType TargetArchType = Triple::InvalidArch,
298            bool HasJIT = false>
299   struct RegisterTarget {
300     RegisterTarget(Target &T, const char *Name, const char *Desc) {
301       TargetRegistry::RegisterTarget(T, Name, Desc,
302                                      &getTripleMatchQuality,
303                                      HasJIT);
304     }
305
306     static unsigned getTripleMatchQuality(const std::string &TT) {
307       if (Triple(TT.c_str()).getArch() == TargetArchType)
308         return 20;
309       return 0;
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 std::string &TT,
329                                     const std::string &FS) {
330       return new TargetMachineImpl(T, TT, 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
357   /// assembly parser, for use in the target machine initialization
358   /// function. Usage:
359   ///
360   /// extern "C" void LLVMInitializeFooAsmParser() {
361   ///   extern Target TheFooTarget;
362   ///   RegisterAsmParser<FooAsmParser> 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, MCAsmParser &P) {
372       return new AsmParserImpl(T, P);
373     }
374   };
375
376 }
377
378 #endif