diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 7ae2c3033d3..5c8244c638b 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -95,7 +95,7 @@ public: /// @{ Triple() : Data(""), Arch(InvalidArch) {} - explicit Triple(const char *Str) : Data(Str), Arch(InvalidArch) {} + explicit Triple(const StringRef &Str) : Data(Str), Arch(InvalidArch) {} explicit Triple(const char *ArchStr, const char *VendorStr, const char *OSStr) : Data(ArchStr), Arch(InvalidArch) { Data += '-'; @@ -212,6 +212,10 @@ public: /// getOSTypeName - Get the canonical name for the \arg Kind vendor. static const char *getOSTypeName(OSType Kind); + /// getArchTypeForLLVMName - The canonical type for the given LLVM + /// architecture name (e.g., "x86"). + static ArchType getArchTypeForLLVMName(const StringRef &Str); + /// @} }; diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h index 9b164ba23e8..93991dc6873 100644 --- a/include/llvm/Target/TargetRegistry.h +++ b/include/llvm/Target/TargetRegistry.h @@ -51,6 +51,7 @@ namespace llvm { typedef TargetMachine *(*TargetMachineCtorTy)(const Target &, const Module &, + const std::string &, const std::string &); typedef FunctionPass *(*AsmPrinterCtorTy)(formatted_raw_ostream &, TargetMachine &, @@ -110,12 +111,21 @@ namespace llvm { /// hasAsmParser - Check if this target supports .s parsing. bool hasAsmParser() const { return AsmParserCtorFn != 0; } - /// createTargetMachine - Create a target specific machine implementation. + /// createTargetMachine - Create a target specific machine implementation + /// for the module \arg M and \arg Triple. + /// + /// \arg M - This argument is used for some machines to access the target + /// data. + /// \arg Triple - This argument is used to determine the target machine + /// feature set; it should always be provided. Generally this should be + /// either the target triple from the module, or the target triple of the + /// host if that does not exist. TargetMachine *createTargetMachine(const Module &M, + const std::string &Triple, const std::string &Features) const { if (!TargetMachineCtorFn) return 0; - return TargetMachineCtorFn(*this, M, Features); + return TargetMachineCtorFn(*this, M, Triple, Features); } /// createAsmPrinter - Create a target specific assembly printer pass. @@ -325,8 +335,9 @@ namespace llvm { private: static TargetMachine *Allocator(const Target &T, const Module &M, + const std::string &TT, const std::string &FS) { - return new TargetMachineImpl(T, M.getTargetTriple(), FS); + return new TargetMachineImpl(T, TT, FS); } }; @@ -338,6 +349,7 @@ namespace llvm { private: static TargetMachine *Allocator(const Target &T, const Module &M, + const std::string &TT, const std::string &FS) { return new TargetMachineImpl(T, M, FS); } diff --git a/lib/ExecutionEngine/JIT/TargetSelect.cpp b/lib/ExecutionEngine/JIT/TargetSelect.cpp index 84b745b3f9a..55ff44121dd 100644 --- a/lib/ExecutionEngine/JIT/TargetSelect.cpp +++ b/lib/ExecutionEngine/JIT/TargetSelect.cpp @@ -16,8 +16,10 @@ #include "JIT.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" +#include "llvm/ADT/Triple.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Streams.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/System/Host.h" #include "llvm/Target/SubtargetFeature.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegistry.h" @@ -41,35 +43,28 @@ MAttrs("mattr", /// selectTarget - Pick a target either via -march or by guessing the native /// arch. Add any CPU features specified via -mcpu or -mattr. TargetMachine *JIT::selectTarget(ModuleProvider *MP, std::string *ErrorStr) { - const Target *TheTarget = 0; - if (MArch.empty()) { - std::string Error; - TheTarget = TargetRegistry::getClosestTargetForJIT(Error); - if (TheTarget == 0) { - if (ErrorStr) - *ErrorStr = Error; - return 0; - } - } else { - for (TargetRegistry::iterator it = TargetRegistry::begin(), - ie = TargetRegistry::end(); it != ie; ++it) { - if (MArch == it->getName()) { - TheTarget = &*it; - break; - } - } - - if (TheTarget == 0) { - if (ErrorStr) - *ErrorStr = std::string("invalid target '" + MArch + "'.\n"); - return 0; - } + Triple TheTriple(sys::getHostTriple()); - if (!TheTarget->hasJIT()) { - cerr << "WARNING: This target JIT is not designed for the host you are" + // Adjust the triple to match what the user requested. + if (!MArch.empty()) + TheTriple.setArch(Triple::getArchTypeForLLVMName(MArch)); + + std::string Error; + const Target *TheTarget = + TargetRegistry::lookupTarget(TheTriple.getTriple(), + /*FallbackToHost=*/false, + /*RequireJIT=*/false, + Error); + if (TheTarget == 0) { + if (ErrorStr) + *ErrorStr = Error; + return 0; + } + + if (!TheTarget->hasJIT()) { + errs() << "WARNING: This target JIT is not designed for the host you are" << " running. If bad things happen, please choose a different " << "-march switch.\n"; - } } // Package up features to be passed to target/subtarget @@ -84,7 +79,8 @@ TargetMachine *JIT::selectTarget(ModuleProvider *MP, std::string *ErrorStr) { // Allocate a target... TargetMachine *Target = - TheTarget->createTargetMachine(*MP->getModule(), FeaturesStr); + TheTarget->createTargetMachine(*MP->getModule(), TheTriple.getTriple(), + FeaturesStr); assert(Target && "Could not allocate target machine!"); return Target; } diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index 391c98656df..1cdaac0c2b1 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -71,6 +71,41 @@ const char *Triple::getOSTypeName(OSType Kind) { return ""; } +Triple::ArchType Triple::getArchTypeForLLVMName(const StringRef &Name) { + if (Name == "alpha") + return alpha; + if (Name == "arm") + return arm; + if (Name == "bfin") + return bfin; + if (Name == "cellspu") + return cellspu; + if (Name == "mips") + return mips; + if (Name == "mipsel") + return mipsel; + if (Name == "msp430") + return msp430; + if (Name == "ppc64") + return ppc64; + if (Name == "ppc") + return ppc; + if (Name == "sparc") + return sparc; + if (Name == "systemz") + return systemz; + if (Name == "thumb") + return thumb; + if (Name == "x86") + return x86; + if (Name == "x86_64") + return x86_64; + if (Name == "xcore") + return xcore; + + return UnknownArch; +} + // void Triple::Parse() const { diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 84f7c11e5d6..c014006f54c 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -24,6 +24,8 @@ #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" #include "llvm/InlineAsm.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/ConstantsScanner.h" #include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/LoopInfo.h" @@ -41,9 +43,7 @@ #include "llvm/Support/InstVisitor.h" #include "llvm/Support/Mangler.h" #include "llvm/Support/MathExtras.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/MathExtras.h" +#include "llvm/System/Host.h" #include "llvm/Config/config.h" #include #include @@ -3181,16 +3181,21 @@ std::string CWriter::InterpretASMConstraint(InlineAsm::ConstraintInfo& c) { // Grab the translation table from TargetAsmInfo if it exists. if (!TAsm) { + std::string Triple = TheModule->getTargetTriple(); + if (Triple.empty()) + Triple = llvm::sys::getHostTriple(); + std::string E; const Target *Match = - TargetRegistry::lookupTarget(TheModule->getTargetTriple(), - /*FallbackToHost=*/true, + TargetRegistry::lookupTarget(Triple, + /*FallbackToHost=*/false, /*RequireJIT=*/false, E); if (Match) { // Per platform Target Machines don't exist, so create it; // this must be done only once. - const TargetMachine* TM = Match->createTargetMachine(*TheModule, ""); + const TargetMachine* TM = Match->createTargetMachine(*TheModule, Triple, + ""); TAsm = TM->getTargetAsmInfo(); } } diff --git a/test/CodeGen/Mips/2008-08-08-bswap.ll b/test/CodeGen/Mips/2008-08-08-bswap.ll index 71c2b85d8df..1de9580bb36 100644 --- a/test/CodeGen/Mips/2008-08-08-bswap.ll +++ b/test/CodeGen/Mips/2008-08-08-bswap.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=mips | grep wsbw | count 1 +; RUN: llvm-as < %s | llc | grep wsbw | count 1 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" target triple = "psp" diff --git a/test/CodeGen/X86/fastcall-correct-mangling.ll b/test/CodeGen/X86/fastcall-correct-mangling.ll index d2db2795512..303fce5b89e 100644 --- a/test/CodeGen/X86/fastcall-correct-mangling.ll +++ b/test/CodeGen/X86/fastcall-correct-mangling.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 -mtriple=mingw32 | \ +; RUN: llvm-as < %s | llc -mtriple=i386-unknown-mingw32 | \ ; RUN: grep {@12} ; Check that a fastcall function gets correct mangling diff --git a/test/CodeGen/X86/memset-2.ll b/test/CodeGen/X86/memset-2.ll index 2ad665cda75..0011a7cd6f7 100644 --- a/test/CodeGen/X86/memset-2.ll +++ b/test/CodeGen/X86/memset-2.ll @@ -1,5 +1,7 @@ -; RUN: llvm-as < %s | llc -march=x86 | not grep rep -; RUN: llvm-as < %s | llc -march=x86 | grep memset +; RUN: llvm-as < %s | llc | not grep rep +; RUN: llvm-as < %s | llc | grep memset + +target triple = "i386" declare void @llvm.memset.i32(i8*, i8, i32, i32) nounwind diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 9f7f0a43f15..e3468575142 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -13,21 +13,20 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/CodeGen/FileWriters.h" -#include "llvm/CodeGen/LinkAllCodegenComponents.h" -#include "llvm/CodeGen/LinkAllAsmWriterComponents.h" -#include "llvm/CodeGen/ObjectCodeEmitter.h" -#include "llvm/Target/SubtargetFeature.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Transforms/Scalar.h" #include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" #include "llvm/PassManager.h" #include "llvm/Pass.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/CodeGen/FileWriters.h" +#include "llvm/CodeGen/LinkAllAsmWriterComponents.h" +#include "llvm/CodeGen/LinkAllCodegenComponents.h" +#include "llvm/CodeGen/ObjectCodeEmitter.h" +#include "llvm/Config/config.h" +#include "llvm/LinkAllVMCore.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Support/FormattedStream.h" @@ -35,11 +34,14 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Analysis/Verifier.h" +#include "llvm/System/Host.h" #include "llvm/System/Signals.h" -#include "llvm/Config/config.h" -#include "llvm/LinkAllVMCore.h" +#include "llvm/Target/SubtargetFeature.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegistry.h" #include "llvm/Target/TargetSelect.h" +#include "llvm/Transforms/Scalar.h" #include using namespace llvm; @@ -234,8 +236,13 @@ int main(int argc, char **argv) { if (!TargetTriple.empty()) mod.setTargetTriple(TargetTriple); - // Allocate target machine. First, check whether the user has - // explicitly specified an architecture to compile for. + Triple TheTriple(mod.getTargetTriple()); + if (TheTriple.getTriple().empty()) + TheTriple.setTriple(sys::getHostTriple()); + + // 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(), @@ -249,11 +256,17 @@ int main(int argc, char **argv) { 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(mod.getTargetTriple(), - /*FallbackToHost=*/true, + TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), + /*FallbackToHost=*/false, /*RequireJIT=*/false, Err); if (TheTarget == 0) { @@ -275,7 +288,8 @@ int main(int argc, char **argv) { } std::auto_ptr - target(TheTarget->createTargetMachine(mod, FeaturesStr)); + target(TheTarget->createTargetMachine(mod, TheTriple.getTriple(), + FeaturesStr)); assert(target.get() && "Could not allocate target machine!"); TargetMachine &Target = *target.get(); diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index a5023fb2f4f..ac7af13cb80 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -35,6 +35,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/StandardPasses.h" #include "llvm/Support/SystemUtils.h" +#include "llvm/System/Host.h" #include "llvm/System/Signals.h" #include "llvm/Target/SubtargetFeature.h" #include "llvm/Target/TargetOptions.h" @@ -326,11 +327,15 @@ bool LTOCodeGenerator::assemble(const std::string& asmPath, bool LTOCodeGenerator::determineTarget(std::string& errMsg) { if ( _target == NULL ) { + std::string Triple = _linker.getModule()->getTargetTriple(); + if (Triple.empty()) + Triple = sys::getHostTriple(); + // create target machine from info for merged modules Module* mergedModule = _linker.getModule(); const Target *march = - TargetRegistry::lookupTarget(mergedModule->getTargetTriple(), - /*FallbackToHost=*/true, + TargetRegistry::lookupTarget(Triple, + /*FallbackToHost=*/false, /*RequireJIT=*/false, errMsg); if ( march == NULL ) @@ -351,9 +356,8 @@ bool LTOCodeGenerator::determineTarget(std::string& errMsg) } // construct LTModule, hand over ownership of module and target - std::string FeatureStr = - getFeatureString(_linker.getModule()->getTargetTriple().c_str()); - _target = march->createTargetMachine(*mergedModule, FeatureStr.c_str()); + std::string FeatureStr = getFeatureString(Triple.c_str()); + _target = march->createTargetMachine(*mergedModule, Triple, FeatureStr); } return false; } diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index 4a2c5ad1dc3..9a8b155275f 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -24,6 +24,7 @@ #include "llvm/Support/Mangler.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MathExtras.h" +#include "llvm/System/Host.h" #include "llvm/System/Path.h" #include "llvm/System/Process.h" #include "llvm/Target/SubtargetFeature.h" @@ -149,17 +150,22 @@ LTOModule* LTOModule::makeLTOModule(MemoryBuffer* buffer, OwningPtr m(ParseBitcodeFile(buffer, getGlobalContext(), &errMsg)); if ( !m ) return NULL; + + std::string Triple = m->getTargetTriple(); + if (Triple.empty()) + Triple = sys::getHostTriple(); + // find machine architecture for this module - const Target* march = TargetRegistry::lookupTarget(m->getTargetTriple(), - /*FallbackToHost=*/true, + const Target* march = TargetRegistry::lookupTarget(Triple, + /*FallbackToHost=*/false, /*RequireJIT=*/false, errMsg); if ( march == NULL ) return NULL; // construct LTModule, hand over ownership of module and target - std::string FeatureStr = getFeatureString(m->getTargetTriple().c_str()); - TargetMachine* target = march->createTargetMachine(*m, FeatureStr); + std::string FeatureStr = getFeatureString(Triple.c_str()); + TargetMachine* target = march->createTargetMachine(*m, Triple, FeatureStr); return new LTOModule(m.take(), target); }