1 //===- JITTargetMachineBuilder.h - Build TargetMachines for JIT -*- C++ -*-===//
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 // A utitily for building TargetMachines for JITs.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_EXECUTIONENGINE_ORC_JITTARGETMACHINEBUILDER_H
14 #define LLVM_EXECUTIONENGINE_ORC_JITTARGETMACHINEBUILDER_H
15 
16 #include "llvm/Support/CodeGen.h"
17 #include "llvm/Support/Error.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "llvm/Target/TargetOptions.h"
20 #include "llvm/TargetParser/SubtargetFeature.h"
21 #include "llvm/TargetParser/Triple.h"
22 #include <memory>
23 #include <optional>
24 #include <string>
25 #include <vector>
26 
27 namespace llvm {
28 
29 class raw_ostream;
30 
31 namespace orc {
32 
33 /// A utility class for building TargetMachines for JITs.
34 class JITTargetMachineBuilder {
35 #ifndef NDEBUG
36   friend class JITTargetMachineBuilderPrinter;
37 #endif
38 public:
39   /// Create a JITTargetMachineBuilder based on the given triple.
40   ///
41   /// Note: TargetOptions is default-constructed, then EmulatedTLS is set to
42   /// true. If EmulatedTLS is not required, these values should be reset before
43   /// calling createTargetMachine.
44   JITTargetMachineBuilder(Triple TT);
45 
46   /// Create a JITTargetMachineBuilder for the host system.
47   ///
48   /// Note: TargetOptions is default-constructed, then EmulatedTLS is set to
49   /// true. If EmulatedTLS is not required, these values should be reset before
50   /// calling createTargetMachine.
51   static Expected<JITTargetMachineBuilder> detectHost();
52 
53   /// Create a TargetMachine.
54   ///
55   /// This operation will fail if the requested target is not registered,
56   /// in which case see llvm/Support/TargetSelect.h. To JIT IR the Target and
57   /// the target's AsmPrinter must both be registered. To JIT assembly
58   /// (including inline and module level assembly) the target's AsmParser must
59   /// also be registered.
60   Expected<std::unique_ptr<TargetMachine>> createTargetMachine();
61 
62   /// Get the default DataLayout for the target.
63   ///
64   /// Note: This is reasonably expensive, as it creates a temporary
65   /// TargetMachine instance under the hood. It is only suitable for use during
66   /// JIT setup.
67   Expected<DataLayout> getDefaultDataLayoutForTarget() {
68     auto TM = createTargetMachine();
69     if (!TM)
70       return TM.takeError();
71     return (*TM)->createDataLayout();
72   }
73 
74   /// Set the CPU string.
75   JITTargetMachineBuilder &setCPU(std::string CPU) {
76     this->CPU = std::move(CPU);
77     return *this;
78   }
79 
80   /// Returns the CPU string.
81   const std::string &getCPU() const { return CPU; }
82 
83   /// Set the relocation model.
84   JITTargetMachineBuilder &setRelocationModel(std::optional<Reloc::Model> RM) {
85     this->RM = std::move(RM);
86     return *this;
87   }
88 
89   /// Get the relocation model.
90   const std::optional<Reloc::Model> &getRelocationModel() const { return RM; }
91 
92   /// Set the code model.
93   JITTargetMachineBuilder &setCodeModel(std::optional<CodeModel::Model> CM) {
94     this->CM = std::move(CM);
95     return *this;
96   }
97 
98   /// Get the code model.
99   const std::optional<CodeModel::Model> &getCodeModel() const { return CM; }
100 
101   /// Set the LLVM CodeGen optimization level.
102   JITTargetMachineBuilder &setCodeGenOptLevel(CodeGenOpt::Level OptLevel) {
103     this->OptLevel = OptLevel;
104     return *this;
105   }
106 
107   /// Set subtarget features.
108   JITTargetMachineBuilder &setFeatures(StringRef FeatureString) {
109     Features = SubtargetFeatures(FeatureString);
110     return *this;
111   }
112 
113   /// Add subtarget features.
114   JITTargetMachineBuilder &
115   addFeatures(const std::vector<std::string> &FeatureVec);
116 
117   /// Access subtarget features.
118   SubtargetFeatures &getFeatures() { return Features; }
119 
120   /// Access subtarget features.
121   const SubtargetFeatures &getFeatures() const { return Features; }
122 
123   /// Set TargetOptions.
124   ///
125   /// Note: This operation will overwrite any previously configured options,
126   /// including EmulatedTLS and UseInitArray which the JITTargetMachineBuilder
127   /// sets by default. Clients are responsible for re-enabling these overwritten
128   /// options.
129   JITTargetMachineBuilder &setOptions(TargetOptions Options) {
130     this->Options = std::move(Options);
131     return *this;
132   }
133 
134   /// Access TargetOptions.
135   TargetOptions &getOptions() { return Options; }
136 
137   /// Access TargetOptions.
138   const TargetOptions &getOptions() const { return Options; }
139 
140   /// Access Triple.
141   Triple &getTargetTriple() { return TT; }
142 
143   /// Access Triple.
144   const Triple &getTargetTriple() const { return TT; }
145 
146 private:
147   Triple TT;
148   std::string CPU;
149   SubtargetFeatures Features;
150   TargetOptions Options;
151   std::optional<Reloc::Model> RM;
152   std::optional<CodeModel::Model> CM;
153   CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
154 };
155 
156 #ifndef NDEBUG
157 class JITTargetMachineBuilderPrinter {
158 public:
159   JITTargetMachineBuilderPrinter(JITTargetMachineBuilder &JTMB,
160                                  StringRef Indent)
161       : JTMB(JTMB), Indent(Indent) {}
162   void print(raw_ostream &OS) const;
163 
164   friend raw_ostream &operator<<(raw_ostream &OS,
165                                  const JITTargetMachineBuilderPrinter &JTMBP) {
166     JTMBP.print(OS);
167     return OS;
168   }
169 
170 private:
171   JITTargetMachineBuilder &JTMB;
172   StringRef Indent;
173 };
174 #endif // NDEBUG
175 
176 } // end namespace orc
177 } // end namespace llvm
178 
179 #endif // LLVM_EXECUTIONENGINE_ORC_JITTARGETMACHINEBUILDER_H
180