1//===-- llvm/Support/CodeGen.h - CodeGen Concepts ---------------*- 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// This file define some types which define code generation concepts. For
10// example, relocation model.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_SUPPORT_CODEGEN_H
15#define LLVM_SUPPORT_CODEGEN_H
16
17#include "llvm/ADT/StringRef.h"
18#include <cstdint>
19#include <optional>
20
21namespace llvm {
22
23 // Relocation model types.
24 namespace Reloc {
25 // Cannot be named PIC due to collision with -DPIC
26 enum Model { Static, PIC_, DynamicNoPIC, ROPI, RWPI, ROPI_RWPI };
27 }
28
29 // Code model types.
30 namespace CodeModel {
31 // Sync changes with CodeGenCWrappers.h.
32 enum Model { Tiny, Small, Kernel, Medium, Large };
33 }
34
35 namespace PICLevel {
36 // This is used to map -fpic/-fPIC.
37 enum Level { NotPIC=0, SmallPIC=1, BigPIC=2 };
38 }
39
40 namespace PIELevel {
41 enum Level { Default=0, Small=1, Large=2 };
42 }
43
44 // TLS models.
45 namespace TLSModel {
46 enum Model {
47 GeneralDynamic,
48 LocalDynamic,
49 InitialExec,
50 LocalExec
51 };
52 }
53
54 enum class ExceptionHandling : int {
55 Default, ///< Not specified; resolve to the target's default model
56 None, ///< No exception support
57 DwarfCFI, ///< DWARF-like instruction based exceptions
58 SjLj, ///< setjmp/longjmp based exceptions
59 ARM, ///< ARM EHABI
60 WinEH, ///< Windows Exception Handling
61 Wasm, ///< WebAssembly Exception Handling
62 Emscripten, ///< Emscripten JavaScript-based exception handling
63 AIX, ///< AIX Exception Handling
64 ZOS, ///< z/OS MVS Exception Handling. Very similar to DwarfCFI, but the
65 ///< PPA1 is used instead of an .eh_frame section.
66 };
67
68 /// Returns the "exception-model" module flag spelling for an
69 /// ExceptionHandling value. Default, AIX, and ZOS have no spelling and return
70 /// "".
71 inline StringRef getExceptionModelName(ExceptionHandling EH) {
72 switch (EH) {
73 case ExceptionHandling::None:
74 return "none";
75 case ExceptionHandling::DwarfCFI:
76 return "dwarf";
77 case ExceptionHandling::SjLj:
78 return "sjlj";
79 case ExceptionHandling::ARM:
80 return "arm";
81 case ExceptionHandling::WinEH:
82 return "wineh";
83 case ExceptionHandling::Wasm:
84 return "wasm";
85 case ExceptionHandling::Emscripten:
86 return "emscripten";
87 case ExceptionHandling::Default:
88 case ExceptionHandling::AIX:
89 case ExceptionHandling::ZOS:
90 break;
91 }
92 return "";
93 }
94
95 /// Parses the string spelling used by the "exception-model" IR module flag
96 /// into an ExceptionHandling value, returning std::nullopt if it does not
97 /// name a supported exception model.
98 inline std::optional<ExceptionHandling> parseExceptionModel(StringRef Name) {
99 if (Name == "none")
100 return ExceptionHandling::None;
101 if (Name == "dwarf")
102 return ExceptionHandling::DwarfCFI;
103 if (Name == "sjlj")
104 return ExceptionHandling::SjLj;
105 if (Name == "arm")
106 return ExceptionHandling::ARM;
107 if (Name == "wineh")
108 return ExceptionHandling::WinEH;
109 if (Name == "wasm")
110 return ExceptionHandling::Wasm;
111 if (Name == "emscripten")
112 return ExceptionHandling::Emscripten;
113 return std::nullopt;
114 }
115
116 /// The floating-point format used for the target's "long double" type.
117 enum class LongDoubleFormat {
118 IEEEsingle,
119 IEEEdouble,
120 X87DoubleExtended,
121 IEEEquad,
122 PPCDoubleDouble,
123 };
124
125 /// Returns the IR floating-point type name for a LongDoubleFormat.
126 inline StringRef getLongDoubleFormatName(LongDoubleFormat Format) {
127 switch (Format) {
128 case LongDoubleFormat::IEEEsingle:
129 return "float";
130 case LongDoubleFormat::IEEEdouble:
131 return "double";
132 case LongDoubleFormat::X87DoubleExtended:
133 return "x86_fp80";
134 case LongDoubleFormat::IEEEquad:
135 return "fp128";
136 case LongDoubleFormat::PPCDoubleDouble:
137 return "ppc_fp128";
138 }
139 return "";
140 }
141
142 /// Parses an IR floating-point type name into a LongDoubleFormat, returning
143 /// std::nullopt if it does not name a supported long double format.
144 inline std::optional<LongDoubleFormat> parseLongDoubleFormat(StringRef Name) {
145 if (Name == "float")
146 return LongDoubleFormat::IEEEsingle;
147 if (Name == "double")
148 return LongDoubleFormat::IEEEdouble;
149 if (Name == "x86_fp80")
150 return LongDoubleFormat::X87DoubleExtended;
151 if (Name == "fp128")
152 return LongDoubleFormat::IEEEquad;
153 if (Name == "ppc_fp128")
154 return LongDoubleFormat::PPCDoubleDouble;
155 return std::nullopt;
156 }
157
158 namespace FloatABI {
159 enum ABIType {
160 Default, // Target-specific (either soft or hard depending on triple, etc).
161 Soft, // Soft float.
162 Hard // Hard float.
163 };
164
165 /// Parse the string spelling used by the "float-abi" IR module flag into an
166 /// ABIType.
167 inline std::optional<ABIType> parseABIType(StringRef S) {
168 if (S == "soft")
169 return Soft;
170 if (S == "hard")
171 return Hard;
172 return std::nullopt;
173 }
174
175 /// Returns the string spelling used by the "float-abi" IR module flag for a
176 /// Soft or Hard ABIType. Default has no spelling.
177 inline StringRef getABITypeName(ABIType ABI) {
178 switch (ABI) {
179 case Soft:
180 return "soft";
181 case Hard:
182 return "hard";
183 case Default:
184 break;
185 }
186 return "";
187 }
188 } // namespace FloatABI
189
190 /// The threading model to assume for lowering, e.g. of atomics.
191 enum class ThreadModel {
192 POSIX, // POSIX Threads
193 Single, // Single Threaded Environment
194 };
195
196 /// Parse the string spelling used by the "thread-model" IR module flag into a
197 /// ThreadModel.
198 inline std::optional<ThreadModel> parseThreadModel(StringRef S) {
199 if (S == "posix")
200 return ThreadModel::POSIX;
201 if (S == "single")
202 return ThreadModel::Single;
203 return std::nullopt;
204 }
205
206 /// Returns the string spelling used by the "thread-model" IR module flag for
207 /// a ThreadModel.
208 inline StringRef getThreadModelName(ThreadModel TM) {
209 switch (TM) {
210 case ThreadModel::POSIX:
211 return "posix";
212 case ThreadModel::Single:
213 return "single";
214 }
215 return "";
216 }
217
218 enum class EABI {
219 Unknown,
220 Default, // Default means not specified
221 EABI4, // Target-specific (either 4, 5 or gnu depending on triple).
222 EABI5,
223 GNU
224 };
225
226 /// Code generation optimization level.
227 enum class CodeGenOptLevel {
228 None = 0, ///< -O0
229 Less = 1, ///< -O1
230 Default = 2, ///< -O2, -Os, -Oz
231 Aggressive = 3 ///< -O3
232 };
233
234 namespace CodeGenOpt {
235 /// Get the \c Level identified by the integer \p OL.
236 ///
237 /// Returns std::nullopt if \p OL is invalid.
238 inline std::optional<CodeGenOptLevel> getLevel(int OL) {
239 if (OL < 0 || OL > 3)
240 return std::nullopt;
241 return static_cast<CodeGenOptLevel>(OL);
242 }
243 /// Parse \p C as a single digit integer and get matching \c CodeGenLevel.
244 ///
245 /// Returns std::nullopt if the input is not a valid optimization level.
246 inline std::optional<CodeGenOptLevel> parseLevel(char C) {
247 if (C < '0')
248 return std::nullopt;
249 return getLevel(OL: static_cast<int>(C - '0'));
250 }
251 } // namespace CodeGenOpt
252
253 /// These enums are meant to be passed into addPassesToEmitFile to indicate
254 /// what type of file to emit, and returned by it to indicate what type of
255 /// file could actually be made.
256 enum class CodeGenFileType {
257 AssemblyFile,
258 ObjectFile,
259 Null // Do not emit any output.
260 };
261
262 // Specify what functions should keep the frame pointer.
263 enum class FramePointerKind {
264 None,
265 NonLeaf,
266 All,
267 Reserved,
268 NonLeafNoReserve
269 };
270
271 // Specify what type of zeroing callee-used registers.
272 namespace ZeroCallUsedRegs {
273 const unsigned ONLY_USED = 1U << 1;
274 const unsigned ONLY_GPR = 1U << 2;
275 const unsigned ONLY_ARG = 1U << 3;
276
277 enum class ZeroCallUsedRegsKind : unsigned int {
278 // Don't zero any call-used regs.
279 Skip = 1U << 0,
280 // Only zeros call-used GPRs used in the fn and pass args.
281 UsedGPRArg = ONLY_USED | ONLY_GPR | ONLY_ARG,
282 // Only zeros call-used GPRs used in the fn.
283 UsedGPR = ONLY_USED | ONLY_GPR,
284 // Only zeros call-used regs used in the fn and pass args.
285 UsedArg = ONLY_USED | ONLY_ARG,
286 // Only zeros call-used regs used in the fn.
287 Used = ONLY_USED,
288 // Zeros all call-used GPRs that pass args.
289 AllGPRArg = ONLY_GPR | ONLY_ARG,
290 // Zeros all call-used GPRs.
291 AllGPR = ONLY_GPR,
292 // Zeros all call-used regs that pass args.
293 AllArg = ONLY_ARG,
294 // Zeros all call-used regs.
295 All = 0,
296 };
297 } // namespace ZeroCallUsedRegs
298
299 enum class UWTableKind {
300 None = 0, ///< No unwind table requested
301 Sync = 1, ///< "Synchronous" unwind tables
302 Async = 2, ///< "Asynchronous" unwind tables (instr precise)
303 Default = 2,
304 };
305
306 enum class FunctionReturnThunksKind : unsigned int {
307 Keep = 0, ///< No function return thunk.
308 Extern = 1, ///< Replace returns with jump to thunk, don't emit thunk.
309 Invalid = 2, ///< Not used.
310 };
311
312 enum class WinX64EHUnwindMode {
313 Default = 4, // Toolchain default/auto.
314 // Using '4' to avoid renumbering the existing values.
315
316 V1 = 0, // V1 unwind info.
317 V2BestEffort = 1, // V2 where possible, fall back to V1.
318 V2Required = 2, // V2 required — error if a function cannot use V2.
319 V3 = 3, // V3 unwind info.
320 };
321
322 enum class ControlFlowGuardMode {
323 // Don't enable Control Flow Guard.
324 Disabled = 0,
325 // Emit the Control Flow Guard tables in the binary, but don't emit any
326 // checks.
327 TableOnly = 1,
328 // Enable Control Flow Guard checks and emit the tables.
329 Enabled = 2,
330 };
331
332 enum class ControlFlowGuardMechanism {
333 // Choose the mechanism automatically based on the target.
334 Automatic = 0,
335 Check = 1,
336 Dispatch = 2,
337 };
338
339 } // namespace llvm
340
341#endif
342