LLVM API Documentation
00001 //===--- TargetRegistry.cpp - Target registration -------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "llvm/Support/TargetRegistry.h" 00011 #include "llvm/ADT/STLExtras.h" 00012 #include "llvm/ADT/StringRef.h" 00013 #include "llvm/Support/Host.h" 00014 #include "llvm/Support/raw_ostream.h" 00015 #include <cassert> 00016 #include <vector> 00017 using namespace llvm; 00018 00019 // Clients are responsible for avoid race conditions in registration. 00020 static Target *FirstTarget = nullptr; 00021 00022 TargetRegistry::iterator TargetRegistry::begin() { 00023 return iterator(FirstTarget); 00024 } 00025 00026 const Target *TargetRegistry::lookupTarget(const std::string &ArchName, 00027 Triple &TheTriple, 00028 std::string &Error) { 00029 // Allocate target machine. First, check whether the user has explicitly 00030 // specified an architecture to compile for. If so we have to look it up by 00031 // name, because it might be a backend that has no mapping to a target triple. 00032 const Target *TheTarget = nullptr; 00033 if (!ArchName.empty()) { 00034 for (TargetRegistry::iterator it = TargetRegistry::begin(), 00035 ie = TargetRegistry::end(); it != ie; ++it) { 00036 if (ArchName == it->getName()) { 00037 TheTarget = &*it; 00038 break; 00039 } 00040 } 00041 00042 if (!TheTarget) { 00043 Error = "error: invalid target '" + ArchName + "'.\n"; 00044 return nullptr; 00045 } 00046 00047 // Adjust the triple to match (if known), otherwise stick with the 00048 // given triple. 00049 Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName); 00050 if (Type != Triple::UnknownArch) 00051 TheTriple.setArch(Type); 00052 } else { 00053 // Get the target specific parser. 00054 std::string TempError; 00055 TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), TempError); 00056 if (!TheTarget) { 00057 Error = ": error: unable to get target for '" 00058 + TheTriple.getTriple() 00059 + "', see --version and --triple.\n"; 00060 return nullptr; 00061 } 00062 } 00063 00064 return TheTarget; 00065 } 00066 00067 const Target *TargetRegistry::lookupTarget(const std::string &TT, 00068 std::string &Error) { 00069 // Provide special warning when no targets are initialized. 00070 if (begin() == end()) { 00071 Error = "Unable to find target for this triple (no targets are registered)"; 00072 return nullptr; 00073 } 00074 const Target *Matching = nullptr; 00075 Triple::ArchType Arch = Triple(TT).getArch(); 00076 for (iterator it = begin(), ie = end(); it != ie; ++it) { 00077 if (it->ArchMatchFn(Arch)) { 00078 if (Matching) { 00079 Error = std::string("Cannot choose between targets \"") + 00080 Matching->Name + "\" and \"" + it->Name + "\""; 00081 return nullptr; 00082 } 00083 Matching = &*it; 00084 } 00085 } 00086 00087 if (!Matching) { 00088 Error = "No available targets are compatible with this triple, " 00089 "see -version for the available targets."; 00090 return nullptr; 00091 } 00092 00093 return Matching; 00094 } 00095 00096 void TargetRegistry::RegisterTarget(Target &T, 00097 const char *Name, 00098 const char *ShortDesc, 00099 Target::ArchMatchFnTy ArchMatchFn, 00100 bool HasJIT) { 00101 assert(Name && ShortDesc && ArchMatchFn && 00102 "Missing required target information!"); 00103 00104 // Check if this target has already been initialized, we allow this as a 00105 // convenience to some clients. 00106 if (T.Name) 00107 return; 00108 00109 // Add to the list of targets. 00110 T.Next = FirstTarget; 00111 FirstTarget = &T; 00112 00113 T.Name = Name; 00114 T.ShortDesc = ShortDesc; 00115 T.ArchMatchFn = ArchMatchFn; 00116 T.HasJIT = HasJIT; 00117 } 00118 00119 static int TargetArraySortFn(const std::pair<StringRef, const Target *> *LHS, 00120 const std::pair<StringRef, const Target *> *RHS) { 00121 return LHS->first.compare(RHS->first); 00122 } 00123 00124 void TargetRegistry::printRegisteredTargetsForVersion() { 00125 std::vector<std::pair<StringRef, const Target*> > Targets; 00126 size_t Width = 0; 00127 for (TargetRegistry::iterator I = TargetRegistry::begin(), 00128 E = TargetRegistry::end(); 00129 I != E; ++I) { 00130 Targets.push_back(std::make_pair(I->getName(), &*I)); 00131 Width = std::max(Width, Targets.back().first.size()); 00132 } 00133 array_pod_sort(Targets.begin(), Targets.end(), TargetArraySortFn); 00134 00135 raw_ostream &OS = outs(); 00136 OS << " Registered Targets:\n"; 00137 for (unsigned i = 0, e = Targets.size(); i != e; ++i) { 00138 OS << " " << Targets[i].first; 00139 OS.indent(Width - Targets[i].first.size()) << " - " 00140 << Targets[i].second->getShortDescription() << '\n'; 00141 } 00142 if (Targets.empty()) 00143 OS << " (none)\n"; 00144 }