xref: /freebsd-src/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===----- JITTargetMachineBuilder.cpp - Build TargetMachines for JIT -----===//
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 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
100b57cec5SDimitry Andric 
11*0fca6ea1SDimitry Andric #include "llvm/ADT/StringMap.h"
12349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
135ffd83dbSDimitry Andric #include "llvm/Support/raw_ostream.h"
1406c3fb27SDimitry Andric #include "llvm/TargetParser/Host.h"
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric namespace llvm {
170b57cec5SDimitry Andric namespace orc {
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric JITTargetMachineBuilder::JITTargetMachineBuilder(Triple TT)
200b57cec5SDimitry Andric     : TT(std::move(TT)) {
210b57cec5SDimitry Andric   Options.EmulatedTLS = true;
2281ad6265SDimitry Andric   Options.UseInitArray = true;
230b57cec5SDimitry Andric }
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() {
268bcb0991SDimitry Andric   JITTargetMachineBuilder TMBuilder((Triple(sys::getProcessTriple())));
278bcb0991SDimitry Andric 
288bcb0991SDimitry Andric   // Retrieve host CPU name and sub-target features and add them to builder.
298bcb0991SDimitry Andric   // Relocation model, code model and codegen opt level are kept to default
308bcb0991SDimitry Andric   // values.
31*0fca6ea1SDimitry Andric   for (const auto &Feature : llvm::sys::getHostCPUFeatures())
32480093f4SDimitry Andric     TMBuilder.getFeatures().AddFeature(Feature.first(), Feature.second);
338bcb0991SDimitry Andric 
345ffd83dbSDimitry Andric   TMBuilder.setCPU(std::string(llvm::sys::getHostCPUName()));
358bcb0991SDimitry Andric 
368bcb0991SDimitry Andric   return TMBuilder;
370b57cec5SDimitry Andric }
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric Expected<std::unique_ptr<TargetMachine>>
400b57cec5SDimitry Andric JITTargetMachineBuilder::createTargetMachine() {
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   std::string ErrMsg;
430b57cec5SDimitry Andric   auto *TheTarget = TargetRegistry::lookupTarget(TT.getTriple(), ErrMsg);
440b57cec5SDimitry Andric   if (!TheTarget)
450b57cec5SDimitry Andric     return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
460b57cec5SDimitry Andric 
47fcaf7f86SDimitry Andric   if (!TheTarget->hasJIT())
48fcaf7f86SDimitry Andric     return make_error<StringError>("Target has no JIT support",
49fcaf7f86SDimitry Andric                                    inconvertibleErrorCode());
50fcaf7f86SDimitry Andric 
510b57cec5SDimitry Andric   auto *TM =
520b57cec5SDimitry Andric       TheTarget->createTargetMachine(TT.getTriple(), CPU, Features.getString(),
530b57cec5SDimitry Andric                                      Options, RM, CM, OptLevel, /*JIT*/ true);
540b57cec5SDimitry Andric   if (!TM)
550b57cec5SDimitry Andric     return make_error<StringError>("Could not allocate target machine",
560b57cec5SDimitry Andric                                    inconvertibleErrorCode());
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   return std::unique_ptr<TargetMachine>(TM);
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric JITTargetMachineBuilder &JITTargetMachineBuilder::addFeatures(
620b57cec5SDimitry Andric     const std::vector<std::string> &FeatureVec) {
630b57cec5SDimitry Andric   for (const auto &F : FeatureVec)
640b57cec5SDimitry Andric     Features.AddFeature(F);
650b57cec5SDimitry Andric   return *this;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
685ffd83dbSDimitry Andric #ifndef NDEBUG
69fe6060f1SDimitry Andric void JITTargetMachineBuilderPrinter::print(raw_ostream &OS) const {
70fe6060f1SDimitry Andric   OS << Indent << "{\n"
71fe6060f1SDimitry Andric      << Indent << "  Triple = \"" << JTMB.TT.str() << "\"\n"
72fe6060f1SDimitry Andric      << Indent << "  CPU = \"" << JTMB.CPU << "\"\n"
73fe6060f1SDimitry Andric      << Indent << "  Features = \"" << JTMB.Features.getString() << "\"\n"
74fe6060f1SDimitry Andric      << Indent << "  Options = <not-printable>\n"
75fe6060f1SDimitry Andric      << Indent << "  Relocation Model = ";
765ffd83dbSDimitry Andric 
775ffd83dbSDimitry Andric   if (JTMB.RM) {
785ffd83dbSDimitry Andric     switch (*JTMB.RM) {
795ffd83dbSDimitry Andric     case Reloc::Static:
805ffd83dbSDimitry Andric       OS << "Static";
815ffd83dbSDimitry Andric       break;
825ffd83dbSDimitry Andric     case Reloc::PIC_:
835ffd83dbSDimitry Andric       OS << "PIC_";
845ffd83dbSDimitry Andric       break;
855ffd83dbSDimitry Andric     case Reloc::DynamicNoPIC:
865ffd83dbSDimitry Andric       OS << "DynamicNoPIC";
875ffd83dbSDimitry Andric       break;
885ffd83dbSDimitry Andric     case Reloc::ROPI:
895ffd83dbSDimitry Andric       OS << "ROPI";
905ffd83dbSDimitry Andric       break;
915ffd83dbSDimitry Andric     case Reloc::RWPI:
925ffd83dbSDimitry Andric       OS << "RWPI";
935ffd83dbSDimitry Andric       break;
945ffd83dbSDimitry Andric     case Reloc::ROPI_RWPI:
955ffd83dbSDimitry Andric       OS << "ROPI_RWPI";
965ffd83dbSDimitry Andric       break;
975ffd83dbSDimitry Andric     }
985ffd83dbSDimitry Andric   } else
99fe6060f1SDimitry Andric     OS << "unspecified (will use target default)";
1005ffd83dbSDimitry Andric 
101fe6060f1SDimitry Andric   OS << "\n"
102fe6060f1SDimitry Andric      << Indent << "  Code Model = ";
1035ffd83dbSDimitry Andric 
1045ffd83dbSDimitry Andric   if (JTMB.CM) {
1055ffd83dbSDimitry Andric     switch (*JTMB.CM) {
1065ffd83dbSDimitry Andric     case CodeModel::Tiny:
1075ffd83dbSDimitry Andric       OS << "Tiny";
1085ffd83dbSDimitry Andric       break;
1095ffd83dbSDimitry Andric     case CodeModel::Small:
1105ffd83dbSDimitry Andric       OS << "Small";
1115ffd83dbSDimitry Andric       break;
1125ffd83dbSDimitry Andric     case CodeModel::Kernel:
1135ffd83dbSDimitry Andric       OS << "Kernel";
1145ffd83dbSDimitry Andric       break;
1155ffd83dbSDimitry Andric     case CodeModel::Medium:
1165ffd83dbSDimitry Andric       OS << "Medium";
1175ffd83dbSDimitry Andric       break;
1185ffd83dbSDimitry Andric     case CodeModel::Large:
1195ffd83dbSDimitry Andric       OS << "Large";
1205ffd83dbSDimitry Andric       break;
1215ffd83dbSDimitry Andric     }
1225ffd83dbSDimitry Andric   } else
123fe6060f1SDimitry Andric     OS << "unspecified (will use target default)";
1245ffd83dbSDimitry Andric 
125fe6060f1SDimitry Andric   OS << "\n"
126fe6060f1SDimitry Andric      << Indent << "  Optimization Level = ";
1275ffd83dbSDimitry Andric   switch (JTMB.OptLevel) {
1285f757f3fSDimitry Andric   case CodeGenOptLevel::None:
1295ffd83dbSDimitry Andric     OS << "None";
1305ffd83dbSDimitry Andric     break;
1315f757f3fSDimitry Andric   case CodeGenOptLevel::Less:
1325ffd83dbSDimitry Andric     OS << "Less";
1335ffd83dbSDimitry Andric     break;
1345f757f3fSDimitry Andric   case CodeGenOptLevel::Default:
1355ffd83dbSDimitry Andric     OS << "Default";
1365ffd83dbSDimitry Andric     break;
1375f757f3fSDimitry Andric   case CodeGenOptLevel::Aggressive:
1385ffd83dbSDimitry Andric     OS << "Aggressive";
1395ffd83dbSDimitry Andric     break;
1405ffd83dbSDimitry Andric   }
1415ffd83dbSDimitry Andric 
142fe6060f1SDimitry Andric   OS << "\n" << Indent << "}\n";
1435ffd83dbSDimitry Andric }
1445ffd83dbSDimitry Andric #endif // NDEBUG
1455ffd83dbSDimitry Andric 
1460b57cec5SDimitry Andric } // End namespace orc.
1470b57cec5SDimitry Andric } // End namespace llvm.
148