1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

Add TargetRegistry::lookupTarget.

- This is a simplified mechanism which just looks up a target based on the
   target triple, with a few additional flags.

 - Remove getClosestStaticTargetForModule, the moral equivalent is now:
     lookupTarget(Mod->getTargetTriple, true, false, ...);

 - This no longer does the fuzzy matching with target data (based on endianness
   and pointer width) that getClosestStaticTargetForModule was doing, but this
   was deemed unnecessary.

llvm-svn: 77111
This commit is contained in:
Daniel Dunbar 2009-07-26 02:12:58 +00:00
parent 32fefa61d9
commit 62e74f03c7
8 changed files with 57 additions and 107 deletions

View File

@ -490,6 +490,9 @@ clients should be unaffected by this transition, unless they are used to <tt>Val
</ul>
</li>
<li>The registration interfaces for backend Targets has changed (what was
previously TargetMachineRegistry). FIXME: Complete this section, explain client
changes, point to documentation on new backend interface.</li>
<li>llvm-dis now fails if output file exists, instead of dumping to stdout.
FIXME: describe any other tool changes due to the raw_fd_ostream change. FIXME:

View File

@ -183,24 +183,27 @@ namespace llvm {
static iterator end() { return iterator(); }
/// getClosestStaticTargetForTriple - Given a target triple, pick the most
/// capable target for that triple.
static const Target *getClosestStaticTargetForTriple(const std::string &TT,
std::string &Error);
/// getClosestStaticTargetForModule - Given an LLVM module, pick the best
/// target that is compatible with the module. If no close target can be
/// found, this returns null and sets the Error string to a reason.
static const Target *getClosestStaticTargetForModule(const Module &M,
std::string &Error);
/// lookupTarget - Lookup a target based on a target triple.
///
/// \param Triple - The triple to use for finding a target.
/// \param FallbackToHost - If true and no target is found for the given
/// \arg Triple, then the host's triple will be used.
/// \param RequireJIT - Require the target to support JIT compilation.
/// \param Error - On failure, an error string describing why no target was
/// found.
static const Target *lookupTarget(const std::string &Triple,
bool FallbackToHost,
bool RequireJIT,
std::string &Error);
/// getClosestTargetForJIT - Pick the best target that is compatible with
/// the current host. If no close target can be found, this returns null
/// and sets the Error string to a reason.
//
// FIXME: Do we still need this interface, clients can always look for the
// match for the host triple.
static const Target *getClosestTargetForJIT(std::string &Error);
///
/// Mainted for compatibility through 2.6.
static const Target *getClosestTargetForJIT(std::string &Error) {
return lookupTarget("", true, true, Error);
}
/// @}
/// @name Target Registration

View File

@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/Module.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/System/Host.h"
#include <cassert>
@ -19,9 +20,10 @@ TargetRegistry::iterator TargetRegistry::begin() {
return iterator(FirstTarget);
}
const Target *
TargetRegistry::getClosestStaticTargetForTriple(const std::string &TT,
std::string &Error) {
const Target *TargetRegistry::lookupTarget(const std::string &TT,
bool FallbackToHost,
bool RequireJIT,
std::string &Error) {
// Provide special warning when no targets are initialized.
if (begin() == end()) {
Error = "Unable to find target for this triple (no targets are registered)";
@ -30,6 +32,9 @@ TargetRegistry::getClosestStaticTargetForTriple(const std::string &TT,
const Target *Best = 0, *EquallyBest = 0;
unsigned BestQuality = 0;
for (iterator it = begin(), ie = end(); it != ie; ++it) {
if (RequireJIT && !it->hasJIT())
continue;
if (unsigned Qual = it->TripleMatchQualityFn(TT)) {
if (!Best || Qual > BestQuality) {
Best = &*it;
@ -40,6 +45,15 @@ TargetRegistry::getClosestStaticTargetForTriple(const std::string &TT,
}
}
// FIXME: Hack. If we only have an extremely weak match and the client
// requested to fall back to the host, then ignore it and try again.
if (BestQuality == 1 && FallbackToHost)
Best = 0;
// Fallback to the host triple if we didn't find anything.
if (!Best && FallbackToHost)
return lookupTarget(sys::getHostTriple(), false, RequireJIT, Error);
if (!Best) {
Error = "No available targets are compatible with this triple";
return 0;
@ -56,88 +70,6 @@ TargetRegistry::getClosestStaticTargetForTriple(const std::string &TT,
return Best;
}
const Target *
TargetRegistry::getClosestStaticTargetForModule(const Module &M,
std::string &Error) {
// Provide special warning when no targets are initialized.
if (begin() == end()) {
Error = "Unable to find target for this module (no targets are registered)";
return 0;
}
const Target *Best = 0, *EquallyBest = 0;
unsigned BestQuality = 0;
for (iterator it = begin(), ie = end(); it != ie; ++it) {
if (unsigned Qual = it->ModuleMatchQualityFn(M)) {
if (!Best || Qual > BestQuality) {
Best = &*it;
EquallyBest = 0;
BestQuality = Qual;
} else if (Qual == BestQuality)
EquallyBest = &*it;
}
}
// FIXME: This is a hack to ignore super weak matches like msil, etc. and look
// by host instead. They will be found again via the triple.
if (Best && BestQuality == 1)
Best = EquallyBest = 0;
// If that failed, try looking up the host triple.
if (!Best)
Best = getClosestStaticTargetForTriple(sys::getHostTriple(), Error);
if (!Best) {
Error = "No available targets are compatible with this module";
return Best;
}
// 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;
}
const Target *
TargetRegistry::getClosestTargetForJIT(std::string &Error) {
std::string Triple = sys::getHostTriple();
// Provide special warning when no targets are initialized.
if (begin() == end()) {
Error = "No JIT is available for this host (no targets are registered)";
return 0;
}
const Target *Best = 0, *EquallyBest = 0;
unsigned BestQuality = 0;
for (iterator it = begin(), ie = end(); it != ie; ++it) {
if (!it->hasJIT())
continue;
if (unsigned Qual = it->TripleMatchQualityFn(Triple)) {
if (!Best || Qual > BestQuality) {
Best = &*it;
EquallyBest = 0;
BestQuality = Qual;
} else if (Qual == BestQuality)
EquallyBest = &*it;
}
}
if (!Best) {
Error = "No JIT is available for this host";
return 0;
}
// Return the best, ignoring ties.
return Best;
}
void TargetRegistry::RegisterTarget(Target &T,
const char *Name,
const char *ShortDesc,

View File

@ -3185,7 +3185,10 @@ std::string CWriter::InterpretASMConstraint(InlineAsm::ConstraintInfo& c) {
if (!TAsm) {
std::string E;
const Target *Match =
TargetRegistry::getClosestStaticTargetForModule(*TheModule, E);
TargetRegistry::lookupTarget(TheModule->getTargetTriple(),
/*FallbackToHost=*/true,
/*RequireJIT=*/false,
E);
if (Match) {
// Per platform Target Machines don't exist, so create it;
// this must be done only once.

View File

@ -252,7 +252,10 @@ int main(int argc, char **argv) {
}
} else {
std::string Err;
TheTarget = TargetRegistry::getClosestStaticTargetForModule(mod, Err);
TheTarget = TargetRegistry::lookupTarget(mod.getTargetTriple(),
/*FallbackToHost=*/true,
/*RequireJIT=*/false,
Err);
if (TheTarget == 0) {
errs() << argv[0] << ": error auto-selecting target for module '"
<< Err << "'. Please use the -march option to explicitly "

View File

@ -147,7 +147,10 @@ static int AssembleInput(const char *ProgName) {
// Get the target specific parser.
std::string Error;
const Target *TheTarget =
TargetRegistry::getClosestStaticTargetForTriple(Triple, Error);
TargetRegistry::lookupTarget(Triple,
/*FallbackToHost=*/true,
/*RequireJIT=*/false,
Error);
if (TheTarget == 0) {
errs() << ProgName << ": error: unable to get target for '" << Triple
<< "', see --version and --triple.\n";

View File

@ -330,8 +330,10 @@ bool LTOCodeGenerator::determineTarget(std::string& errMsg)
// create target machine from info for merged modules
Module* mergedModule = _linker.getModule();
const Target *march =
TargetRegistry::getClosestStaticTargetForModule(*mergedModule,
errMsg);
TargetRegistry::lookupTarget(mergedModule->getTargetTriple(),
/*FallbackToHost=*/true,
/*RequireJIT=*/false,
errMsg);
if ( march == NULL )
return true;

View File

@ -145,9 +145,10 @@ LTOModule* LTOModule::makeLTOModule(MemoryBuffer* buffer,
if ( !m )
return NULL;
// find machine architecture for this module
const Target* march =
TargetRegistry::getClosestStaticTargetForModule(*m, errMsg);
const Target* march = TargetRegistry::lookupTarget(m->getTargetTriple(),
/*FallbackToHost=*/true,
/*RequireJIT=*/false,
errMsg);
if ( march == NULL )
return NULL;