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
This commit is contained in:
Rafael Espindola 2013-12-13 16:05:32 +00:00
parent 5a37a68afd
commit 77962b5146
4 changed files with 29 additions and 39 deletions

View File

@ -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;
}
};

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)";
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;
}

View File

@ -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() {

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'