TargetRegistry.cpp revision d6fd377f3333922c4e928019cdfa124ff7f4dd2e
1bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar//===--- TargetRegistry.cpp - Target registration -------------------------===//
2bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar//
3bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar//                     The LLVM Compiler Infrastructure
4bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar//
5bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar// This file is distributed under the University of Illinois Open Source
6bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar// License. See LICENSE.TXT for details.
7bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar//
8bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar//===----------------------------------------------------------------------===//
9bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
10bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar#include "llvm/Target/TargetRegistry.h"
11d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar#include "llvm/System/Host.h"
12bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar#include <cassert>
13bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarusing namespace llvm;
14bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
1573b3ec41349511dbf28c18997e3f64761ff0f114Daniel Dunbar// Clients are responsible for avoid race conditions in registration.
16bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarstatic Target *FirstTarget = 0;
17bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
18603bea32743dc9914a1d32ae36fc64fe497af801Daniel DunbarTargetRegistry::iterator TargetRegistry::begin() {
19603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar  return iterator(FirstTarget);
20603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar}
21603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar
22bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarconst Target *
23bb061291406b1b9f0c976e9845f69f9faf985606Daniel DunbarTargetRegistry::getClosestStaticTargetForTriple(const std::string &TT,
24bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar                                                std::string &Error) {
257df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar  // Provide special warning when no targets are initialized.
267df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar  if (begin() == end()) {
277df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar    Error = "Unable to find target for this triple (no targets are registered)";
287df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar    return 0;
297df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar  }
30603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar  const Target *Best = 0, *EquallyBest = 0;
31bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  unsigned BestQuality = 0;
32603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar  for (iterator it = begin(), ie = end(); it != ie; ++it) {
33603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar    if (unsigned Qual = it->TripleMatchQualityFn(TT)) {
34bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar      if (!Best || Qual > BestQuality) {
35603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar        Best = &*it;
36bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar        EquallyBest = 0;
37bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar        BestQuality = Qual;
38bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar      } else if (Qual == BestQuality)
39603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar        EquallyBest = &*it;
40bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    }
41bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  }
42bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
43bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  if (!Best) {
447df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar    Error = "No available targets are compatible with this triple";
45bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    return 0;
46bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  }
47bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
48bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  // Otherwise, take the best target, but make sure we don't have two equally
49bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  // good best targets.
50bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  if (EquallyBest) {
51bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    Error = std::string("Cannot choose between targets \"") +
52bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar      Best->Name  + "\" and \"" + EquallyBest->Name + "\"";
53bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    return 0;
54bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  }
55bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
56bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  return Best;
57bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar}
58bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
59bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarconst Target *
60bb061291406b1b9f0c976e9845f69f9faf985606Daniel DunbarTargetRegistry::getClosestStaticTargetForModule(const Module &M,
61bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar                                                std::string &Error) {
627df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar  // Provide special warning when no targets are initialized.
637df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar  if (begin() == end()) {
647df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar    Error = "Unable to find target for this module (no targets are registered)";
657df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar    return 0;
667df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar  }
677df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar
68603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar  const Target *Best = 0, *EquallyBest = 0;
69bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  unsigned BestQuality = 0;
70603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar  for (iterator it = begin(), ie = end(); it != ie; ++it) {
71603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar    if (unsigned Qual = it->ModuleMatchQualityFn(M)) {
72bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar      if (!Best || Qual > BestQuality) {
73603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar        Best = &*it;
74bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar        EquallyBest = 0;
75bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar        BestQuality = Qual;
76bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar      } else if (Qual == BestQuality)
77603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar        EquallyBest = &*it;
78bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    }
79bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  }
80bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
81d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar  // FIXME: This is a hack to ignore super weak matches like msil, etc. and look
82d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar  // by host instead. They will be found again via the triple.
83d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar  if (Best && BestQuality == 1)
84d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar    Best = EquallyBest = 0;
85d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar
86d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar  // If that failed, try looking up the host triple.
87d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar  if (!Best)
88d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar    Best = getClosestStaticTargetForTriple(sys::getHostTriple(), Error);
89d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar
90bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  if (!Best) {
91bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    Error = "No available targets are compatible with this module";
92d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar    return Best;
93bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  }
94bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
95bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  // Otherwise, take the best target, but make sure we don't have two equally
96bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  // good best targets.
97bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  if (EquallyBest) {
98bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    Error = std::string("Cannot choose between targets \"") +
99bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar      Best->Name  + "\" and \"" + EquallyBest->Name + "\"";
100bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    return 0;
101bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  }
102bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
103bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  return Best;
104bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar}
105bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
106bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarconst Target *
107bb061291406b1b9f0c976e9845f69f9faf985606Daniel DunbarTargetRegistry::getClosestTargetForJIT(std::string &Error) {
108d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar  std::string Triple = sys::getHostTriple();
109d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar
1107df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar  // Provide special warning when no targets are initialized.
1117df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar  if (begin() == end()) {
1127df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar    Error = "No JIT is available for this host (no targets are registered)";
1137df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar    return 0;
1147df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar  }
1157df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar
116603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar  const Target *Best = 0, *EquallyBest = 0;
117bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  unsigned BestQuality = 0;
118603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar  for (iterator it = begin(), ie = end(); it != ie; ++it) {
119d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar    if (!it->hasJIT())
120d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar      continue;
121d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar
122d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar    if (unsigned Qual = it->TripleMatchQualityFn(Triple)) {
123bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar      if (!Best || Qual > BestQuality) {
124603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar        Best = &*it;
125bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar        EquallyBest = 0;
126bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar        BestQuality = Qual;
127bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar      } else if (Qual == BestQuality)
128603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar        EquallyBest = &*it;
129bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    }
130bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  }
131bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
132bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  if (!Best) {
133bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    Error = "No JIT is available for this host";
134bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    return 0;
135bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  }
136bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
137bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  // Return the best, ignoring ties.
138bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  return Best;
139bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar}
140bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
141bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarvoid TargetRegistry::RegisterTarget(Target &T,
142bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar                                    const char *Name,
143bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar                                    const char *ShortDesc,
144bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar                                    Target::TripleMatchQualityFnTy TQualityFn,
145bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar                                    Target::ModuleMatchQualityFnTy MQualityFn,
146d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar                                    bool HasJIT) {
147d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar  assert(Name && ShortDesc && TQualityFn && MQualityFn &&
148bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar         "Missing required target information!");
14951b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar
15051b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar  // Check if this target has already been initialized, we allow this as a
15151b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar  // convenience to some clients.
15251b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar  if (T.Name)
15351b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar    return;
154bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
155bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  // Add to the list of targets.
156bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  T.Next = FirstTarget;
157f23d4930bdd5ee00354883f8756388573fa43e88Daniel Dunbar  FirstTarget = &T;
158bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
159bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  T.Name = Name;
160bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  T.ShortDesc = ShortDesc;
161bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  T.TripleMatchQualityFn = TQualityFn;
162bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  T.ModuleMatchQualityFn = MQualityFn;
163d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar  T.HasJIT = HasJIT;
164bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar}
165bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
166