Coverage Report

Created: 2025-08-29 06:29

/src/WasmEdge/lib/llvm/llvm.h
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: 2019-2024 Second State INC
3
#pragma once
4
5
#if defined(__GNUC__) || defined(__clang__)
6
#pragma GCC diagnostic push
7
#pragma GCC diagnostic ignored "-Wcpp"
8
#include <ciso646>
9
#pragma GCC diagnostic pop
10
#endif
11
12
#include "common/errcode.h"
13
#include "common/span.h"
14
#include <llvm-c/Analysis.h>
15
#include <llvm-c/Core.h>
16
#include <llvm-c/Error.h>
17
#include <llvm-c/Object.h>
18
#include <llvm-c/Orc.h>
19
#include <llvm-c/Target.h>
20
#include <llvm-c/TargetMachine.h>
21
#include <llvm-c/Types.h>
22
#include <mutex>
23
#include <string_view>
24
#include <utility>
25
#include <vector>
26
27
#if LLVM_VERSION_MAJOR >= 12
28
#include <llvm-c/LLJIT.h>
29
#endif
30
31
#if LLVM_VERSION_MAJOR < 12 && WASMEDGE_OS_WINDOWS
32
using LLVMOrcObjectLayerRef = struct LLVMOrcOpaqueObjectLayer *;
33
using LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction =
34
    LLVMOrcObjectLayerRef (*)(void *Ctx, LLVMOrcExecutionSessionRef ES,
35
                              const char *Triple) noexcept;
36
static void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(
37
    LLVMOrcLLJITBuilderRef Builder,
38
    LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F, void *Ctx) noexcept;
39
#endif
40
#if LLVM_VERSION_MAJOR < 13
41
using LLVMOrcMaterializationResponsibilityRef =
42
    struct LLVMOrcOpaqueMaterializationResponsibility *;
43
using LLVMOrcIRTransformLayerRef = struct LLVMOrcOpaqueIRTransformLayer *;
44
using LLVMOrcIRTransformLayerTransformFunction =
45
    LLVMErrorRef (*)(void *Ctx, LLVMOrcThreadSafeModuleRef *ModInOut,
46
                     LLVMOrcMaterializationResponsibilityRef MR) noexcept;
47
using LLVMOrcGenericIRModuleOperationFunction =
48
    LLVMErrorRef (*)(void *Ctx, LLVMModuleRef M) noexcept;
49
static LLVMOrcIRTransformLayerRef
50
LLVMOrcLLJITGetIRTransformLayer(LLVMOrcLLJITRef J) noexcept;
51
static void LLVMOrcIRTransformLayerSetTransform(
52
    LLVMOrcIRTransformLayerRef IRTransformLayer,
53
    LLVMOrcIRTransformLayerTransformFunction TransformFunction,
54
    void *Ctx) noexcept;
55
static LLVMErrorRef
56
LLVMOrcThreadSafeModuleWithModuleDo(LLVMOrcThreadSafeModuleRef TSM,
57
                                    LLVMOrcGenericIRModuleOperationFunction F,
58
                                    void *Ctx) noexcept;
