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