TargetRegistry.cpp revision 3e74d6fdd248e20a280f1dff3da9a6c689c2c4c3
1bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar//===--- TargetRegistry.cpp - Target registration -------------------------===// 2bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar// 3bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar// The LLVM Compiler Infrastructure 4bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar// 5bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar// This file is distributed under the University of Illinois Open Source 6bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar// License. See LICENSE.TXT for details. 7bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar// 8bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar//===----------------------------------------------------------------------===// 9bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 103e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 11077c40871780136f7016a496703b20ebea9c0978Chandler Carruth#include "llvm/ADT/STLExtras.h" 12077c40871780136f7016a496703b20ebea9c0978Chandler Carruth#include "llvm/ADT/StringRef.h" 131f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Host.h" 14077c40871780136f7016a496703b20ebea9c0978Chandler Carruth#include "llvm/Support/raw_ostream.h" 15bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar#include <cassert> 16077c40871780136f7016a496703b20ebea9c0978Chandler Carruth#include <vector> 17bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarusing namespace llvm; 18bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 1973b3ec41349511dbf28c18997e3f64761ff0f114Daniel Dunbar// Clients are responsible for avoid race conditions in registration. 20bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarstatic Target *FirstTarget = 0; 21bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 22603bea32743dc9914a1d32ae36fc64fe497af801Daniel DunbarTargetRegistry::iterator TargetRegistry::begin() { 23603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar return iterator(FirstTarget); 24603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar} 25603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar 26a5881e3060aee9f82aef3747a97650e5eafe893aDaniel Dunbarconst Target *TargetRegistry::lookupTarget(const std::string &TT, 27a5881e3060aee9f82aef3747a97650e5eafe893aDaniel Dunbar std::string &Error) { 287df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar // Provide special warning when no targets are initialized. 297df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar if (begin() == end()) { 307df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar Error = "Unable to find target for this triple (no targets are registered)"; 317df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar return 0; 327df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar } 33603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar const Target *Best = 0, *EquallyBest = 0; 34bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar unsigned BestQuality = 0; 35603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 36a5881e3060aee9f82aef3747a97650e5eafe893aDaniel Dunbar if (unsigned Qual = it->TripleMatchQualityFn(TT)) { 37bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar if (!Best || Qual > BestQuality) { 38603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar Best = &*it; 39bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar EquallyBest = 0; 40bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar BestQuality = Qual; 41bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } else if (Qual == BestQuality) 42603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar EquallyBest = &*it; 43bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 44bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 45bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 46bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar if (!Best) { 470247656d0aaaee69ab20ff0ad56536bff38b3715Daniel Dunbar Error = "No available targets are compatible with this triple, " 480247656d0aaaee69ab20ff0ad56536bff38b3715Daniel Dunbar "see -version for the available targets."; 49a5881e3060aee9f82aef3747a97650e5eafe893aDaniel Dunbar return 0; 50bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 51bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 52bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar // Otherwise, take the best target, but make sure we don't have two equally 53bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar // good best targets. 54bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar if (EquallyBest) { 55bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar Error = std::string("Cannot choose between targets \"") + 56bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar Best->Name + "\" and \"" + EquallyBest->Name + "\""; 57bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar return 0; 58bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 59bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 60bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar return Best; 61bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar} 62bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 63bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarvoid TargetRegistry::RegisterTarget(Target &T, 64bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar const char *Name, 65bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar const char *ShortDesc, 66bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar Target::TripleMatchQualityFnTy TQualityFn, 67d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar bool HasJIT) { 68fa27ff296d3694a68e7abb3b6b7629588def3e58Daniel Dunbar assert(Name && ShortDesc && TQualityFn && 69bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar "Missing required target information!"); 7051b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar 7151b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar // Check if this target has already been initialized, we allow this as a 7251b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar // convenience to some clients. 7351b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar if (T.Name) 7451b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar return; 75bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 76bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar // Add to the list of targets. 77bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar T.Next = FirstTarget; 78f23d4930bdd5ee00354883f8756388573fa43e88Daniel Dunbar FirstTarget = &T; 79bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 80bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar T.Name = Name; 81bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar T.ShortDesc = ShortDesc; 82bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar T.TripleMatchQualityFn = TQualityFn; 83d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar T.HasJIT = HasJIT; 84bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar} 85bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 864bd03abe593222b26e84066223feb321bf738625Daniel Dunbarconst Target *TargetRegistry::getClosestTargetForJIT(std::string &Error) { 874bd03abe593222b26e84066223feb321bf738625Daniel Dunbar const Target *TheTarget = lookupTarget(sys::getHostTriple(), Error); 884bd03abe593222b26e84066223feb321bf738625Daniel Dunbar 894bd03abe593222b26e84066223feb321bf738625Daniel Dunbar if (TheTarget && !TheTarget->hasJIT()) { 904bd03abe593222b26e84066223feb321bf738625Daniel Dunbar Error = "No JIT compatible target available for this host"; 914bd03abe593222b26e84066223feb321bf738625Daniel Dunbar return 0; 924bd03abe593222b26e84066223feb321bf738625Daniel Dunbar } 934bd03abe593222b26e84066223feb321bf738625Daniel Dunbar 944bd03abe593222b26e84066223feb321bf738625Daniel Dunbar return TheTarget; 954bd03abe593222b26e84066223feb321bf738625Daniel Dunbar} 964bd03abe593222b26e84066223feb321bf738625Daniel Dunbar 97077c40871780136f7016a496703b20ebea9c0978Chandler Carruthstatic int TargetArraySortFn(const void *LHS, const void *RHS) { 98077c40871780136f7016a496703b20ebea9c0978Chandler Carruth typedef std::pair<StringRef, const Target*> pair_ty; 99077c40871780136f7016a496703b20ebea9c0978Chandler Carruth return ((const pair_ty*)LHS)->first.compare(((const pair_ty*)RHS)->first); 100077c40871780136f7016a496703b20ebea9c0978Chandler Carruth} 101077c40871780136f7016a496703b20ebea9c0978Chandler Carruth 102077c40871780136f7016a496703b20ebea9c0978Chandler Carruthvoid TargetRegistry::printRegisteredTargetsForVersion() { 103077c40871780136f7016a496703b20ebea9c0978Chandler Carruth std::vector<std::pair<StringRef, const Target*> > Targets; 104077c40871780136f7016a496703b20ebea9c0978Chandler Carruth size_t Width = 0; 105077c40871780136f7016a496703b20ebea9c0978Chandler Carruth for (TargetRegistry::iterator I = TargetRegistry::begin(), 106077c40871780136f7016a496703b20ebea9c0978Chandler Carruth E = TargetRegistry::end(); 107077c40871780136f7016a496703b20ebea9c0978Chandler Carruth I != E; ++I) { 108077c40871780136f7016a496703b20ebea9c0978Chandler Carruth Targets.push_back(std::make_pair(I->getName(), &*I)); 109077c40871780136f7016a496703b20ebea9c0978Chandler Carruth Width = std::max(Width, Targets.back().first.size()); 110077c40871780136f7016a496703b20ebea9c0978Chandler Carruth } 111077c40871780136f7016a496703b20ebea9c0978Chandler Carruth array_pod_sort(Targets.begin(), Targets.end(), TargetArraySortFn); 112077c40871780136f7016a496703b20ebea9c0978Chandler Carruth 113077c40871780136f7016a496703b20ebea9c0978Chandler Carruth raw_ostream &OS = outs(); 114077c40871780136f7016a496703b20ebea9c0978Chandler Carruth OS << " Registered Targets:\n"; 115077c40871780136f7016a496703b20ebea9c0978Chandler Carruth for (unsigned i = 0, e = Targets.size(); i != e; ++i) { 116077c40871780136f7016a496703b20ebea9c0978Chandler Carruth OS << " " << Targets[i].first; 117077c40871780136f7016a496703b20ebea9c0978Chandler Carruth OS.indent(Width - Targets[i].first.size()) << " - " 118077c40871780136f7016a496703b20ebea9c0978Chandler Carruth << Targets[i].second->getShortDescription() << '\n'; 119077c40871780136f7016a496703b20ebea9c0978Chandler Carruth } 120077c40871780136f7016a496703b20ebea9c0978Chandler Carruth if (Targets.empty()) 121077c40871780136f7016a496703b20ebea9c0978Chandler Carruth OS << " (none)\n"; 122077c40871780136f7016a496703b20ebea9c0978Chandler Carruth} 123