TargetRegistry.cpp revision d6fd377f3333922c4e928019cdfa124ff7f4dd2e
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 10bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar#include "llvm/Target/TargetRegistry.h" 11d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar#include "llvm/System/Host.h" 12bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar#include <cassert> 13bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarusing namespace llvm; 14bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 1573b3ec41349511dbf28c18997e3f64761ff0f114Daniel Dunbar// Clients are responsible for avoid race conditions in registration. 16bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarstatic Target *FirstTarget = 0; 17bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 18603bea32743dc9914a1d32ae36fc64fe497af801Daniel DunbarTargetRegistry::iterator TargetRegistry::begin() { 19603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar return iterator(FirstTarget); 20603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar} 21603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar 22bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarconst Target * 23bb061291406b1b9f0c976e9845f69f9faf985606Daniel DunbarTargetRegistry::getClosestStaticTargetForTriple(const std::string &TT, 24bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar std::string &Error) { 257df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar // Provide special warning when no targets are initialized. 267df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar if (begin() == end()) { 277df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar Error = "Unable to find target for this triple (no targets are registered)"; 287df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar return 0; 297df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar } 30603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar const Target *Best = 0, *EquallyBest = 0; 31bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar unsigned BestQuality = 0; 32603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 33603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar if (unsigned Qual = it->TripleMatchQualityFn(TT)) { 34bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar if (!Best || Qual > BestQuality) { 35603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar Best = &*it; 36bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar EquallyBest = 0; 37bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar BestQuality = Qual; 38bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } else if (Qual == BestQuality) 39603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar EquallyBest = &*it; 40bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 41bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 42bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 43bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar if (!Best) { 447df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar Error = "No available targets are compatible with this triple"; 45bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar return 0; 46bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 47bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 48bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar // Otherwise, take the best target, but make sure we don't have two equally 49bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar // good best targets. 50bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar if (EquallyBest) { 51bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar Error = std::string("Cannot choose between targets \"") + 52bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar Best->Name + "\" and \"" + EquallyBest->Name + "\""; 53bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar return 0; 54bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 55bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 56bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar return Best; 57bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar} 58bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 59bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarconst Target * 60bb061291406b1b9f0c976e9845f69f9faf985606Daniel DunbarTargetRegistry::getClosestStaticTargetForModule(const Module &M, 61bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar std::string &Error) { 627df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar // Provide special warning when no targets are initialized. 637df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar if (begin() == end()) { 647df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar Error = "Unable to find target for this module (no targets are registered)"; 657df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar return 0; 667df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar } 677df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar 68603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar const Target *Best = 0, *EquallyBest = 0; 69bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar unsigned BestQuality = 0; 70603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 71603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar if (unsigned Qual = it->ModuleMatchQualityFn(M)) { 72bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar if (!Best || Qual > BestQuality) { 73603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar Best = &*it; 74bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar EquallyBest = 0; 75bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar BestQuality = Qual; 76bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } else if (Qual == BestQuality) 77603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar EquallyBest = &*it; 78bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 79bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 80bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 81d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar // FIXME: This is a hack to ignore super weak matches like msil, etc. and look 82d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar // by host instead. They will be found again via the triple. 83d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar if (Best && BestQuality == 1) 84d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar Best = EquallyBest = 0; 85d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar 86d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar // If that failed, try looking up the host triple. 87d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar if (!Best) 88d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar Best = getClosestStaticTargetForTriple(sys::getHostTriple(), Error); 89d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar 90bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar if (!Best) { 91bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar Error = "No available targets are compatible with this module"; 92d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar return Best; 93bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 94bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 95bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar // Otherwise, take the best target, but make sure we don't have two equally 96bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar // good best targets. 97bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar if (EquallyBest) { 98bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar Error = std::string("Cannot choose between targets \"") + 99bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar Best->Name + "\" and \"" + EquallyBest->Name + "\""; 100bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar return 0; 101bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 102bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 103bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar return Best; 104bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar} 105bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 106bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarconst Target * 107bb061291406b1b9f0c976e9845f69f9faf985606Daniel DunbarTargetRegistry::getClosestTargetForJIT(std::string &Error) { 108d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar std::string Triple = sys::getHostTriple(); 109d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar 1107df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar // Provide special warning when no targets are initialized. 1117df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar if (begin() == end()) { 1127df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar Error = "No JIT is available for this host (no targets are registered)"; 1137df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar return 0; 1147df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar } 1157df0c07dbcd60e2f07220852e60f0f97c80e94d6Daniel Dunbar 116603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar const Target *Best = 0, *EquallyBest = 0; 117bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar unsigned BestQuality = 0; 118603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 119d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar if (!it->hasJIT()) 120d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar continue; 121d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar 122d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar if (unsigned Qual = it->TripleMatchQualityFn(Triple)) { 123bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar if (!Best || Qual > BestQuality) { 124603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar Best = &*it; 125bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar EquallyBest = 0; 126bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar BestQuality = Qual; 127bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } else if (Qual == BestQuality) 128603bea32743dc9914a1d32ae36fc64fe497af801Daniel Dunbar EquallyBest = &*it; 129bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 130bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 131bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 132bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar if (!Best) { 133bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar Error = "No JIT is available for this host"; 134bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar return 0; 135bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar } 136bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 137bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar // Return the best, ignoring ties. 138bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar return Best; 139bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar} 140bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 141bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbarvoid TargetRegistry::RegisterTarget(Target &T, 142bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar const char *Name, 143bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar const char *ShortDesc, 144bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar Target::TripleMatchQualityFnTy TQualityFn, 145bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar Target::ModuleMatchQualityFnTy MQualityFn, 146d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar bool HasJIT) { 147d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar assert(Name && ShortDesc && TQualityFn && MQualityFn && 148bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar "Missing required target information!"); 14951b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar 15051b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar // Check if this target has already been initialized, we allow this as a 15151b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar // convenience to some clients. 15251b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar if (T.Name) 15351b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar return; 154bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 155bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar // Add to the list of targets. 156bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar T.Next = FirstTarget; 157f23d4930bdd5ee00354883f8756388573fa43e88Daniel Dunbar FirstTarget = &T; 158bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 159bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar T.Name = Name; 160bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar T.ShortDesc = ShortDesc; 161bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar T.TripleMatchQualityFn = TQualityFn; 162bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar T.ModuleMatchQualityFn = MQualityFn; 163d6fd377f3333922c4e928019cdfa124ff7f4dd2eDaniel Dunbar T.HasJIT = HasJIT; 164bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar} 165bb061291406b1b9f0c976e9845f69f9faf985606Daniel Dunbar 166