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