From 77962b5146e64db4a952d09a4f9ce54853961273 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 13 Dec 2013 16:05:32 +0000 Subject: [PATCH] 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. llvm-svn: 197241 --- include/llvm/Support/TargetRegistry.h | 22 +++++------- lib/Support/TargetRegistry.cpp | 36 ++++++++----------- .../TargetInfo/CppBackendTargetInfo.cpp | 7 ++-- test/CodeGen/Generic/no-target.ll | 3 ++ 4 files changed, 29 insertions(+), 39 deletions(-) create mode 100644 test/CodeGen/Generic/no-target.ll diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index 9ecee3b7c21..9455437c923 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -79,7 +79,7 @@ namespace llvm { public: friend struct TargetRegistry; - typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT); + typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch); typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI, StringRef TT); @@ -154,9 +154,8 @@ namespace llvm { /// TargetRegistry. Target *Next; - /// TripleMatchQualityFn - The target function for rating the match quality - /// of a triple. - TripleMatchQualityFnTy TripleMatchQualityFn; + /// The target function for checking if an architecture is supported. + ArchMatchFnTy ArchMatchFn; /// Name - The target name. const char *Name; @@ -578,14 +577,13 @@ namespace llvm { /// @param Name - The target name. This should be a static string. /// @param ShortDesc - A short target description. This should be a static /// string. - /// @param TQualityFn - The triple match quality computation function for - /// this target. + /// @param ArchMatchFn - The arch match checking function for this target. /// @param HasJIT - Whether the target supports JIT code /// generation. static void RegisterTarget(Target &T, const char *Name, const char *ShortDesc, - Target::TripleMatchQualityFnTy TQualityFn, + Target::ArchMatchFnTy ArchMatchFn, bool HasJIT = false); /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the @@ -831,15 +829,11 @@ namespace llvm { bool HasJIT = false> struct RegisterTarget { RegisterTarget(Target &T, const char *Name, const char *Desc) { - TargetRegistry::RegisterTarget(T, Name, Desc, - &getTripleMatchQuality, - HasJIT); + TargetRegistry::RegisterTarget(T, Name, Desc, &getArchMatch, HasJIT); } - static unsigned getTripleMatchQuality(const std::string &TT) { - if (Triple(TT).getArch() == TargetArchType) - return 20; - return 0; + static bool getArchMatch(Triple::ArchType Arch) { + return Arch == TargetArchType; } }; diff --git a/lib/Support/TargetRegistry.cpp b/lib/Support/TargetRegistry.cpp index 0c90c17fefb..8d91a53c226 100644 --- a/lib/Support/TargetRegistry.cpp +++ b/lib/Support/TargetRegistry.cpp @@ -71,42 +71,34 @@ const Target *TargetRegistry::lookupTarget(const std::string &TT, Error = "Unable to find target for this triple (no targets are registered)"; return 0; } - const Target *Best = 0, *EquallyBest = 0; - unsigned BestQuality = 0; + const Target *Matching = 0; + Triple::ArchType Arch = Triple(TT).getArch(); for (iterator it = begin(), ie = end(); it != ie; ++it) { - if (unsigned Qual = it->TripleMatchQualityFn(TT)) { - if (!Best || Qual > BestQuality) { - Best = &*it; - EquallyBest = 0; - BestQuality = Qual; - } else if (Qual == BestQuality) - EquallyBest = &*it; + if (it->ArchMatchFn(Arch)) { + if (Matching) { + Error = std::string("Cannot choose between targets \"") + + Matching->Name + "\" and \"" + it->Name + "\""; + return 0; + } + Matching = &*it; } } - if (!Best) { + if (!Matching) { Error = "No available targets are compatible with this triple, " "see -version for the available targets."; return 0; } - // Otherwise, take the best target, but make sure we don't have two equally - // good best targets. - if (EquallyBest) { - Error = std::string("Cannot choose between targets \"") + - Best->Name + "\" and \"" + EquallyBest->Name + "\""; - return 0; - } - - return Best; + return Matching; } void TargetRegistry::RegisterTarget(Target &T, const char *Name, const char *ShortDesc, - Target::TripleMatchQualityFnTy TQualityFn, + Target::ArchMatchFnTy ArchMatchFn, bool HasJIT) { - assert(Name && ShortDesc && TQualityFn && + assert(Name && ShortDesc && ArchMatchFn && "Missing required target information!"); // 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.ShortDesc = ShortDesc; - T.TripleMatchQualityFn = TQualityFn; + T.ArchMatchFn = ArchMatchFn; T.HasJIT = HasJIT; } diff --git a/lib/Target/CppBackend/TargetInfo/CppBackendTargetInfo.cpp b/lib/Target/CppBackend/TargetInfo/CppBackendTargetInfo.cpp index 1ca74a4895c..096dc7350db 100644 --- a/lib/Target/CppBackend/TargetInfo/CppBackendTargetInfo.cpp +++ b/lib/Target/CppBackend/TargetInfo/CppBackendTargetInfo.cpp @@ -14,9 +14,10 @@ using namespace llvm; Target llvm::TheCppBackendTarget; -static unsigned CppBackend_TripleMatchQuality(const std::string &TT) { - // This class always works, but shouldn't be the default in most cases. - return 1; +static bool CppBackend_TripleMatchQuality(Triple::ArchType Arch) { + // This backend doesn't correspond to any architecture. It must be explicitly + // selected with -march. + return false; } extern "C" void LLVMInitializeCppBackendTargetInfo() { diff --git a/test/CodeGen/Generic/no-target.ll b/test/CodeGen/Generic/no-target.ll new file mode 100644 index 00000000000..4a4724fdf2d --- /dev/null +++ b/test/CodeGen/Generic/no-target.ll @@ -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'