1//===----- JITTargetMachineBuilder.cpp - Build TargetMachines for JIT -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
10
11#include "llvm/Support/Host.h"
12#include "llvm/Support/TargetRegistry.h"
13#include "llvm/Support/raw_ostream.h"
14
15namespace llvm {
16namespace orc {
17
18JITTargetMachineBuilder::JITTargetMachineBuilder(Triple TT)
19    : TT(std::move(TT)) {
20  Options.EmulatedTLS = true;
21  Options.ExplicitEmulatedTLS = true;
22}
23
24Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() {
25  // FIXME: getProcessTriple is bogus. It returns the host LLVM was compiled on,
26  //        rather than a valid triple for the current process.
27  JITTargetMachineBuilder TMBuilder((Triple(sys::getProcessTriple())));
28
29  // Retrieve host CPU name and sub-target features and add them to builder.
30  // Relocation model, code model and codegen opt level are kept to default
31  // values.
32  llvm::StringMap<bool> FeatureMap;
33  llvm::sys::getHostCPUFeatures(FeatureMap);
34  for (auto &Feature : FeatureMap)
35    TMBuilder.getFeatures().AddFeature(Feature.first(), Feature.second);
36
37  TMBuilder.setCPU(std::string(llvm::sys::getHostCPUName()));
38
39  return TMBuilder;
40}
41
42Expected<std::unique_ptr<TargetMachine>>
43JITTargetMachineBuilder::createTargetMachine() {
44
45  std::string ErrMsg;
46  auto *TheTarget = TargetRegistry::lookupTarget(TT.getTriple(), ErrMsg);
47  if (!TheTarget)
48    return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
49
50  auto *TM =
51      TheTarget->createTargetMachine(TT.getTriple(), CPU, Features.getString(),
52                                     Options, RM, CM, OptLevel, /*JIT*/ true);
53  if (!TM)
54    return make_error<StringError>("Could not allocate target machine",
55                                   inconvertibleErrorCode());
56
57  return std::unique_ptr<TargetMachine>(TM);
58}
59
60JITTargetMachineBuilder &JITTargetMachineBuilder::addFeatures(
61    const std::vector<std::string> &FeatureVec) {
62  for (const auto &F : FeatureVec)
63    Features.AddFeature(F);
64  return *this;
65}
66
67#ifndef NDEBUG
68raw_ostream &operator<<(raw_ostream &OS, const JITTargetMachineBuilder &JTMB) {
69  OS << "{ Triple = \"" << JTMB.TT.str() << "\", CPU = \"" << JTMB.CPU
70     << "\", Options = <not-printable>, Relocation Model = ";
71
72  if (JTMB.RM) {
73    switch (*JTMB.RM) {
74    case Reloc::Static:
75      OS << "Static";
76      break;
77    case Reloc::PIC_:
78      OS << "PIC_";
79      break;
80    case Reloc::DynamicNoPIC:
81      OS << "DynamicNoPIC";
82      break;
83    case Reloc::ROPI:
84      OS << "ROPI";
85      break;
86    case Reloc::RWPI:
87      OS << "RWPI";
88      break;
89    case Reloc::ROPI_RWPI:
90      OS << "ROPI_RWPI";
91      break;
92    }
93  } else
94    OS << "unspecified";
95
96  OS << ", Code Model = ";
97
98  if (JTMB.CM) {
99    switch (*JTMB.CM) {
100    case CodeModel::Tiny:
101      OS << "Tiny";
102      break;
103    case CodeModel::Small:
104      OS << "Small";
105      break;
106    case CodeModel::Kernel:
107      OS << "Kernel";
108      break;
109    case CodeModel::Medium:
110      OS << "Medium";
111      break;
112    case CodeModel::Large:
113      OS << "Large";
114      break;
115    }
116  } else
117    OS << "unspecified";
118
119  OS << ", Optimization Level = ";
120  switch (JTMB.OptLevel) {
121  case CodeGenOpt::None:
122    OS << "None";
123    break;
124  case CodeGenOpt::Less:
125    OS << "Less";
126    break;
127  case CodeGenOpt::Default:
128    OS << "Default";
129    break;
130  case CodeGenOpt::Aggressive:
131    OS << "Aggressive";
132    break;
133  }
134
135  OS << " }";
136  return OS;
137}
138#endif // NDEBUG
139
140} // End namespace orc.
141} // End namespace llvm.
142