mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-29 22:30:33 +00:00
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:
parent
5a37a68afd
commit
77962b5146
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
3
test/CodeGen/Generic/no-target.ll
Normal file
3
test/CodeGen/Generic/no-target.ll
Normal 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'
|
Loading…
Reference in New Issue
Block a user