59
#endif
60
61
#if LLVM_VERSION_MAJOR >= 13
62
#include <llvm-c/Transforms/PassBuilder.h>
63
#else
64
#include <llvm-c/Transforms/IPO.h>
65
#include <llvm-c/Transforms/PassManagerBuilder.h>
66
#include <llvm-c/Transforms/Scalar.h>
67
#endif
68
69
// Enable __x86_64__ for MSVC
70
#if defined(_M_X64) && !defined(__x86_64__)
71
#define __x86_64__ 1
72
#endif
73
74
namespace WasmEdge::LLVM {
75
76
class Core {
77
public:
78
1.96k
  static inline void init() noexcept { std::call_once(Once, initOnce); }
79
80
  static inline const unsigned int NotIntrinsic = 0;
81
  static inline unsigned int Ceil = 0;
82
  static inline unsigned int CopySign = 0;
83
  static inline unsigned int Ctlz = 0;
84
  static inline unsigned int Cttz = 0;
85
  static inline unsigned int Ctpop = 0;
86
  static inline unsigned int Expect = 0;
87
  static inline unsigned int ExperimentalConstrainedFAdd = 0;
88
  static inline unsigned int ExperimentalConstrainedFDiv = 0;
89
  static inline unsigned int ExperimentalConstrainedFMul = 0;
90
  static inline unsigned int ExperimentalConstrainedFPExt = 0;
91
  static inline unsigned int ExperimentalConstrainedFPTrunc = 0;
92
  static inline unsigned int ExperimentalConstrainedFSub = 0;
93
  static inline unsigned int Fabs = 0;
94
  static inline unsigned int Floor = 0;
95
  static inline unsigned int FShl = 0;
96
  static inline unsigned int FShr = 0;
97
  static inline unsigned int MaxNum = 0;
98
  static inline unsigned int MinNum = 0;
99
  static inline unsigned int Nearbyint = 0;
100
  static inline unsigned int Roundeven = 0;
101
  static inline unsigned int SAddSat = 0;
102
  static inline unsigned int Sqrt = 0;
103
  static inline unsigned int SSubSat = 0;
104
  static inline unsigned int Trunc = 0;
105
  static inline unsigned int UAddSat = 0;
106
  static inline unsigned int USubSat = 0;
107
  static inline unsigned int Bswap = 0;
108
#if defined(__x86_64__)
109
  static inline unsigned int X86SSE2PAvgB = 0;
110
  static inline unsigned int X86SSE2PAvgW = 0;
111
  static inline unsigned int X86SSE2PMAddWd = 0;
112
  static inline unsigned int X86SSE41RoundPd = 0;
113
  static inline unsigned int X86SSE41RoundPs = 0;
114
  static inline unsigned int X86SSE41RoundSd = 0;
115
  static inline unsigned int X86SSE41RoundSs = 0;
116
  static inline unsigned int X86SSSE3PMAddUbSw128 = 0;
117
  static inline unsigned int X86SSSE3PMulHrSw128 = 0;
118
  static inline unsigned int X86SSSE3PShufB128 = 0;
119
  static inline unsigned int X86XOpVPHAddBW = 0;
120
  static inline unsigned int X86XOpVPHAddUBW = 0;
121
  static inline unsigned int X86XOpVPHAddUWD = 0;
122
  static inline unsigned int X86XOpVPHAddWD = 0;
123
#endif
124
#if defined(__aarch64__)
125
  static inline unsigned int AArch64NeonFRIntN = 0;
126
  static inline unsigned int AArch64NeonSAddLP = 0;
127
  static inline unsigned int AArch64NeonSQRDMulH = 0;
128
  static inline unsigned int AArch64NeonTbl1 = 0;
129
  static inline unsigned int AArch64NeonUAddLP = 0;
130
  static inline unsigned int AArch64NeonURHAdd = 0;
131
#endif
132
#if defined(__s390x__)
133
  static inline unsigned int S390VPerm = 0;
134
#endif
135
136
  static inline unsigned int Cold = 0;
137
  static inline unsigned int NoAlias = 0;
138
  static inline unsigned int NoInline = 0;
139
  static inline unsigned int NoReturn = 0;
140
  static inline unsigned int ReadOnly = 0;
141
  static inline unsigned int StrictFP = 0;
142
  static inline unsigned int UWTable = 0;
143
#if LLVM_VERSION_MAJOR >= 15
144
  static constexpr inline const unsigned int UWTableDefault = 2;
145
#else
146
  static constexpr inline const unsigned int UWTableDefault = 0;
147
#endif
148
149
  static inline unsigned int InvariantGroup = 0;
150
151
private:
152
  static inline std::once_flag Once;
153
1
  static inline void initOnce() noexcept {
154
1
    using namespace std::literals;
155
1
#if LLVM_VERSION_MAJOR < 17
156
1
    LLVMInitializeCore(LLVMGetGlobalPassRegistry());
157
1
#endif
158
1
    LLVMInitializeNativeTarget();
159
1
    LLVMInitializeNativeAsmPrinter();
160
161
1
    Ceil = getIntrinsicID("llvm.ceil"sv);
162
1
    CopySign = getIntrinsicID("llvm.copysign"sv);
163
1
    Ctlz = getIntrinsicID("llvm.ctlz"sv);
164
1
    Cttz = getIntrinsicID("llvm.cttz"sv);
165
1
    Ctpop = getIntrinsicID("llvm.ctpop"sv);
166
1
    Expect = getIntrinsicID("llvm.expect");
167
1
    ExperimentalConstrainedFAdd =
168
1
        getIntrinsicID("llvm.experimental.constrained.fadd"sv);
169
1
    ExperimentalConstrainedFDiv =
170
1
        getIntrinsicID("llvm.experimental.constrained.fdiv"sv);
171
1
    ExperimentalConstrainedFMul =
172
1
        getIntrinsicID("llvm.experimental.constrained.fmul"sv);
173
1
    ExperimentalConstrainedFPExt =
174
1
        getIntrinsicID("llvm.experimental.constrained.fpext"sv);
175
1
    ExperimentalConstrainedFPTrunc =
176
1
        getIntrinsicID("llvm.experimental.constrained.fptrunc"sv);
177
1
    ExperimentalConstrainedFSub =
178
1
        getIntrinsicID("llvm.experimental.constrained.fsub"sv);
179
1
    Fabs = getIntrinsicID("llvm.fabs"sv);
180
1
    Floor = getIntrinsicID("llvm.floor"sv);
181
1
    FShl = getIntrinsicID("llvm.fshl"sv);
182
1
    FShr = getIntrinsicID("llvm.fshr"sv);
183
1
    MaxNum = getIntrinsicID("llvm.maxnum"sv);
184
1
    MinNum = getIntrinsicID("llvm.minnum"sv);
185
1
    Nearbyint = getIntrinsicID("llvm.nearbyint"sv);
186
1
    Roundeven = getIntrinsicID("llvm.roundeven"sv);
187
1
    SAddSat = getIntrinsicID("llvm.sadd.sat"sv);
188
1
    Sqrt = getIntrinsicID("llvm.sqrt"sv);
189
1
    SSubSat = getIntrinsicID("llvm.ssub.sat"sv);
190
1
    Trunc = getIntrinsicID("llvm.trunc"sv);
191
1
    UAddSat = getIntrinsicID("llvm.uadd.sat"sv);
192
1
    USubSat = getIntrinsicID("llvm.usub.sat"sv);
193
1
    Bswap = getIntrinsicID("llvm.bswap"sv);
194
195
1
#if defined(__x86_64__)
196
1
    X86SSE2PAvgB = getIntrinsicID("llvm.x86.sse2.pavg.b"sv);
197
1
    X86SSE2PAvgW = getIntrinsicID("llvm.x86.sse2.pavg.w"sv);
198
1
    X86SSE2PMAddWd = getIntrinsicID("llvm.x86.sse2.pmadd.wd"sv);
199
1
    X86SSE41RoundPd = getIntrinsicID("llvm.x86.sse41.round.pd"sv);
200
1
    X86SSE41RoundPs = getIntrinsicID("llvm.x86.sse41.round.ps"sv);
201
1
    X86SSE41RoundSd = getIntrinsicID("llvm.x86.sse41.round.sd"sv);
202
1
    X86SSE41RoundSs = getIntrinsicID("llvm.x86.sse41.round.ss"sv);
203
1
    X86SSSE3PMAddUbSw128 = getIntrinsicID("llvm.x86.ssse3.pmadd.ub.sw.128"sv);
204
1
    X86SSSE3PMulHrSw128 = getIntrinsicID("llvm.x86.ssse3.pmul.hr.sw.128"sv);
205
1
    X86SSSE3PShufB128 = getIntrinsicID("llvm.x86.ssse3.pshuf.b.128"sv);
206
1
    X86XOpVPHAddBW = getIntrinsicID("llvm.x86.xop.vphaddbw"sv);
207
1
    X86XOpVPHAddUBW = getIntrinsicID("llvm.x86.xop.vphaddubw"sv);
208
1
    X86XOpVPHAddUWD = getIntrinsicID("llvm.x86.xop.vphadduwd"sv);
209
1
    X86XOpVPHAddWD = getIntrinsicID("llvm.x86.xop.vphaddwd"sv);
210
1
#endif
211
#if defined(__aarch64__)
212
    AArch64NeonFRIntN = getIntrinsicID("llvm.aarch64.neon.frintn"sv);
213
    AArch64NeonSAddLP = getIntrinsicID("llvm.aarch64.neon.saddlp"sv);
214
    AArch64NeonSQRDMulH = getIntrinsicID("llvm.aarch64.neon.sqrdmulh"sv);
215
    AArch64NeonTbl1 = getIntrinsicID("llvm.aarch64.neon.tbl1"sv);
216
    AArch64NeonUAddLP = getIntrinsicID("llvm.aarch64.neon.uaddlp"sv);
217
    AArch64NeonURHAdd = getIntrinsicID("llvm.aarch64.neon.urhadd"sv);
218
#endif
219
#if defined(__s390x__)
220
    S390VPerm = getIntrinsicID("llvm.s390.vperm"sv);
221
#endif
222
223
1
    Cold = getEnumAttributeKind("cold"sv);
224
1
    NoAlias = getEnumAttributeKind("noalias"sv);
225
1
    NoInline = getEnumAttributeKind("noinline"sv);
226
1
    NoReturn = getEnumAttributeKind("noreturn"sv);
227
1
    ReadOnly = getEnumAttributeKind("readonly"sv);
228
1
    StrictFP = getEnumAttributeKind("strictfp"sv);
229
1
    UWTable = getEnumAttributeKind("uwtable"sv);
230
231
1
    InvariantGroup = getMetadataKind("invariant.group"sv);
232
1
  }
233
234
  template <typename... ArgsT>
235
  static unsigned int getIntrinsicID(std::string_view Name,
236
41
                                     ArgsT &&...Args) noexcept {
237
41
    const auto Value = LLVMLookupIntrinsicID(Name.data(), Name.size());
238
41
    if constexpr (sizeof...(Args) == 0) {
239
41
      return Value;
240
    } else {
241
      if (Value == NotIntrinsic) {
242
        return getIntrinsicID(std::forward<ArgsT>(Args)...);
243
      }
244
    }
245
41
  }
246
7
  static unsigned int getEnumAttributeKind(std::string_view Name) noexcept {
247
7
    return LLVMGetEnumAttributeKindForName(Name.data(), Name.size());
248
7
  }
249
1
  static unsigned int getMetadataKind(std::string_view Name) noexcept {
250
1
    return LLVMGetMDKindID(Name.data(), static_cast<unsigned int>(Name.size()));
251
1
  }
252
};
253
254
class Attribute;
255
class Message;
256
class Metadata;
257
class PassManager;
258
class Type;
259
class Value;
260
class Builder;
261
class BasicBlock;
262
263
class Context {
264
public:
265
5.88k
  constexpr Context(LLVMContextRef R) noexcept : Ref(R) {}
266
  Context(const Context &) = default;
267
  Context &operator=(const Context &) = default;
268
269
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
270
1.96k
  constexpr auto &unwrap() const noexcept { return Ref; }
271
173k
  constexpr auto &unwrap() noexcept { return Ref; }
272
0
  friend void swap(Context &LHS, Context &RHS) noexcept {
273
0
    using std::swap;
274
0
    swap(LHS.Ref, RHS.Ref);
275
0
  }
276
277
  inline Type getVoidTy() noexcept;
278
  inline Type getInt1Ty() noexcept;
279
  inline Type getInt8Ty() noexcept;
280
  inline Type getInt16Ty() noexcept;
281
  inline Type getInt32Ty() noexcept;
282
  inline Type getInt64Ty() noexcept;
283
  inline Type getInt128Ty() noexcept;
284
  inline Type getIntNTy(unsigned int NumBits) noexcept;
285
  inline Type getFloatTy() noexcept;
286
  inline Type getDoubleTy() noexcept;
287
288
  inline Value getFalse() noexcept;
289
  inline Value getTrue() noexcept;
290
  inline Value getInt8(uint8_t C) noexcept;
291
  inline Value getInt16(uint16_t C) noexcept;
292
  inline Value getInt32(uint32_t C) noexcept;
293
  inline Value getInt64(uint64_t C) noexcept;
294
  inline Value getFloat(float C) noexcept;
295
  inline Value getDouble(double C) noexcept;
296
297
private:
298
  LLVMContextRef Ref = nullptr;
299
};
300
301
class Module {
302
public:
303
  constexpr Module() noexcept = default;
304
0
  constexpr Module(LLVMModuleRef R) noexcept : Ref(R) {}
305
  Module(const Module &) = delete;
306
  Module &operator=(const Module &) = delete;
307
0
  Module(Module &&M) noexcept : Module() { swap(*this, M); }
308
0
  Module &operator=(Module &&M) noexcept {
309
0
    swap(*this, M);
310
0
    return *this;
311
0
  }
312
313
  Module(const Context &C, const char *Name) noexcept
314
1.96k
      : Ref(LLVMModuleCreateWithNameInContext(Name, C.unwrap())) {}
315
1.96k
  ~Module() noexcept { LLVMDisposeModule(Ref); }
316
317
1.96k
  const char *getTarget() noexcept { return LLVMGetTarget(Ref); }
318
1.96k
  void setTarget(const char *Triple) noexcept { LLVMSetTarget(Ref, Triple); }
319
  inline Value addFunction(Type Ty, LLVMLinkage Linkage,
320
                           const char *Name = "") noexcept;
321
  inline Value addGlobal(Type Ty, bool IsConstant, LLVMLinkage Linkage,
322
                         Value Initializer, const char *Name = "") noexcept;
323
  inline Value getNamedGlobal(const char *Name) noexcept;
324
  inline Value addAlias(Type Ty, Value V, const char *Name,
325
                        unsigned int AddrSpace = 0) noexcept;
326
  inline void addFlag(LLVMModuleFlagBehavior Behavior, std::string_view Key,
327
                      const Metadata &Val) noexcept;
328
  inline void addFlag(LLVMModuleFlagBehavior Behavior, std::string_view Key,
329
                      const Value &Val) noexcept;
330
  inline void addFlag(LLVMModuleFlagBehavior Behavior, std::string_view Key,
331
                      uint32_t Val) noexcept;
332
  inline Value getFirstGlobal() noexcept;
333
  inline Value getFirstFunction() noexcept;
334
  inline Value getNamedFunction(const char *Name) noexcept;
335
  inline Message printModuleToFile(const char *File) noexcept;
336
  inline Message verify(LLVMVerifierFailureAction Action) noexcept;
337
338
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
339
0
  constexpr auto &unwrap() const noexcept { return Ref; }
340
5.88k
  constexpr auto &unwrap() noexcept { return Ref; }
341
0
  LLVMModuleRef release() noexcept { return std::exchange(Ref, nullptr); }
342
0
  friend void swap(Module &LHS, Module &RHS) noexcept {
343
0
    using std::swap;
344
0
    swap(LHS.Ref, RHS.Ref);
345
0
  }
346
347
private:
348
  LLVMModuleRef Ref = nullptr;
349
};
350
351
class ErrorMessage {
352
public:
353
  constexpr ErrorMessage() noexcept = default;
354
0
  constexpr ErrorMessage(char *M) noexcept : Data(M) {}
355
  ErrorMessage(const ErrorMessage &) = delete;
356
  ErrorMessage &operator=(const ErrorMessage &) = delete;
357
0
  ErrorMessage(ErrorMessage &&M) noexcept : ErrorMessage() { swap(*this, M); }
358
0
  ErrorMessage &operator=(ErrorMessage &&M) noexcept {
359
0
    swap(*this, M);
360
0
    return *this;
361
0
  }
362
363
0
  ~ErrorMessage() noexcept { LLVMDisposeErrorMessage(Data); }
364
365
0
  constexpr operator bool() const noexcept { return Data != nullptr; }
366
0
  constexpr auto &unwrap() const noexcept { return Data; }
367
0
  constexpr auto &unwrap() noexcept { return Data; }
368
0
  friend void swap(ErrorMessage &LHS, ErrorMessage &RHS) noexcept {
369
0
    using std::swap;
370
0
    swap(LHS.Data, RHS.Data);
371
0
  }
372
373
0
  std::string_view string_view() const noexcept { return Data; }
374
375
private:
376
  char *Data = nullptr;
377
};
378
379
class Error {
380
public:
381
  constexpr Error() noexcept = default;
382
0
  constexpr Error(LLVMErrorRef R) noexcept : Ref(R) {}
383
  Error(const Error &) = delete;
384
  Error &operator=(const Error &) = delete;
385
0
  Error(Error &&E) noexcept : Error() { swap(*this, E); }
386
0
  Error &operator=(Error &&E) noexcept {
387
0
    swap(*this, E);
388
0
    return *this;
389
0
  }
390
391
0
  ~Error() noexcept { LLVMConsumeError(Ref); }
392
393
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
394
0
  constexpr auto &unwrap() const noexcept { return Ref; }
395
0
  constexpr auto &unwrap() noexcept { return Ref; }
396
0
  LLVMErrorRef release() noexcept { return std::exchange(Ref, nullptr); }
397
0
  friend void swap(Error &LHS, Error &RHS) noexcept {
398
0
    using std::swap;
399
0
    swap(LHS.Ref, RHS.Ref);
400
0
  }
401
402
0
  ErrorMessage message() noexcept {
403
0
    return LLVMGetErrorMessage(std::exchange(Ref, nullptr));
404
0
  }
405
406
private:
407
  LLVMErrorRef Ref = nullptr;
408
};
409
410
class Message {
411
public:
412
11.7k
  constexpr Message() noexcept = default;
413
7.84k
  constexpr Message(char *M) noexcept : Data(M) {}
414
  Message(const Message &) = delete;
415
  Message &operator=(const Message &) = delete;
416
0
  Message(Message &&M) noexcept : Message() { swap(*this, M); }
417
1.96k
  Message &operator=(Message &&M) noexcept {
418
1.96k
    swap(*this, M);
419
1.96k
    return *this;
420
1.96k
  }
421
422
19.6k
  ~Message() noexcept { LLVMDisposeMessage(Data); }
423
424
7.84k
  constexpr operator bool() const noexcept { return Data != nullptr; }
425
0
  constexpr auto &unwrap() const noexcept { return Data; }
426
13.7k
  constexpr auto &unwrap() noexcept { return Data; }
427
1.96k
  friend void swap(Message &LHS, Message &RHS) noexcept {
428
1.96k
    using std::swap;
429
1.96k
    swap(LHS.Data, RHS.Data);
430
1.96k
  }
431
432
3.92k
  std::string_view string_view() const noexcept { return Data; }
433
434
private:
435
  char *Data = nullptr;
436
};
437
438
class MemoryBuffer {
439
public:
440
5.88k
  constexpr MemoryBuffer() noexcept = default;
441
0
  constexpr MemoryBuffer(LLVMMemoryBufferRef R) noexcept : Ref(R) {}
442
  MemoryBuffer(const MemoryBuffer &) = delete;
443
  MemoryBuffer &operator=(const MemoryBuffer &) = delete;
444
0
  MemoryBuffer(MemoryBuffer &&M) noexcept : MemoryBuffer() { swap(*this, M); }
445
1.96k
  MemoryBuffer &operator=(MemoryBuffer &&M) noexcept {
446
1.96k
    swap(*this, M);
447
1.96k
    return *this;
448
1.96k
  }
449
450
5.88k
  ~MemoryBuffer() noexcept { LLVMDisposeMemoryBuffer(Ref); }
451
452
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
453
0
  constexpr auto &unwrap() const noexcept { return Ref; }
454
5.88k
  constexpr auto &unwrap() noexcept { return Ref; }
455
1.96k
  friend void swap(MemoryBuffer &LHS, MemoryBuffer &RHS) noexcept {
456
1.96k
    using std::swap;
457
1.96k
    swap(LHS.Ref, RHS.Ref);
458
1.96k
  }
459
460
1.96k
  static std::pair<MemoryBuffer, Message> getFile(const char *Path) noexcept {
461
1.96k
    std::pair<MemoryBuffer, Message> Result;
462
1.96k
    LLVMCreateMemoryBufferWithContentsOfFile(Path, &Result.first.unwrap(),
463
1.96k
                                             &Result.second.unwrap());
464
1.96k
    return Result;
465
1.96k
  }
466
3.92k
  const char *data() const noexcept { return LLVMGetBufferStart(Ref); }
467
3.92k
  size_t size() const noexcept { return LLVMGetBufferSize(Ref); }
468
469
private:
470
  LLVMMemoryBufferRef Ref = nullptr;
471
};
472
473
class Type {
474
public:
475
3.61M
  constexpr Type() = default;
476
11.0M
  constexpr Type(LLVMTypeRef R) noexcept : Ref(R) {}
477
  constexpr Type(const Type &) = default;
478
  constexpr Type &operator=(const Type &) = default;
479
3.50M
  Type(Type &&T) noexcept : Type() { swap(*this, T); }
480
101k
  Type &operator=(Type &&T) noexcept {
481
101k
    swap(*this, T);
482
101k
    return *this;
483
101k
  }
484
485
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
486
0
  constexpr auto &unwrap() const noexcept { return Ref; }
487
11.6M
  constexpr auto &unwrap() noexcept { return Ref; }
488
3.60M
  friend void swap(Type &LHS, Type &RHS) noexcept {
489
3.60M
    using std::swap;
490
3.60M
    swap(LHS.Ref, RHS.Ref);
491
3.60M
  }
492
493
  static Type getFunctionType(Type ReturnType, Span<const Type> ParamTypes,
494
23.7k
                              bool IsVarArg = false) noexcept {
495
23.7k
    const auto Data = const_cast<LLVMTypeRef *>(
496
23.7k
        reinterpret_cast<const LLVMTypeRef *>(ParamTypes.data()));
497
23.7k
    const auto Size = static_cast<unsigned int>(ParamTypes.size());
498
23.7k
    return LLVMFunctionType(ReturnType.unwrap(), Data, Size, IsVarArg);
499
23.7k
  }
500
  static Type getPointerType(Type ElementType,
501
0
                             unsigned int AddressSpace = 0) noexcept {
502
0
    return LLVMPointerType(ElementType.unwrap(), AddressSpace);
503
0
  }
504
  static Type getArrayType(Type ElementType,
505
4.76k
                           unsigned int ElementCount) noexcept {
506
4.76k
    return LLVMArrayType(ElementType.unwrap(), ElementCount);
507
4.76k
  }
508
  static Type getVectorType(Type ElementType,
509
3.91M
                            unsigned int ElementCount) noexcept {
510
3.91M
    return LLVMVectorType(ElementType.unwrap(), ElementCount);
511
3.91M
  }
512
  static Type getStructType(Span<const Type> ElementTypes,
513
596
                            bool Packed = false) noexcept {
514
596
    const auto Data = const_cast<LLVMTypeRef *>(
515
596
        reinterpret_cast<const LLVMTypeRef *>(ElementTypes.data()));
516
596
    const auto Size = static_cast<unsigned int>(ElementTypes.size());
517
596
    assuming(Size >= 1);
518
596
    return LLVMStructTypeInContext(LLVMGetTypeContext(Data[0]), Data, Size,
519
596
                                   Packed);
520
596
  }
521
  static Type getStructType(const char *Name, Span<const Type> ElementTypes,
522
1.96k
                            bool Packed = false) noexcept {
523
1.96k
    const auto Data = const_cast<LLVMTypeRef *>(
524
1.96k
        reinterpret_cast<const LLVMTypeRef *>(ElementTypes.data()));
525
1.96k
    const auto Size = static_cast<unsigned int>(ElementTypes.size());
526
1.96k
    assuming(Size >= 1);
527
1.96k
    Type Ty = LLVMStructCreateNamed(LLVMGetTypeContext(Data[0]), Name);
528
1.96k
    LLVMStructSetBody(Ty.unwrap(), Data, Size, Packed);
529
1.96k
    return Ty;
530
1.96k
  }
531
532
17.9k
  bool isVoidTy() const noexcept {
533
17.9k
    return LLVMGetTypeKind(Ref) == LLVMVoidTypeKind;
534
17.9k
  }
535
43.8k
  bool isFloatTy() const noexcept {
536
43.8k
    return LLVMGetTypeKind(Ref) == LLVMFloatTypeKind;
537
43.8k
  }
538
19.3k
  bool isDoubleTy() const noexcept {
539
19.3k
    return LLVMGetTypeKind(Ref) == LLVMDoubleTypeKind;
540
19.3k
  }
541
3.32k
  bool isIntegerTy() const noexcept {
542
3.32k
    return LLVMGetTypeKind(Ref) == LLVMIntegerTypeKind;
543
3.32k
  }
544
12.2k
  bool isStructTy() const noexcept {
545
12.2k
    return LLVMGetTypeKind(Ref) == LLVMStructTypeKind;
546
12.2k
  }
547
0
  bool isVectorTy() const noexcept {
548
0
    return LLVMGetTypeKind(Ref) == LLVMVectorTypeKind;
549
0
  }
550
551
3.32k
  unsigned int getPrimitiveSizeInBits() const noexcept {
552
3.32k
    switch (LLVMGetTypeKind(Ref)) {
553
0
    case LLVMBFloatTypeKind:
554
0
      return 16;
555
0
    case LLVMHalfTypeKind:
556
0
      return 16;
557
0
    case LLVMFloatTypeKind:
558
0
      return 32;
559
0
    case LLVMDoubleTypeKind:
560
0
      return 64;
561
0
    case LLVMX86_FP80TypeKind:
562
0
      return 80;
563
0
    case LLVMFP128TypeKind:
564
0
      return 128;
565
0
    case LLVMPPC_FP128TypeKind:
566
0
      return 128;
567
0
#if LLVM_VERSION_MAJOR < 20
568
0
    case LLVMX86_MMXTypeKind:
569
0
      return 64;
570
0
#endif
571
3.32k
    case LLVMIntegerTypeKind:
572
3.32k
      return getIntegerBitWidth();
573
0
    case LLVMVectorTypeKind:
574
0
      return getElementType().getPrimitiveSizeInBits() * getVectorSize();
575
0
    default:
576
0
      return 0;
577
3.32k
    }
578
3.32k
  }
579
7.88k
  unsigned int getFPMantissaWidth() const noexcept {
580
7.88k
    switch (LLVMGetTypeKind(Ref)) {
581
0
    case LLVMBFloatTypeKind:
582
0
      return 8;
583
0
    case LLVMHalfTypeKind:
584
0
      return 11;
585
3.52k
    case LLVMFloatTypeKind:
586
3.52k
      return 24;
587
4.36k
    case LLVMDoubleTypeKind:
588
4.36k
      return 53;
589
0
    case LLVMX86_FP80TypeKind:
590
0
      return 64;
591
0
    case LLVMFP128TypeKind:
592
0
      return 113;
593
0
    default:
594
0
      return 0;
595
7.88k
    }
596
7.88k
  }
597
598
75.4k
  Type getElementType() const noexcept { return LLVMGetElementType(Ref); }
599
29.1k
  unsigned int getIntegerBitWidth() const noexcept {
600
29.1k
    return LLVMGetIntTypeWidth(Ref);
601
29.1k
  }
602
9.77k
  Type getIntegerExtendedType() const noexcept {
603
9.77k
    return LLVMIntTypeInContext(LLVMGetTypeContext(Ref),
604
9.77k
                                getIntegerBitWidth() * 2);
605
9.77k
  }
606
683
  Type getIntegerTruncatedType() const noexcept {
607
683
    return LLVMIntTypeInContext(LLVMGetTypeContext(Ref),
608
683
                                getIntegerBitWidth() / 2);
609
683
  }
610
674
  unsigned int getStructNumElements() const noexcept {
611
674
    return LLVMCountStructElementTypes(Ref);
612
674
  }
613
86
  Type getStructElementType(unsigned int Index) const noexcept {
614
86
    return LLVMStructGetTypeAtIndex(Ref, Index);
615
86
  }
616
66.6k
  Type getPointerTo(unsigned int AddressSpace = 0) const noexcept {
617
66.6k
    return LLVMPointerType(Ref, AddressSpace);
618
66.6k
  }
619
14.6k
  Type getReturnType() const noexcept { return LLVMGetReturnType(Ref); }
620
7.44k
  unsigned int getNumParams() const noexcept {
621
7.44k
    return LLVMCountParamTypes(Ref);
622
7.44k
  }
623
3.72k
  void getParamTypes(Span<Type> Types) const noexcept {
624
3.72k
    LLVMGetParamTypes(Ref, reinterpret_cast<LLVMTypeRef *>(Types.data()));
625
3.72k
  }
626
80.8k
  unsigned int getVectorSize() const noexcept { return LLVMGetVectorSize(Ref); }
627
9.77k
  Type getExtendedElementVectorType() const noexcept {
628
9.77k
    return getVectorType(getElementType().getIntegerExtendedType(),
629
9.77k
                         getVectorSize());
630
9.77k
  }
631
683
  Type getTruncatedElementVectorType() const noexcept {
632
683
    return getVectorType(getElementType().getIntegerTruncatedType(),
633
683
                         getVectorSize());
634
683
  }
635
2.12k
  Type getHalfElementsVectorType() const noexcept {
636
2.12k
    return getVectorType(getElementType(), getVectorSize() / 2);
637
2.12k
  }
638
639
private:
640
  LLVMTypeRef Ref = nullptr;
641
};
642
643
class Value {
644
public:
645
4.41M
  constexpr Value() = default;
646
11.1M
  constexpr Value(LLVMValueRef R) noexcept : Ref(R) {}
647
  constexpr Value(const Value &) = default;
648
  constexpr Value &operator=(const Value &) = default;
649
4.28M
  Value(Value &&V) noexcept : Value() { swap(*this, V); }
650
386k
  Value &operator=(Value &&V) noexcept {
651
386k
    swap(*this, V);
652
386k
    return *this;
653
386k
  }
654
655
2.91M
  constexpr operator bool() const noexcept { return Ref != nullptr; }
656
0
  constexpr auto &unwrap() const noexcept { return Ref; }
657
7.85M
  constexpr auto &unwrap() noexcept { return Ref; }
658
659
4.67M
  friend void swap(Value &LHS, Value &RHS) noexcept {
660
4.67M
    using std::swap;
661
4.67M
    swap(LHS.Ref, RHS.Ref);
662
4.67M
  }
663
664
2.68M
  static Value getConstNull(Type Ty) noexcept {
665
2.68M
    return LLVMConstNull(Ty.unwrap());
666
2.68M
  }
667
65
  static Value getConstAllOnes(Type Ty) noexcept {
668
65
    return LLVMConstAllOnes(Ty.unwrap());
669
65
  }
670
94.7k
  static Value getUndef(Type Ty) noexcept { return LLVMGetUndef(Ty.unwrap()); }
671
719
  static Value getConstPointerNull(Type Ty) noexcept {
672
719
    return LLVMConstPointerNull(Ty.unwrap());
673
719
  }
674
  static Value getConstInt(Type IntTy, unsigned long long N,
675
1.37M
                           bool SignExtend = false) noexcept {
676
1.37M
    return LLVMConstInt(IntTy.unwrap(), N, SignExtend);
677
1.37M
  }
678
35.9k
  template <typename T> static Value getConstReal(Type Ty, T N) noexcept {
679
35.9k
    if (Ty.isFloatTy()) {
680
21.0k
      const auto V = static_cast<float>(N);
681
21.0k
      uint32_t Raw;
682
21.0k
      static_assert(sizeof(V) == sizeof(Raw));
683
21.0k
      std::memcpy(&Raw, &V, sizeof(V));
684
21.0k
      Type Int32Ty = LLVMInt32TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
685
21.0k
      Value Ret = getConstInt(Int32Ty, Raw);
686
21.0k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
687
21.0k
    }
688
14.9k
    if (Ty.isDoubleTy()) {
689
14.9k
      const auto V = static_cast<double>(N);
690
14.9k
      uint64_t Raw;
691
14.9k
      static_assert(sizeof(V) == sizeof(Raw));
692
14.9k
      std::memcpy(&Raw, &V, sizeof(V));
693
14.9k
      Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
694
14.9k
      Value Ret = getConstInt(Int64Ty, Raw);
695
14.9k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
696
14.9k
    }
697
14.9k
    assumingUnreachable();
698
14.9k
  }
WasmEdge::LLVM::Value WasmEdge::LLVM::Value::getConstReal<float>(WasmEdge::LLVM::Type, float)
Line
Count
Source
678
13.9k
  template <typename T> static Value getConstReal(Type Ty, T N) noexcept {
679
13.9k
    if (Ty.isFloatTy()) {
680
13.9k
      const auto V = static_cast<float>(N);
681
13.9k
      uint32_t Raw;
682
13.9k
      static_assert(sizeof(V) == sizeof(Raw));
683
13.9k
      std::memcpy(&Raw, &V, sizeof(V));
684
13.9k
      Type Int32Ty = LLVMInt32TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
685
13.9k
      Value Ret = getConstInt(Int32Ty, Raw);
686
13.9k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
687
13.9k
    }
688
0
    if (Ty.isDoubleTy()) {
689
0
      const auto V = static_cast<double>(N);
690
0
      uint64_t Raw;
691
0
      static_assert(sizeof(V) == sizeof(Raw));
692
0
      std::memcpy(&Raw, &V, sizeof(V));
693
0
      Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
694
0
      Value Ret = getConstInt(Int64Ty, Raw);
695
0
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
696
0
    }
697
0
    assumingUnreachable();
698
0
  }
WasmEdge::LLVM::Value WasmEdge::LLVM::Value::getConstReal<double>(WasmEdge::LLVM::Type, double)
Line
Count
Source
678
6.21k
  template <typename T> static Value getConstReal(Type Ty, T N) noexcept {
679
6.21k
    if (Ty.isFloatTy()) {
680
0
      const auto V = static_cast<float>(N);
681
0
      uint32_t Raw;
682
0
      static_assert(sizeof(V) == sizeof(Raw));
683
0
      std::memcpy(&Raw, &V, sizeof(V));
684
0
      Type Int32Ty = LLVMInt32TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
685
0
      Value Ret = getConstInt(Int32Ty, Raw);
686
0
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
687
0
    }
688
6.21k
    if (Ty.isDoubleTy()) {
689
6.21k
      const auto V = static_cast<double>(N);
690
6.21k
      uint64_t Raw;
691
6.21k
      static_assert(sizeof(V) == sizeof(Raw));
692
6.21k
      std::memcpy(&Raw, &V, sizeof(V));
693
6.21k
      Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
694
6.21k
      Value Ret = getConstInt(Int64Ty, Raw);
695
6.21k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
696
6.21k
    }
697
0
    assumingUnreachable();
698
6.21k
  }
WasmEdge::LLVM::Value WasmEdge::LLVM::Value::getConstReal<long>(WasmEdge::LLVM::Type, long)
Line
Count
Source
678
6.34k
  template <typename T> static Value getConstReal(Type Ty, T N) noexcept {
679
6.34k
    if (Ty.isFloatTy()) {
680
3.92k
      const auto V = static_cast<float>(N);
681
3.92k
      uint32_t Raw;
682
3.92k
      static_assert(sizeof(V) == sizeof(Raw));
683
3.92k
      std::memcpy(&Raw, &V, sizeof(V));
684
3.92k
      Type Int32Ty = LLVMInt32TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
685
3.92k
      Value Ret = getConstInt(Int32Ty, Raw);
686
3.92k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
687
3.92k
    }
688
2.42k
    if (Ty.isDoubleTy()) {
689
2.42k
      const auto V = static_cast<double>(N);
690
2.42k
      uint64_t Raw;
691
2.42k
      static_assert(sizeof(V) == sizeof(Raw));
692
2.42k
      std::memcpy(&Raw, &V, sizeof(V));
693
2.42k
      Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
694
2.42k
      Value Ret = getConstInt(Int64Ty, Raw);
695
2.42k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
696
2.42k
    }
697
0
    assumingUnreachable();
698
2.42k
  }
WasmEdge::LLVM::Value WasmEdge::LLVM::Value::getConstReal<unsigned long>(WasmEdge::LLVM::Type, unsigned long)
Line
Count
Source
678
9.43k
  template <typename T> static Value getConstReal(Type Ty, T N) noexcept {
679
9.43k
    if (Ty.isFloatTy()) {
680
3.13k
      const auto V = static_cast<float>(N);
681
3.13k
      uint32_t Raw;
682
3.13k
      static_assert(sizeof(V) == sizeof(Raw));
683
3.13k
      std::memcpy(&Raw, &V, sizeof(V));
684
3.13k
      Type Int32Ty = LLVMInt32TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
685
3.13k
      Value Ret = getConstInt(Int32Ty, Raw);
686
3.13k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
687
3.13k
    }
688
6.30k
    if (Ty.isDoubleTy()) {
689
6.30k
      const auto V = static_cast<double>(N);
690
6.30k
      uint64_t Raw;
691
6.30k
      static_assert(sizeof(V) == sizeof(Raw));
692
6.30k
      std::memcpy(&Raw, &V, sizeof(V));
693
6.30k
      Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
694
6.30k
      Value Ret = getConstInt(Int64Ty, Raw);
695
6.30k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
696
6.30k
    }
697
0
    assumingUnreachable();
698
6.30k
  }
699
  static Value getConstString(Context &C, std::string_view Str,
700
0
                              bool DontNullTerminate) noexcept {
701
0
    return LLVMConstStringInContext(C.unwrap(), Str.data(),
702
0
                                    static_cast<unsigned int>(Str.size()),
703
0
                                    DontNullTerminate);
704
0
  }
705
  static Value getConstInBoundsGEP(Type Ty, Value ConstantVal,
706
0
                                   Span<const Value> ConstantIndices) noexcept {
707
0
    const auto Data = const_cast<LLVMValueRef *>(
708
0
        reinterpret_cast<const LLVMValueRef *>(ConstantIndices.data()));
709
0
    const auto Size = static_cast<unsigned int>(ConstantIndices.size());
710
0
    return LLVMConstInBoundsGEP2(Ty.unwrap(), ConstantVal.unwrap(), Data, Size);
711
0
  }
712
  static Value getConstInBoundsGEP1_64(Type Ty, Value ConstantVal,
713
0
                                       uint64_t Idx0) noexcept {
714
0
    return getConstInBoundsGEP(
715
0
        Ty, ConstantVal,
716
0
        {LLVM::Value::getConstInt(
717
0
            LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap())), Idx0)});
718
0
  }
