blob: f9026f12afd1cef2ff327013ed585ae52279a2c2 [file] [log] [blame]
Daniel Dunbarbb061292009-07-15 04:24:58 +00001//===--- 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"
Daniel Dunbard6fd3772009-07-25 10:09:50 +000011#include "llvm/System/Host.h"
Daniel Dunbarbb061292009-07-15 04:24:58 +000012#include <cassert>
13using namespace llvm;
14
Daniel Dunbar73b3ec42009-07-15 07:09:29 +000015// Clients are responsible for avoid race conditions in registration.
Daniel Dunbarbb061292009-07-15 04:24:58 +000016static Target *FirstTarget = 0;
17
Daniel Dunbar603bea32009-07-16 02:06:09 +000018TargetRegistry::iterator TargetRegistry::begin() {
19 return iterator(FirstTarget);
20}
21
Daniel Dunbarbb061292009-07-15 04:24:58 +000022const Target *
23TargetRegistry::getClosestStaticTargetForTriple(const std::string &TT,
24 std::string &Error) {
Daniel Dunbar7df0c072009-07-17 15:50:49 +000025 // Provide special warning when no targets are initialized.
26 if (begin() == end()) {
27 Error = "Unable to find target for this triple (no targets are registered)";
28 return 0;
29 }
Daniel Dunbar603bea32009-07-16 02:06:09 +000030 const Target *Best = 0, *EquallyBest = 0;
Daniel Dunbarbb061292009-07-15 04:24:58 +000031 unsigned BestQuality = 0;
Daniel Dunbar603bea32009-07-16 02:06:09 +000032 for (iterator it = begin(), ie = end(); it != ie; ++it) {
33 if (unsigned Qual = it->TripleMatchQualityFn(TT)) {
Daniel Dunbarbb061292009-07-15 04:24:58 +000034 if (!Best || Qual > BestQuality) {
Daniel Dunbar603bea32009-07-16 02:06:09 +000035 Best = &*it;
Daniel Dunbarbb061292009-07-15 04:24:58 +000036 EquallyBest = 0;
37 BestQuality = Qual;
38 } else if (Qual == BestQuality)
Daniel Dunbar603bea32009-07-16 02:06:09 +000039 EquallyBest = &*it;
Daniel Dunbarbb061292009-07-15 04:24:58 +000040 }
41 }
42
43 if (!Best) {
Daniel Dunbar7df0c072009-07-17 15:50:49 +000044 Error = "No available targets are compatible with this triple";
Daniel Dunbarbb061292009-07-15 04:24:58 +000045 return 0;
46 }
47
48 // Otherwise, take the best target, but make sure we don't have two equally
49 // good best targets.
50 if (EquallyBest) {
51 Error = std::string("Cannot choose between targets \"") +
52 Best->Name + "\" and \"" + EquallyBest->Name + "\"";
53 return 0;
54 }
55
56 return Best;
57}
58
59const Target *
60TargetRegistry::getClosestStaticTargetForModule(const Module &M,
61 std::string &Error) {
Daniel Dunbar7df0c072009-07-17 15:50:49 +000062 // Provide special warning when no targets are initialized.
63 if (begin() == end()) {
64 Error = "Unable to find target for this module (no targets are registered)";
65 return 0;
66 }
67
Daniel Dunbar603bea32009-07-16 02:06:09 +000068 const Target *Best = 0, *EquallyBest = 0;
Daniel Dunbarbb061292009-07-15 04:24:58 +000069 unsigned BestQuality = 0;
Daniel Dunbar603bea32009-07-16 02:06:09 +000070 for (iterator it = begin(), ie = end(); it != ie; ++it) {
71 if (unsigned Qual = it->ModuleMatchQualityFn(M)) {
Daniel Dunbarbb061292009-07-15 04:24:58 +000072 if (!Best || Qual > BestQuality) {
Daniel Dunbar603bea32009-07-16 02:06:09 +000073 Best = &*it;
Daniel Dunbarbb061292009-07-15 04:24:58 +000074 EquallyBest = 0;
75 BestQuality = Qual;
76 } else if (Qual == BestQuality)
Daniel Dunbar603bea32009-07-16 02:06:09 +000077 EquallyBest = &*it;
Daniel Dunbarbb061292009-07-15 04:24:58 +000078 }
79 }
80
Daniel Dunbard6fd3772009-07-25 10:09:50 +000081 // FIXME: This is a hack to ignore super weak matches like msil, etc. and look
82 // by host instead. They will be found again via the triple.
83 if (Best && BestQuality == 1)
84 Best = EquallyBest = 0;
85
86 // If that failed, try looking up the host triple.
87 if (!Best)
88 Best = getClosestStaticTargetForTriple(sys::getHostTriple(), Error);
89
Daniel Dunbarbb061292009-07-15 04:24:58 +000090 if (!Best) {
91 Error = "No available targets are compatible with this module";
Daniel Dunbard6fd3772009-07-25 10:09:50 +000092 return Best;
Daniel Dunbarbb061292009-07-15 04:24:58 +000093 }
94
95 // Otherwise, take the best target, but make sure we don't have two equally
96 // good best targets.
97 if (EquallyBest) {
98 Error = std::string("Cannot choose between targets \"") +
99 Best->Name + "\" and \"" + EquallyBest->Name + "\"";
100 return 0;
101 }
102
103 return Best;
104}
105
106const Target *
107TargetRegistry::getClosestTargetForJIT(std::string &Error) {
Daniel Dunbard6fd3772009-07-25 10:09:50 +0000108 std::string Triple = sys::getHostTriple();
109
Daniel Dunbar7df0c072009-07-17 15:50:49 +0000110 // Provide special warning when no targets are initialized.
111 if (begin() == end()) {
112 Error = "No JIT is available for this host (no targets are registered)";
113 return 0;
114 }
115
Daniel Dunbar603bea32009-07-16 02:06:09 +0000116 const Target *Best = 0, *EquallyBest = 0;
Daniel Dunbarbb061292009-07-15 04:24:58 +0000117 unsigned BestQuality = 0;
Daniel Dunbar603bea32009-07-16 02:06:09 +0000118 for (iterator it = begin(), ie = end(); it != ie; ++it) {
Daniel Dunbard6fd3772009-07-25 10:09:50 +0000119 if (!it->hasJIT())
120 continue;
121
122 if (unsigned Qual = it->TripleMatchQualityFn(Triple)) {
Daniel Dunbarbb061292009-07-15 04:24:58 +0000123 if (!Best || Qual > BestQuality) {
Daniel Dunbar603bea32009-07-16 02:06:09 +0000124 Best = &*it;
Daniel Dunbarbb061292009-07-15 04:24:58 +0000125 EquallyBest = 0;
126 BestQuality = Qual;
127 } else if (Qual == BestQuality)
Daniel Dunbar603bea32009-07-16 02:06:09 +0000128 EquallyBest = &*it;
Daniel Dunbarbb061292009-07-15 04:24:58 +0000129 }
130 }
131
132 if (!Best) {
133 Error = "No JIT is available for this host";
134 return 0;
135 }
136
137 // Return the best, ignoring ties.
138 return Best;
139}
140
141void TargetRegistry::RegisterTarget(Target &T,
142 const char *Name,
143 const char *ShortDesc,
144 Target::TripleMatchQualityFnTy TQualityFn,
145 Target::ModuleMatchQualityFnTy MQualityFn,
Daniel Dunbard6fd3772009-07-25 10:09:50 +0000146 bool HasJIT) {
147 assert(Name && ShortDesc && TQualityFn && MQualityFn &&
Daniel Dunbarbb061292009-07-15 04:24:58 +0000148 "Missing required target information!");
Daniel Dunbar51b198a2009-07-15 20:24:03 +0000149
150 // Check if this target has already been initialized, we allow this as a
151 // convenience to some clients.
152 if (T.Name)
153 return;
Daniel Dunbarbb061292009-07-15 04:24:58 +0000154
155 // Add to the list of targets.
156 T.Next = FirstTarget;
Daniel Dunbarf23d4932009-07-15 07:37:49 +0000157 FirstTarget = &T;
Daniel Dunbarbb061292009-07-15 04:24:58 +0000158
159 T.Name = Name;
160 T.ShortDesc = ShortDesc;
161 T.TripleMatchQualityFn = TQualityFn;
162 T.ModuleMatchQualityFn = MQualityFn;
Daniel Dunbard6fd3772009-07-25 10:09:50 +0000163 T.HasJIT = HasJIT;
Daniel Dunbarbb061292009-07-15 04:24:58 +0000164}
165