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(const std::string
&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
= "error: invalid target '" + ArchName
+ "'.\n";
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
= ": error: unable to get target for '"
53 + TheTriple
.getTriple()
54 + "', see --version and --triple.\n";
62 const Target
*TargetRegistry::lookupTarget(const std::string
&TT
,
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)";
69 Triple::ArchType Arch
= Triple(TT
).getArch();
70 auto ArchMatch
= [&](const Target
&T
) { return T
.ArchMatchFn(Arch
); };
71 auto I
= find_if(targets(), ArchMatch
);
73 if (I
== targets().end()) {
74 Error
= "No available targets are compatible with triple \"" + TT
+ "\"";
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
+ "\"";
88 void TargetRegistry::RegisterTarget(Target
&T
, const char *Name
,
89 const char *ShortDesc
,
90 const char *BackendName
,
91 Target::ArchMatchFnTy ArchMatchFn
,
93 assert(Name
&& ShortDesc
&& ArchMatchFn
&&
94 "Missing required target information!");
96 // Check if this target has already been initialized, we allow this as a
97 // convenience to some clients.
101 // Add to the list of targets.
102 T
.Next
= FirstTarget
;
106 T
.ShortDesc
= ShortDesc
;
107 T
.BackendName
= BackendName
;
108 T
.ArchMatchFn
= ArchMatchFn
;
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
);
117 void TargetRegistry::printRegisteredTargetsForVersion(raw_ostream
&OS
) {
118 std::vector
<std::pair
<StringRef
, const Target
*> > Targets
;
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());
124 array_pod_sort(Targets
.begin(), Targets
.end(), TargetArraySortFn
);
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';