1*9880d681SAndroid Build Coastguard Worker //===-- TargetSelect.cpp - Target Chooser Code ----------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This just asks the TargetRegistry for the appropriate target to use, and
11*9880d681SAndroid Build Coastguard Worker // allows the user to specify a specific one on the commandline with -march=x,
12*9880d681SAndroid Build Coastguard Worker // -mcpu=y, and -mattr=a,-b,+c. Clients should initialize targets prior to
13*9880d681SAndroid Build Coastguard Worker // calling selectTarget().
14*9880d681SAndroid Build Coastguard Worker //
15*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/ExecutionEngine.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/SubtargetFeature.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Host.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker using namespace llvm;
26*9880d681SAndroid Build Coastguard Worker
selectTarget()27*9880d681SAndroid Build Coastguard Worker TargetMachine *EngineBuilder::selectTarget() {
28*9880d681SAndroid Build Coastguard Worker Triple TT;
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker // MCJIT can generate code for remote targets, but the old JIT and Interpreter
31*9880d681SAndroid Build Coastguard Worker // must use the host architecture.
32*9880d681SAndroid Build Coastguard Worker if (WhichEngine != EngineKind::Interpreter && M)
33*9880d681SAndroid Build Coastguard Worker TT.setTriple(M->getTargetTriple());
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker return selectTarget(TT, MArch, MCPU, MAttrs);
36*9880d681SAndroid Build Coastguard Worker }
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker /// selectTarget - Pick a target either via -march or by guessing the native
39*9880d681SAndroid Build Coastguard Worker /// arch. Add any CPU features specified via -mcpu or -mattr.
selectTarget(const Triple & TargetTriple,StringRef MArch,StringRef MCPU,const SmallVectorImpl<std::string> & MAttrs)40*9880d681SAndroid Build Coastguard Worker TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
41*9880d681SAndroid Build Coastguard Worker StringRef MArch,
42*9880d681SAndroid Build Coastguard Worker StringRef MCPU,
43*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<std::string>& MAttrs) {
44*9880d681SAndroid Build Coastguard Worker Triple TheTriple(TargetTriple);
45*9880d681SAndroid Build Coastguard Worker if (TheTriple.getTriple().empty())
46*9880d681SAndroid Build Coastguard Worker TheTriple.setTriple(sys::getProcessTriple());
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker // Adjust the triple to match what the user requested.
49*9880d681SAndroid Build Coastguard Worker const Target *TheTarget = nullptr;
50*9880d681SAndroid Build Coastguard Worker if (!MArch.empty()) {
51*9880d681SAndroid Build Coastguard Worker auto I = std::find_if(
52*9880d681SAndroid Build Coastguard Worker TargetRegistry::targets().begin(), TargetRegistry::targets().end(),
53*9880d681SAndroid Build Coastguard Worker [&](const Target &T) { return MArch == T.getName(); });
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker if (I == TargetRegistry::targets().end()) {
56*9880d681SAndroid Build Coastguard Worker if (ErrorStr)
57*9880d681SAndroid Build Coastguard Worker *ErrorStr = "No available targets are compatible with this -march, "
58*9880d681SAndroid Build Coastguard Worker "see -version for the available targets.\n";
59*9880d681SAndroid Build Coastguard Worker return nullptr;
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker TheTarget = &*I;
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker // Adjust the triple to match (if known), otherwise stick with the
65*9880d681SAndroid Build Coastguard Worker // requested/host triple.
66*9880d681SAndroid Build Coastguard Worker Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
67*9880d681SAndroid Build Coastguard Worker if (Type != Triple::UnknownArch)
68*9880d681SAndroid Build Coastguard Worker TheTriple.setArch(Type);
69*9880d681SAndroid Build Coastguard Worker } else {
70*9880d681SAndroid Build Coastguard Worker std::string Error;
71*9880d681SAndroid Build Coastguard Worker TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error);
72*9880d681SAndroid Build Coastguard Worker if (!TheTarget) {
73*9880d681SAndroid Build Coastguard Worker if (ErrorStr)
74*9880d681SAndroid Build Coastguard Worker *ErrorStr = Error;
75*9880d681SAndroid Build Coastguard Worker return nullptr;
76*9880d681SAndroid Build Coastguard Worker }
77*9880d681SAndroid Build Coastguard Worker }
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker // Package up features to be passed to target/subtarget
80*9880d681SAndroid Build Coastguard Worker std::string FeaturesStr;
81*9880d681SAndroid Build Coastguard Worker if (!MAttrs.empty()) {
82*9880d681SAndroid Build Coastguard Worker SubtargetFeatures Features;
83*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i != MAttrs.size(); ++i)
84*9880d681SAndroid Build Coastguard Worker Features.AddFeature(MAttrs[i]);
85*9880d681SAndroid Build Coastguard Worker FeaturesStr = Features.getString();
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker // FIXME: non-iOS ARM FastISel is broken with MCJIT.
89*9880d681SAndroid Build Coastguard Worker if (TheTriple.getArch() == Triple::arm &&
90*9880d681SAndroid Build Coastguard Worker !TheTriple.isiOS() &&
91*9880d681SAndroid Build Coastguard Worker OptLevel == CodeGenOpt::None) {
92*9880d681SAndroid Build Coastguard Worker OptLevel = CodeGenOpt::Less;
93*9880d681SAndroid Build Coastguard Worker }
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker // Allocate a target...
96*9880d681SAndroid Build Coastguard Worker TargetMachine *Target = TheTarget->createTargetMachine(TheTriple.getTriple(),
97*9880d681SAndroid Build Coastguard Worker MCPU, FeaturesStr,
98*9880d681SAndroid Build Coastguard Worker Options,
99*9880d681SAndroid Build Coastguard Worker RelocModel, CMModel,
100*9880d681SAndroid Build Coastguard Worker OptLevel);
101*9880d681SAndroid Build Coastguard Worker assert(Target && "Could not allocate target machine!");
102*9880d681SAndroid Build Coastguard Worker return Target;
103*9880d681SAndroid Build Coastguard Worker }
104