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 118bcb0991SDimitry Andric #include "llvm/Support/Host.h" 120b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h" 13*5ffd83dbSDimitry 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; 220b57cec5SDimitry Andric } 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() { 250b57cec5SDimitry Andric // FIXME: getProcessTriple is bogus. It returns the host LLVM was compiled on, 260b57cec5SDimitry Andric // rather than a valid triple for the current process. 278bcb0991SDimitry Andric JITTargetMachineBuilder TMBuilder((Triple(sys::getProcessTriple()))); 288bcb0991SDimitry Andric 298bcb0991SDimitry Andric // Retrieve host CPU name and sub-target features and add them to builder. 308bcb0991SDimitry Andric // Relocation model, code model and codegen opt level are kept to default 318bcb0991SDimitry Andric // values. 328bcb0991SDimitry Andric llvm::StringMap<bool> FeatureMap; 338bcb0991SDimitry Andric llvm::sys::getHostCPUFeatures(FeatureMap); 348bcb0991SDimitry Andric for (auto &Feature : FeatureMap) 35480093f4SDimitry Andric TMBuilder.getFeatures().AddFeature(Feature.first(), Feature.second); 368bcb0991SDimitry Andric 37*5ffd83dbSDimitry Andric TMBuilder.setCPU(std::string(llvm::sys::getHostCPUName())); 388bcb0991SDimitry Andric 398bcb0991SDimitry Andric return TMBuilder; 400b57cec5SDimitry Andric } 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric Expected<std::unique_ptr<TargetMachine>> 430b57cec5SDimitry Andric JITTargetMachineBuilder::createTargetMachine() { 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric std::string ErrMsg; 460b57cec5SDimitry Andric auto *TheTarget = TargetRegistry::lookupTarget(TT.getTriple(), ErrMsg); 470b57cec5SDimitry Andric if (!TheTarget) 480b57cec5SDimitry Andric return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()); 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric auto *TM = 510b57cec5SDimitry Andric TheTarget->createTargetMachine(TT.getTriple(), CPU, Features.getString(), 520b57cec5SDimitry Andric Options, RM, CM, OptLevel, /*JIT*/ true); 530b57cec5SDimitry Andric if (!TM) 540b57cec5SDimitry Andric return make_error<StringError>("Could not allocate target machine", 550b57cec5SDimitry Andric inconvertibleErrorCode()); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric return std::unique_ptr<TargetMachine>(TM); 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric JITTargetMachineBuilder &JITTargetMachineBuilder::addFeatures( 610b57cec5SDimitry Andric const std::vector<std::string> &FeatureVec) { 620b57cec5SDimitry Andric for (const auto &F : FeatureVec) 630b57cec5SDimitry Andric Features.AddFeature(F); 640b57cec5SDimitry Andric return *this; 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric 67*5ffd83dbSDimitry Andric #ifndef NDEBUG 68*5ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const JITTargetMachineBuilder &JTMB) { 69*5ffd83dbSDimitry Andric OS << "{ Triple = \"" << JTMB.TT.str() << "\", CPU = \"" << JTMB.CPU 70*5ffd83dbSDimitry Andric << "\", Options = <not-printable>, Relocation Model = "; 71*5ffd83dbSDimitry Andric 72*5ffd83dbSDimitry Andric if (JTMB.RM) { 73*5ffd83dbSDimitry Andric switch (*JTMB.RM) { 74*5ffd83dbSDimitry Andric case Reloc::Static: 75*5ffd83dbSDimitry Andric OS << "Static"; 76*5ffd83dbSDimitry Andric break; 77*5ffd83dbSDimitry Andric case Reloc::PIC_: 78*5ffd83dbSDimitry Andric OS << "PIC_"; 79*5ffd83dbSDimitry Andric break; 80*5ffd83dbSDimitry Andric case Reloc::DynamicNoPIC: 81*5ffd83dbSDimitry Andric OS << "DynamicNoPIC"; 82*5ffd83dbSDimitry Andric break; 83*5ffd83dbSDimitry Andric case Reloc::ROPI: 84*5ffd83dbSDimitry Andric OS << "ROPI"; 85*5ffd83dbSDimitry Andric break; 86*5ffd83dbSDimitry Andric case Reloc::RWPI: 87*5ffd83dbSDimitry Andric OS << "RWPI"; 88*5ffd83dbSDimitry Andric break; 89*5ffd83dbSDimitry Andric case Reloc::ROPI_RWPI: 90*5ffd83dbSDimitry Andric OS << "ROPI_RWPI"; 91*5ffd83dbSDimitry Andric break; 92*5ffd83dbSDimitry Andric } 93*5ffd83dbSDimitry Andric } else 94*5ffd83dbSDimitry Andric OS << "unspecified"; 95*5ffd83dbSDimitry Andric 96*5ffd83dbSDimitry Andric OS << ", Code Model = "; 97*5ffd83dbSDimitry Andric 98*5ffd83dbSDimitry Andric if (JTMB.CM) { 99*5ffd83dbSDimitry Andric switch (*JTMB.CM) { 100*5ffd83dbSDimitry Andric case CodeModel::Tiny: 101*5ffd83dbSDimitry Andric OS << "Tiny"; 102*5ffd83dbSDimitry Andric break; 103*5ffd83dbSDimitry Andric case CodeModel::Small: 104*5ffd83dbSDimitry Andric OS << "Small"; 105*5ffd83dbSDimitry Andric break; 106*5ffd83dbSDimitry Andric case CodeModel::Kernel: 107*5ffd83dbSDimitry Andric OS << "Kernel"; 108*5ffd83dbSDimitry Andric break; 109*5ffd83dbSDimitry Andric case CodeModel::Medium: 110*5ffd83dbSDimitry Andric OS << "Medium"; 111*5ffd83dbSDimitry Andric break; 112*5ffd83dbSDimitry Andric case CodeModel::Large: 113*5ffd83dbSDimitry Andric OS << "Large"; 114*5ffd83dbSDimitry Andric break; 115*5ffd83dbSDimitry Andric } 116*5ffd83dbSDimitry Andric } else 117*5ffd83dbSDimitry Andric OS << "unspecified"; 118*5ffd83dbSDimitry Andric 119*5ffd83dbSDimitry Andric OS << ", Optimization Level = "; 120*5ffd83dbSDimitry Andric switch (JTMB.OptLevel) { 121*5ffd83dbSDimitry Andric case CodeGenOpt::None: 122*5ffd83dbSDimitry Andric OS << "None"; 123*5ffd83dbSDimitry Andric break; 124*5ffd83dbSDimitry Andric case CodeGenOpt::Less: 125*5ffd83dbSDimitry Andric OS << "Less"; 126*5ffd83dbSDimitry Andric break; 127*5ffd83dbSDimitry Andric case CodeGenOpt::Default: 128*5ffd83dbSDimitry Andric OS << "Default"; 129*5ffd83dbSDimitry Andric break; 130*5ffd83dbSDimitry Andric case CodeGenOpt::Aggressive: 131*5ffd83dbSDimitry Andric OS << "Aggressive"; 132*5ffd83dbSDimitry Andric break; 133*5ffd83dbSDimitry Andric } 134*5ffd83dbSDimitry Andric 135*5ffd83dbSDimitry Andric OS << " }"; 136*5ffd83dbSDimitry Andric return OS; 137*5ffd83dbSDimitry Andric } 138*5ffd83dbSDimitry Andric #endif // NDEBUG 139*5ffd83dbSDimitry Andric 1400b57cec5SDimitry Andric } // End namespace orc. 1410b57cec5SDimitry Andric } // End namespace llvm. 142