blob: bf631feb686b61e0497f44c4f4ab9039d130a2f8 [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"
11#include <cassert>
12using namespace llvm;
13
Daniel Dunbar73b3ec42009-07-15 07:09:29 +000014// Clients are responsible for avoid race conditions in registration.
Daniel Dunbarbb061292009-07-15 04:24:58 +000015static Target *FirstTarget = 0;
16
Daniel Dunbar603bea32009-07-16 02:06:09 +000017TargetRegistry::iterator TargetRegistry::begin() {
18 return iterator(FirstTarget);
19}
20
Daniel Dunbarbb061292009-07-15 04:24:58 +000021const Target *
22TargetRegistry::getClosestStaticTargetForTriple(const std::string &TT,
23 std::string &Error) {
Daniel Dunbar603bea32009-07-16 02:06:09 +000024 const Target *Best = 0, *EquallyBest = 0;
Daniel Dunbarbb061292009-07-15 04:24:58 +000025 unsigned BestQuality = 0;
Daniel Dunbar603bea32009-07-16 02:06:09 +000026 for (iterator it = begin(), ie = end(); it != ie; ++it) {
27 if (unsigned Qual = it->TripleMatchQualityFn(TT)) {
Daniel Dunbarbb061292009-07-15 04:24:58 +000028 if (!Best || Qual > BestQuality) {
Daniel Dunbar603bea32009-07-16 02:06:09 +000029 Best = &*it;
Daniel Dunbarbb061292009-07-15 04:24:58 +000030 EquallyBest = 0;
31 BestQuality = Qual;
32 } else if (Qual == BestQuality)
Daniel Dunbar603bea32009-07-16 02:06:09 +000033 EquallyBest = &*it;
Daniel Dunbarbb061292009-07-15 04:24:58 +000034 }
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
53const Target *
54TargetRegistry::getClosestStaticTargetForModule(const Module &M,
55 std::string &Error) {
Daniel Dunbar603bea32009-07-16 02:06:09 +000056 const Target *Best = 0, *EquallyBest = 0;
Daniel Dunbarbb061292009-07-15 04:24:58 +000057 unsigned BestQuality = 0;
Daniel Dunbar603bea32009-07-16 02:06:09 +000058 for (iterator it = begin(), ie = end(); it != ie; ++it) {
59 if (unsigned Qual = it->ModuleMatchQualityFn(M)) {
Daniel Dunbarbb061292009-07-15 04:24:58 +000060 if (!Best || Qual > BestQuality) {
Daniel Dunbar603bea32009-07-16 02:06:09 +000061 Best = &*it;
Daniel Dunbarbb061292009-07-15 04:24:58 +000062 EquallyBest = 0;
63 BestQuality = Qual;
64 } else if (Qual == BestQuality)
Daniel Dunbar603bea32009-07-16 02:06:09 +000065 EquallyBest = &*it;
Daniel Dunbarbb061292009-07-15 04:24:58 +000066 }
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
85const Target *
86TargetRegistry::getClosestTargetForJIT(std::string &Error) {
Daniel Dunbar603bea32009-07-16 02:06:09 +000087 const Target *Best = 0, *EquallyBest = 0;
Daniel Dunbarbb061292009-07-15 04:24:58 +000088 unsigned BestQuality = 0;
Daniel Dunbar603bea32009-07-16 02:06:09 +000089 for (iterator it = begin(), ie = end(); it != ie; ++it) {
90 if (unsigned Qual = it->JITMatchQualityFn()) {
Daniel Dunbarbb061292009-07-15 04:24:58 +000091 if (!Best || Qual > BestQuality) {
Daniel Dunbar603bea32009-07-16 02:06:09 +000092 Best = &*it;
Daniel Dunbarbb061292009-07-15 04:24:58 +000093 EquallyBest = 0;
94 BestQuality = Qual;
95 } else if (Qual == BestQuality)
Daniel Dunbar603bea32009-07-16 02:06:09 +000096 EquallyBest = &*it;
Daniel Dunbarbb061292009-07-15 04:24:58 +000097 }
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
109void TargetRegistry::RegisterTarget(Target &T,
110 const char *Name,
111 const char *ShortDesc,
112 Target::TripleMatchQualityFnTy TQualityFn,
113 Target::ModuleMatchQualityFnTy MQualityFn,
114 Target::JITMatchQualityFnTy JITQualityFn) {
Daniel Dunbarbb061292009-07-15 04:24:58 +0000115 assert(Name && ShortDesc && TQualityFn && MQualityFn && JITQualityFn &&
116 "Missing required target information!");
Daniel Dunbar51b198a2009-07-15 20:24:03 +0000117
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;
Daniel Dunbarbb061292009-07-15 04:24:58 +0000122
123 // Add to the list of targets.
124 T.Next = FirstTarget;
Daniel Dunbarf23d4932009-07-15 07:37:49 +0000125 FirstTarget = &T;
Daniel Dunbarbb061292009-07-15 04:24:58 +0000126
127 T.Name = Name;
128 T.ShortDesc = ShortDesc;
129 T.TripleMatchQualityFn = TQualityFn;
130 T.ModuleMatchQualityFn = MQualityFn;
131 T.JITMatchQualityFn = JITQualityFn;
132}
133