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