1 //===--- TargetRegistry.cpp - Target registration -------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/MC/TargetRegistry.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/Support/raw_ostream.h"
17 // Clients are responsible for avoid race conditions in registration.
18 static Target
*FirstTarget
= nullptr;
20 iterator_range
<TargetRegistry::iterator
> TargetRegistry::targets() {
21 return make_range(iterator(FirstTarget
), iterator());
24 const Target
*TargetRegistry::lookupTarget(StringRef ArchName
,
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(); });
35 if (I
== targets().end()) {
36 Error
= ("invalid target '" + ArchName
+ "'.\n").str();
42 // Adjust the triple to match (if known), otherwise stick with the
44 Triple::ArchType Type
= Triple::getArchTypeForLLVMName(ArchName
);
45 if (Type
!= Triple::UnknownArch
)
46 TheTriple
.setArch(Type
);
48 // Get the target specific parser.
49 std::string TempError
;
50 TheTarget
= TargetRegistry::lookupTarget(TheTriple
.getTriple(), TempError
);
52 Error
= "unable to get target for '" + TheTriple
.getTriple() +
53 "', see --version and --triple.";
61 const Target
*TargetRegistry::lookupTarget(StringRef TT
, std::string
&Error
) {
62 // Provide special warning when no targets are initialized.
63 if (targets().begin() == targets().end()) {
64 Error
= "Unable to find target for this triple (no targets are registered)";
67 Triple::ArchType Arch
= Triple(TT
).getArch();
68 auto ArchMatch
= [&](const Target
&T
) { return T
.ArchMatchFn(Arch
); };
69 auto I
= find_if(targets(), ArchMatch
);
71 if (I
== targets().end()) {
72 Error
= ("No available targets are compatible with triple \"" + TT
+ "\"")
77 auto J
= std::find_if(std::next(I
), targets().end(), ArchMatch
);
78 if (J
!= targets().end()) {
79 Error
= std::string("Cannot choose between targets \"") + I
->Name
+
80 "\" and \"" + J
->Name
+ "\"";
87 void TargetRegistry::RegisterTarget(Target
&T
, const char *Name
,
88 const char *ShortDesc
,
89 const char *BackendName
,
90 Target::ArchMatchFnTy ArchMatchFn
,
92 assert(Name
&& ShortDesc
&& ArchMatchFn
&&
93 "Missing required target information!");
95 // Check if this target has already been initialized, we allow this as a
96 // convenience to some clients.
100 // Add to the list of targets.
101 T
.Next
= FirstTarget
;
105 T
.ShortDesc
= ShortDesc
;
106 T
.BackendName
= BackendName
;
107 T
.ArchMatchFn
= ArchMatchFn
;
111 static int TargetArraySortFn(const std::pair
<StringRef
, const Target
*> *LHS
,
112 const std::pair
<StringRef
, const Target
*> *RHS
) {
113 return LHS
->first
.compare(RHS
->first
);
116 void TargetRegistry::printRegisteredTargetsForVersion(raw_ostream
&OS
) {
117 std::vector
<std::pair
<StringRef
, const Target
*> > Targets
;
119 for (const auto &T
: TargetRegistry::targets()) {
120 Targets
.push_back(std::make_pair(T
.getName(), &T
));
121 Width
= std::max(Width
, Targets
.back().first
.size());
123 array_pod_sort(Targets
.begin(), Targets
.end(), TargetArraySortFn
);
126 OS
<< " Registered Targets:\n";
127 for (const auto &Target
: Targets
) {
128 OS
<< " " << Target
.first
;
129 OS
.indent(Width
- Target
.first
.size())
130 << " - " << Target
.second
->getShortDescription() << '\n';