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
JITTargetMachineBuilder(Triple TT)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
detectHost()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>>
createTargetMachine()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
addFeatures(const std::vector<std::string> & FeatureVec)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
print(raw_ostream & OS) const69fe6060f1SDimitry 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