xref: /freebsd-src/contrib/llvm-project/llvm/lib/ExecutionEngine/TargetSelect.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric //===-- TargetSelect.cpp - Target Chooser Code ----------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This just asks the TargetRegistry for the appropriate target to use, and
100b57cec5SDimitry Andric // allows the user to specify a specific one on the commandline with -march=x,
110b57cec5SDimitry Andric // -mcpu=y, and -mattr=a,-b,+c. Clients should initialize targets prior to
120b57cec5SDimitry Andric // calling selectTarget().
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/ExecutionEngine/ExecutionEngine.h"
170b57cec5SDimitry Andric #include "llvm/IR/Module.h"
18349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
190b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
20*06c3fb27SDimitry Andric #include "llvm/TargetParser/Host.h"
21*06c3fb27SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
22*06c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric using namespace llvm;
250b57cec5SDimitry Andric 
selectTarget()260b57cec5SDimitry Andric TargetMachine *EngineBuilder::selectTarget() {
270b57cec5SDimitry Andric   Triple TT;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric   // MCJIT can generate code for remote targets, but the old JIT and Interpreter
300b57cec5SDimitry Andric   // must use the host architecture.
310b57cec5SDimitry Andric   if (WhichEngine != EngineKind::Interpreter && M)
320b57cec5SDimitry Andric     TT.setTriple(M->getTargetTriple());
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric   return selectTarget(TT, MArch, MCPU, MAttrs);
350b57cec5SDimitry Andric }
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric /// selectTarget - Pick a target either via -march or by guessing the native
380b57cec5SDimitry Andric /// arch.  Add any CPU features specified via -mcpu or -mattr.
selectTarget(const Triple & TargetTriple,StringRef MArch,StringRef MCPU,const SmallVectorImpl<std::string> & MAttrs)390b57cec5SDimitry Andric TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
400b57cec5SDimitry Andric                               StringRef MArch,
410b57cec5SDimitry Andric                               StringRef MCPU,
420b57cec5SDimitry Andric                               const SmallVectorImpl<std::string>& MAttrs) {
430b57cec5SDimitry Andric   Triple TheTriple(TargetTriple);
440b57cec5SDimitry Andric   if (TheTriple.getTriple().empty())
450b57cec5SDimitry Andric     TheTriple.setTriple(sys::getProcessTriple());
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric   // Adjust the triple to match what the user requested.
480b57cec5SDimitry Andric   const Target *TheTarget = nullptr;
490b57cec5SDimitry Andric   if (!MArch.empty()) {
500b57cec5SDimitry Andric     auto I = find_if(TargetRegistry::targets(),
510b57cec5SDimitry Andric                      [&](const Target &T) { return MArch == T.getName(); });
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric     if (I == TargetRegistry::targets().end()) {
540b57cec5SDimitry Andric       if (ErrorStr)
550b57cec5SDimitry Andric         *ErrorStr = "No available targets are compatible with this -march, "
560b57cec5SDimitry Andric                     "see -version for the available targets.\n";
570b57cec5SDimitry Andric       return nullptr;
580b57cec5SDimitry Andric     }
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric     TheTarget = &*I;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric     // Adjust the triple to match (if known), otherwise stick with the
630b57cec5SDimitry Andric     // requested/host triple.
640b57cec5SDimitry Andric     Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
650b57cec5SDimitry Andric     if (Type != Triple::UnknownArch)
660b57cec5SDimitry Andric       TheTriple.setArch(Type);
670b57cec5SDimitry Andric   } else {
680b57cec5SDimitry Andric     std::string Error;
690b57cec5SDimitry Andric     TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error);
700b57cec5SDimitry Andric     if (!TheTarget) {
710b57cec5SDimitry Andric       if (ErrorStr)
720b57cec5SDimitry Andric         *ErrorStr = Error;
730b57cec5SDimitry Andric       return nullptr;
740b57cec5SDimitry Andric     }
750b57cec5SDimitry Andric   }
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric   // Package up features to be passed to target/subtarget
780b57cec5SDimitry Andric   std::string FeaturesStr;
790b57cec5SDimitry Andric   if (!MAttrs.empty()) {
800b57cec5SDimitry Andric     SubtargetFeatures Features;
810b57cec5SDimitry Andric     for (unsigned i = 0; i != MAttrs.size(); ++i)
820b57cec5SDimitry Andric       Features.AddFeature(MAttrs[i]);
830b57cec5SDimitry Andric     FeaturesStr = Features.getString();
840b57cec5SDimitry Andric   }
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   // Allocate a target...
870b57cec5SDimitry Andric   TargetMachine *Target =
880b57cec5SDimitry Andric       TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr,
890b57cec5SDimitry Andric                                      Options, RelocModel, CMModel, OptLevel,
900b57cec5SDimitry Andric 				     /*JIT*/ true);
910b57cec5SDimitry Andric   Target->Options.EmulatedTLS = EmulatedTLS;
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   assert(Target && "Could not allocate target machine!");
940b57cec5SDimitry Andric   return Target;
950b57cec5SDimitry Andric }
96