1223013Sdim//===-- TargetSelect.cpp - Target Chooser Code ----------------------------===//
2223013Sdim//
3223013Sdim//                     The LLVM Compiler Infrastructure
4223013Sdim//
5223013Sdim// This file is distributed under the University of Illinois Open Source
6223013Sdim// License. See LICENSE.TXT for details.
7223013Sdim//
8223013Sdim//===----------------------------------------------------------------------===//
9223013Sdim//
10234353Sdim// This just asks the TargetRegistry for the appropriate target to use, and
11234353Sdim// allows the user to specify a specific one on the commandline with -march=x,
12234353Sdim// -mcpu=y, and -mattr=a,-b,+c. Clients should initialize targets prior to
13234353Sdim// calling selectTarget().
14223013Sdim//
15223013Sdim//===----------------------------------------------------------------------===//
16223013Sdim
17223013Sdim#include "llvm/ExecutionEngine/ExecutionEngine.h"
18223013Sdim#include "llvm/ADT/Triple.h"
19249423Sdim#include "llvm/IR/Module.h"
20224145Sdim#include "llvm/MC/SubtargetFeature.h"
21223013Sdim#include "llvm/Support/CommandLine.h"
22226633Sdim#include "llvm/Support/Host.h"
23226633Sdim#include "llvm/Support/TargetRegistry.h"
24249423Sdim#include "llvm/Target/TargetMachine.h"
25234353Sdim
26223013Sdimusing namespace llvm;
27223013Sdim
28234353SdimTargetMachine *EngineBuilder::selectTarget() {
29243830Sdim  Triple TT;
30243830Sdim
31243830Sdim  // MCJIT can generate code for remote targets, but the old JIT and Interpreter
32243830Sdim  // must use the host architecture.
33243830Sdim  if (UseMCJIT && WhichEngine != EngineKind::Interpreter && M)
34243830Sdim    TT.setTriple(M->getTargetTriple());
35249423Sdim
36234353Sdim  return selectTarget(TT, MArch, MCPU, MAttrs);
37234353Sdim}
38234353Sdim
39223013Sdim/// selectTarget - Pick a target either via -march or by guessing the native
40223013Sdim/// arch.  Add any CPU features specified via -mcpu or -mattr.
41234353SdimTargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
42223013Sdim                              StringRef MArch,
43223013Sdim                              StringRef MCPU,
44234353Sdim                              const SmallVectorImpl<std::string>& MAttrs) {
45234353Sdim  Triple TheTriple(TargetTriple);
46223013Sdim  if (TheTriple.getTriple().empty())
47249423Sdim    TheTriple.setTriple(sys::getProcessTriple());
48223013Sdim
49223013Sdim  // Adjust the triple to match what the user requested.
50223013Sdim  const Target *TheTarget = 0;
51223013Sdim  if (!MArch.empty()) {
52223013Sdim    for (TargetRegistry::iterator it = TargetRegistry::begin(),
53223013Sdim           ie = TargetRegistry::end(); it != ie; ++it) {
54223013Sdim      if (MArch == it->getName()) {
55223013Sdim        TheTarget = &*it;
56223013Sdim        break;
57223013Sdim      }
58223013Sdim    }
59223013Sdim
60223013Sdim    if (!TheTarget) {
61239462Sdim      if (ErrorStr)
62239462Sdim        *ErrorStr = "No available targets are compatible with this -march, "
63239462Sdim                    "see -version for the available targets.\n";
64223013Sdim      return 0;
65223013Sdim    }
66223013Sdim
67223013Sdim    // Adjust the triple to match (if known), otherwise stick with the
68234353Sdim    // requested/host triple.
69223013Sdim    Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
70223013Sdim    if (Type != Triple::UnknownArch)
71223013Sdim      TheTriple.setArch(Type);
72223013Sdim  } else {
73223013Sdim    std::string Error;
74223013Sdim    TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error);
75223013Sdim    if (TheTarget == 0) {
76223013Sdim      if (ErrorStr)
77223013Sdim        *ErrorStr = Error;
78223013Sdim      return 0;
79223013Sdim    }
80223013Sdim  }
81223013Sdim
82223013Sdim  // Package up features to be passed to target/subtarget
83223013Sdim  std::string FeaturesStr;
84224145Sdim  if (!MAttrs.empty()) {
85223013Sdim    SubtargetFeatures Features;
86223013Sdim    for (unsigned i = 0; i != MAttrs.size(); ++i)
87223013Sdim      Features.AddFeature(MAttrs[i]);
88223013Sdim    FeaturesStr = Features.getString();
89223013Sdim  }
90223013Sdim
91263508Sdim  // FIXME: non-iOS ARM FastISel is broken with MCJIT.
92263508Sdim  if (UseMCJIT &&
93263508Sdim      TheTriple.getArch() == Triple::arm &&
94263508Sdim      !TheTriple.isiOS() &&
95263508Sdim      OptLevel == CodeGenOpt::None) {
96263508Sdim    OptLevel = CodeGenOpt::Less;
97263508Sdim  }
98263508Sdim
99223013Sdim  // Allocate a target...
100226633Sdim  TargetMachine *Target = TheTarget->createTargetMachine(TheTriple.getTriple(),
101226633Sdim                                                         MCPU, FeaturesStr,
102234353Sdim                                                         Options,
103234353Sdim                                                         RelocModel, CMModel,
104234353Sdim                                                         OptLevel);
105223013Sdim  assert(Target && "Could not allocate target machine!");
106223013Sdim  return Target;
107223013Sdim}
108