TargetRegistry.cpp revision 3e74d6fdd248e20a280f1dff3da9a6c689c2c4c3
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
103e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
11077c40871780136f7016a496703b20ebea9c0978Chandler Carruth#include "llvm/ADT/STLExtras.h"
12077c40871780136f7016a496703b20ebea9c0978Chandler Carruth#include "llvm/ADT/StringRef.h"
131f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Host.h"
14077c40871780136f7016a496703b20ebea9c0978Chandler Carruth#include "llvm/Support/raw_ostream.h"
15bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar#include <cassert>
16077c40871780136f7016a496703b20ebea9c0978Chandler Carruth#include <vector>
17bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarusing namespace llvm;
18bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
1973b3ec41349511dbf28c18997e3f64761ff0f114Daniel Dunbar// Clients are responsible for avoid race conditions in registration.
20bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarstatic Target *FirstTarget = 0;
21bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
22603bea32743dc9914a1d32ae36fc64fe497af801Daniel DunbarTargetRegistry::iterator TargetRegistry::begin() {
23603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar  return iterator(FirstTarget);
24603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar}
25603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar
26a5881e3060aee9f82aef3747a97650e5eafe893aDaniel Dunbarconst Target *TargetRegistry::lookupTarget(const std::string &TT,
27a5881e3060aee9f82aef3747a97650e5eafe893aDaniel Dunbar                                           std::string &Error) {
287df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar  // Provide special warning when no targets are initialized.
297df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar  if (begin() == end()) {
307df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar    Error = "Unable to find target for this triple (no targets are registered)";
317df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar    return 0;
327df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar  }
33603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar  const Target *Best = 0, *EquallyBest = 0;
34bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  unsigned BestQuality = 0;
35603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar  for (iterator it = begin(), ie = end(); it != ie; ++it) {
36a5881e3060aee9f82aef3747a97650e5eafe893aDaniel Dunbar    if (unsigned Qual = it->TripleMatchQualityFn(TT)) {
37bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar      if (!Best || Qual > BestQuality) {
38603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar        Best = &*it;
39bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar        EquallyBest = 0;
40bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar        BestQuality = Qual;
41bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar      } else if (Qual == BestQuality)
42603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar        EquallyBest = &*it;
43bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    }
44bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  }
45bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
46bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  if (!Best) {
470247656d0aaaee69ab20ff0ad56536bff38b3715Daniel Dunbar    Error = "No available targets are compatible with this triple, "
480247656d0aaaee69ab20ff0ad56536bff38b3715Daniel Dunbar      "see -version for the available targets.";
49a5881e3060aee9f82aef3747a97650e5eafe893aDaniel Dunbar    return 0;
50bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  }
51bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
52bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  // Otherwise, take the best target, but make sure we don't have two equally
53bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  // good best targets.
54bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  if (EquallyBest) {
55bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    Error = std::string("Cannot choose between targets \"") +
56bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar      Best->Name  + "\" and \"" + EquallyBest->Name + "\"";
57bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar    return 0;
58bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  }
59bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
60bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  return Best;
61bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar}
62bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
63bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarvoid TargetRegistry::RegisterTarget(Target &T,
64bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar                                    const char *Name,
65bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar                                    const char *ShortDesc,
66bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar                                    Target::TripleMatchQualityFnTy TQualityFn,
67d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar                                    bool HasJIT) {
68fa27ff296d3694a68e7abb3b6b7629588def3e58Daniel Dunbar  assert(Name && ShortDesc && TQualityFn &&
69bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar         "Missing required target information!");
7051b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar
7151b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar  // Check if this target has already been initialized, we allow this as a
7251b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar  // convenience to some clients.
7351b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar  if (T.Name)
7451b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar    return;
75bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
76bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  // Add to the list of targets.
77bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  T.Next = FirstTarget;
78f23d4930bdd5ee00354883f8756388573fa43e88Daniel Dunbar  FirstTarget = &T;
79bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
80bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  T.Name = Name;
81bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  T.ShortDesc = ShortDesc;
82bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar  T.TripleMatchQualityFn = TQualityFn;
83d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar  T.HasJIT = HasJIT;
84bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar}
85bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar
864bd03abe593222b26e84066223feb321bf738625Daniel Dunbarconst Target *TargetRegistry::getClosestTargetForJIT(std::string &Error) {
874bd03abe593222b26e84066223feb321bf738625Daniel Dunbar  const Target *TheTarget = lookupTarget(sys::getHostTriple(), Error);
884bd03abe593222b26e84066223feb321bf738625Daniel Dunbar
894bd03abe593222b26e84066223feb321bf738625Daniel Dunbar  if (TheTarget && !TheTarget->hasJIT()) {
904bd03abe593222b26e84066223feb321bf738625Daniel Dunbar    Error = "No JIT compatible target available for this host";
914bd03abe593222b26e84066223feb321bf738625Daniel Dunbar    return 0;
924bd03abe593222b26e84066223feb321bf738625Daniel Dunbar  }
934bd03abe593222b26e84066223feb321bf738625Daniel Dunbar
944bd03abe593222b26e84066223feb321bf738625Daniel Dunbar  return TheTarget;
954bd03abe593222b26e84066223feb321bf738625Daniel Dunbar}
964bd03abe593222b26e84066223feb321bf738625Daniel Dunbar
97077c40871780136f7016a496703b20ebea9c0978Chandler Carruthstatic int TargetArraySortFn(const void *LHS, const void *RHS) {
98077c40871780136f7016a496703b20ebea9c0978Chandler Carruth  typedef std::pair<StringRef, const Target*> pair_ty;
99077c40871780136f7016a496703b20ebea9c0978Chandler Carruth  return ((const pair_ty*)LHS)->first.compare(((const pair_ty*)RHS)->first);
100077c40871780136f7016a496703b20ebea9c0978Chandler Carruth}
101077c40871780136f7016a496703b20ebea9c0978Chandler Carruth
102077c40871780136f7016a496703b20ebea9c0978Chandler Carruthvoid TargetRegistry::printRegisteredTargetsForVersion() {
103077c40871780136f7016a496703b20ebea9c0978Chandler Carruth  std::vector<std::pair<StringRef, const Target*> > Targets;
104077c40871780136f7016a496703b20ebea9c0978Chandler Carruth  size_t Width = 0;
105077c40871780136f7016a496703b20ebea9c0978Chandler Carruth  for (TargetRegistry::iterator I = TargetRegistry::begin(),
106077c40871780136f7016a496703b20ebea9c0978Chandler Carruth       E = TargetRegistry::end();
107077c40871780136f7016a496703b20ebea9c0978Chandler Carruth       I != E; ++I) {
108077c40871780136f7016a496703b20ebea9c0978Chandler Carruth    Targets.push_back(std::make_pair(I->getName(), &*I));
109077c40871780136f7016a496703b20ebea9c0978Chandler Carruth    Width = std::max(Width, Targets.back().first.size());
110077c40871780136f7016a496703b20ebea9c0978Chandler Carruth  }
111077c40871780136f7016a496703b20ebea9c0978Chandler Carruth  array_pod_sort(Targets.begin(), Targets.end(), TargetArraySortFn);
112077c40871780136f7016a496703b20ebea9c0978Chandler Carruth
113077c40871780136f7016a496703b20ebea9c0978Chandler Carruth  raw_ostream &OS = outs();
114077c40871780136f7016a496703b20ebea9c0978Chandler Carruth  OS << "  Registered Targets:\n";
115077c40871780136f7016a496703b20ebea9c0978Chandler Carruth  for (unsigned i = 0, e = Targets.size(); i != e; ++i) {
116077c40871780136f7016a496703b20ebea9c0978Chandler Carruth    OS << "    " << Targets[i].first;
117077c40871780136f7016a496703b20ebea9c0978Chandler Carruth    OS.indent(Width - Targets[i].first.size()) << " - "
118077c40871780136f7016a496703b20ebea9c0978Chandler Carruth      << Targets[i].second->getShortDescription() << '\n';
119077c40871780136f7016a496703b20ebea9c0978Chandler Carruth  }
120077c40871780136f7016a496703b20ebea9c0978Chandler Carruth  if (Targets.empty())
121077c40871780136f7016a496703b20ebea9c0978Chandler Carruth    OS << "    (none)\n";
122077c40871780136f7016a496703b20ebea9c0978Chandler Carruth}
123