xref: /aosp_15_r20/external/llvm/lib/ExecutionEngine/TargetSelect.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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