719
  static Value getConstInBoundsGEP2_64(Type Ty, Value ConstantVal,
720
0
                                       uint64_t Idx0, uint64_t Idx1) noexcept {
721
0
    return getConstInBoundsGEP(
722
0
        Ty, ConstantVal,
723
0
        {LLVM::Value::getConstInt(
724
0
            LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap())), Idx0,
725
0
            Idx1)});
726
0
  }
727
34.4k
  static Value getConstVector(Span<const Value> ScalarConstantVals) noexcept {
728
34.4k
    const auto Data = const_cast<LLVMValueRef *>(
729
34.4k
        reinterpret_cast<const LLVMValueRef *>(ScalarConstantVals.data()));
730
34.4k
    const auto Size = static_cast<unsigned int>(ScalarConstantVals.size());
731
34.4k
    return LLVMConstVector(Data, Size);
732
34.4k
  }
733
  static Value getConstVector8(Context &C,
734
23.0k
                               Span<const uint8_t> Elements) noexcept {
735
23.0k
    std::vector<LLVMValueRef> Data(Elements.size());
736
23.0k
    std::transform(
737
23.0k
        Elements.begin(), Elements.end(), Data.begin(),
738
368k
        [&C](const uint8_t Element) { return C.getInt8(Element).unwrap(); });
739
23.0k
    return LLVMConstVector(Data.data(), static_cast<unsigned int>(Data.size()));
740
23.0k
  }
741
  static Value getConstVector16(Context &C,
742
0
                                Span<const uint16_t> Elements) noexcept {
743
0
    std::vector<LLVMValueRef> Data(Elements.size());
744
0
    std::transform(
745
0
        Elements.begin(), Elements.end(), Data.begin(),
746
0
        [&C](const uint16_t Element) { return C.getInt16(Element).unwrap(); });
747
0
    return LLVMConstVector(Data.data(), static_cast<unsigned int>(Data.size()));
748
0
  }
749
  static Value getConstVector32(Context &C,
750
15.5k
                                Span<const uint32_t> Elements) noexcept {
751
15.5k
    std::vector<LLVMValueRef> Data(Elements.size());
752
15.5k
    std::transform(
753
15.5k
        Elements.begin(), Elements.end(), Data.begin(),
754
70.6k
        [&C](const uint32_t Element) { return C.getInt32(Element).unwrap(); });
755
15.5k
    return LLVMConstVector(Data.data(), static_cast<unsigned int>(Data.size()));
756
15.5k
  }
757
  static Value getConstVector64(Context &C,
758
372
                                Span<const uint64_t> Elements) noexcept {
759
372
    std::vector<LLVMValueRef> Data(Elements.size());
760
372
    std::transform(
761
372
        Elements.begin(), Elements.end(), Data.begin(),
762
744
        [&C](const uint64_t Element) { return C.getInt64(Element).unwrap(); });
763
372
    return LLVMConstVector(Data.data(), static_cast<unsigned int>(Data.size()));
764
372
  }
765
766
#define DECLARE_VALUE_CHECK(name)                                              \
767
0
  bool isA##name() const noexcept { return LLVMIsA##name(Ref) != nullptr; }
Unexecuted instantiation: WasmEdge::LLVM::Value::isAArgument() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isABasicBlock() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAInlineAsm() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAUser() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstant() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isABlockAddress() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstantAggregateZero() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstantArray() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstantDataSequential() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstantDataArray() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstantDataVector() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstantExpr() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstantFP() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstantInt() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstantPointerNull() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstantStruct() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstantTokenNone() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAConstantVector() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAGlobalValue() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAGlobalAlias() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAGlobalIFunc() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAGlobalObject() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAFunction() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAGlobalVariable() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAUndefValue() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAPoisonValue() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAInstruction() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAUnaryOperator() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isABinaryOperator() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isACallInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAIntrinsicInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isADbgInfoIntrinsic() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isADbgVariableIntrinsic() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isADbgDeclareInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isADbgLabelInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAMemIntrinsic() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAMemCpyInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAMemMoveInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAMemSetInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isACmpInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAFCmpInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAICmpInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAExtractElementInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAGetElementPtrInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAInsertElementInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAInsertValueInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isALandingPadInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAPHINode() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isASelectInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAShuffleVectorInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAStoreInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isABranchInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAIndirectBrInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAInvokeInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAReturnInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isASwitchInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAUnreachableInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAResumeInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isACleanupReturnInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isACatchReturnInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isACatchSwitchInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isACallBrInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAFuncletPadInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isACatchPadInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isACleanupPadInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAUnaryInstruction() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAAllocaInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isACastInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAAddrSpaceCastInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isABitCastInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAFPExtInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAFPToSIInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAFPToUIInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAFPTruncInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAIntToPtrInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAPtrToIntInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isASExtInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isASIToFPInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isATruncInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAUIToFPInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAZExtInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAExtractValueInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isALoadInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAVAArgInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAFreezeInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAAtomicCmpXchgInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAAtomicRMWInst() const
Unexecuted instantiation: WasmEdge::LLVM::Value::isAFenceInst() const
768
  LLVM_FOR_EACH_VALUE_SUBCLASS(DECLARE_VALUE_CHECK)
769
#undef DECLARE_VALUE_CHECK
770
771
0
  std::string_view getValueName() noexcept {
772
0
    size_t Size;
773
0
    const auto Ptr = LLVMGetValueName2(Ref, &Size);
774
0
    return {Ptr, Size};
775
0
  }
776
  inline void addFnAttr(const Attribute &A) noexcept;
777
  inline void addParamAttr(unsigned Index, const Attribute &A) noexcept;
778
  inline void addCallSiteAttribute(const Attribute &A) noexcept;
779
  inline void setMetadata(Context &C, unsigned int KindID,
780
                          Metadata Node) noexcept;
781
782
28.5k
  Value getFirstParam() noexcept { return LLVMGetFirstParam(Ref); }
783
33.1k
  Value getNextParam() noexcept { return LLVMGetNextParam(Ref); }
784
3.93k
  Value getNextGlobal() noexcept { return LLVMGetNextGlobal(Ref); }
785
34.2k
  Value getNextFunction() noexcept { return LLVMGetNextFunction(Ref); }
786
0
  unsigned int countBasicBlocks() noexcept { return LLVMCountBasicBlocks(Ref); }
787
788
118k
  Type getType() const noexcept { return LLVMTypeOf(Ref); }
789
0
  Value getInitializer() noexcept { return LLVMGetInitializer(Ref); }
790
3.92k
  void setInitializer(Value ConstantVal) noexcept {
791
3.92k
    LLVMSetInitializer(Ref, ConstantVal.unwrap());
792
3.92k
  }
793
5.88k
  void setGlobalConstant(bool IsConstant) noexcept {
794
5.88k
    LLVMSetGlobalConstant(Ref, IsConstant);
795
5.88k
  }
796
18.9k
  LLVMLinkage getLinkage() noexcept { return LLVMGetLinkage(Ref); }
797
20.2k
  void setLinkage(LLVMLinkage Linkage) noexcept {
798
20.2k
    LLVMSetLinkage(Ref, Linkage);
799
20.2k
  }
800
17.1k
  void setVisibility(LLVMVisibility Viz) noexcept {
801
17.1k
    LLVMSetVisibility(Ref, Viz);
802
17.1k
  }
803
  inline void setDSOLocal(bool Local) noexcept;
804
17.1k
  void setDLLStorageClass(LLVMDLLStorageClass Class) noexcept {
805
17.1k
    LLVMSetDLLStorageClass(Ref, Class);
806
17.1k
  }
807
0
  bool getVolatile() noexcept { return LLVMGetVolatile(Ref); }
808
0
  void setVolatile(bool IsVolatile) noexcept {
809
0
    LLVMSetVolatile(Ref, IsVolatile);
810
0
  }
811
0
  bool getWeak() noexcept { return LLVMGetWeak(Ref); }
812
0
  void setWeak(bool IsWeak) noexcept { LLVMSetWeak(Ref, IsWeak); }
813
0
  unsigned int getAlignment() noexcept { return LLVMGetAlignment(Ref); }
814
20.7k
  void setAlignment(unsigned int Bytes) noexcept {
815
20.7k
    LLVMSetAlignment(Ref, Bytes);
816
20.7k
  }
817
0
  LLVMAtomicOrdering getOrdering() noexcept { return LLVMGetOrdering(Ref); }
818
0
  void setOrdering(LLVMAtomicOrdering Ordering) noexcept {
819
0
    LLVMSetOrdering(Ref, Ordering);
820
0
  }
821
0
  std::string_view getName() noexcept {
822
0
    size_t Length;
823
0
    auto Data = LLVMGetValueName2(Ref, &Length);
824
0
    return {Data, Length};
825
0
  }
826
827
  inline void addCase(Value OnVal, BasicBlock Dest) noexcept;
828
  inline void addDestination(BasicBlock Dest) noexcept;
829
  inline void addIncoming(Value IncomingValue,
830
                          BasicBlock IncomingBlocks) noexcept;
831
  inline void addIncoming(Span<const Value> IncomingValue,
832
                          Span<const BasicBlock> IncomingBlocks) noexcept;
833
  inline void eliminateUnreachableBlocks() noexcept;
834
835
private:
836
  LLVMValueRef Ref = nullptr;
