Fix pr18235.

The cpp backend is not a reasonable fallback for a missing target. It is a
very special backend, so it is reasonable to use it only if explicitly
requested.

While at it, simplify the interface a bit.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197241 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2013-12-13 16:05:32 +00:00
parent 584940e3c6
commit 7b3aa0356d
4 changed files with 29 additions and 39 deletions

View File

@ -79,7 +79,7 @@ namespace llvm {
public: public:
friend struct TargetRegistry; friend struct TargetRegistry;
typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT); typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch);
typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI, typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
StringRef TT); StringRef TT);
@ -154,9 +154,8 @@ namespace llvm {
/// TargetRegistry. /// TargetRegistry.
Target *Next; Target *Next;
/// TripleMatchQualityFn - The target function for rating the match quality /// The target function for checking if an architecture is supported.
/// of a triple. ArchMatchFnTy ArchMatchFn;
TripleMatchQualityFnTy TripleMatchQualityFn;
/// Name - The target name. /// Name - The target name.
const char *Name; const char *Name;
@ -578,14 +577,13 @@ namespace llvm {
/// @param Name - The target name. This should be a static string. /// @param Name - The target name. This should be a static string.
/// @param ShortDesc - A short target description. This should be a static /// @param ShortDesc - A short target description. This should be a static
/// string. /// string.
/// @param TQualityFn - The triple match quality computation function for /// @param ArchMatchFn - The arch match checking function for this target.
/// this target.
/// @param HasJIT - Whether the target supports JIT code /// @param HasJIT - Whether the target supports JIT code
/// generation. /// generation.
static void RegisterTarget(Target &T, static void RegisterTarget(Target &T,
const char *Name, const char *Name,
const char *ShortDesc, const char *ShortDesc,
Target::TripleMatchQualityFnTy TQualityFn, Target::ArchMatchFnTy ArchMatchFn,
bool HasJIT = false); bool HasJIT = false);
/// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
@ -831,15 +829,11 @@ namespace llvm {
bool HasJIT = false> bool HasJIT = false>
struct RegisterTarget { struct RegisterTarget {
RegisterTarget(Target &T, const char *Name, const char *Desc) { RegisterTarget(Target &T, const char *Name, const char *Desc) {
TargetRegistry::RegisterTarget(T, Name, Desc, TargetRegistry::RegisterTarget(T, Name, Desc, &getArchMatch, HasJIT);
&getTripleMatchQuality,
HasJIT);
} }
static unsigned getTripleMatchQuality(const std::string &TT) { static bool getArchMatch(Triple::ArchType Arch) {
if (Triple(TT).getArch() == TargetArchType) return Arch == TargetArchType;
return 20;
return 0;
} }
}; };

View File

@ -71,42 +71,34 @@ const Target *TargetRegistry::lookupTarget(const std::string &TT,
Error = "Unable to find target for this triple (no targets are registered)"; Error = "Unable to find target for this triple (no targets are registered)";
return 0; return 0;
} }
const Target *Best = 0, *EquallyBest = 0; const Target *Matching = 0;
unsigned BestQuality = 0; Triple::ArchType Arch = Triple(TT).getArch();
for (iterator it = begin(), ie = end(); it != ie; ++it) { for (iterator it = begin(), ie = end(); it != ie; ++it) {
if (unsigned Qual = it->TripleMatchQualityFn(TT)) { if (it->ArchMatchFn(Arch)) {
if (!Best || Qual > BestQuality) { if (Matching) {
Best = &*it; Error = std::string("Cannot choose between targets \"") +
EquallyBest = 0; Matching->Name + "\" and \"" + it->Name + "\"";
BestQuality = Qual; return 0;
} else if (Qual == BestQuality) }
EquallyBest = &*it; Matching = &*it;
} }
} }
if (!Best) { if (!Matching) {
Error = "No available targets are compatible with this triple, " Error = "No available targets are compatible with this triple, "
"see -version for the available targets."; "see -version for the available targets.";
return 0; return 0;
} }
// Otherwise, take the best target, but make sure we don't have two equally return Matching;
// good best targets.
if (EquallyBest) {
Error = std::string("Cannot choose between targets \"") +
Best->Name + "\" and \"" + EquallyBest->Name + "\"";
return 0;
}
return Best;
} }
void TargetRegistry::RegisterTarget(Target &T, void TargetRegistry::RegisterTarget(Target &T,
const char *Name, const char *Name,
const char *ShortDesc, const char *ShortDesc,
Target::TripleMatchQualityFnTy TQualityFn, Target::ArchMatchFnTy ArchMatchFn,
bool HasJIT) { bool HasJIT) {
assert(Name && ShortDesc && TQualityFn && assert(Name && ShortDesc && ArchMatchFn &&
"Missing required target information!"); "Missing required target information!");
// Check if this target has already been initialized, we allow this as a // Check if this target has already been initialized, we allow this as a
@ -120,7 +112,7 @@ void TargetRegistry::RegisterTarget(Target &T,
T.Name = Name; T.Name = Name;
T.ShortDesc = ShortDesc; T.ShortDesc = ShortDesc;
T.TripleMatchQualityFn = TQualityFn; T.ArchMatchFn = ArchMatchFn;
T.HasJIT = HasJIT; T.HasJIT = HasJIT;
} }

View File

@ -14,9 +14,10 @@ using namespace llvm;
Target llvm::TheCppBackendTarget; Target llvm::TheCppBackendTarget;
static unsigned CppBackend_TripleMatchQuality(const std::string &TT) { static bool CppBackend_TripleMatchQuality(Triple::ArchType Arch) {
// This class always works, but shouldn't be the default in most cases. // This backend doesn't correspond to any architecture. It must be explicitly
return 1; // selected with -march.
return false;
} }
extern "C" void LLVMInitializeCppBackendTargetInfo() { extern "C" void LLVMInitializeCppBackendTargetInfo() {

View File

@ -0,0 +1,3 @@
; RUN: not llc -mtriple le32-unknown-nacl %s -o - 2>&1 | FileCheck %s
; CHECK: error: unable to get target for 'le32-unknown-nacl'