LLVM  14.0.0git
TargetRegistry.cpp
Go to the documentation of this file.
1 //===--- TargetRegistry.cpp - Target registration -------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/StringRef.h"
13 #include <cassert>
14 #include <vector>
15 using namespace llvm;
16 
17 // Clients are responsible for avoid race conditions in registration.
18 static Target *FirstTarget = nullptr;
19 
22 }
23 
24 const Target *TargetRegistry::lookupTarget(const std::string &ArchName,
25  Triple &TheTriple,
26  std::string &Error) {
27  // Allocate target machine. First, check whether the user has explicitly
28  // specified an architecture to compile for. If so we have to look it up by
29  // name, because it might be a backend that has no mapping to a target triple.
30  const Target *TheTarget = nullptr;
31  if (!ArchName.empty()) {
32  auto I = find_if(targets(),
33  [&](const Target &T) { return ArchName == T.getName(); });
34 
35  if (I == targets().end()) {
36  Error = "error: invalid target '" + ArchName + "'.\n";
37  return nullptr;
38  }
39 
40  TheTarget = &*I;
41 
42  // Adjust the triple to match (if known), otherwise stick with the
43  // given triple.
46  TheTriple.setArch(Type);
47  } else {
48  // Get the target specific parser.
49  std::string TempError;
50  TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), TempError);
51  if (!TheTarget) {
52  Error = ": error: unable to get target for '"
53  + TheTriple.getTriple()
54  + "', see --version and --triple.\n";
55  return nullptr;
56  }
57  }
58 
59  return TheTarget;
60 }
61 
62 const Target *TargetRegistry::lookupTarget(const std::string &TT,
63  std::string &Error) {
64  // Provide special warning when no targets are initialized.
65  if (targets().begin() == targets().end()) {
66  Error = "Unable to find target for this triple (no targets are registered)";
67  return nullptr;
68  }
69  Triple::ArchType Arch = Triple(TT).getArch();
70  auto ArchMatch = [&](const Target &T) { return T.ArchMatchFn(Arch); };
71  auto I = find_if(targets(), ArchMatch);
72 
73  if (I == targets().end()) {
74  Error = "No available targets are compatible with triple \"" + TT + "\"";
75  return nullptr;
76  }
77 
78  auto J = std::find_if(std::next(I), targets().end(), ArchMatch);
79  if (J != targets().end()) {
80  Error = std::string("Cannot choose between targets \"") + I->Name +
81  "\" and \"" + J->Name + "\"";
82  return nullptr;
83  }
84 
85  return &*I;
86 }
87 
89  const char *ShortDesc,
90  const char *BackendName,
91  Target::ArchMatchFnTy ArchMatchFn,
92  bool HasJIT) {
93  assert(Name && ShortDesc && ArchMatchFn &&
94  "Missing required target information!");
95 
96  // Check if this target has already been initialized, we allow this as a
97  // convenience to some clients.
98  if (T.Name)
99  return;
100 
101  // Add to the list of targets.
102  T.Next = FirstTarget;
103  FirstTarget = &T;
104 
105  T.Name = Name;
106  T.ShortDesc = ShortDesc;
107  T.BackendName = BackendName;
108  T.ArchMatchFn = ArchMatchFn;
109  T.HasJIT = HasJIT;
110 }
111 
112 static int TargetArraySortFn(const std::pair<StringRef, const Target *> *LHS,
113  const std::pair<StringRef, const Target *> *RHS) {
114  return LHS->first.compare(RHS->first);
115 }
116 
118  std::vector<std::pair<StringRef, const Target*> > Targets;
119  size_t Width = 0;
120  for (const auto &T : TargetRegistry::targets()) {
121  Targets.push_back(std::make_pair(T.getName(), &T));
122  Width = std::max(Width, Targets.back().first.size());
123  }
124  array_pod_sort(Targets.begin(), Targets.end(), TargetArraySortFn);
125 
126  OS << " Registered Targets:\n";
127  for (unsigned i = 0, e = Targets.size(); i != e; ++i) {
128  OS << " " << Targets[i].first;
129  OS.indent(Width - Targets[i].first.size()) << " - "
130  << Targets[i].second->getShortDescription() << '\n';
131  }
132  if (Targets.empty())
133  OS << " (none)\n";
134 }
i
i
Definition: README.txt:29
llvm::array_pod_sort
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
Definition: STLExtras.h:1450
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
llvm::Triple::UnknownArch
@ UnknownArch
Definition: Triple.h:48
T
StringRef.h
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:137
llvm::Triple::getArchTypeForLLVMName
static ArchType getArchTypeForLLVMName(StringRef Str)
The canonical type for the given LLVM architecture name (e.g., "x86").
Definition: Triple.cpp:275
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:233
llvm::sys::path::begin
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:224
llvm::TargetRegistry::iterator
Definition: TargetRegistry.h:685
STLExtras.h
llvm::TargetRegistry::lookupTarget
static const Target * lookupTarget(const std::string &Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
Definition: TargetRegistry.cpp:62
llvm::Triple::ArchType
ArchType
Definition: Triple.h:47
llvm::TargetRegistry::targets
static iterator_range< iterator > targets()
Definition: TargetRegistry.cpp:20
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::Triple::getArch
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition: Triple.h:310
llvm::Triple::getTriple
const std::string & getTriple() const
Definition: Triple.h:380
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
llvm::TargetRegistry::RegisterTarget
static void RegisterTarget(Target &T, const char *Name, const char *ShortDesc, const char *BackendName, Target::ArchMatchFnTy ArchMatchFn, bool HasJIT=false)
RegisterTarget - Register the given target.
Definition: TargetRegistry.cpp:88
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::Triple::setArch
void setArch(ArchType Kind, SubArchType SubArch=NoSubArch)
Set the architecture (first) component of the triple to a known type.
Definition: Triple.cpp:1238
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
FirstTarget
static Target * FirstTarget
Definition: TargetRegistry.cpp:18
llvm::Target::ArchMatchFnTy
bool(*)(Triple::ArchType Arch) ArchMatchFnTy
Definition: TargetRegistry.h:141
llvm::TargetRegistry::printRegisteredTargetsForVersion
static void printRegisteredTargetsForVersion(raw_ostream &OS)
printRegisteredTargetsForVersion - Print the registered targets appropriately for inclusion in a tool...
Definition: TargetRegistry.cpp:117
llvm::find_if
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1578
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::AMDGPU::Hwreg::Width
Width
Definition: SIDefines.h:413
llvm::raw_ostream::indent
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
Definition: raw_ostream.cpp:497
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
raw_ostream.h
TargetRegistry.h
TargetArraySortFn
static int TargetArraySortFn(const std::pair< StringRef, const Target * > *LHS, const std::pair< StringRef, const Target * > *RHS)
Definition: TargetRegistry.cpp:112