xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp (revision fcaf7f8644a9988098ac6be2165bce3ea4786e91)
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 
11349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
128bcb0991SDimitry Andric #include "llvm/Support/Host.h"
135ffd83dbSDimitry Andric #include "llvm/Support/raw_ostream.h"
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric namespace llvm {
160b57cec5SDimitry Andric namespace orc {
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric JITTargetMachineBuilder::JITTargetMachineBuilder(Triple TT)
190b57cec5SDimitry Andric     : TT(std::move(TT)) {
200b57cec5SDimitry Andric   Options.EmulatedTLS = true;
210b57cec5SDimitry Andric   Options.ExplicitEmulatedTLS = true;
2281ad6265SDimitry Andric   Options.UseInitArray = true;
230b57cec5SDimitry Andric }
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() {
260b57cec5SDimitry Andric   // FIXME: getProcessTriple is bogus. It returns the host LLVM was compiled on,
270b57cec5SDimitry Andric   //        rather than a valid triple for the current process.
288bcb0991SDimitry Andric   JITTargetMachineBuilder TMBuilder((Triple(sys::getProcessTriple())));
298bcb0991SDimitry Andric 
308bcb0991SDimitry Andric   // Retrieve host CPU name and sub-target features and add them to builder.
318bcb0991SDimitry Andric   // Relocation model, code model and codegen opt level are kept to default
328bcb0991SDimitry Andric   // values.
338bcb0991SDimitry Andric   llvm::StringMap<bool> FeatureMap;
348bcb0991SDimitry Andric   llvm::sys::getHostCPUFeatures(FeatureMap);
358bcb0991SDimitry Andric   for (auto &Feature : FeatureMap)
36480093f4SDimitry Andric     TMBuilder.getFeatures().AddFeature(Feature.first(), Feature.second);
378bcb0991SDimitry Andric 
385ffd83dbSDimitry Andric   TMBuilder.setCPU(std::string(llvm::sys::getHostCPUName()));
398bcb0991SDimitry Andric 
408bcb0991SDimitry Andric   return TMBuilder;
410b57cec5SDimitry Andric }
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric Expected<std::unique_ptr<TargetMachine>>
440b57cec5SDimitry Andric JITTargetMachineBuilder::createTargetMachine() {
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric   std::string ErrMsg;
470b57cec5SDimitry Andric   auto *TheTarget = TargetRegistry::lookupTarget(TT.getTriple(), ErrMsg);
480b57cec5SDimitry Andric   if (!TheTarget)
490b57cec5SDimitry Andric     return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
500b57cec5SDimitry Andric 
51*fcaf7f86SDimitry Andric   if (!TheTarget->hasJIT())
52*fcaf7f86SDimitry Andric     return make_error<StringError>("Target has no JIT support",
53*fcaf7f86SDimitry Andric                                    inconvertibleErrorCode());
54*fcaf7f86SDimitry Andric 
550b57cec5SDimitry Andric   auto *TM =
560b57cec5SDimitry Andric       TheTarget->createTargetMachine(TT.getTriple(), CPU, Features.getString(),
570b57cec5SDimitry Andric                                      Options, RM, CM, OptLevel, /*JIT*/ true);
580b57cec5SDimitry Andric   if (!TM)
590b57cec5SDimitry Andric     return make_error<StringError>("Could not allocate target machine",
600b57cec5SDimitry Andric                                    inconvertibleErrorCode());
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   return std::unique_ptr<TargetMachine>(TM);
630b57cec5SDimitry Andric }
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric JITTargetMachineBuilder &JITTargetMachineBuilder::addFeatures(
660b57cec5SDimitry Andric     const std::vector<std::string> &FeatureVec) {
670b57cec5SDimitry Andric   for (const auto &F : FeatureVec)
680b57cec5SDimitry Andric     Features.AddFeature(F);
690b57cec5SDimitry Andric   return *this;
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric 
725ffd83dbSDimitry Andric #ifndef NDEBUG
73fe6060f1SDimitry Andric void JITTargetMachineBuilderPrinter::print(raw_ostream &OS) const {
74fe6060f1SDimitry Andric   OS << Indent << "{\n"
75fe6060f1SDimitry Andric      << Indent << "  Triple = \"" << JTMB.TT.str() << "\"\n"
76fe6060f1SDimitry Andric      << Indent << "  CPU = \"" << JTMB.CPU << "\"\n"
77fe6060f1SDimitry Andric      << Indent << "  Features = \"" << JTMB.Features.getString() << "\"\n"
78fe6060f1SDimitry Andric      << Indent << "  Options = <not-printable>\n"
79fe6060f1SDimitry Andric      << Indent << "  Relocation Model = ";
805ffd83dbSDimitry Andric 
815ffd83dbSDimitry Andric   if (JTMB.RM) {
825ffd83dbSDimitry Andric     switch (*JTMB.RM) {
835ffd83dbSDimitry Andric     case Reloc::Static:
845ffd83dbSDimitry Andric       OS << "Static";
855ffd83dbSDimitry Andric       break;
865ffd83dbSDimitry Andric     case Reloc::PIC_:
875ffd83dbSDimitry Andric       OS << "PIC_";
885ffd83dbSDimitry Andric       break;
895ffd83dbSDimitry Andric     case Reloc::DynamicNoPIC:
905ffd83dbSDimitry Andric       OS << "DynamicNoPIC";
915ffd83dbSDimitry Andric       break;
925ffd83dbSDimitry Andric     case Reloc::ROPI:
935ffd83dbSDimitry Andric       OS << "ROPI";
945ffd83dbSDimitry Andric       break;
955ffd83dbSDimitry Andric     case Reloc::RWPI:
965ffd83dbSDimitry Andric       OS << "RWPI";
975ffd83dbSDimitry Andric       break;
985ffd83dbSDimitry Andric     case Reloc::ROPI_RWPI:
995ffd83dbSDimitry Andric       OS << "ROPI_RWPI";
1005ffd83dbSDimitry Andric       break;
1015ffd83dbSDimitry Andric     }
1025ffd83dbSDimitry Andric   } else
103fe6060f1SDimitry Andric     OS << "unspecified (will use target default)";
1045ffd83dbSDimitry Andric 
105fe6060f1SDimitry Andric   OS << "\n"
106fe6060f1SDimitry Andric      << Indent << "  Code Model = ";
1075ffd83dbSDimitry Andric 
1085ffd83dbSDimitry Andric   if (JTMB.CM) {
1095ffd83dbSDimitry Andric     switch (*JTMB.CM) {
1105ffd83dbSDimitry Andric     case CodeModel::Tiny:
1115ffd83dbSDimitry Andric       OS << "Tiny";
1125ffd83dbSDimitry Andric       break;
1135ffd83dbSDimitry Andric     case CodeModel::Small:
1145ffd83dbSDimitry Andric       OS << "Small";
1155ffd83dbSDimitry Andric       break;
1165ffd83dbSDimitry Andric     case CodeModel::Kernel:
1175ffd83dbSDimitry Andric       OS << "Kernel";
1185ffd83dbSDimitry Andric       break;
1195ffd83dbSDimitry Andric     case CodeModel::Medium:
1205ffd83dbSDimitry Andric       OS << "Medium";
1215ffd83dbSDimitry Andric       break;
1225ffd83dbSDimitry Andric     case CodeModel::Large:
1235ffd83dbSDimitry Andric       OS << "Large";
1245ffd83dbSDimitry Andric       break;
1255ffd83dbSDimitry Andric     }
1265ffd83dbSDimitry Andric   } else
127fe6060f1SDimitry Andric     OS << "unspecified (will use target default)";
1285ffd83dbSDimitry Andric 
129fe6060f1SDimitry Andric   OS << "\n"
130fe6060f1SDimitry Andric      << Indent << "  Optimization Level = ";
1315ffd83dbSDimitry Andric   switch (JTMB.OptLevel) {
1325ffd83dbSDimitry Andric   case CodeGenOpt::None:
1335ffd83dbSDimitry Andric     OS << "None";
1345ffd83dbSDimitry Andric     break;
1355ffd83dbSDimitry Andric   case CodeGenOpt::Less:
1365ffd83dbSDimitry Andric     OS << "Less";
1375ffd83dbSDimitry Andric     break;
1385ffd83dbSDimitry Andric   case CodeGenOpt::Default:
1395ffd83dbSDimitry Andric     OS << "Default";
1405ffd83dbSDimitry Andric     break;
1415ffd83dbSDimitry Andric   case CodeGenOpt::Aggressive:
1425ffd83dbSDimitry Andric     OS << "Aggressive";
1435ffd83dbSDimitry Andric     break;
1445ffd83dbSDimitry Andric   }
1455ffd83dbSDimitry Andric 
146fe6060f1SDimitry Andric   OS << "\n" << Indent << "}\n";
1475ffd83dbSDimitry Andric }
1485ffd83dbSDimitry Andric #endif // NDEBUG
1495ffd83dbSDimitry Andric 
1500b57cec5SDimitry Andric } // End namespace orc.
1510b57cec5SDimitry Andric } // End namespace llvm.
152