bf631feb686b61e0497f44c4f4ab9039d130a2f8
[oota-llvm.git] / lib / Support / TargetRegistry.cpp
1 //===--- TargetRegistry.cpp - Target registration -------------------------===//
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 #include "llvm/Target/TargetRegistry.h"
11 #include <cassert>
12 using namespace llvm;
13
14 // Clients are responsible for avoid race conditions in registration.
15 static Target *FirstTarget = 0;
16
17 TargetRegistry::iterator TargetRegistry::begin() {
18   return iterator(FirstTarget);
19 }
20
21 const Target *
22 TargetRegistry::getClosestStaticTargetForTriple(const std::string &TT,
23                                                 std::string &Error) {
24   const Target *Best = 0, *EquallyBest = 0;
25   unsigned BestQuality = 0;
26   for (iterator it = begin(), ie = end(); it != ie; ++it) {
27     if (unsigned Qual = it->TripleMatchQualityFn(TT)) {
28       if (!Best || Qual > BestQuality) {
29         Best = &*it;
30         EquallyBest = 0;
31         BestQuality = Qual;
32       } else if (Qual == BestQuality)
33         EquallyBest = &*it;
34     }
35   }
36
37   if (!Best) {
38     Error = "No available targets are compatible with this module";
39     return 0;
40   }
41
42   // Otherwise, take the best target, but make sure we don't have two equally
43   // good best targets.
44   if (EquallyBest) {
45     Error = std::string("Cannot choose between targets \"") +
46       Best->Name  + "\" and \"" + EquallyBest->Name + "\"";
47     return 0;
48   }
49
50   return Best;
51 }
52
53 const Target *
54 TargetRegistry::getClosestStaticTargetForModule(const Module &M,
55                                                 std::string &Error) {
56   const Target *Best = 0, *EquallyBest = 0;
57   unsigned BestQuality = 0;
58   for (iterator it = begin(), ie = end(); it != ie; ++it) {
59     if (unsigned Qual = it->ModuleMatchQualityFn(M)) {
60       if (!Best || Qual > BestQuality) {
61         Best = &*it;
62         EquallyBest = 0;
63         BestQuality = Qual;
64       } else if (Qual == BestQuality)
65         EquallyBest = &*it;
66     }
67   }
68
69   if (!Best) {
70     Error = "No available targets are compatible with this module";
71     return 0;
72   }
73
74   // Otherwise, take the best target, but make sure we don't have two equally
75   // good best targets.
76   if (EquallyBest) {
77     Error = std::string("Cannot choose between targets \"") +
78       Best->Name  + "\" and \"" + EquallyBest->Name + "\"";
79     return 0;
80   }
81
82   return Best;
83 }
84
85 const Target *
86 TargetRegistry::getClosestTargetForJIT(std::string &Error) {
87   const Target *Best = 0, *EquallyBest = 0;
88   unsigned BestQuality = 0;
89   for (iterator it = begin(), ie = end(); it != ie; ++it) {
90     if (unsigned Qual = it->JITMatchQualityFn()) {
91       if (!Best || Qual > BestQuality) {
92         Best = &*it;
93         EquallyBest = 0;
94         BestQuality = Qual;
95       } else if (Qual == BestQuality)
96         EquallyBest = &*it;
97     }
98   }
99
100   if (!Best) {
101     Error = "No JIT is available for this host";
102     return 0;
103   }
104
105   // Return the best, ignoring ties.
106   return Best;
107 }
108
109 void TargetRegistry::RegisterTarget(Target &T,
110                                     const char *Name,
111                                     const char *ShortDesc,
112                                     Target::TripleMatchQualityFnTy TQualityFn,
113                                     Target::ModuleMatchQualityFnTy MQualityFn,
114                                     Target::JITMatchQualityFnTy JITQualityFn) {
115   assert(Name && ShortDesc && TQualityFn && MQualityFn && JITQualityFn &&
116          "Missing required target information!");
117
118   // Check if this target has already been initialized, we allow this as a
119   // convenience to some clients.
120   if (T.Name)
121     return;
122          
123   // Add to the list of targets.
124   T.Next = FirstTarget;
125   FirstTarget = &T;
126
127   T.Name = Name;
128   T.ShortDesc = ShortDesc;
129   T.TripleMatchQualityFn = TQualityFn;
130   T.ModuleMatchQualityFn = MQualityFn;
131   T.JITMatchQualityFn = JITQualityFn;
132 }
133