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