blob: 258d703d16df403d518b9a8b726e9719ba6578eb [file] [log] [blame]
Daniel Dunbar351304b2009-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 Dunbar988af812009-07-15 07:09:29 +000014// Clients are responsible for avoid race conditions in registration.
Daniel Dunbar351304b2009-07-15 04:24:58 +000015static Target *FirstTarget = 0;
16
17const Target *
18TargetRegistry::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
50const Target *
51TargetRegistry::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
83const Target *
84TargetRegistry::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
108void TargetRegistry::RegisterTarget(Target &T,
109 const char *Name,
110 const char *ShortDesc,
111 Target::TripleMatchQualityFnTy TQualityFn,
112 Target::ModuleMatchQualityFnTy MQualityFn,
113 Target::JITMatchQualityFnTy JITQualityFn) {
Stuart Hastings1721b8d2009-07-15 17:27:11 +0000114 // 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
Daniel Dunbar351304b2009-07-15 04:24:58 +0000121 assert(Name && ShortDesc && TQualityFn && MQualityFn && JITQualityFn &&
122 "Missing required target information!");
123
124 // Add to the list of targets.
125 T.Next = FirstTarget;
Daniel Dunbar0a346f42009-07-15 07:37:49 +0000126 FirstTarget = &T;
Daniel Dunbar351304b2009-07-15 04:24:58 +0000127
128 T.Name = Name;
129 T.ShortDesc = ShortDesc;
130 T.TripleMatchQualityFn = TQualityFn;
131 T.ModuleMatchQualityFn = MQualityFn;
132 T.JITMatchQualityFn = JITQualityFn;
133}
134