837
};
838
839
struct FunctionCallee {
840
101k
  FunctionCallee() = default;
841
19.8k
  FunctionCallee(Type T, Value F) : Ty(T), Fn(F) {}
842
  Type Ty;
843
  Value Fn;
844
};
845
846
class Metadata {
847
public:
848
0
  constexpr Metadata(LLVMMetadataRef R) noexcept : Ref(R) {}
849
  Metadata(const Metadata &) = delete;
850
  Metadata &operator=(const Metadata &) = delete;
851
0
  Metadata(Metadata &&M) noexcept : Metadata() { swap(*this, M); }
852
0
  Metadata &operator=(Metadata &&M) noexcept {
853
0
    swap(*this, M);
854
0
    return *this;
855
0
  }
856
26.0k
  Metadata(Context &C, Span<Metadata> M) noexcept {
857
26.0k
    const auto Data = const_cast<LLVMMetadataRef *>(
858
26.0k
        reinterpret_cast<const LLVMMetadataRef *>(M.data()));
859
26.0k
    const auto Size = static_cast<unsigned int>(M.size());
860
26.0k
    Ref = LLVMMDNodeInContext2(C.unwrap(), Data, Size);
861
26.0k
  }
862
1.96k
  Metadata(Value V) noexcept : Ref(LLVMValueAsMetadata(V.unwrap())) {}
863
864
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
865
0
  constexpr auto &unwrap() const noexcept { return Ref; }
866
27.9k
  constexpr auto unwrap() noexcept { return Ref; }
867
0
  friend void swap(Metadata &LHS, Metadata &RHS) noexcept {
868
0
    using std::swap;
869
0
    swap(LHS.Ref, RHS.Ref);
870
0
  }
871
872
private:
873
  constexpr Metadata() noexcept = default;
874
  LLVMMetadataRef Ref = nullptr;
875
};
876
877
class Attribute {
878
public:
879
137k
  constexpr Attribute(LLVMAttributeRef R) noexcept : Ref(R) {}
880
  Attribute(const Attribute &) = delete;
881
  Attribute &operator=(const Attribute &) = delete;
882
0
  Attribute(Attribute &&M) noexcept : Attribute() { swap(*this, M); }
883
0
  Attribute &operator=(Attribute &&M) noexcept {
884
0
    swap(*this, M);
885
0
    return *this;
886
0
  }
887
888
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
889
216k
  constexpr auto &unwrap() const noexcept { return Ref; }
890
0
  constexpr auto unwrap() noexcept { return Ref; }
891
0
  friend void swap(Attribute &LHS, Attribute &RHS) noexcept {
892
0
    using std::swap;
893
0
    swap(LHS.Ref, RHS.Ref);
894
0
  }
895
896
  static Attribute createEnum(Context &C, unsigned int KindID,
897
13.7k
                              uint64_t Val) noexcept {
898
13.7k
    return LLVMCreateEnumAttribute(C.unwrap(), KindID, Val);
899
13.7k
  }
900
  static Attribute createString(Context &C, std::string_view Kind,
901
1.96k
                                std::string_view Val) noexcept {
902
1.96k
    return LLVMCreateStringAttribute(
903
1.96k
        C.unwrap(), Kind.data(), static_cast<unsigned int>(Kind.size()),
904
1.96k
        Val.data(), static_cast<unsigned int>(Val.size()));
905
1.96k
  }
906
907
private:
908
  constexpr Attribute() noexcept = default;
909
  LLVMAttributeRef Ref = nullptr;
910
};
911
912
Value Module::addFunction(Type Ty, LLVMLinkage Linkage,
913
15.2k
                          const char *Name) noexcept {
914
15.2k
  Value Fn = LLVMAddFunction(Ref, Name, Ty.unwrap());
915
15.2k
  Fn.setLinkage(Linkage);
916
15.2k
  return Fn;
917
15.2k
}
918
919
Value Module::addGlobal(Type Ty, bool IsConstant, LLVMLinkage Linkage,
920
4.76k
                        Value Initializer, const char *Name) noexcept {
921
4.76k
  Value G = LLVMAddGlobal(Ref, Ty.unwrap(), Name);
922
4.76k
  G.setLinkage(Linkage);
923
4.76k
  G.setGlobalConstant(IsConstant);
924
4.76k
  if (Initializer) {
925
2.80k
    G.setInitializer(Initializer);
926
2.80k
  }
927
4.76k
  return G;
928
4.76k
}
929
930
1.96k
Value Module::getNamedGlobal(const char *Name) noexcept {
931
1.96k
  return LLVMGetNamedGlobal(Ref, Name);
932
1.96k
}
933
934
Value Module::addAlias(Type Ty, Value V, const char *Name,
935
125
                       unsigned int AddrSpace [[maybe_unused]]) noexcept {
936
#if LLVM_VERSION_MAJOR >= 14
937
  return LLVMAddAlias2(Ref, Ty.unwrap(), AddrSpace, V.unwrap(), Name);
938
#else
939
125
  return LLVMAddAlias(Ref, Ty.unwrap(), V.unwrap(), Name);
940
125
#endif
941
125
}
942
943
void Module::addFlag(LLVMModuleFlagBehavior Behavior, std::string_view Key,
944
0
                     const Metadata &Val) noexcept {
945
0
  LLVMAddModuleFlag(Ref, Behavior, Key.data(), Key.size(), Val.unwrap());
946
0
}
947
948
void Module::addFlag(LLVMModuleFlagBehavior Behavior, std::string_view Key,
949
0
                     const Value &Val) noexcept {
950
0
  LLVMAddModuleFlag(Ref, Behavior, Key.data(), Key.size(),
951
0
                    Metadata(Val).unwrap());
952
0
}
953
954
void Module::addFlag(LLVMModuleFlagBehavior Behavior, std::string_view Key,
955
1.96k
                     uint32_t Val) noexcept {
956
1.96k
  Type Int32Ty = LLVMInt32TypeInContext(LLVMGetModuleContext(Ref));
957
1.96k
  LLVMAddModuleFlag(Ref, Behavior, Key.data(), Key.size(),
958
1.96k
                    Metadata(Value::getConstInt(Int32Ty, Val)).unwrap());
959
1.96k
}
960
961
1.96k
Value Module::getFirstGlobal() noexcept { return LLVMGetFirstGlobal(Ref); }
962
3.92k
Value Module::getFirstFunction() noexcept { return LLVMGetFirstFunction(Ref); }
963
964
0
Value Module::getNamedFunction(const char *Name) noexcept {
965
0
  return LLVMGetNamedFunction(Ref, Name);
966
0
}
967
968
0
Message Module::printModuleToFile(const char *Filename) noexcept {
969
0
  Message M;
970
0
  LLVMPrintModuleToFile(Ref, Filename, &M.unwrap());
971
0
  return M;
972
0
}
973
974
1.96k
Message Module::verify(LLVMVerifierFailureAction Action) noexcept {
975
1.96k
  Message M;
976
1.96k
  LLVMVerifyModule(Ref, Action, &M.unwrap());
977
1.96k
  return M;
978
1.96k
}
979
980
5.31k
Type Context::getVoidTy() noexcept { return LLVMVoidTypeInContext(Ref); }
981
5.57k
Type Context::getInt1Ty() noexcept { return LLVMInt1TypeInContext(Ref); }
982
371k
Type Context::getInt8Ty() noexcept { return LLVMInt8TypeInContext(Ref); }
983
4.47k
Type Context::getInt16Ty() noexcept { return LLVMInt16TypeInContext(Ref); }
984
1.64M
Type Context::getInt32Ty() noexcept { return LLVMInt32TypeInContext(Ref); }
985
4.42M
Type Context::getInt64Ty() noexcept { return LLVMInt64TypeInContext(Ref); }
986
1.96k
Type Context::getInt128Ty() noexcept { return LLVMInt128TypeInContext(Ref); }
987
1.78k
Type Context::getIntNTy(unsigned int NumBits) noexcept {
988
1.78k
  return LLVMIntTypeInContext(Ref, NumBits);
989
1.78k
}
990
122k
Type Context::getFloatTy() noexcept { return LLVMFloatTypeInContext(Ref); }
991
46.2k
Type Context::getDoubleTy() noexcept { return LLVMDoubleTypeInContext(Ref); }
992
993
5.02k
Value Context::getFalse() noexcept {
994
5.02k
  return Value::getConstInt(getInt1Ty(), 0);
995
5.02k
}
996
0
Value Context::getTrue() noexcept { return Value::getConstInt(getInt1Ty(), 1); }
997
368k
Value Context::getInt8(uint8_t C) noexcept {
998
368k
  return Value::getConstInt(getInt8Ty(), C);
999
368k
}
1000
2.51k
Value Context::getInt16(uint16_t C) noexcept {
1001
2.51k
  return Value::getConstInt(getInt16Ty(), C);
1002
2.51k
}
1003
664k
Value Context::getInt32(uint32_t C) noexcept {
1004
664k
  return Value::getConstInt(getInt32Ty(), C);
1005
664k
}
1006
207k
Value Context::getInt64(uint64_t C) noexcept {
1007
207k
  return Value::getConstInt(getInt64Ty(), C);
1008
207k
}
1009
13.9k
Value Context::getFloat(float C) noexcept {
1010
13.9k
  return Value::getConstReal(getFloatTy(), C);
1011
13.9k
}
1012
6.21k
Value Context::getDouble(double C) noexcept {
1013
6.21k
  return Value::getConstReal(getDoubleTy(), C);
1014
6.21k
}
1015
1016
51.7k
void Value::addFnAttr(const Attribute &A) noexcept {
1017
51.7k
  LLVMAddAttributeAtIndex(
1018
51.7k
      Ref, static_cast<unsigned int>(LLVMAttributeFunctionIndex), A.unwrap());
1019
51.7k
}
1020
37.8k
void Value::addParamAttr(unsigned Index, const Attribute &A) noexcept {
1021
37.8k
  LLVMAddAttributeAtIndex(Ref, 1 + Index, A.unwrap());
1022
37.8k
}
1023
126k
void Value::addCallSiteAttribute(const Attribute &A) noexcept {
1024
126k
  LLVMAddCallSiteAttribute(
1025
126k
      Ref, static_cast<unsigned int>(LLVMAttributeFunctionIndex), A.unwrap());
1026
126k
}
1027
void Value::setMetadata(Context &C, unsigned int KindID,
1028
26.0k
                        Metadata Node) noexcept {
1029
26.0k
  LLVMSetMetadata(Ref, KindID, LLVMMetadataAsValue(C.unwrap(), Node.unwrap()));
1030
26.0k
}
1031
1032
1.96k
static inline Message getDefaultTargetTriple() noexcept {
1033
1.96k
  return LLVMGetDefaultTargetTriple();
1034
1.96k
}
compiler.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Line
Count
Source
1032
1.96k
static inline Message getDefaultTargetTriple() noexcept {
1033
1.96k
  return LLVMGetDefaultTargetTriple();
1034
1.96k
}
Unexecuted instantiation: codegen.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Unexecuted instantiation: data.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Unexecuted instantiation: jit.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
1035
1.96k
static inline Message getHostCPUName() noexcept { return LLVMGetHostCPUName(); }
compiler.cpp:WasmEdge::LLVM::getHostCPUName()
Line
Count
Source
1035
1.96k
static inline Message getHostCPUName() noexcept { return LLVMGetHostCPUName(); }
Unexecuted instantiation: codegen.cpp:WasmEdge::LLVM::getHostCPUName()
Unexecuted instantiation: data.cpp:WasmEdge::LLVM::getHostCPUName()
Unexecuted instantiation: jit.cpp:WasmEdge::LLVM::getHostCPUName()
1036
3.92k
static inline Message getHostCPUFeatures() noexcept {
1037
3.92k
  return LLVMGetHostCPUFeatures();
1038
3.92k
}
compiler.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Line
Count
Source
1036
3.92k
static inline Message getHostCPUFeatures() noexcept {
1037
3.92k
  return LLVMGetHostCPUFeatures();
1038
3.92k
}
Unexecuted instantiation: codegen.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Unexecuted instantiation: data.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Unexecuted instantiation: jit.cpp:WasmEdge::LLVM::getHostCPUFeatures()
1039
1040
class BasicBlock {
1041
public:
1042
115k
  constexpr BasicBlock() noexcept = default;
1043
106k
  constexpr BasicBlock(LLVMBasicBlockRef R) noexcept : Ref(R) {}
1044
  BasicBlock(const BasicBlock &) = default;
1045
  BasicBlock &operator=(const BasicBlock &) = default;
1046
82.4k
  BasicBlock(BasicBlock &&B) noexcept : BasicBlock() { swap(*this, B); }
1047
2.64k
  BasicBlock &operator=(BasicBlock &&B) noexcept {
1048
2.64k
    swap(*this, B);
1049
2.64k
    return *this;
1050
2.64k
  }
1051
1052
72.1k
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1053
0
  constexpr auto &unwrap() const noexcept { return Ref; }
1054
243k
  constexpr auto &unwrap() noexcept { return Ref; }
1055
85.1k
  friend void swap(BasicBlock &LHS, BasicBlock &RHS) noexcept {
1056
85.1k
    using std::swap;
1057
85.1k
    swap(LHS.Ref, RHS.Ref);
1058
85.1k
  }
1059
1060
88.3k
  static BasicBlock create(Context &C, Value F, const char *Name) noexcept {
1061
88.3k
    return LLVMAppendBasicBlockInContext(C.unwrap(), F.unwrap(), Name);
1062
88.3k
  }
1063
0
  void erase() noexcept { LLVMDeleteBasicBlock(Ref); }
1064
1065
private:
1066
  LLVMBasicBlockRef Ref = nullptr;
1067
};
1068
1069
35.4k
void Value::addCase(Value OnVal, BasicBlock Dest) noexcept {
1070
35.4k
  LLVMAddCase(Ref, OnVal.unwrap(), Dest.unwrap());
1071
35.4k
}
1072
1073
0
void Value::addDestination(BasicBlock Dest) noexcept {
1074
0
  LLVMAddDestination(Ref, Dest.unwrap());
1075
0
}
1076
1077
void Value::addIncoming(Value IncomingValue,
1078
16.7k
                        BasicBlock IncomingBlocks) noexcept {
1079
16.7k
  LLVMAddIncoming(Ref, &IncomingValue.unwrap(), &IncomingBlocks.unwrap(), 1);
1080
16.7k
}
1081
1082
void Value::addIncoming(Span<const Value> IncomingValue,
1083
0
                        Span<const BasicBlock> IncomingBlocks) noexcept {
1084
0
  assuming(IncomingBlocks.size() == IncomingValue.size());
1085
0
  const auto ValueData = const_cast<LLVMValueRef *>(
1086
0
      reinterpret_cast<const LLVMValueRef *>(IncomingValue.data()));
1087
0
  const auto BlockData = const_cast<LLVMBasicBlockRef *>(
1088
0
      reinterpret_cast<const LLVMBasicBlockRef *>(IncomingBlocks.data()));
1089
0
  const auto Size = static_cast<unsigned int>(IncomingValue.size());
1090
0
  LLVMAddIncoming(Ref, ValueData, BlockData, Size);
1091
0
}
1092
1093
class Builder {
1094
private:
1095
406k
  LLVMValueRef getFn() noexcept {
1096
406k
    return LLVMGetBasicBlockParent(LLVMGetInsertBlock(Ref));
1097
406k
  }
1098
406k
  LLVMModuleRef getMod() noexcept { return LLVMGetGlobalParent(getFn()); }
1099
306k
  LLVMContextRef getCtx() noexcept { return LLVMGetModuleContext(getMod()); }
1100
1101
public:
1102
  constexpr Builder() noexcept = default;
1103
0
  constexpr Builder(LLVMBuilderRef R) noexcept : Ref(R) {}
1104
  Builder(const Builder &) = delete;
1105
  Builder &operator=(const Builder &) = delete;
1106
0
  Builder(Builder &&B) noexcept : Builder() { swap(*this, B); }
1107
0
  Builder &operator=(Builder &&B) noexcept {
1108
0
    swap(*this, B);
1109
0
    return *this;
1110
0
  }
1111
15.2k
  ~Builder() noexcept { LLVMDisposeBuilder(Ref); }
1112
1113
15.2k
  Builder(Context &C) noexcept : Ref(LLVMCreateBuilderInContext(C.unwrap())) {}
1114
1115
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1116
0
  constexpr auto &unwrap() const noexcept { return Ref; }
1117
0
  constexpr auto &unwrap() noexcept { return Ref; }
1118
0
  friend void swap(Builder &LHS, Builder &RHS) noexcept {
1119
0
    using std::swap;
1120
0
    swap(LHS.Ref, RHS.Ref);
1121
0
  }
1122
1123
90.6k
  void positionAtEnd(BasicBlock B) noexcept {
1124
90.6k
    LLVMPositionBuilderAtEnd(Ref, B.unwrap());
1125
90.6k
  }
1126
18.3k
  BasicBlock getInsertBlock() noexcept { return LLVMGetInsertBlock(Ref); }
1127
1128
5.71k
  Value createRetVoid() noexcept { return LLVMBuildRetVoid(Ref); }
1129
7.97k
  Value createRet(Value V) noexcept { return LLVMBuildRet(Ref, V.unwrap()); }
1130
323
  Value createAggregateRet(Span<const Value> RetVals) noexcept {
1131
323
    const auto Data = const_cast<LLVMValueRef *>(
1132
323
        reinterpret_cast<const LLVMValueRef *>(RetVals.data()));
1133
323
    const auto Size = static_cast<unsigned int>(RetVals.size());
1134
323
    return LLVMBuildAggregateRet(Ref, Data, Size);
1135
323
  }
1136
24.3k
  Value createBr(BasicBlock Dest) noexcept {
1137
24.3k
    return LLVMBuildBr(Ref, Dest.unwrap());
1138
24.3k
  }
1139
37.5k
  Value createCondBr(Value If, BasicBlock Then, BasicBlock Else) noexcept {
1140
37.5k
    return LLVMBuildCondBr(Ref, If.unwrap(), Then.unwrap(), Else.unwrap());
1141
37.5k
  }
1142
922
  Value createSwitch(Value V, BasicBlock Else, unsigned int NumCases) noexcept {
1143
922
    return LLVMBuildSwitch(Ref, V.unwrap(), Else.unwrap(), NumCases);
1144
922
  }
1145
0
  Value createIndirectBr(Value Addr, unsigned int NumDests) noexcept {
1146
0
    return LLVMBuildIndirectBr(Ref, Addr.unwrap(), NumDests);
1147
0
  }
1148
11.5k
  Value createUnreachable() noexcept { return LLVMBuildUnreachable(Ref); }
1149
1150
15.0k
  Value createAdd(Value LHS, Value RHS, const char *Name = "") noexcept {
1151
15.0k
    return LLVMBuildAdd(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1152
15.0k
  }
1153
0
  Value createNSWAdd(Value LHS, Value RHS, const char *Name = "") noexcept {
1154
0
    return LLVMBuildNSWAdd(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1155
0
  }
1156
0
  Value createNUWAdd(Value LHS, Value RHS, const char *Name = "") noexcept {
1157
0
    return LLVMBuildNUWAdd(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1158
0
  }
1159
2.34k
  Value createFAdd(Value LHS, Value RHS, const char *Name = "") noexcept {
1160
2.34k
    Value Ret = createIntrinsic(
1161
2.34k
        Core::ExperimentalConstrainedFAdd, {LHS.getType()},
1162
2.34k
        {LHS, RHS, getConstrainedFPRounding(), getConstrainedFPExcept()}, Name);
1163
2.34k
    Ret.addCallSiteAttribute(
1164
2.34k
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1165
2.34k
    return Ret;
1166
2.34k
  }
1167
2.73k
  Value createSub(Value LHS, Value RHS, const char *Name = "") noexcept {
1168
2.73k
    return LLVMBuildSub(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1169
2.73k
  }
1170
0
  Value createNSWSub(Value LHS, Value RHS, const char *Name = "") noexcept {
1171
0
    return LLVMBuildNSWSub(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1172
0
  }
1173
0
  Value createNUWSub(Value LHS, Value RHS, const char *Name = "") noexcept {
1174
0
    return LLVMBuildNUWSub(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1175
0
  }
1176
876
  Value createFSub(Value LHS, Value RHS, const char *Name = "") noexcept {
1177
876
    Value Ret = createIntrinsic(
1178
876
        Core::ExperimentalConstrainedFSub, {LHS.getType()},
1179
876
        {LHS, RHS, getConstrainedFPRounding(), getConstrainedFPExcept()}, Name);
1180
876
    Ret.addCallSiteAttribute(
1181
876
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1182
876
    return Ret;
1183
876
  }
1184
3.36k
  Value createMul(Value LHS, Value RHS, const char *Name = "") noexcept {
1185
3.36k
    return LLVMBuildMul(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1186
3.36k
  }
1187
0
  Value createNSWMul(Value LHS, Value RHS, const char *Name = "") noexcept {
1188
0
    return LLVMBuildNSWMul(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1189
0
  }
1190
0
  Value createNUWMul(Value LHS, Value RHS, const char *Name = "") noexcept {
1191
0
    return LLVMBuildNUWMul(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1192
0
  }
1193
881
  Value createFMul(Value LHS, Value RHS, const char *Name = "") noexcept {
1194
881
    Value Ret = createIntrinsic(
1195
881
        Core::ExperimentalConstrainedFMul, {LHS.getType()},
1196
881
        {LHS, RHS, getConstrainedFPRounding(), getConstrainedFPExcept()}, Name);
1197
881
    Ret.addCallSiteAttribute(
1198
881
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1199
881
    return Ret;
1200
881
  }
1201
3.37k
  Value createUDiv(Value LHS, Value RHS, const char *Name = "") noexcept {
1202
3.37k
    return LLVMBuildUDiv(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1203
3.37k
  }
1204
0
  Value createExactUDiv(Value LHS, Value RHS, const char *Name = "") noexcept {
1205
0
    return LLVMBuildExactUDiv(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1206
0
  }
1207
1.94k
  Value createSDiv(Value LHS, Value RHS, const char *Name = "") noexcept {
1208
1.94k
    return LLVMBuildSDiv(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1209
1.94k
  }
1210
0
  Value createExactSDiv(Value LHS, Value RHS, const char *Name = "") noexcept {
1211
0
    return LLVMBuildExactSDiv(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1212
0
  }
1213
793
  Value createFDiv(Value LHS, Value RHS, const char *Name = "") noexcept {
1214
793
    Value Ret = createIntrinsic(
1215
793
        Core::ExperimentalConstrainedFDiv, {LHS.getType()},
1216
793
        {LHS, RHS, getConstrainedFPRounding(), getConstrainedFPExcept()}, Name);
1217
793
    Ret.addCallSiteAttribute(
1218
793
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1219
793
    return Ret;
1220
793
  }
1221
1.55k
  Value createURem(Value LHS, Value RHS, const char *Name = "") noexcept {
1222
1.55k
    return LLVMBuildURem(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1223
1.55k
  }
1224
1.37k
  Value createSRem(Value LHS, Value RHS, const char *Name = "") noexcept {
1225
1.37k
    return LLVMBuildSRem(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1226
1.37k
  }
1227
3.08k
  Value createShl(Value LHS, Value RHS, const char *Name = "") noexcept {
1228
3.08k
    return LLVMBuildShl(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1229
3.08k
  }
1230
4.43k
  Value createLShr(Value LHS, Value RHS, const char *Name = "") noexcept {
1231
4.43k
    return LLVMBuildLShr(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1232
4.43k
  }
1233
3.86k
  Value createAShr(Value LHS, Value RHS, const char *Name = "") noexcept {
1234
3.86k
    return LLVMBuildAShr(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1235
3.86k
  }
1236
14.8k
  Value createAnd(Value LHS, Value RHS, const char *Name = "") noexcept {
1237
14.8k
    return LLVMBuildAnd(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1238
14.8k
  }
1239
5.65k
  Value createOr(Value LHS, Value RHS, const char *Name = "") noexcept {
1240
5.65k
    return LLVMBuildOr(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1241
5.65k
  }
1242
2.41k
  Value createXor(Value LHS, Value RHS, const char *Name = "") noexcept {
1243
2.41k
    return LLVMBuildXor(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1244
2.41k
  }
1245
4.37k
  Value createNeg(Value V, const char *Name = "") noexcept {
1246
4.37k
    return LLVMBuildNeg(Ref, V.unwrap(), Name);
1247
4.37k
  }
1248
2.75k
  Value createFNeg(Value V, const char *Name = "") noexcept {
1249
2.75k
    return LLVMBuildFNeg(Ref, V.unwrap(), Name);
1250
2.75k
  }
1251
838
  Value createNot(Value V, const char *Name = "") noexcept {
1252
838
    return LLVMBuildNot(Ref, V.unwrap(), Name);
1253
838
  }
1254
2.66M
  Value createAlloca(Type Ty, const char *Name = "") noexcept {
1255
2.66M
    return LLVMBuildAlloca(Ref, Ty.unwrap(), Name);
1256
2.66M
  }
1257
1.03k
  Value createArrayAlloca(Type Ty, Value Val, const char *Name = "") noexcept {
1258
1.03k
    return LLVMBuildArrayAlloca(Ref, Ty.unwrap(), Val.unwrap(), Name);
1259
1.03k
  }
1260
  Value createLoad(Type Ty, Value PointerVal, bool Volatile = false,
1261
93.0k
                   const char *Name = "") noexcept {
1262
93.0k
    auto Ret = LLVMBuildLoad2(Ref, Ty.unwrap(), PointerVal.unwrap(), Name);
1263
93.0k
    if (Volatile) {
1264
16.6k
      LLVMSetVolatile(Ret, true);
1265
16.6k
    }
1266
93.0k
    return Ret;
1267
93.0k
  }
1268
2.67M
  Value createStore(Value Val, Value Ptr, bool Volatile = false) noexcept {
1269
2.67M
    auto Ret = LLVMBuildStore(Ref, Val.unwrap(), Ptr.unwrap());
1270
2.67M
    if (Volatile) {
1271
4.44k
      LLVMSetVolatile(Ret, true);
1272
4.44k
    }
1273
2.67M
    return Ret;
1274
2.67M
  }
1275
1276
  Value createInBoundsGEP1(Type Ty, Value Pointer, Value Idx0,
1277
59.5k
                           const char *Name = "") noexcept {
1278
59.5k
    LLVMValueRef Data[1] = {Idx0.unwrap()};
1279
59.5k
    return LLVMBuildInBoundsGEP2(Ref, Ty.unwrap(), Pointer.unwrap(), Data,
1280
59.5k
                                 static_cast<unsigned>(std::size(Data)), Name);
1281
59.5k
  }
1282
  Value createInBoundsGEP2(Type Ty, Value Pointer, Value Idx0, Value Idx1,
1283
5.93k
                           const char *Name = "") noexcept {
1284
5.93k
    LLVMValueRef Data[2] = {Idx0.unwrap(), Idx1.unwrap()};
1285
5.93k
    return LLVMBuildInBoundsGEP2(Ref, Ty.unwrap(), Pointer.unwrap(), Data,
1286
5.93k
                                 static_cast<unsigned>(std::size(Data)), Name);
1287
5.93k
  }
1288
  Value createConstInBoundsGEP1_64(Type Ty, Value Pointer, uint64_t Idx0,
1289
8.37k
                                   const char *Name = "") noexcept {
1290
8.37k
    Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
1291
8.37k
    LLVMValueRef Data[1] = {Value::getConstInt(Int64Ty, Idx0).unwrap()};
1292
8.37k
    return LLVMBuildInBoundsGEP2(Ref, Ty.unwrap(), Pointer.unwrap(), Data,
1293
8.37k
                                 static_cast<unsigned>(std::size(Data)), Name);
1294
8.37k
  }
1295
1296
  Value createConstInBoundsGEP2_64(Type Ty, Value Pointer, uint64_t Idx0,
1297
                                   uint64_t Idx1,
1298
0
                                   const char *Name = "") noexcept {
1299
0
    Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
1300
0
    LLVMValueRef Data[2] = {Value::getConstInt(Int64Ty, Idx0).unwrap(),
1301
0
                            Value::getConstInt(Int64Ty, Idx1).unwrap()};
1302
0
    return LLVMBuildInBoundsGEP2(Ref, Ty.unwrap(), Pointer.unwrap(), Data,
1303
0
                                 static_cast<unsigned>(std::size(Data)), Name);
1304
0
  }
1305
1306
56.9k
  Value createTrunc(Value Val, Type DestTy, const char *Name = "") noexcept {
1307
56.9k
    return LLVMBuildTrunc(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1308
56.9k
  }
1309
71.6k
  Value createZExt(Value Val, Type DestTy, const char *Name = "") noexcept {
1310
71.6k
    return LLVMBuildZExt(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1311
71.6k
  }
1312
24.7k
  Value createSExt(Value Val, Type DestTy, const char *Name = "") noexcept {
1313
24.7k
    return LLVMBuildSExt(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1314
24.7k
  }
1315
10.5k
  Value createFPToUI(Value Val, Type DestTy, const char *Name = "") noexcept {
1316
10.5k
    return LLVMBuildFPToUI(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1317
10.5k
  }
1318
4.07k
  Value createFPToSI(Value Val, Type DestTy, const char *Name = "") noexcept {
1319
4.07k
    return LLVMBuildFPToSI(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1320
4.07k
  }
1321
16.8k
  Value createUIToFP(Value Val, Type DestTy, const char *Name = "") noexcept {
1322
16.8k
    return LLVMBuildUIToFP(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1323
16.8k
  }
1324
10.4k
  Value createSIToFP(Value Val, Type DestTy, const char *Name = "") noexcept {
1325
10.4k
    return LLVMBuildSIToFP(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1326
10.4k
  }
1327
742
  Value createFPTrunc(Value Val, Type DestTy, const char *Name = "") noexcept {
1328
742
    Value Ret = createIntrinsic(
1329
742
        Core::ExperimentalConstrainedFPTrunc, {DestTy, Val.getType()},
1330
742
        {Val, getConstrainedFPRounding(), getConstrainedFPExcept()}, Name);
1331
742
    Ret.addCallSiteAttribute(
1332
742
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1333
742
    return Ret;
1334
742
  }
1335
646
  Value createFPExt(Value Val, Type DestTy, const char *Name = "") noexcept {
1336
646
    Value Ret = createIntrinsic(Core::ExperimentalConstrainedFPExt,
1337
646
                                {DestTy, Val.getType()},
1338
646
                                {Val, getConstrainedFPExcept()}, Name);
1339
646
    Ret.addCallSiteAttribute(
1340
646
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1341
646
    return Ret;
1342
646
  }
1343
0
  Value createPtrToInt(Value Val, Type DestTy, const char *Name = "") noexcept {
1344
0
    return LLVMBuildPtrToInt(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1345
0
  }
1346
0
  Value createIntToPtr(Value Val, Type DestTy, const char *Name = "") noexcept {
1347
0
    return LLVMBuildIntToPtr(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1348
0
  }
1349
251k
  Value createBitCast(Value Val, Type DestTy, const char *Name = "") noexcept {
1350
251k
    return LLVMBuildBitCast(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1351
251k
  }
1352
  Value createZExtOrBitCast(Value Val, Type DestTy,
1353
0
                            const char *Name = "") noexcept {
1354
0
    return LLVMBuildZExtOrBitCast(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1355
0
  }
1356
  Value createSExtOrBitCast(Value Val, Type DestTy,
1357
0
                            const char *Name = "") noexcept {
1358
0
    return LLVMBuildSExtOrBitCast(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1359
0
  }
1360
  Value createTruncOrBitCast(Value Val, Type DestTy,
1361
0
                             const char *Name = "") noexcept {
1362
0
    return LLVMBuildTruncOrBitCast(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1363
0
  }
1364
  Value createZExtOrTrunc(Value Val, Type DestTy,
1365
1.66k
                          const char *Name = "") noexcept {
1366
1.66k
    const auto VTy = Val.getType();
1367
1.66k
    assuming(DestTy.isIntegerTy() || DestTy.isVectorTy());
1368
1.66k
    assuming(VTy.isIntegerTy() || VTy.isVectorTy());
1369
1.66k
    const auto VTySize = VTy.getPrimitiveSizeInBits();
1370
1.66k
    const auto DestTySize = DestTy.getPrimitiveSizeInBits();
1371
1.66k
    if (VTySize < DestTySize) {
1372
423
      return createZExt(Val, DestTy, Name);
1373
423
    }
1374
1.23k
    if (VTySize > DestTySize) {
1375
0
      return createTrunc(Val, DestTy, Name);
1376
0
    }
1377
1.23k
    return Val;
1378
1.23k
  }
1379
  Value createSExtOrTrunc(Value Val, Type DestTy,
1380
0
                          const char *Name = "") noexcept {
1381
0
    const auto VTy = Val.getType();
1382
0
    assuming(DestTy.isIntegerTy() || DestTy.isVectorTy());
1383
0
    assuming(VTy.isIntegerTy() || VTy.isVectorTy());
1384
0
    const auto VTySize = VTy.getPrimitiveSizeInBits();
1385
0
    const auto DestTySize = DestTy.getPrimitiveSizeInBits();
1386
0
    if (VTySize < DestTySize) {
1387
0
      return createSExt(Val, DestTy, Name);
1388
0
    }
1389
0
    if (VTySize > DestTySize) {
1390
0
      return createTrunc(Val, DestTy, Name);
1391
0
    }
1392
0
    return Val;
1393
0
  }
1394
1395
  Value createICmp(LLVMIntPredicate Op, Value LHS, Value RHS,
1396
70.5k
                   const char *Name = "") noexcept {
1397
70.5k
    return LLVMBuildICmp(Ref, Op, LHS.unwrap(), RHS.unwrap(), Name);
1398
70.5k
  }
1399
11.8k
  Value createICmpEQ(Value LHS, Value RHS, const char *Name = "") noexcept {
1400
11.8k
    return createICmp(LLVMIntEQ, LHS, RHS, Name);
1401
11.8k
  }
1402
18.8k
  Value createICmpNE(Value LHS, Value RHS, const char *Name = "") noexcept {
1403
18.8k
    return createICmp(LLVMIntNE, LHS, RHS, Name);
1404
18.8k
  }
1405
6.66k
  Value createICmpUGT(Value LHS, Value RHS, const char *Name = "") noexcept {
1406
6.66k
    return createICmp(LLVMIntUGT, LHS, RHS, Name);
1407
6.66k
  }
1408
2.96k
  Value createICmpUGE(Value LHS, Value RHS, const char *Name = "") noexcept {
1409
2.96k
    return createICmp(LLVMIntUGE, LHS, RHS, Name);
1410
2.96k
  }
1411
6.30k
  Value createICmpULT(Value LHS, Value RHS, const char *Name = "") noexcept {
1412
6.30k
    return createICmp(LLVMIntULT, LHS, RHS, Name);
1413
6.30k
  }
1414
2.34k
  Value createICmpULE(Value LHS, Value RHS, const char *Name = "") noexcept {
1415
2.34k
    return createICmp(LLVMIntULE, LHS, RHS, Name);
1416
2.34k
  }
1417
2.78k
  Value createICmpSGT(Value LHS, Value RHS, const char *Name = "") noexcept {
1418
2.78k
    return createICmp(LLVMIntSGT, LHS, RHS, Name);
1419
2.78k
  }
1420
1.56k
  Value createICmpSGE(Value LHS, Value RHS, const char *Name = "") noexcept {
1421
1.56k
    return createICmp(LLVMIntSGE, LHS, RHS, Name);
1422
1.56k
  }
1423
9.20k
  Value createICmpSLT(Value LHS, Value RHS, const char *Name = "") noexcept {
1424
9.20k
    return createICmp(LLVMIntSLT, LHS, RHS, Name);
1425
9.20k
  }
1426
3.00k
  Value createICmpSLE(Value LHS, Value RHS, const char *Name = "") noexcept {
1427
3.00k
    return createICmp(LLVMIntSLE, LHS, RHS, Name);
1428
3.00k
  }
1429
  Value createFCmp(LLVMRealPredicate Op, Value LHS, Value RHS,
1430
11.2k
                   const char *Name = "") noexcept {
1431
11.2k
    return LLVMBuildFCmp(Ref, Op, LHS.unwrap(), RHS.unwrap(), Name);
1432
11.2k
  }
1433
212
  Value createFCmpOEQ(Value LHS, Value RHS, const char *Name = "") noexcept {
1434
212
    return LLVMBuildFCmp(Ref, LLVMRealOEQ, LHS.unwrap(), RHS.unwrap(), Name);
1435
212
  }
1436
1.02k
  Value createFCmpOGT(Value LHS, Value RHS, const char *Name = "") noexcept {
1437
1.02k
    return LLVMBuildFCmp(Ref, LLVMRealOGT, LHS.unwrap(), RHS.unwrap(), Name);
1438
1.02k
  }
1439
13.9k
  Value createFCmpOGE(Value LHS, Value RHS, const char *Name = "") noexcept {
1440
13.9k
    return LLVMBuildFCmp(Ref, LLVMRealOGE, LHS.unwrap(), RHS.unwrap(), Name);
1441
13.9k
  }
1442
1.09k
  Value createFCmpOLT(Value LHS, Value RHS, const char *Name = "") noexcept {
1443
1.09k
    return LLVMBuildFCmp(Ref, LLVMRealOLT, LHS.unwrap(), RHS.unwrap(), Name);
1444
1.09k
  }
1445
175
  Value createFCmpOLE(Value LHS, Value RHS, const char *Name = "") noexcept {
1446
175
    return LLVMBuildFCmp(Ref, LLVMRealOLE, LHS.unwrap(), RHS.unwrap(), Name);
1447
175
  }
1448
0
  Value createFCmpONE(Value LHS, Value RHS, const char *Name = "") noexcept {
1449
0
    return LLVMBuildFCmp(Ref, LLVMRealONE, LHS.unwrap(), RHS.unwrap(), Name);
1450
0
  }
1451
7.83k
  Value createFCmpORD(Value LHS, Value RHS, const char *Name = "") noexcept {
1452
7.83k
    return LLVMBuildFCmp(Ref, LLVMRealORD, LHS.unwrap(), RHS.unwrap(), Name);
1453
7.83k
  }
1454
2.55k
  Value createFCmpUNO(Value LHS, Value RHS, const char *Name = "") noexcept {
1455
2.55k
    return LLVMBuildFCmp(Ref, LLVMRealUNO, LHS.unwrap(), RHS.unwrap(), Name);
1456
2.55k
  }
1457
1.59k
  Value createFCmpUEQ(Value LHS, Value RHS, const char *Name = "") noexcept {
1458
1.59k
    return LLVMBuildFCmp(Ref, LLVMRealUEQ, LHS.unwrap(), RHS.unwrap(), Name);
1459
1.59k
  }
1460
0
  Value createFCmpUGT(Value LHS, Value RHS, const char *Name = "") noexcept {
1461
0
    return LLVMBuildFCmp(Ref, LLVMRealUGT, LHS.unwrap(), RHS.unwrap(), Name);
1462
0
  }
1463
905
  Value createFCmpUGE(Value LHS, Value RHS, const char *Name = "") noexcept {
1464
905
    return LLVMBuildFCmp(Ref, LLVMRealUGE, LHS.unwrap(), RHS.unwrap(), Name);
1465
905
  }
1466
6.69k
  Value createFCmpULT(Value LHS, Value RHS, const char *Name = "") noexcept {
1467
6.69k
    return LLVMBuildFCmp(Ref, LLVMRealULT, LHS.unwrap(), RHS.unwrap(), Name);
1468
6.69k
  }
1469
0
  Value createFCmpULE(Value LHS, Value RHS, const char *Name = "") noexcept {
1470
0
    return LLVMBuildFCmp(Ref, LLVMRealULE, LHS.unwrap(), RHS.unwrap(), Name);
1471
0
  }
1472
123
  Value createFCmpUNE(Value LHS, Value RHS, const char *Name = "") noexcept {
1473
123
    return LLVMBuildFCmp(Ref, LLVMRealUNE, LHS.unwrap(), RHS.unwrap(), Name);
1474
123
  }
1475
5.82k
  Value createPHI(Type Ty, const char *Name = "") noexcept {
1476
5.82k
    return LLVMBuildPhi(Ref, Ty.unwrap(), Name);
1477
5.82k
  }
1478
  Value createCall(FunctionCallee Callee, Span<const Value> Args,
1479
115k
                   const char *Name = "") noexcept {
1480
115k
    const auto Data = const_cast<LLVMValueRef *>(
1481
115k
        reinterpret_cast<const LLVMValueRef *>(Args.data()));
1482
115k
    const auto Size = static_cast<unsigned int>(Args.size());
1483
115k
    Value Ret = LLVMBuildCall2(Ref, Callee.Ty.unwrap(), Callee.Fn.unwrap(),
1484
115k
                               Data, Size, Name);
1485
115k
    Ret.addCallSiteAttribute(
1486
115k
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1487
115k
    return Ret;
1488
115k
  }
1489
  Value createSelect(Value If, Value Then, Value Else,
1490
27.4k
                     const char *Name = "") noexcept {
1491
27.4k
    return LLVMBuildSelect(Ref, If.unwrap(), Then.unwrap(), Else.unwrap(),
1492
27.4k
                           Name);
1493
27.4k
  }
1494
  Value createExtractElement(Value VecVal, Value Index,
1495
2.21k
                             const char *Name = "") noexcept {
1496
2.21k
    return LLVMBuildExtractElement(Ref, VecVal.unwrap(), Index.unwrap(), Name);
1497
2.21k
  }
1498
  Value createInsertElement(Value VecVal, Value EltVal, Value Index,
1499
80.4k
                            const char *Name = "") noexcept {
1500
80.4k
    return LLVMBuildInsertElement(Ref, VecVal.unwrap(), EltVal.unwrap(),
1501
80.4k
                                  Index.unwrap(), Name);
1502
80.4k
  }
1503
  Value createShuffleVector(Value V1, Value V2, Value Mask,
1504
94.8k
                            const char *Name = "") noexcept {
1505
94.8k
    return LLVMBuildShuffleVector(Ref, V1.unwrap(), V2.unwrap(), Mask.unwrap(),
1506
94.8k
                                  Name);
1507
94.8k
  }
1508
  Value createExtractValue(Value AggVal, unsigned int Index,
1509
21.0k
                           const char *Name = "") noexcept {
1510
21.0k
    return LLVMBuildExtractValue(Ref, AggVal.unwrap(), Index, Name);
1511
21.0k
  }
1512
  Value createInsertValue(Value AggVal, Value EltVal, unsigned int Index,
1513
0
                          const char *Name = "") noexcept {
1514
0
    return LLVMBuildInsertValue(Ref, AggVal.unwrap(), EltVal.unwrap(), Index,
1515
0
                                Name);
1516
0
  }
1517
1518
610
  Value createIsNull(Value Val, const char *Name = "") noexcept {
1519
610
    return LLVMBuildIsNull(Ref, Val.unwrap(), Name);
1520
610
  }
1521
0
  Value createIsNotNull(Value Val, const char *Name = "") noexcept {
1522
0
    return LLVMBuildIsNotNull(Ref, Val.unwrap(), Name);
1523
0
  }
1524
  Value createFence(LLVMAtomicOrdering Ordering, bool SingleThread = false,
1525
188
                    const char *Name = "") noexcept {
1526
188
    return LLVMBuildFence(Ref, Ordering, SingleThread, Name);
1527
188
  }
1528
  Value createAtomicRMW(LLVMAtomicRMWBinOp Op, Value Ptr, Value Val,
1529
                        LLVMAtomicOrdering Ordering,
1530
0
                        bool SingleThread = false) noexcept {
1531
0
    return LLVMBuildAtomicRMW(Ref, Op, Ptr.unwrap(), Val.unwrap(), Ordering,
1532
0
                              SingleThread);
1533
0
  }
1534
  Value createAtomicCmpXchg(Value Ptr, Value Cmp, Value New,
1535
                            LLVMAtomicOrdering SuccessOrdering,
1536
                            LLVMAtomicOrdering FailureOrdering,
1537
0
                            bool SingleThread = false) noexcept {
1538
0
    return LLVMBuildAtomicCmpXchg(Ref, Ptr.unwrap(), Cmp.unwrap(), New.unwrap(),
1539
0
                                  SuccessOrdering, FailureOrdering,
1540
0
                                  SingleThread);
1541
0
  }
1542
1543
  Value createIntrinsic(unsigned int ID, Span<const Type> Types,
1544
                        Span<const Value> Args,
1545
58.3k
                        const char *Name = "") noexcept {
1546
58.3k
    FunctionCallee C;
1547
58.3k
    {
1548
58.3k
      const auto Data = const_cast<LLVMTypeRef *>(
1549
58.3k
          reinterpret_cast<const LLVMTypeRef *>(Types.data()));
1550
58.3k
      const auto Size = static_cast<unsigned int>(Types.size());
1551
58.3k
      C.Fn = LLVMGetIntrinsicDeclaration(getMod(), ID, Data, Size);
1552
58.3k
      C.Ty = LLVMIntrinsicGetType(getCtx(), ID, Data, Size);
1553
58.3k
    }
1554
58.3k
    return createCall(C, Args, Name);
1555
58.3k
  }
1556
  Value createUnaryIntrinsic(unsigned int ID, Value V,
1557
41.1k
                             const char *Name = "") noexcept {
1558
41.1k
    FunctionCallee C;
1559
41.1k
    {
1560
41.1k
      LLVMTypeRef ParamTypes[1] = {V.getType().unwrap()};
1561
41.1k
      C.Fn = LLVMGetIntrinsicDeclaration(getMod(), ID, ParamTypes, 1);
1562
41.1k
      C.Ty = LLVMIntrinsicGetType(getCtx(), ID, ParamTypes, 1);
1563
41.1k
    }
1564
41.1k
    return createCall(C, {V}, Name);
1565
41.1k
  }
1566
  Value createBinaryIntrinsic(unsigned int ID, Value LHS, Value RHS,
1567
0
                              const char *Name = "") noexcept {
1568
0
    FunctionCallee C;
1569
0
    {
1570
0
      LLVMTypeRef ParamTypes[2] = {LHS.getType().unwrap(),
1571
0
                                   RHS.getType().unwrap()};
1572
0
      C.Fn = LLVMGetIntrinsicDeclaration(getMod(), ID, ParamTypes, 2);
1573
0
      C.Ty = LLVMIntrinsicGetType(getCtx(), ID, ParamTypes, 2);
1574
0
    }
1575
0
    return createCall(C, {LHS, RHS}, Name);
1576
0
  }
1577
1578
  Value createVectorSplat(unsigned int ElementCount, Value V,
1579
34.4k
                          const char *Name = "") noexcept {
1580
34.4k
    Value Zero = Value::getConstInt(LLVMInt32TypeInContext(getCtx()), 0);
1581
34.4k
    auto Empty =
1582
34.4k
        Value::getUndef(Type::getVectorType(V.getType(), ElementCount));
1583
34.4k
    auto One = createInsertElement(Empty, V, Zero);
1584
34.4k
    std::vector<Value> Mask(ElementCount, Zero);
1585
34.4k
    return createShuffleVector(One, Empty, Value::getConstVector(Mask), Name);
1586
34.4k
  }
1587
1588
34.9k
  Value createLikely(Value V) noexcept {
1589
34.9k
    Type Int1Ty = LLVMInt1TypeInContext(getCtx());
1590
34.9k
    return createIntrinsic(LLVM::Core::Expect, {Int1Ty},
1591
34.9k
                           {V, Value::getConstInt(Int1Ty, 1)});
1592
34.9k
  }
1593
1594
5.64k
  Value getConstrainedFPRounding() noexcept {
1595
5.64k
    using namespace std::literals;
1596
5.64k
    auto Ctx = getCtx();
1597
5.64k
    auto RoundingStr = "round.tonearest"sv;
1598
5.64k
    auto RoundingMDS =
1599
5.64k
        LLVMMDStringInContext2(Ctx, RoundingStr.data(), RoundingStr.size());
1600
5.64k
    return LLVMMetadataAsValue(Ctx, RoundingMDS);
1601
5.64k
  }
1602
6.28k
  Value getConstrainedFPExcept() noexcept {
1603
6.28k
    using namespace std::literals;
1604
6.28k
    auto Ctx = getCtx();
1605
6.28k
    auto ExceptStr = "fpexcept.strict"sv;
1606
6.28k
    auto ExceptMDS =
1607
6.28k
        LLVMMDStringInContext2(Ctx, ExceptStr.data(), ExceptStr.size());
1608
6.28k
    return LLVMMetadataAsValue(Ctx, ExceptMDS);
1609
6.28k
  }
1610
1611
1.75k
  Value createArray(size_t Num, uint32_t Align) noexcept {
1612
1.75k
    Value Size = Value::getConstInt(LLVMInt64TypeInContext(getCtx()),
1613
1.75k
                                    static_cast<uint64_t>(Num) * Align);
1614
1.75k
    Type Int8Ty = LLVMInt8TypeInContext(getCtx());
1615
1.75k
    if (Num > 0) {
1616
1.03k
      auto Arr = createArrayAlloca(Int8Ty, Size);
1617
1.03k
      Arr.setAlignment(Align);
1618
1.03k
      return Arr;
1619
1.03k
    }
1620
719
    return Value::getConstPointerNull(Int8Ty.getPointerTo());
1621
1.75k
  }
1622
1623
  Value createValuePtrLoad(Type Ty, Value Ptr, Type PtrTy, uint64_t Idx0 = 0,
1624
4.61k
                           const char *Name = "") noexcept {
1625
4.61k
    auto VPtr = createConstInBoundsGEP1_64(PtrTy, Ptr, Idx0, Name);
1626
4.61k
    return createLoad(Ty, createBitCast(VPtr, Ty.getPointerTo()));
1627
4.61k
  }
1628
1629
  void createValuePtrStore(Value V, Value Ptr, Type PtrTy, uint64_t Idx0 = 0,
1630
2.31k
                           const char *Name = "") noexcept {
1631
2.31k
    auto VPtr = createConstInBoundsGEP1_64(PtrTy, Ptr, Idx0, Name);
1632
2.31k
    createStore(V, createBitCast(VPtr, V.getType().getPointerTo(), Name));
1633
2.31k
  }
1634
1635
  std::vector<Value> createArrayPtrLoad(size_t RetSize, Type Ty, Value Ptr,
1636
                                        Type PtrTy, uint32_t Align = 1,
1637
43
                                        const char *Name = "") noexcept {
1638
43
    std::vector<Value> ValVec;
1639
43
    ValVec.reserve(RetSize);
1640
129
    for (size_t I = 0; I < RetSize; ++I) {
1641
86
      auto VPtr = createConstInBoundsGEP1_64(PtrTy, Ptr, I * Align, Name);
1642
86
      auto TargetTy = Ty.getStructElementType(static_cast<unsigned int>(I));
1643
86
      ValVec.push_back(
1644
86
          createLoad(TargetTy, createBitCast(VPtr, TargetTy.getPointerTo())));
1645
86
    }
1646
43
    return ValVec;
1647
43
  }
1648
1649
  void createArrayPtrStore(Span<const Value> Vals, Value Ptr, Type PtrTy,
1650
899
                           uint32_t Align = 1, const char *Name = "") noexcept {
1651
2.26k
    for (size_t I = 0; I < Vals.size(); ++I) {
1652
1.36k
      auto VPtr = createConstInBoundsGEP1_64(PtrTy, Ptr, I * Align, Name);
1653
1.36k
      auto Val = Vals[I];
1654
1.36k
      createStore(Val, createBitCast(VPtr, Val.getType().getPointerTo()), Name);
1655
1.36k
    }
1656
899
  }
1657
1658
private:
1659
  LLVMBuilderRef Ref = nullptr;
1660
};
1661
1662
class Target {
1663
public:
1664
1.96k
  constexpr Target() noexcept = default;
1665
0
  constexpr Target(LLVMTargetRef R) noexcept : Ref(R) {}
1666
  Target(const Target &) = delete;
1667
  Target &operator=(const Target &) = delete;
1668
0
  Target(Target &&M) noexcept : Target() { swap(*this, M); }
1669
0
  Target &operator=(Target &&M) noexcept {
1670
0
    swap(*this, M);
1671
0
    return *this;
1672
0
  }
1673
1674
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1675
3.92k
  constexpr auto &unwrap() noexcept { return Ref; }
1676
0
  friend void swap(Target &LHS, Target &RHS) noexcept {
1677
0
    using std::swap;
1678
0
    swap(LHS.Ref, RHS.Ref);
1679
0
  }
1680
1681
1.96k
  static std::pair<Target, Message> getFromTriple(const char *Triple) noexcept {
1682
1.96k
    std::pair<Target, Message> Result;
1683
1.96k
    LLVMGetTargetFromTriple(Triple, &Result.first.unwrap(),
1684
1.96k
                            &Result.second.unwrap());
1685
1.96k
    return Result;
1686
1.96k
  }
1687
1688
private:
1689
  LLVMTargetRef Ref = nullptr;
1690
};
1691
1692
#if LLVM_VERSION_MAJOR < 13
1693
class PassManager {
1694
public:
1695
  constexpr PassManager() noexcept = default;
1696
3.92k
  constexpr PassManager(LLVMPassManagerRef R) noexcept : Ref(R) {}
1697
  PassManager(const PassManager &) = delete;
1698
  PassManager &operator=(const PassManager &) = delete;
1699
0
  PassManager(PassManager &&M) noexcept : PassManager() { swap(*this, M); }
1700
0
  PassManager &operator=(PassManager &&M) noexcept {
1701
0
    swap(*this, M);
1702
0
    return *this;
1703
0
  }
1704
1705
3.92k
  ~PassManager() noexcept { LLVMDisposePassManager(Ref); }
1706
1707
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1708
0
  constexpr auto &unwrap() const noexcept { return Ref; }
1709
7.84k
  constexpr auto &unwrap() noexcept { return Ref; }
1710
0
  friend void swap(PassManager &LHS, PassManager &RHS) noexcept {
1711
0
    using std::swap;
1712
0
    swap(LHS.Ref, RHS.Ref);
1713
0
  }
1714
1715
1.96k
  static PassManager create() noexcept { return LLVMCreatePassManager(); }
1716
1717
1.96k
  static PassManager createForModule(Module &M) noexcept {
1718
1.96k
    return LLVMCreateFunctionPassManagerForModule(M.unwrap());
1719
1.96k
  }
1720
1721
0
  void addTailCallEliminationPass() noexcept {
1722
0
    LLVMAddTailCallEliminationPass(Ref);
1723
0
  }
1724
0
  void addAlwaysInlinerPass() noexcept { LLVMAddAlwaysInlinerPass(Ref); }
1725
1726
1.96k
  void initializeFunctionPassManager() noexcept {
1727
1.96k
    LLVMInitializeFunctionPassManager(Ref);
1728
1.96k
  }
1729
1.96k
  void finalizeFunctionPassManager() noexcept {
1730
1.96k
    LLVMFinalizeFunctionPassManager(Ref);
1731
1.96k
  }
1732
19.3k
  void runFunctionPassManager(Value F) noexcept {
1733
19.3k
    LLVMRunFunctionPassManager(Ref, F.unwrap());
1734
19.3k
  }
1735
1.96k
  void runPassManager(Module &M) noexcept {
1736
1.96k
    LLVMRunPassManager(Ref, M.unwrap());
1737
1.96k
  }
1738
1739
private:
1740
  LLVMPassManagerRef Ref = nullptr;
1741
};
1742
1743
class PassManagerBuilder {
1744
public:
1745
  constexpr PassManagerBuilder() noexcept = default;
1746
1.96k
  constexpr PassManagerBuilder(LLVMPassManagerBuilderRef R) noexcept : Ref(R) {}
1747
  PassManagerBuilder(const PassManagerBuilder &) = delete;
1748
  PassManagerBuilder &operator=(const PassManagerBuilder &) = delete;
1749
0
  PassManagerBuilder(PassManagerBuilder &&M) noexcept : PassManagerBuilder() {
1750
0
    swap(*this, M);
1751
0
  }
1752
0
  PassManagerBuilder &operator=(PassManagerBuilder &&M) noexcept {
1753
0
    swap(*this, M);
1754
0
    return *this;
1755
0
  }
1756
1757
1.96k
  ~PassManagerBuilder() noexcept { LLVMPassManagerBuilderDispose(Ref); }
1758
1759
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1760
0
  constexpr auto &unwrap() const noexcept { return Ref; }
1761
0
  constexpr auto &unwrap() noexcept { return Ref; }
1762
0
  friend void swap(PassManagerBuilder &LHS, PassManagerBuilder &RHS) noexcept {
1763
0
    using std::swap;
1764
0
    swap(LHS.Ref, RHS.Ref);
1765
0
  }
1766
1767
1.96k
  static PassManagerBuilder create() noexcept {
1768
1.96k
    return LLVMPassManagerBuilderCreate();
1769
1.96k
  }
1770
1.96k
  void setOptLevel(unsigned int OptLevel) noexcept {
1771
1.96k
    LLVMPassManagerBuilderSetOptLevel(Ref, OptLevel);
1772
1.96k
  }
1773
1.96k
  void setSizeLevel(unsigned int SizeLevel) noexcept {
1774
1.96k
    LLVMPassManagerBuilderSetSizeLevel(Ref, SizeLevel);
1775
1.96k
  }
1776
1.96k
  void populateFunctionPassManager(PassManager &P) noexcept {
1777
1.96k
    LLVMPassManagerBuilderPopulateFunctionPassManager(Ref, P.unwrap());
1778
1.96k
  }
1779
1.96k
  void populateModulePassManager(PassManager &P) noexcept {
1780
1.96k
    LLVMPassManagerBuilderPopulateModulePassManager(Ref, P.unwrap());
1781
1.96k
  }
1782
1783
private:
1784
  LLVMPassManagerBuilderRef Ref = nullptr;
1785
};
1786
#endif
1787
1788
class TargetMachine {
1789
public:
1790
1.96k
  constexpr TargetMachine() noexcept = default;
1791
1.96k
  constexpr TargetMachine(LLVMTargetMachineRef R) noexcept : Ref(R) {}
1792
  TargetMachine(const TargetMachine &) = delete;
1793
  TargetMachine &operator=(const TargetMachine &) = delete;
1794
0
  TargetMachine(TargetMachine &&M) noexcept : TargetMachine() {
1795
0
    swap(*this, M);
1796
0
  }
1797
1.96k
  TargetMachine &operator=(TargetMachine &&M) noexcept {
1798
1.96k
    swap(*this, M);
1799
1.96k
    return *this;
1800
1.96k
  }
1801
1802
3.92k
  ~TargetMachine() noexcept { LLVMDisposeTargetMachine(Ref); }
1803
1804
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1805
0
  constexpr auto &unwrap() const noexcept { return Ref; }
1806
0
  constexpr auto &unwrap() noexcept { return Ref; }
1807
1.96k
  friend void swap(TargetMachine &LHS, TargetMachine &RHS) noexcept {
1808
1.96k
    using std::swap;
1809
1.96k
    swap(LHS.Ref, RHS.Ref);
1810
1.96k
  }
1811
1812
  static TargetMachine create(Target &T, const char *Triple, const char *CPU,
1813
                              const char *Features, LLVMCodeGenOptLevel Level,
1814
                              LLVMRelocMode Reloc,
1815
1.96k
                              LLVMCodeModel CodeModel) noexcept {
1816
1.96k
    return LLVMCreateTargetMachine(T.unwrap(), Triple, CPU, Features, Level,
1817
1.96k
                                   Reloc, CodeModel);
1818
1.96k
  }
1819
1820
#if LLVM_VERSION_MAJOR < 13
1821
3.92k
  void addAnalysisPasses(PassManager &P) noexcept {
1822
3.92k
    LLVMAddAnalysisPasses(Ref, P.unwrap());
1823
3.92k
  }
1824
#endif
1825
1826
  std::pair<MemoryBuffer, Message>
1827
1.96k
  emitToMemoryBuffer(Module &M, LLVMCodeGenFileType CodeGen) noexcept {
1828
1.96k
    std::pair<MemoryBuffer, Message> Result;
1829
1.96k
    LLVMTargetMachineEmitToMemoryBuffer(Ref, M.unwrap(), CodeGen,
1830
1.96k
                                        &Result.second.unwrap(),
1831
1.96k
                                        &Result.first.unwrap());
1832
1.96k
    return Result;
1833
1.96k
  }
1834
1835
private:
1836
  LLVMTargetMachineRef Ref = nullptr;
1837
};
1838
1839
#if LLVM_VERSION_MAJOR >= 13
1840
class PassBuilderOptions {
1841
public:
1842
  constexpr PassBuilderOptions() noexcept = default;
1843
  constexpr PassBuilderOptions(LLVMPassBuilderOptionsRef R) noexcept : Ref(R) {}
1844
  PassBuilderOptions(const PassBuilderOptions &) = delete;
1845
  PassBuilderOptions &operator=(const PassBuilderOptions &) = delete;
1846
  PassBuilderOptions(PassBuilderOptions &&O) noexcept : PassBuilderOptions() {
1847
    swap(*this, O);
1848
  }
1849
  PassBuilderOptions &operator=(PassBuilderOptions &&O) noexcept {
1850
    swap(*this, O);
1851
    return *this;
1852
  }
1853
1854
  ~PassBuilderOptions() noexcept { LLVMDisposePassBuilderOptions(Ref); }
1855
1856
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1857
  constexpr auto &unwrap() noexcept { return Ref; }
1858
  friend void swap(PassBuilderOptions &LHS, PassBuilderOptions &RHS) noexcept {
1859
    using std::swap;
1860
    swap(LHS.Ref, RHS.Ref);
1861
  }
1862
1863
  static PassBuilderOptions create() noexcept {
1864
    return LLVMCreatePassBuilderOptions();
1865
  }
1866
1867
  void setVerifyEach(bool VerifyEach) noexcept {
1868
    LLVMPassBuilderOptionsSetVerifyEach(Ref, VerifyEach);
1869
  }
1870
1871
  void setDebugLogging(bool DebugLogging) noexcept {
1872
    LLVMPassBuilderOptionsSetDebugLogging(Ref, DebugLogging);
1873
  }
1874
1875
  void setLoopInterleaving(bool LoopInterleaving) noexcept {
1876
    LLVMPassBuilderOptionsSetLoopInterleaving(Ref, LoopInterleaving);
1877
  }
1878
1879
  void setLoopVectorization(bool LoopVectorization) noexcept {
1880
    LLVMPassBuilderOptionsSetLoopVectorization(Ref, LoopVectorization);
1881
  }
1882
1883
  void setSLPVectorization(bool SLPVectorization) noexcept {
1884
    LLVMPassBuilderOptionsSetSLPVectorization(Ref, SLPVectorization);
1885
  }
1886
1887
  void setLoopUnrolling(bool LoopUnrolling) noexcept {
1888
    LLVMPassBuilderOptionsSetLoopUnrolling(Ref, LoopUnrolling);
1889
  }
1890
1891
  void setForgetAllSCEVInLoopUnroll(bool ForgetAllSCEVInLoopUnroll) noexcept {
1892
    LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll(
1893
        Ref, ForgetAllSCEVInLoopUnroll);
1894
  }
1895
1896
  void setLicmMssaOptCap(unsigned int LicmMssaOptCap) noexcept {
1897
    LLVMPassBuilderOptionsSetLicmMssaOptCap(Ref, LicmMssaOptCap);
1898
  }
1899
1900
  void setLicmMssaNoAccForPromotionCap(
1901
      unsigned int LicmMssaNoAccForPromotionCap) noexcept {
1902
    LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap(
1903
        Ref, LicmMssaNoAccForPromotionCap);
1904
  }
1905
1906
  void setCallGraphProfile(bool CallGraphProfile) noexcept {
1907
    LLVMPassBuilderOptionsSetCallGraphProfile(Ref, CallGraphProfile);
1908
  }
1909
1910
  void setMergeFunctions(bool MergeFunctions) noexcept {
1911
    LLVMPassBuilderOptionsSetMergeFunctions(Ref, MergeFunctions);
1912
  }
1913
1914
  Error runPasses(Module &M, const char *Passes,
1915
                  const TargetMachine &TM = nullptr) noexcept {
1916
    return LLVMRunPasses(M.unwrap(), Passes, TM.unwrap(), Ref);
1917
  }
1918
1919
private:
1920
  LLVMPassBuilderOptionsRef Ref = nullptr;
1921
};
1922
#endif
1923
1924
class SectionIterator {
1925
public:
1926
  constexpr SectionIterator() noexcept = default;
1927
3.92k
  constexpr SectionIterator(LLVMSectionIteratorRef R) noexcept : Ref(R) {}
1928
  SectionIterator(const SectionIterator &) = delete;
1929
  SectionIterator &operator=(const SectionIterator &) = delete;
1930
0
  SectionIterator(SectionIterator &&B) noexcept : SectionIterator() {
1931
0
    swap(*this, B);
1932
0
  }
1933
0
  SectionIterator &operator=(SectionIterator &&B) noexcept {
1934
0
    swap(*this, B);
1935
0
    return *this;
1936
0
  }
1937
1938
3.92k
  ~SectionIterator() noexcept { LLVMDisposeSectionIterator(Ref); }
1939
1940
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1941
62.0k
  constexpr auto &unwrap() const noexcept { return Ref; }
1942
0
  constexpr auto &unwrap() noexcept { return Ref; }
1943
0
  friend void swap(SectionIterator &LHS, SectionIterator &RHS) noexcept {
1944
0
    using std::swap;
1945
0
    swap(LHS.Ref, RHS.Ref);
1946
0
  }
1947
1948
58.1k
  void next() const noexcept { LLVMMoveToNextSection(Ref); }
1949
1950
54.2k
  const char *getName() const noexcept { return LLVMGetSectionName(Ref); }
1951
9.47k
  uint64_t getAddress() const noexcept { return LLVMGetSectionAddress(Ref); }
1952
85.2k
  uint64_t getSize() const noexcept { return LLVMGetSectionSize(Ref); }
1953
25.1k
  Span<const uint8_t> getContents() const noexcept {
1954
25.1k
    return {reinterpret_cast<const uint8_t *>(LLVMGetSectionContents(Ref)),
1955
25.1k
            static_cast<size_t>(LLVMGetSectionSize(Ref))};
1956
25.1k
  }
1957
1958
  inline bool isText() const noexcept;
1959
  inline bool isData() const noexcept;
1960
  inline bool isBSS() const noexcept;
1961
  inline bool isPData() const noexcept;
1962
  inline bool isEHFrame() const noexcept;
1963
  inline bool isVirtual() const noexcept;
1964
1965
private:
1966
  LLVMSectionIteratorRef Ref = nullptr;
1967
};
1968
1969
class SymbolIterator {
1970
public:
1971
  constexpr SymbolIterator() noexcept = default;
1972
1.96k
  constexpr SymbolIterator(LLVMSymbolIteratorRef R) noexcept : Ref(R) {}
1973
  SymbolIterator(const SymbolIterator &) = delete;
1974
  SymbolIterator &operator=(const SymbolIterator &) = delete;
1975
0
  SymbolIterator(SymbolIterator &&B) noexcept : SymbolIterator() {
1976
0
    swap(*this, B);
1977
0
  }
1978
0
  SymbolIterator &operator=(SymbolIterator &&B) noexcept {
1979
0
    swap(*this, B);
1980
0
    return *this;
1981
0
  }
1982
1983
1.96k
  ~SymbolIterator() noexcept { LLVMDisposeSymbolIterator(Ref); }
1984
1985
21.0k
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1986
21.0k
  constexpr auto &unwrap() const noexcept { return Ref; }
1987
0
  constexpr auto &unwrap() noexcept { return Ref; }
1988
0
  friend void swap(SymbolIterator &LHS, SymbolIterator &RHS) noexcept {
1989
0
    using std::swap;
1990
0
    swap(LHS.Ref, RHS.Ref);
1991
0
  }
1992
1993
19.0k
  void next() const noexcept { LLVMMoveToNextSymbol(Ref); }
1994
1995
19.0k
  const char *getName() const noexcept { return LLVMGetSymbolName(Ref); }
1996
19.0k
  uint64_t getAddress() const noexcept { return LLVMGetSymbolAddress(Ref); }
1997
0
  uint64_t getSize() const noexcept { return LLVMGetSymbolSize(Ref); }
1998
1999
private:
2000
  LLVMSymbolIteratorRef Ref = nullptr;
2001
};
2002
2003
class Binary {
2004
public:
2005
3.92k
  constexpr Binary() noexcept = default;
2006
1.96k
  constexpr Binary(LLVMBinaryRef R) noexcept : Ref(R) {}
2007
  Binary(const Binary &) = delete;
2008
  Binary &operator=(const Binary &) = delete;
2009
0
  Binary(Binary &&B) noexcept : Binary() { swap(*this, B); }
2010
3.92k
  Binary &operator=(Binary &&B) noexcept {
2011
3.92k
    swap(*this, B);
2012
3.92k
    return *this;
2013
3.92k
  }
2014
2015
5.88k
  ~Binary() noexcept { LLVMDisposeBinary(Ref); }
2016
2017
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2018
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2019
0
  constexpr auto &unwrap() noexcept { return Ref; }
2020
3.92k
  friend void swap(Binary &LHS, Binary &RHS) noexcept {
2021
3.92k
    using std::swap;
2022
3.92k
    swap(LHS.Ref, RHS.Ref);
2023
3.92k
  }
2024
2025
  static std::pair<Binary, Message> create(MemoryBuffer &M,
2026
1.96k
                                           Context &C) noexcept {
2027
1.96k
    std::pair<Binary, Message> Result;
2028
1.96k
    Result.first =
2029
1.96k
        LLVMCreateBinary(M.unwrap(), C.unwrap(), &Result.second.unwrap());
2030
1.96k
    return Result;
2031
1.96k
  }
2032
2033
0
  LLVMBinaryType getType() const noexcept { return LLVMBinaryGetType(Ref); }
2034
3.92k
  SectionIterator sections() const noexcept {
2035
3.92k
    return LLVMObjectFileCopySectionIterator(Ref);
2036
3.92k
  }
2037
62.0k
  bool isSectionEnd(const SectionIterator &It) const noexcept {
2038
62.0k
    return LLVMObjectFileIsSectionIteratorAtEnd(Ref, It.unwrap());
2039
62.0k
  }
2040
1.96k
  SymbolIterator symbols() const noexcept {
2041
1.96k
    return LLVMObjectFileCopySymbolIterator(Ref);
2042
1.96k
  }
2043
21.0k
  bool isSymbolEnd(const SymbolIterator &It) const noexcept {
2044
21.0k
    return LLVMObjectFileIsSymbolIteratorAtEnd(Ref, It.unwrap());
2045
21.0k
  }
2046
2047
private:
2048
  LLVMBinaryRef Ref = nullptr;
2049
};
2050
2051
class OrcThreadSafeContext {
2052
public:
2053
  constexpr OrcThreadSafeContext(LLVMOrcThreadSafeContextRef R) noexcept
2054
0
      : Ref(R) {}
2055
  OrcThreadSafeContext(const OrcThreadSafeContext &) = delete;
2056
  OrcThreadSafeContext &operator=(const OrcThreadSafeContext &) = delete;
2057
  OrcThreadSafeContext(OrcThreadSafeContext &&B) noexcept
2058
0
      : OrcThreadSafeContext() {
2059
0
    swap(*this, B);
2060
0
  }
2061
0
  OrcThreadSafeContext &operator=(OrcThreadSafeContext &&B) noexcept {
2062
0
    swap(*this, B);
2063
0
    return *this;
2064
0
  }
2065
2066
1.96k
  OrcThreadSafeContext() noexcept : Ref(LLVMOrcCreateNewThreadSafeContext()) {}
2067
1.96k
  ~OrcThreadSafeContext() noexcept { LLVMOrcDisposeThreadSafeContext(Ref); }
2068
2069
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2070
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2071
0
  constexpr auto &unwrap() noexcept { return Ref; }
2072
0
  LLVMOrcThreadSafeContextRef release() noexcept {
2073
0
    return std::exchange(Ref, nullptr);
2074
0
  }
2075
  friend void swap(OrcThreadSafeContext &LHS,
2076
0
                   OrcThreadSafeContext &RHS) noexcept {
2077
0
    using std::swap;
2078
0
    swap(LHS.Ref, RHS.Ref);
2079
0
  }
2080
2081
5.88k
  Context getContext() noexcept {
2082
5.88k
    return LLVMOrcThreadSafeContextGetContext(Ref);
2083
5.88k
  }
2084
2085
private:
2086
  LLVMOrcThreadSafeContextRef Ref = nullptr;
2087
};
2088
2089
class OrcThreadSafeModule {
2090
public:
2091
  constexpr OrcThreadSafeModule() noexcept = default;
2092
  constexpr OrcThreadSafeModule(LLVMOrcThreadSafeModuleRef R) noexcept
2093
0
      : Ref(R) {}
2094
  OrcThreadSafeModule(const OrcThreadSafeModule &) = delete;
2095
  OrcThreadSafeModule &operator=(const OrcThreadSafeModule &) = delete;
2096
  OrcThreadSafeModule(OrcThreadSafeModule &&B) noexcept
2097
0
      : OrcThreadSafeModule() {
2098
0
    swap(*this, B);
2099
0
  }
2100
0
  OrcThreadSafeModule &operator=(OrcThreadSafeModule &&B) noexcept {
2101
0
    swap(*this, B);
2102
0
    return *this;
2103
0
  }
2104
2105
  OrcThreadSafeModule(Module &&M, OrcThreadSafeContext &C) noexcept
2106
0
      : Ref(LLVMOrcCreateNewThreadSafeModule(M.release(), C.unwrap())) {}
2107
0
  ~OrcThreadSafeModule() noexcept { LLVMOrcDisposeThreadSafeModule(Ref); }
2108
2109
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2110
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2111
0
  constexpr auto &unwrap() noexcept { return Ref; }
2112
0
  LLVMOrcThreadSafeModuleRef release() noexcept {
2113
0
    return std::exchange(Ref, nullptr);
2114
0
  }
2115
  friend void swap(OrcThreadSafeModule &LHS,
2116
0
                   OrcThreadSafeModule &RHS) noexcept {
2117
0
    using std::swap;
2118
0
    swap(LHS.Ref, RHS.Ref);
2119
0
  }
2120
  Error withModuleDo(LLVMOrcGenericIRModuleOperationFunction F,
2121
0
                     void *Ctx) noexcept {
2122
0
    return LLVMOrcThreadSafeModuleWithModuleDo(Ref, F, Ctx);
2123
0
  }
2124
2125
private:
2126
  LLVMOrcThreadSafeModuleRef Ref = nullptr;
2127
};
2128
2129
class OrcJITDylib {
2130
public:
2131
  constexpr OrcJITDylib() noexcept = default;
2132
0
  constexpr OrcJITDylib(LLVMOrcJITDylibRef R) noexcept : Ref(R) {}
2133
  OrcJITDylib(const OrcJITDylib &) = delete;
2134
  OrcJITDylib &operator=(const OrcJITDylib &) = delete;
2135
0
  OrcJITDylib(OrcJITDylib &&B) noexcept : OrcJITDylib() { swap(*this, B); }
2136
0
  OrcJITDylib &operator=(OrcJITDylib &&B) noexcept {
2137
0
    swap(*this, B);
2138
0
    return *this;
2139
0
  }
2140
2141
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2142
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2143
0
  constexpr auto &unwrap() noexcept { return Ref; }
2144
0
  friend void swap(OrcJITDylib &LHS, OrcJITDylib &RHS) noexcept {
2145
0
    using std::swap;
2146
0
    swap(LHS.Ref, RHS.Ref);
2147
0
  }
2148
2149
private:
2150
  LLVMOrcJITDylibRef Ref = nullptr;
2151
};
2152
2153
class OrcIRTransformLayer {
2154
public:
2155
  constexpr OrcIRTransformLayer() noexcept = default;
2156
  constexpr OrcIRTransformLayer(LLVMOrcIRTransformLayerRef R) noexcept
2157
0
      : Ref(R) {}
2158
  OrcIRTransformLayer(const OrcIRTransformLayer &) = delete;
2159
  OrcIRTransformLayer &operator=(const OrcIRTransformLayer &) = delete;
2160
  OrcIRTransformLayer(OrcIRTransformLayer &&B) noexcept
2161
0
      : OrcIRTransformLayer() {
2162
0
    swap(*this, B);
2163
0
  }
2164
0
  OrcIRTransformLayer &operator=(OrcIRTransformLayer &&B) noexcept {
2165
0
    swap(*this, B);
2166
0
    return *this;
2167
0
  }
2168
2169
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2170
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2171
0
  constexpr auto &unwrap() noexcept { return Ref; }
2172
  friend void swap(OrcIRTransformLayer &LHS,
2173
0
                   OrcIRTransformLayer &RHS) noexcept {
2174
0
    using std::swap;
2175
0
    swap(LHS.Ref, RHS.Ref);
2176
0
  }
2177
2178
  void setTransform(LLVMOrcIRTransformLayerTransformFunction TransformFunction,
2179
0
                    void *Ctx) noexcept {
2180
0
    LLVMOrcIRTransformLayerSetTransform(Ref, TransformFunction, Ctx);
2181
0
  }
2182
2183
private:
2184
  LLVMOrcIRTransformLayerRef Ref = nullptr;
2185
};
2186
2187
class OrcLLJIT {
2188
public:
2189
0
  constexpr OrcLLJIT() noexcept = default;
2190
0
  constexpr OrcLLJIT(LLVMOrcLLJITRef R) noexcept : Ref(R) {}
2191
  OrcLLJIT(const OrcLLJIT &) = delete;
2192
  OrcLLJIT &operator=(const OrcLLJIT &) = delete;
2193
0
  OrcLLJIT(OrcLLJIT &&B) noexcept : OrcLLJIT() { swap(*this, B); }
2194
0
  OrcLLJIT &operator=(OrcLLJIT &&B) noexcept {
2195
0
    swap(*this, B);
2196
0
    return *this;
2197
0
  }
2198
2199
0
  ~OrcLLJIT() noexcept { LLVMOrcDisposeLLJIT(Ref); }
2200
2201
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2202
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2203
0
  constexpr auto &unwrap() noexcept { return Ref; }
2204
0
  friend void swap(OrcLLJIT &LHS, OrcLLJIT &RHS) noexcept {
2205
0
    using std::swap;
2206
0
    swap(LHS.Ref, RHS.Ref);
2207
0
  }
2208
2209
0
  static cxx20::expected<OrcLLJIT, Error> create() noexcept {
2210
0
    OrcLLJIT Result;
2211
0
    if (auto Err = LLVMOrcCreateLLJIT(&Result.Ref, getBuilder())) {
2212
0
      return cxx20::unexpected(Err);
2213
0
    } else {
2214
0
      return Result;
2215
0
    }
2216
0
  }
2217
2218
0
  OrcJITDylib getMainJITDylib() noexcept {
2219
0
    return LLVMOrcLLJITGetMainJITDylib(Ref);
2220
0
  }
2221
2222
0
  Error addLLVMIRModule(const OrcJITDylib &L, OrcThreadSafeModule M) noexcept {
2223
0
    return LLVMOrcLLJITAddLLVMIRModule(Ref, L.unwrap(), M.release());
2224
0
  }
2225
2226
  template <typename T>
2227
0
  cxx20::expected<T *, Error> lookup(const char *Name) noexcept {
2228
0
    LLVMOrcJITTargetAddress Addr;
2229
0
    if (auto Err = LLVMOrcLLJITLookup(Ref, &Addr, Name)) {
2230
0
      return cxx20::unexpected(Err);
2231
0
    }
2232
0
    return reinterpret_cast<T *>(Addr);
2233
0
  }
Unexecuted instantiation: cxx20::expected<void* const (**) [38], WasmEdge::LLVM::Error> WasmEdge::LLVM::OrcLLJIT::lookup<void* const (*) [38]>(char const*)
Unexecuted instantiation: cxx20::expected<void (*)(void*, void*, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant>*), WasmEdge::LLVM::Error> WasmEdge::LLVM::OrcLLJIT::lookup<void (void*, void*, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant>*)>(char const*)
Unexecuted instantiation: cxx20::expected<void*, WasmEdge::LLVM::Error> WasmEdge::LLVM::OrcLLJIT::lookup<void>(char const*)
2234
2235
0
  OrcIRTransformLayer getIRTransformLayer() noexcept {
2236
0
    return LLVMOrcLLJITGetIRTransformLayer(Ref);
2237
0
  }
2238
2239
private:
2240
  LLVMOrcLLJITRef Ref = nullptr;
2241
2242
  static inline LLVMOrcLLJITBuilderRef getBuilder() noexcept;
2243
};
2244
2245
} // namespace WasmEdge::LLVM
2246
2247
#include <llvm/IR/GlobalValue.h>
2248
#include <llvm/Object/ObjectFile.h>
2249
#include <llvm/Transforms/Utils/BasicBlockUtils.h>
2250
#if LLVM_VERSION_MAJOR < 12 || WASMEDGE_OS_WINDOWS
2251
#include <llvm/ExecutionEngine/Orc/Core.h>
2252
#endif
2253
#if LLVM_VERSION_MAJOR < 13
2254
#include <llvm/ExecutionEngine/Orc/LLJIT.h>
2255
#include <llvm/Support/CBindingWrapping.h>
2256
#include <llvm/Support/Error.h>
2257
#endif
2258
2259
#if WASMEDGE_OS_WINDOWS
2260
#include <llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h>
2261
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
2262
#include <llvm/Support/Process.h>
2263
#include <system/winapi.h>
2264
#endif
2265
2266
namespace llvm {
2267
#if WASMEDGE_OS_WINDOWS
2268
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::ExecutionSession,
2269
                                   LLVMOrcExecutionSessionRef)
2270
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::ObjectLayer, LLVMOrcObjectLayerRef)
2271
#endif
2272
#if LLVM_VERSION_MAJOR < 12
2273
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::LLJITBuilder, LLVMOrcLLJITBuilderRef)
2274
#endif
2275
#if LLVM_VERSION_MAJOR < 13
2276
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::ThreadSafeModule,
2277
                                   LLVMOrcThreadSafeModuleRef)
2278
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::IRTransformLayer,
2279
                                   LLVMOrcIRTransformLayerRef)
2280
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::MaterializationResponsibility,
2281
                                   LLVMOrcMaterializationResponsibilityRef)
2282
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::LLJIT, LLVMOrcLLJITRef)
2283
#endif
2284
} // namespace llvm
2285
2286
namespace WasmEdge::LLVM {
2287
2288
19.3k
void Value::setDSOLocal(bool Local) noexcept {
2289
19.3k
  llvm::cast<llvm::GlobalValue>(reinterpret_cast<llvm::Value *>(Ref))
2290
19.3k
      ->setDSOLocal(Local);
2291
19.3k
}
2292
2293
9.34k
void Value::eliminateUnreachableBlocks() noexcept {
2294
9.34k
  llvm::EliminateUnreachableBlocks(
2295
9.34k
      *llvm::cast<llvm::Function>(reinterpret_cast<llvm::Value *>(Ref)));
2296
9.34k
}
2297
2298
50.5k
bool SectionIterator::isText() const noexcept {
2299
50.5k
  auto *S = reinterpret_cast<const llvm::object::section_iterator *>(Ref);
2300
50.5k
  return (*S)->isText();
2301
50.5k
}
2302
2303
46.8k
bool SectionIterator::isData() const noexcept {
2304
46.8k
  auto *S = reinterpret_cast<const llvm::object::section_iterator *>(Ref);
2305
46.8k
  return (*S)->isData();
2306
46.8k
}
2307
2308
39.2k
bool SectionIterator::isBSS() const noexcept {
2309
39.2k
  auto *S = reinterpret_cast<const llvm::object::section_iterator *>(Ref);
2310
39.2k
  return (*S)->isBSS();
2311
39.2k
}
2312
2313
50.5k
bool SectionIterator::isPData() const noexcept {
2314
#if WASMEDGE_OS_WINDOWS
2315
  using namespace std::literals;
2316
  return ".pdata"sv == getName();
2317
#else
2318
50.5k
  return false;
2319
50.5k
#endif
2320
50.5k
}
2321
2322
54.2k
bool SectionIterator::isEHFrame() const noexcept {
2323
54.2k
#if WASMEDGE_OS_LINUX
2324
54.2k
  using namespace std::literals;
2325
54.2k
  return ".eh_frame"sv == getName();
2326
#elif WASMEDGE_OS_MACOS
2327
  using namespace std::literals;
2328
  return "__eh_frame"sv == getName();
2329
#else
2330
  return false;
2331
#endif
2332
54.2k
}
2333
2334
27.1k
bool SectionIterator::isVirtual() const noexcept {
2335
27.1k
  auto *S = reinterpret_cast<const llvm::object::section_iterator *>(Ref);
2336
27.1k
  return (*S)->isVirtual();
2337
27.1k
}
2338
2339
#if WASMEDGE_OS_WINDOWS
2340
class DefaultMMapper final : public llvm::SectionMemoryManager::MemoryMapper {
2341
public:
2342
  llvm::sys::MemoryBlock allocateMappedMemory(
2343
      llvm::SectionMemoryManager::AllocationPurpose /*Purpose*/,
2344
      size_t NumBytes, const llvm::sys::MemoryBlock *const NearBlock,
2345
      unsigned Flags, std::error_code &EC) override {
2346
    return llvm::sys::Memory::allocateMappedMemory(NumBytes, NearBlock, Flags,
2347
                                                   EC);
2348
  }
2349
  std::error_code protectMappedMemory(const llvm::sys::MemoryBlock &Block,
2350
                                      unsigned Flags) override {
2351
    return llvm::sys::Memory::protectMappedMemory(Block, Flags);
2352
  }
2353
2354
  std::error_code releaseMappedMemory(llvm::sys::MemoryBlock &M) override {
2355
    return llvm::sys::Memory::releaseMappedMemory(M);
2356
  }
2357
};
2358
2359
class ContiguousSectionMemoryManager : public llvm::RTDyldMemoryManager {
2360
public:
2361
  explicit ContiguousSectionMemoryManager(
2362
      llvm::SectionMemoryManager::MemoryMapper *UnownedMM = nullptr)
2363
      : MMapper(UnownedMM), OwnedMMapper(nullptr) {
2364
    if (!MMapper) {
2365
      OwnedMMapper = std::make_unique<DefaultMMapper>();
2366
      MMapper = OwnedMMapper.get();
2367
    }
2368
  }
2369
2370
  ~ContiguousSectionMemoryManager() noexcept override {
2371
    using namespace std::literals;
2372
    if (Preallocated.allocatedSize() != 0) {
2373
      auto EC = MMapper->releaseMappedMemory(Preallocated);
2374
      if (EC) {
2375
        spdlog::error("releaseMappedMemory failed with error: {}"sv,
2376
                      EC.message());
2377
      }
2378
    }
2379
  }
2380
2381
  bool needsToReserveAllocationSpace() override { return true; }
2382
2383
  void reserveAllocationSpace(uintptr_t CodeSize, llvm::Align CodeAlign,
2384
                              uintptr_t RODataSize, llvm::Align RODataAlign,
2385
                              uintptr_t RWDataSize,
2386
                              llvm::Align RWDataAlign) override {
2387
    using namespace std::literals;
2388
    assuming(Preallocated.allocatedSize() == 0);
2389
2390
    static const size_t PageSize = llvm::sys::Process::getPageSizeEstimate();
2391
    assuming(CodeAlign.value() <= PageSize);
2392
    assuming(RODataAlign.value() <= PageSize);
2393
    assuming(RWDataAlign.value() <= PageSize);
2394
    CodeSize = roundUpTo(CodeSize + CodeAlign.value(), PageSize);
2395
    RODataSize = roundUpTo(RODataSize + RODataAlign.value(), PageSize);
2396
    RWDataSize = roundUpTo(RWDataSize + RWDataAlign.value(), PageSize);
2397
    const uintptr_t TotalSize =
2398
        CodeSize + RODataSize + RWDataSize + PageSize * 3;
2399
2400
    std::error_code EC;
2401
    Preallocated = MMapper->allocateMappedMemory(
2402
        llvm::SectionMemoryManager::AllocationPurpose::Code, TotalSize, nullptr,
2403
        llvm::sys::Memory::MF_READ | llvm::sys::Memory::MF_WRITE, EC);
2404
    if (EC) {
2405
      spdlog::error("allocateMappedMemory failed with error: {}"sv,
2406
                    EC.message());
2407
      return;
2408
    }
2409
2410
    auto base = reinterpret_cast<std::uintptr_t>(Preallocated.base());
2411
    CodeMem = CodeFree =
2412
        llvm::sys::MemoryBlock(reinterpret_cast<void *>(base), CodeSize);
2413
    base += CodeSize;
2414
    RODataMem = RODataFree =
2415
        llvm::sys::MemoryBlock(reinterpret_cast<void *>(base), RODataSize);
2416
    base += RODataSize;
2417
    RWDataMem = RWDataFree =
2418
        llvm::sys::MemoryBlock(reinterpret_cast<void *>(base), RWDataSize);
2419
  }
2420
2421
  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
2422
                               unsigned /*SectionID*/,
2423
                               llvm::StringRef /*SectionName*/,
2424
                               bool IsReadOnly) override {
2425
    if (IsReadOnly) {
2426
      return Allocate(RODataFree, Size, Alignment);
2427
    } else {
2428
      return Allocate(RWDataFree, Size, Alignment);
2429
    }
2430
  }
2431
2432
  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
2433
                               unsigned /*SectionID*/,
2434
                               llvm::StringRef /*SectionName*/) override {
2435
    return Allocate(CodeFree, Size, Alignment);
2436
  }
2437
2438
  bool finalizeMemory(std::string *ErrMsg) override {
2439
    std::error_code EC;
2440
2441
    EC = MMapper->protectMappedMemory(CodeMem, llvm::sys::Memory::MF_READ |
2442
                                                   llvm::sys::Memory::MF_EXEC);
2443
    if (EC) {
2444
      if (ErrMsg) {
2445
        *ErrMsg = EC.message();
2446
      }
2447
      return true;
2448
    }
2449
    EC = MMapper->protectMappedMemory(RODataMem, llvm::sys::Memory::MF_READ);
2450
    if (EC) {
2451
      if (ErrMsg) {
2452
        *ErrMsg = EC.message();
2453
      }
2454
      return true;
2455
    }
2456
2457
    llvm::sys::Memory::InvalidateInstructionCache(CodeMem.base(),
2458
                                                  CodeMem.allocatedSize());
2459
    return false;
2460
  }
2461
2462
private:
2463
  llvm::sys::MemoryBlock Preallocated;
2464
2465
  // Sections must be in the order code < rodata < rwdata.
2466
  llvm::sys::MemoryBlock CodeMem;
2467
  llvm::sys::MemoryBlock RODataMem;
2468
  llvm::sys::MemoryBlock RWDataMem;
2469
2470
  llvm::sys::MemoryBlock CodeFree;
2471
  llvm::sys::MemoryBlock RODataFree;
2472
  llvm::sys::MemoryBlock RWDataFree;
2473
2474
  llvm::SectionMemoryManager::MemoryMapper *MMapper;
2475
  std::unique_ptr<llvm::SectionMemoryManager::MemoryMapper> OwnedMMapper;
2476
2477
  uint8_t *Allocate(llvm::sys::MemoryBlock &FreeBlock, std::uintptr_t Size,
2478
                    unsigned alignment) {
2479
    using namespace std::literals;
2480
    const auto Base = reinterpret_cast<uintptr_t>(FreeBlock.base());
2481
    const auto Start = roundUpTo(Base, alignment);
2482
    const uintptr_t PaddedSize = (Start - Base) + Size;
2483
    if (PaddedSize > FreeBlock.allocatedSize()) {
2484
      spdlog::error("Failed to satisfy suballocation request for {}"sv, Size);
2485
      return nullptr;
2486
    }
2487
    FreeBlock =
2488
        llvm::sys::MemoryBlock(reinterpret_cast<void *>(Base + PaddedSize),
2489
                               FreeBlock.allocatedSize() - PaddedSize);
2490
    return reinterpret_cast<uint8_t *>(Start);
2491
  }
2492
2493
  static uintptr_t roundUpTo(uintptr_t Value, uintptr_t Divisor) noexcept {
2494
    return ((Value + (Divisor - 1)) / Divisor) * Divisor;
2495
  }
2496
};
2497
2498
// Register stack unwind info for JIT functions
2499
class Win64EHManager : public ContiguousSectionMemoryManager {
2500
  using Base = ContiguousSectionMemoryManager;
2501
  uint64_t CodeAddress = 0;
2502
2503
public:
2504
  ~Win64EHManager() noexcept override {}
2505
2506
  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
2507
                               unsigned SectionID,
2508
                               llvm::StringRef SectionName) override {
2509
    using namespace std::literals;
2510
    const auto Allocated =
2511
        Base::allocateCodeSection(Size, Alignment, SectionID, SectionName);
2512
    if (SectionName == llvm::StringRef(".text"sv)) {
2513
      CodeAddress = reinterpret_cast<uint64_t>(Allocated);
2514
    }
2515
    return Allocated;
2516
  }
2517
2518
  void registerEHFrames(uint8_t *Addr, uint64_t /*LoadAddr*/,
2519
                        size_t Size) noexcept override {
2520
    using namespace std::literals;
2521
    winapi::RUNTIME_FUNCTION_ *const FunctionTable =
2522
        reinterpret_cast<winapi::RUNTIME_FUNCTION_ *>(Addr);
2523
    const uint32_t EntryCount =
2524
        static_cast<uint32_t>(Size / sizeof(winapi::RUNTIME_FUNCTION_));
2525
    if (EntryCount == 0)
2526
      return;
2527
    // Calculate object image base address by assuming that address of the first
2528
    // function is equal to the address of the code section
2529
    const auto ImageBase = CodeAddress - FunctionTable[0].BeginAddress;
2530
    winapi::RtlAddFunctionTable(FunctionTable, EntryCount, ImageBase);
2531
    EHFrames.push_back({Addr, Size});
2532
  }
2533
  void deregisterEHFrames() noexcept override {
2534
    using namespace std::literals;
2535
    for (auto &Frame : EHFrames) {
2536
      winapi::RtlDeleteFunctionTable(
2537
          reinterpret_cast<winapi::RUNTIME_FUNCTION_ *>(Frame.Addr));
2538
    }
2539
    EHFrames.clear();
2540
  }
2541
};
2542
2543
LLVMOrcLLJITBuilderRef OrcLLJIT::getBuilder() noexcept {
2544
  using llvm::unwrap;
2545
  using llvm::wrap;
2546
  const LLVMOrcLLJITBuilderRef Builder = LLVMOrcCreateLLJITBuilder();
2547
  LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(
2548
      Builder,
2549
      [](void *, LLVMOrcExecutionSessionRef ES, const char *) noexcept {
2550
        auto Layer = std::make_unique<llvm::orc::RTDyldObjectLinkingLayer>(
2551
            *unwrap(ES), []() { return std::make_unique<Win64EHManager>(); });
2552
        Layer->setOverrideObjectFlagsWithResponsibilityFlags(true);
2553
        Layer->setAutoClaimResponsibilityForObjectSymbols(true);
2554
        return wrap(static_cast<llvm::orc::ObjectLayer *>(Layer.release()));
2555
      },
2556
      nullptr);
2557
  return Builder;
2558
}
2559
#else
2560
0
LLVMOrcLLJITBuilderRef OrcLLJIT::getBuilder() noexcept { return nullptr; }
2561
#endif
2562
2563
} // namespace WasmEdge::LLVM
2564
2565
#if LLVM_VERSION_MAJOR < 12 && WASMEDGE_OS_WINDOWS
2566
void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(
2567
    LLVMOrcLLJITBuilderRef Builder,
2568
    LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F,
2569
    void *Ctx) noexcept {
2570
  using llvm::unwrap;
2571
  using llvm::wrap;
2572
  unwrap(Builder)->setObjectLinkingLayerCreator(
2573
      [=](llvm::orc::ExecutionSession &ES, const llvm::Triple &TT) {
2574
        auto TTStr = TT.str();
2575
        return std::unique_ptr<llvm::orc::ObjectLayer>(
2576
            unwrap(F(Ctx, wrap(&ES), TTStr.c_str())));
2577
      });
2578
}
2579
#endif
2580
#if LLVM_VERSION_MAJOR < 13
2581
LLVMOrcIRTransformLayerRef
2582
0
LLVMOrcLLJITGetIRTransformLayer(LLVMOrcLLJITRef J) noexcept {
2583
0
  using llvm::unwrap;
2584
0
  using llvm::wrap;
2585
0
  return wrap(&(unwrap(J)->getIRTransformLayer()));
2586
0
}
Unexecuted instantiation: compiler.cpp:LLVMOrcLLJITGetIRTransformLayer(LLVMOrcOpaqueLLJIT*)
Unexecuted instantiation: codegen.cpp:LLVMOrcLLJITGetIRTransformLayer(LLVMOrcOpaqueLLJIT*)
Unexecuted instantiation: data.cpp:LLVMOrcLLJITGetIRTransformLayer(LLVMOrcOpaqueLLJIT*)
Unexecuted instantiation: jit.cpp:LLVMOrcLLJITGetIRTransformLayer(LLVMOrcOpaqueLLJIT*)
2587
void LLVMOrcIRTransformLayerSetTransform(
2588
    LLVMOrcIRTransformLayerRef IRTransformLayer,
2589
    LLVMOrcIRTransformLayerTransformFunction TransformFunction,
2590
0
    void *Ctx) noexcept {
2591
0
  using llvm::unwrap;
2592
0
  using llvm::wrap;
2593
0
  unwrap(IRTransformLayer)
2594
0
      ->setTransform([=](llvm::orc::ThreadSafeModule TSM,
2595
0
                         llvm::orc::MaterializationResponsibility &R)
2596
0
                         -> llvm::Expected<llvm::orc::ThreadSafeModule> {
2597
0
        LLVMOrcThreadSafeModuleRef TSMRef =
2598
0
            wrap(new llvm::orc::ThreadSafeModule(std::move(TSM)));
2599
0
        if (LLVMErrorRef Err = TransformFunction(Ctx, &TSMRef, wrap(&R))) {
2600
0
          return unwrap(Err);
2601
0
        }
2602
0
        return std::move(*unwrap(TSMRef));
2603
0
      });
2604
0
}
Unexecuted instantiation: compiler.cpp:LLVMOrcIRTransformLayerSetTransform(LLVMOrcOpaqueIRTransformLayer*, LLVMOpaqueError* (*)(void*, LLVMOrcOpaqueThreadSafeModule**, LLVMOrcOpaqueMaterializationResponsibility*) noexcept, void*)
Unexecuted instantiation: codegen.cpp:LLVMOrcIRTransformLayerSetTransform(LLVMOrcOpaqueIRTransformLayer*, LLVMOpaqueError* (*)(void*, LLVMOrcOpaqueThreadSafeModule**, LLVMOrcOpaqueMaterializationResponsibility*) noexcept, void*)
Unexecuted instantiation: data.cpp:LLVMOrcIRTransformLayerSetTransform(LLVMOrcOpaqueIRTransformLayer*, LLVMOpaqueError* (*)(void*, LLVMOrcOpaqueThreadSafeModule**, LLVMOrcOpaqueMaterializationResponsibility*) noexcept, void*)
Unexecuted instantiation: jit.cpp:LLVMOrcIRTransformLayerSetTransform(LLVMOrcOpaqueIRTransformLayer*, LLVMOpaqueError* (*)(void*, LLVMOrcOpaqueThreadSafeModule**, LLVMOrcOpaqueMaterializationResponsibility*) noexcept, void*)
2605
2606
LLVMErrorRef
2607
LLVMOrcThreadSafeModuleWithModuleDo(LLVMOrcThreadSafeModuleRef TSM,
2608
                                    LLVMOrcGenericIRModuleOperationFunction F,
2609
0
                                    void *Ctx) noexcept {
2610
0
  using llvm::unwrap;
2611
0
  using llvm::wrap;
2612
0
  return wrap(unwrap(TSM)->withModuleDo(
2613
0
      [&](llvm::Module &M) { return unwrap(F(Ctx, wrap(&M))); }));
2614
0
}
Unexecuted instantiation: compiler.cpp:LLVMOrcThreadSafeModuleWithModuleDo(LLVMOrcOpaqueThreadSafeModule*, LLVMOpaqueError* (*)(void*, LLVMOpaqueModule*) noexcept, void*)
Unexecuted instantiation: codegen.cpp:LLVMOrcThreadSafeModuleWithModuleDo(LLVMOrcOpaqueThreadSafeModule*, LLVMOpaqueError* (*)(void*, LLVMOpaqueModule*) noexcept, void*)
Unexecuted instantiation: data.cpp:LLVMOrcThreadSafeModuleWithModuleDo(LLVMOrcOpaqueThreadSafeModule*, LLVMOpaqueError* (*)(void*, LLVMOpaqueModule*) noexcept, void*)
Unexecuted instantiation: jit.cpp:LLVMOrcThreadSafeModuleWithModuleDo(LLVMOrcOpaqueThreadSafeModule*, LLVMOpaqueError* (*)(void*, LLVMOpaqueModule*) noexcept, void*)
2615
#endif