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