LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TargetRegistry.cpp
Go to the documentation of this file.
1 //===--- 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 
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/Support/Host.h"
15 #include <cassert>
16 #include <vector>
17 using namespace llvm;
18 
19 // Clients are responsible for avoid race conditions in registration.
20 static Target *FirstTarget = 0;
21 
23  return iterator(FirstTarget);
24 }
25 
26 const Target *TargetRegistry::lookupTarget(const std::string &ArchName,
27  Triple &TheTriple,
28  std::string &Error) {
29  // Allocate target machine. First, check whether the user has explicitly
30  // specified an architecture to compile for. If so we have to look it up by
31  // name, because it might be a backend that has no mapping to a target triple.
32  const Target *TheTarget = 0;
33  if (!ArchName.empty()) {
35  ie = TargetRegistry::end(); it != ie; ++it) {
36  if (ArchName == it->getName()) {
37  TheTarget = &*it;
38  break;
39  }
40  }
41 
42  if (!TheTarget) {
43  Error = "error: invalid target '" + ArchName + "'.\n";
44  return 0;
45  }
46 
47  // Adjust the triple to match (if known), otherwise stick with the
48  // given triple.
50  if (Type != Triple::UnknownArch)
51  TheTriple.setArch(Type);
52  } else {
53  // Get the target specific parser.
54  std::string TempError;
55  TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), TempError);
56  if (TheTarget == 0) {
57  Error = ": error: unable to get target for '"
58  + TheTriple.getTriple()
59  + "', see --version and --triple.\n";
60  return 0;
61  }
62  }
63 
64  return TheTarget;
65 }
66 
67 const Target *TargetRegistry::lookupTarget(const std::string &TT,
68  std::string &Error) {
69  // Provide special warning when no targets are initialized.
70  if (begin() == end()) {
71  Error = "Unable to find target for this triple (no targets are registered)";
72  return 0;
73  }
74  const Target *Best = 0, *EquallyBest = 0;
75  unsigned BestQuality = 0;
76  for (iterator it = begin(), ie = end(); it != ie; ++it) {
77  if (unsigned Qual = it->TripleMatchQualityFn(TT)) {
78  if (!Best || Qual > BestQuality) {
79  Best = &*it;
80  EquallyBest = 0;
81  BestQuality = Qual;
82  } else if (Qual == BestQuality)
83  EquallyBest = &*it;
84  }
85  }
86 
87  if (!Best) {
88  Error = "No available targets are compatible with this triple, "
89  "see -version for the available targets.";
90  return 0;
91  }
92 
93  // Otherwise, take the best target, but make sure we don't have two equally
94  // good best targets.
95  if (EquallyBest) {
96  Error = std::string("Cannot choose between targets \"") +
97  Best->Name + "\" and \"" + EquallyBest->Name + "\"";
98  return 0;
99  }
100 
101  return Best;
102 }
103 
105  const char *Name,
106  const char *ShortDesc,
108  bool HasJIT) {
109  assert(Name && ShortDesc && TQualityFn &&
110  "Missing required target information!");
111 
112  // Check if this target has already been initialized, we allow this as a
113  // convenience to some clients.
114  if (T.Name)
115  return;
116 
117  // Add to the list of targets.
118  T.Next = FirstTarget;
119  FirstTarget = &T;
120 
121  T.Name = Name;
122  T.ShortDesc = ShortDesc;
123  T.TripleMatchQualityFn = TQualityFn;
124  T.HasJIT = HasJIT;
125 }
126 
128  const Target *TheTarget = lookupTarget(sys::getDefaultTargetTriple(), Error);
129 
130  if (TheTarget && !TheTarget->hasJIT()) {
131  Error = "No JIT compatible target available for this host";
132  return 0;
133  }
134 
135  return TheTarget;
136 }
137 
138 static int TargetArraySortFn(const std::pair<StringRef, const Target *> *LHS,
139  const std::pair<StringRef, const Target *> *RHS) {
140  return LHS->first.compare(RHS->first);
141 }
142 
144  std::vector<std::pair<StringRef, const Target*> > Targets;
145  size_t Width = 0;
147  E = TargetRegistry::end();
148  I != E; ++I) {
149  Targets.push_back(std::make_pair(I->getName(), &*I));
150  Width = std::max(Width, Targets.back().first.size());
151  }
152  array_pod_sort(Targets.begin(), Targets.end(), TargetArraySortFn);
153 
154  raw_ostream &OS = outs();
155  OS << " Registered Targets:\n";
156  for (unsigned i = 0, e = Targets.size(); i != e; ++i) {
157  OS << " " << Targets[i].first;
158  OS.indent(Width - Targets[i].first.size()) << " - "
159  << Targets[i].second->getShortDescription() << '\n';
160  }
161  if (Targets.empty())
162  OS << " (none)\n";
163 }
static int TargetArraySortFn(const std::pair< StringRef, const Target * > *LHS, const std::pair< StringRef, const Target * > *RHS)
std::string getDefaultTargetTriple()
static const Target * lookupTarget(const std::string &Triple, std::string &Error)
static iterator end()
#define T
static const Target * getClosestTargetForJIT(std::string &Error)
unsigned(* TripleMatchQualityFnTy)(const std::string &TT)
static void RegisterTarget(Target &T, const char *Name, const char *ShortDesc, Target::TripleMatchQualityFnTy TQualityFn, bool HasJIT=false)
bool hasJIT() const
hasJIT - Check if this targets supports the just-in-time compilation.
raw_ostream & outs()
void array_pod_sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:289
static void printRegisteredTargetsForVersion()
const std::string & getTriple() const
Definition: Triple.h:223
static iterator begin()
static Target * FirstTarget
static ArchType getArchTypeForLLVMName(StringRef Str)
Definition: Triple.cpp:161
#define I(x, y, z)
Definition: MD5.cpp:54
void setArch(ArchType Kind)
Definition: Triple.cpp:620