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 10 #include "llvm/Support/TargetRegistry.h" 11 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/ADT/StringRef.h" 13 #include "llvm/Support/Host.h" 14 #include "llvm/Support/raw_ostream.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 22 TargetRegistry::iterator TargetRegistry::begin() { 23 return iterator(FirstTarget); 24 } 25 26 const Target *TargetRegistry::lookupTarget(const std::string &TT, 27 std::string &Error) { 28 // Provide special warning when no targets are initialized. 29 if (begin() == end()) { 30 Error = "Unable to find target for this triple (no targets are registered)"; 31 return 0; 32 } 33 const Target *Best = 0, *EquallyBest = 0; 34 unsigned BestQuality = 0; 35 for (iterator it = begin(), ie = end(); it != ie; ++it) { 36 if (unsigned Qual = it->TripleMatchQualityFn(TT)) { 37 if (!Best || Qual > BestQuality) { 38 Best = &*it; 39 EquallyBest = 0; 40 BestQuality = Qual; 41 } else if (Qual == BestQuality) 42 EquallyBest = &*it; 43 } 44 } 45 46 if (!Best) { 47 Error = "No available targets are compatible with this triple, " 48 "see -version for the available targets."; 49 return 0; 50 } 51 52 // Otherwise, take the best target, but make sure we don't have two equally 53 // good best targets. 54 if (EquallyBest) { 55 Error = std::string("Cannot choose between targets \"") + 56 Best->Name + "\" and \"" + EquallyBest->Name + "\""; 57 return 0; 58 } 59 60 return Best; 61 } 62 63 void TargetRegistry::RegisterTarget(Target &T, 64 const char *Name, 65 const char *ShortDesc, 66 Target::TripleMatchQualityFnTy TQualityFn, 67 bool HasJIT) { 68 assert(Name && ShortDesc && TQualityFn && 69 "Missing required target information!"); 70 71 // Check if this target has already been initialized, we allow this as a 72 // convenience to some clients. 73 if (T.Name) 74 return; 75 76 // Add to the list of targets. 77 T.Next = FirstTarget; 78 FirstTarget = &T; 79 80 T.Name = Name; 81 T.ShortDesc = ShortDesc; 82 T.TripleMatchQualityFn = TQualityFn; 83 T.HasJIT = HasJIT; 84 } 85 86 const Target *TargetRegistry::getClosestTargetForJIT(std::string &Error) { 87 const Target *TheTarget = lookupTarget(sys::getHostTriple(), Error); 88 89 if (TheTarget && !TheTarget->hasJIT()) { 90 Error = "No JIT compatible target available for this host"; 91 return 0; 92 } 93 94 return TheTarget; 95 } 96 97 static int TargetArraySortFn(const void *LHS, const void *RHS) { 98 typedef std::pair<StringRef, const Target*> pair_ty; 99 return ((const pair_ty*)LHS)->first.compare(((const pair_ty*)RHS)->first); 100 } 101 102 void TargetRegistry::printRegisteredTargetsForVersion() { 103 std::vector<std::pair<StringRef, const Target*> > Targets; 104 size_t Width = 0; 105 for (TargetRegistry::iterator I = TargetRegistry::begin(), 106 E = TargetRegistry::end(); 107 I != E; ++I) { 108 Targets.push_back(std::make_pair(I->getName(), &*I)); 109 Width = std::max(Width, Targets.back().first.size()); 110 } 111 array_pod_sort(Targets.begin(), Targets.end(), TargetArraySortFn); 112 113 raw_ostream &OS = outs(); 114 OS << " Registered Targets:\n"; 115 for (unsigned i = 0, e = Targets.size(); i != e; ++i) { 116 OS << " " << Targets[i].first; 117 OS.indent(Width - Targets[i].first.size()) << " - " 118 << Targets[i].second->getShortDescription() << '\n'; 119 } 120 if (Targets.empty()) 121 OS << " (none)\n"; 122 } 123