Address some review comments on TargetRegistry.
[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 const Target *
18 TargetRegistry::getClosestStaticTargetForTriple(const std::string &TT,
19                                                 std::string &Error) {
20   Target *Best = 0, *EquallyBest = 0;
21   unsigned BestQuality = 0;
22   // FIXME: Use iterator.
23   for (Target *i = FirstTarget; i; i = i->Next) {
24     if (unsigned Qual = i->TripleMatchQualityFn(TT)) {
25       if (!Best || Qual > BestQuality) {
26         Best = i;
27         EquallyBest = 0;
28         BestQuality = Qual;
29       } else if (Qual == BestQuality)
30         EquallyBest = i;
31     }
32   }
33
34   if (!Best) {
35     Error = "No available targets are compatible with this module";
36     return 0;
37   }
38
39   // Otherwise, take the best target, but make sure we don't have two equally
40   // good best targets.
41   if (EquallyBest) {
42     Error = std::string("Cannot choose between targets \"") +
43       Best->Name  + "\" and \"" + EquallyBest->Name + "\"";
44     return 0;
45   }
46
47   return Best;
48 }
49
50 const Target *
51 TargetRegistry::getClosestStaticTargetForModule(const Module &M,
52                                                 std::string &Error) {
53   Target *Best = 0, *EquallyBest = 0;
54   unsigned BestQuality = 0;
55   // FIXME: Use iterator.
56   for (Target *i = FirstTarget; i; i = i->Next) {
57     if (unsigned Qual = i->ModuleMatchQualityFn(M)) {
58       if (!Best || Qual > BestQuality) {
59         Best = i;
60         EquallyBest = 0;
61         BestQuality = Qual;
62       } else if (Qual == BestQuality)
63         EquallyBest = i;
64     }
65   }
66
67   if (!Best) {
68     Error = "No available targets are compatible with this module";
69     return 0;
70   }
71
72   // Otherwise, take the best target, but make sure we don't have two equally
73   // good best targets.
74   if (EquallyBest) {
75     Error = std::string("Cannot choose between targets \"") +
76       Best->Name  + "\" and \"" + EquallyBest->Name + "\"";
77     return 0;
78   }
79
80   return Best;
81 }
82
83 const Target *
84 TargetRegistry::getClosestTargetForJIT(std::string &Error) {
85   Target *Best = 0, *EquallyBest = 0;
86   unsigned BestQuality = 0;
87   // FIXME: Use iterator.
88   for (Target *i = FirstTarget; i; i = i->Next) {
89     if (unsigned Qual = i->JITMatchQualityFn()) {
90       if (!Best || Qual > BestQuality) {
91         Best = i;
92         EquallyBest = 0;
93         BestQuality = Qual;
94       } else if (Qual == BestQuality)
95         EquallyBest = i;
96     }
97   }
98
99   if (!Best) {
100     Error = "No JIT is available for this host";
101     return 0;
102   }
103
104   // Return the best, ignoring ties.
105   return Best;
106 }
107
108 void TargetRegistry::RegisterTarget(Target &T,
109                                     const char *Name,
110                                     const char *ShortDesc,
111                                     Target::TripleMatchQualityFnTy TQualityFn,
112                                     Target::ModuleMatchQualityFnTy MQualityFn,
113                                     Target::JITMatchQualityFnTy JITQualityFn) {
114   // Note that we don't require the constructor functions already be defined, in
115   // case a module happens to initialize the optional functionality before the
116   // target.
117   assert(!T.Next && !T.Name && !T.ShortDesc && !T.TripleMatchQualityFn &&
118          !T.ModuleMatchQualityFn && !T.JITMatchQualityFn && 
119          "This Target already registered!");
120
121   assert(Name && ShortDesc && TQualityFn && MQualityFn && JITQualityFn &&
122          "Missing required target information!");
123          
124   // Add to the list of targets.
125   T.Next = FirstTarget;
126   FirstTarget = T.Next;
127
128   T.Name = Name;
129   T.ShortDesc = ShortDesc;
130   T.TripleMatchQualityFn = TQualityFn;
131   T.ModuleMatchQualityFn = MQualityFn;
132   T.JITMatchQualityFn = JITQualityFn;
133 }
134