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