LLVM API Documentation

TargetSelect.cpp
Go to the documentation of this file.
00001 //===-- TargetSelect.cpp - Target Chooser Code ----------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This just asks the TargetRegistry for the appropriate target to use, and
00011 // allows the user to specify a specific one on the commandline with -march=x,
00012 // -mcpu=y, and -mattr=a,-b,+c. Clients should initialize targets prior to
00013 // calling selectTarget().
00014 //
00015 //===----------------------------------------------------------------------===//
00016 
00017 #include "llvm/ExecutionEngine/ExecutionEngine.h"
00018 #include "llvm/ADT/Triple.h"
00019 #include "llvm/IR/Module.h"
00020 #include "llvm/MC/SubtargetFeature.h"
00021 #include "llvm/Support/CommandLine.h"
00022 #include "llvm/Support/Host.h"
00023 #include "llvm/Support/TargetRegistry.h"
00024 #include "llvm/Target/TargetMachine.h"
00025 
00026 using namespace llvm;
00027 
00028 TargetMachine *EngineBuilder::selectTarget() {
00029   Triple TT;
00030 
00031   // MCJIT can generate code for remote targets, but the old JIT and Interpreter
00032   // must use the host architecture.
00033   if (WhichEngine != EngineKind::Interpreter && M)
00034     TT.setTriple(M->getTargetTriple());
00035 
00036   return selectTarget(TT, MArch, MCPU, MAttrs);
00037 }
00038 
00039 /// selectTarget - Pick a target either via -march or by guessing the native
00040 /// arch.  Add any CPU features specified via -mcpu or -mattr.
00041 TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
00042                               StringRef MArch,
00043                               StringRef MCPU,
00044                               const SmallVectorImpl<std::string>& MAttrs) {
00045   Triple TheTriple(TargetTriple);
00046   if (TheTriple.getTriple().empty())
00047     TheTriple.setTriple(sys::getProcessTriple());
00048 
00049   // Adjust the triple to match what the user requested.
00050   const Target *TheTarget = nullptr;
00051   if (!MArch.empty()) {
00052     for (TargetRegistry::iterator it = TargetRegistry::begin(),
00053            ie = TargetRegistry::end(); it != ie; ++it) {
00054       if (MArch == it->getName()) {
00055         TheTarget = &*it;
00056         break;
00057       }
00058     }
00059 
00060     if (!TheTarget) {
00061       if (ErrorStr)
00062         *ErrorStr = "No available targets are compatible with this -march, "
00063                     "see -version for the available targets.\n";
00064       return nullptr;
00065     }
00066 
00067     // Adjust the triple to match (if known), otherwise stick with the
00068     // requested/host triple.
00069     Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
00070     if (Type != Triple::UnknownArch)
00071       TheTriple.setArch(Type);
00072   } else {
00073     std::string Error;
00074     TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error);
00075     if (!TheTarget) {
00076       if (ErrorStr)
00077         *ErrorStr = Error;
00078       return nullptr;
00079     }
00080   }
00081 
00082   // Package up features to be passed to target/subtarget
00083   std::string FeaturesStr;
00084   if (!MAttrs.empty()) {
00085     SubtargetFeatures Features;
00086     for (unsigned i = 0; i != MAttrs.size(); ++i)
00087       Features.AddFeature(MAttrs[i]);
00088     FeaturesStr = Features.getString();
00089   }
00090 
00091   // FIXME: non-iOS ARM FastISel is broken with MCJIT.
00092   if (TheTriple.getArch() == Triple::arm &&
00093       !TheTriple.isiOS() &&
00094       OptLevel == CodeGenOpt::None) {
00095     OptLevel = CodeGenOpt::Less;
00096   }
00097 
00098   // Allocate a target...
00099   TargetMachine *Target = TheTarget->createTargetMachine(TheTriple.getTriple(),
00100                                                          MCPU, FeaturesStr,
00101                                                          Options,
00102                                                          RelocModel, CMModel,
00103                                                          OptLevel);
00104   assert(Target && "Could not allocate target machine!");
00105   return Target;
00106 }