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" 125ffd83dbSDimitry Andric #include "llvm/Support/raw_ostream.h" 1306c3fb27SDimitry Andric #include "llvm/TargetParser/Host.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; 2181ad6265SDimitry Andric Options.UseInitArray = true; 220b57cec5SDimitry Andric } 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() { 258bcb0991SDimitry Andric JITTargetMachineBuilder TMBuilder((Triple(sys::getProcessTriple()))); 268bcb0991SDimitry Andric 278bcb0991SDimitry Andric // Retrieve host CPU name and sub-target features and add them to builder. 288bcb0991SDimitry Andric // Relocation model, code model and codegen opt level are kept to default 298bcb0991SDimitry Andric // values. 308bcb0991SDimitry Andric llvm::StringMap<bool> FeatureMap; 318bcb0991SDimitry Andric llvm::sys::getHostCPUFeatures(FeatureMap); 328bcb0991SDimitry Andric for (auto &Feature : FeatureMap) 33480093f4SDimitry Andric TMBuilder.getFeatures().AddFeature(Feature.first(), Feature.second); 348bcb0991SDimitry Andric 355ffd83dbSDimitry Andric TMBuilder.setCPU(std::string(llvm::sys::getHostCPUName())); 368bcb0991SDimitry Andric 378bcb0991SDimitry Andric return TMBuilder; 380b57cec5SDimitry Andric } 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric Expected<std::unique_ptr<TargetMachine>> 410b57cec5SDimitry Andric JITTargetMachineBuilder::createTargetMachine() { 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric std::string ErrMsg; 440b57cec5SDimitry Andric auto *TheTarget = TargetRegistry::lookupTarget(TT.getTriple(), ErrMsg); 450b57cec5SDimitry Andric if (!TheTarget) 460b57cec5SDimitry Andric return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()); 470b57cec5SDimitry Andric 48fcaf7f86SDimitry Andric if (!TheTarget->hasJIT()) 49fcaf7f86SDimitry Andric return make_error<StringError>("Target has no JIT support", 50fcaf7f86SDimitry Andric inconvertibleErrorCode()); 51fcaf7f86SDimitry Andric 520b57cec5SDimitry Andric auto *TM = 530b57cec5SDimitry Andric TheTarget->createTargetMachine(TT.getTriple(), CPU, Features.getString(), 540b57cec5SDimitry Andric Options, RM, CM, OptLevel, /*JIT*/ true); 550b57cec5SDimitry Andric if (!TM) 560b57cec5SDimitry Andric return make_error<StringError>("Could not allocate target machine", 570b57cec5SDimitry Andric inconvertibleErrorCode()); 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric return std::unique_ptr<TargetMachine>(TM); 600b57cec5SDimitry Andric } 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric JITTargetMachineBuilder &JITTargetMachineBuilder::addFeatures( 630b57cec5SDimitry Andric const std::vector<std::string> &FeatureVec) { 640b57cec5SDimitry Andric for (const auto &F : FeatureVec) 650b57cec5SDimitry Andric Features.AddFeature(F); 660b57cec5SDimitry Andric return *this; 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric 695ffd83dbSDimitry Andric #ifndef NDEBUG 70fe6060f1SDimitry Andric void JITTargetMachineBuilderPrinter::print(raw_ostream &OS) const { 71fe6060f1SDimitry Andric OS << Indent << "{\n" 72fe6060f1SDimitry Andric << Indent << " Triple = \"" << JTMB.TT.str() << "\"\n" 73fe6060f1SDimitry Andric << Indent << " CPU = \"" << JTMB.CPU << "\"\n" 74fe6060f1SDimitry Andric << Indent << " Features = \"" << JTMB.Features.getString() << "\"\n" 75fe6060f1SDimitry Andric << Indent << " Options = <not-printable>\n" 76fe6060f1SDimitry Andric << Indent << " Relocation Model = "; 775ffd83dbSDimitry Andric 785ffd83dbSDimitry Andric if (JTMB.RM) { 795ffd83dbSDimitry Andric switch (*JTMB.RM) { 805ffd83dbSDimitry Andric case Reloc::Static: 815ffd83dbSDimitry Andric OS << "Static"; 825ffd83dbSDimitry Andric break; 835ffd83dbSDimitry Andric case Reloc::PIC_: 845ffd83dbSDimitry Andric OS << "PIC_"; 855ffd83dbSDimitry Andric break; 865ffd83dbSDimitry Andric case Reloc::DynamicNoPIC: 875ffd83dbSDimitry Andric OS << "DynamicNoPIC"; 885ffd83dbSDimitry Andric break; 895ffd83dbSDimitry Andric case Reloc::ROPI: 905ffd83dbSDimitry Andric OS << "ROPI"; 915ffd83dbSDimitry Andric break; 925ffd83dbSDimitry Andric case Reloc::RWPI: 935ffd83dbSDimitry Andric OS << "RWPI"; 945ffd83dbSDimitry Andric break; 955ffd83dbSDimitry Andric case Reloc::ROPI_RWPI: 965ffd83dbSDimitry Andric OS << "ROPI_RWPI"; 975ffd83dbSDimitry Andric break; 985ffd83dbSDimitry Andric } 995ffd83dbSDimitry Andric } else 100fe6060f1SDimitry Andric OS << "unspecified (will use target default)"; 1015ffd83dbSDimitry Andric 102fe6060f1SDimitry Andric OS << "\n" 103fe6060f1SDimitry Andric << Indent << " Code Model = "; 1045ffd83dbSDimitry Andric 1055ffd83dbSDimitry Andric if (JTMB.CM) { 1065ffd83dbSDimitry Andric switch (*JTMB.CM) { 1075ffd83dbSDimitry Andric case CodeModel::Tiny: 1085ffd83dbSDimitry Andric OS << "Tiny"; 1095ffd83dbSDimitry Andric break; 1105ffd83dbSDimitry Andric case CodeModel::Small: 1115ffd83dbSDimitry Andric OS << "Small"; 1125ffd83dbSDimitry Andric break; 1135ffd83dbSDimitry Andric case CodeModel::Kernel: 1145ffd83dbSDimitry Andric OS << "Kernel"; 1155ffd83dbSDimitry Andric break; 1165ffd83dbSDimitry Andric case CodeModel::Medium: 1175ffd83dbSDimitry Andric OS << "Medium"; 1185ffd83dbSDimitry Andric break; 1195ffd83dbSDimitry Andric case CodeModel::Large: 1205ffd83dbSDimitry Andric OS << "Large"; 1215ffd83dbSDimitry Andric break; 1225ffd83dbSDimitry Andric } 1235ffd83dbSDimitry Andric } else 124fe6060f1SDimitry Andric OS << "unspecified (will use target default)"; 1255ffd83dbSDimitry Andric 126fe6060f1SDimitry Andric OS << "\n" 127fe6060f1SDimitry Andric << Indent << " Optimization Level = "; 1285ffd83dbSDimitry Andric switch (JTMB.OptLevel) { 129*5f757f3fSDimitry Andric case CodeGenOptLevel::None: 1305ffd83dbSDimitry Andric OS << "None"; 1315ffd83dbSDimitry Andric break; 132*5f757f3fSDimitry Andric case CodeGenOptLevel::Less: 1335ffd83dbSDimitry Andric OS << "Less"; 1345ffd83dbSDimitry Andric break; 135*5f757f3fSDimitry Andric case CodeGenOptLevel::Default: 1365ffd83dbSDimitry Andric OS << "Default"; 1375ffd83dbSDimitry Andric break; 138*5f757f3fSDimitry Andric case CodeGenOptLevel::Aggressive: 1395ffd83dbSDimitry Andric OS << "Aggressive"; 1405ffd83dbSDimitry Andric break; 1415ffd83dbSDimitry Andric } 1425ffd83dbSDimitry Andric 143fe6060f1SDimitry Andric OS << "\n" << Indent << "}\n"; 1445ffd83dbSDimitry Andric } 1455ffd83dbSDimitry Andric #endif // NDEBUG 1465ffd83dbSDimitry Andric 1470b57cec5SDimitry Andric } // End namespace orc. 1480b57cec5SDimitry Andric } // End namespace llvm. 149