diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index 88081307ac6..c9d5fc34f60 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -510,6 +510,21 @@ namespace llvm { static const Target *lookupTarget(const std::string &Triple, std::string &Error); + /// lookupTarget - Lookup a target based on an architecture name + /// and a target triple. If the architecture name is non-empty, + /// then the lookup is done by architecture. Otherwise, the target + /// triple is used. + /// + /// \param ArchName - The architecture to use for finding a target. + /// \param TheTriple - The triple to use for finding a target. The + /// triple is updated with canonical architecture name if a lookup + /// by architecture is done. + /// \param Error - On failure, an error string describing why no target was + /// found. + static const Target *lookupTarget(const std::string &ArchName, + Triple &TheTriple, + 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. diff --git a/lib/Support/TargetRegistry.cpp b/lib/Support/TargetRegistry.cpp index 53c8d84e7d4..9c81327615c 100644 --- a/lib/Support/TargetRegistry.cpp +++ b/lib/Support/TargetRegistry.cpp @@ -23,6 +23,47 @@ TargetRegistry::iterator TargetRegistry::begin() { return iterator(FirstTarget); } +const Target *TargetRegistry::lookupTarget(const std::string &ArchName, + Triple &TheTriple, + std::string &Error) { + // Allocate target machine. First, check whether the user has explicitly + // specified an architecture to compile for. If so we have to look it up by + // name, because it might be a backend that has no mapping to a target triple. + const Target *TheTarget = 0; + if (!ArchName.empty()) { + for (TargetRegistry::iterator it = TargetRegistry::begin(), + ie = TargetRegistry::end(); it != ie; ++it) { + if (ArchName == it->getName()) { + TheTarget = &*it; + break; + } + } + + if (!TheTarget) { + Error = "error: invalid target '" + ArchName + "'.\n"; + return 0; + } + + // Adjust the triple to match (if known), otherwise stick with the + // given triple. + Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName); + if (Type != Triple::UnknownArch) + TheTriple.setArch(Type); + } else { + // Get the target specific parser. + std::string TempError; + TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), TempError); + if (TheTarget == 0) { + Error = ": error: unable to get target for '" + + TheTriple.getTriple() + + "', see --version and --triple.\n"; + return 0; + } + } + + return TheTarget; +} + const Target *TargetRegistry::lookupTarget(const std::string &TT, std::string &Error) { // Provide special warning when no targets are initialized. diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index ceff8a6c8cc..9f4ab70ba70 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -366,42 +366,18 @@ int main(int argc, char **argv) { if (!TargetTriple.empty()) mod.setTargetTriple(Triple::normalize(TargetTriple)); + // Figure out the target triple. Triple TheTriple(mod.getTargetTriple()); if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getDefaultTargetTriple()); - // Allocate target machine. First, check whether the user has explicitly - // specified an architecture to compile for. If so we have to look it up by - // name, because it might be a backend that has no mapping to a target triple. - const Target *TheTarget = 0; - if (!MArch.empty()) { - for (TargetRegistry::iterator it = TargetRegistry::begin(), - ie = TargetRegistry::end(); it != ie; ++it) { - if (MArch == it->getName()) { - TheTarget = &*it; - break; - } - } - - if (!TheTarget) { - errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n"; - return 1; - } - - // Adjust the triple to match (if known), otherwise stick with the - // module/host triple. - Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch); - if (Type != Triple::UnknownArch) - TheTriple.setArch(Type); - } else { - std::string Err; - TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err); - if (TheTarget == 0) { - errs() << argv[0] << ": error auto-selecting target for module '" - << Err << "'. Please use the -march option to explicitly " - << "pick a target.\n"; - return 1; - } + // Get the target specific parser. + std::string Error; + const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, + Error); + if (!TheTarget) { + errs() << argv[0] << ": " << Error; + return 1; } // Package up features to be passed to target/subtarget diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 36a482e908c..13cb517bcbf 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -180,38 +180,16 @@ static const Target *GetTarget(const char *ProgName) { TripleName = sys::getDefaultTargetTriple(); Triple TheTriple(Triple::normalize(TripleName)); - const Target *TheTarget = 0; - if (!ArchName.empty()) { - for (TargetRegistry::iterator it = TargetRegistry::begin(), - ie = TargetRegistry::end(); it != ie; ++it) { - if (ArchName == it->getName()) { - TheTarget = &*it; - break; - } - } - - if (!TheTarget) { - errs() << ProgName << ": error: invalid target '" << ArchName << "'.\n"; - return 0; - } - - // Adjust the triple to match (if known), otherwise stick with the - // module/host triple. - Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName); - if (Type != Triple::UnknownArch) - TheTriple.setArch(Type); - } else { - // Get the target specific parser. - std::string Error; - TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error); - if (TheTarget == 0) { - errs() << ProgName << ": error: unable to get target for '" - << TheTriple.getTriple() - << "', see --version and --triple.\n"; - return 0; - } + // Get the target specific parser. + std::string Error; + const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple, + Error); + if (!TheTarget) { + errs() << ProgName << ": " << Error; + return 0; } + // Update the triple name and return the found target. TripleName = TheTriple.getTriple(); return TheTarget; } diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 4cf15b614b3..7aaebb28a46 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -106,27 +106,25 @@ static bool error(error_code ec) { static const Target *GetTarget(const ObjectFile *Obj = NULL) { // Figure out the target triple. - llvm::Triple TT("unknown-unknown-unknown"); + llvm::Triple TheTriple("unknown-unknown-unknown"); if (TripleName.empty()) { if (Obj) - TT.setArch(Triple::ArchType(Obj->getArch())); + TheTriple.setArch(Triple::ArchType(Obj->getArch())); } else - TT.setTriple(Triple::normalize(TripleName)); - - if (!ArchName.empty()) - TT.setArchName(ArchName); - - TripleName = TT.str(); + TheTriple.setTriple(Triple::normalize(TripleName)); // Get the target specific parser. std::string Error; - const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); - if (TheTarget) - return TheTarget; + const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple, + Error); + if (!TheTarget) { + errs() << ToolName << ": " << Error; + return 0; + } - errs() << ToolName << ": error: unable to get target for '" << TripleName - << "', see --version and --triple.\n"; - return 0; + // Update the triple name and return the found target. + TripleName = TheTriple.getTriple(); + return TheTarget; } void llvm::StringRefMemoryObject::anchor() { }