Coverage Report

Created: 2026-07-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/lib/llvm/llvm.h
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
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 <cstring>
15
#include <llvm-c/Analysis.h>
16
#include <llvm-c/Core.h>
17
#include <llvm-c/Error.h>
18
#include <llvm-c/Object.h>
19
#include <llvm-c/Orc.h>
20
#include <llvm-c/Target.h>
21
#include <llvm-c/TargetMachine.h>
22
#include <llvm-c/Types.h>
23
#include <mutex>
24
#include <string_view>
25
#include <utility>
26
#include <vector>
27
28
#if LLVM_VERSION_MAJOR >= 12
29
#include <llvm-c/LLJIT.h>
30
#endif
31
32
#if LLVM_VERSION_MAJOR < 12 && WASMEDGE_OS_WINDOWS
33
using LLVMOrcObjectLayerRef = struct LLVMOrcOpaqueObjectLayer *;
34
using LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction =
35
    LLVMOrcObjectLayerRef (*)(void *Ctx, LLVMOrcExecutionSessionRef ES,
36
                              const char *Triple) noexcept;
37
void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(
38
    LLVMOrcLLJITBuilderRef Builder,
39
    LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F, void *Ctx) noexcept;
40
#endif
41
#if LLVM_VERSION_MAJOR < 13
42
using LLVMOrcMaterializationResponsibilityRef =
43
    struct LLVMOrcOpaqueMaterializationResponsibility *;
44
using LLVMOrcIRTransformLayerRef = struct LLVMOrcOpaqueIRTransformLayer *;
45
using LLVMOrcIRTransformLayerTransformFunction =
46
    LLVMErrorRef (*)(void *Ctx, LLVMOrcThreadSafeModuleRef *ModInOut,
47
                     LLVMOrcMaterializationResponsibilityRef MR) noexcept;
48
using LLVMOrcGenericIRModuleOperationFunction =
49
    LLVMErrorRef (*)(void *Ctx, LLVMModuleRef M) noexcept;
50
LLVMOrcIRTransformLayerRef
51
LLVMOrcLLJITGetIRTransformLayer(LLVMOrcLLJITRef J) noexcept;
52
void LLVMOrcIRTransformLayerSetTransform(
53
    LLVMOrcIRTransformLayerRef IRTransformLayer,
54
    LLVMOrcIRTransformLayerTransformFunction TransformFunction,
55
    void *Ctx) noexcept;
56
LLVMErrorRef
57
LLVMOrcThreadSafeModuleWithModuleDo(LLVMOrcThreadSafeModuleRef TSM,
58
                                    LLVMOrcGenericIRModuleOperationFunction F,
59
                                    void *Ctx) noexcept;
60
#endif
61
62
#if LLVM_VERSION_MAJOR >= 13
63
#include <llvm-c/Transforms/PassBuilder.h>
64
#else
65
#include <llvm-c/Transforms/IPO.h>
66
#include <llvm-c/Transforms/PassManagerBuilder.h>
67
#include <llvm-c/Transforms/Scalar.h>
68
#endif
69
70
// Enable __x86_64__ for MSVC
71
#if defined(_M_X64) && !defined(__x86_64__)
72
#define __x86_64__ 1
73
#endif
74
75
#if LLVM_VERSION_MAJOR < 17
76
typedef enum {
77
  LLVMTailCallKindNone = 0,
78
  LLVMTailCallKindTail = 1,
79
  LLVMTailCallKindMustTail = 2,
80
  LLVMTailCallKindNoTail = 3,
81
} LLVMTailCallKind;
82
83
LLVMTailCallKind LLVMGetTailCallKind(LLVMValueRef Call);
84
void LLVMSetTailCallKind(LLVMValueRef Call, LLVMTailCallKind kind);
85
#endif
86
87
namespace WasmEdge::LLVM {
88
89
class Core {
90
public:
91
2.23k
  static inline void init(LLVMContextRef C) noexcept {
92
2.23k
    std::call_once(Once, initOnce, C);
93
2.23k
  }
94
95
  static inline const unsigned int NotIntrinsic = 0;
96
  static inline unsigned int Abs = 0;
97
  static inline unsigned int Ceil = 0;
98
  static inline unsigned int CopySign = 0;
99
  static inline unsigned int Ctlz = 0;
100
  static inline unsigned int Cttz = 0;
101
  static inline unsigned int Ctpop = 0;
102
  static inline unsigned int Expect = 0;
103
  static inline unsigned int ExperimentalConstrainedFAdd = 0;
104
  static inline unsigned int ExperimentalConstrainedFDiv = 0;
105
  static inline unsigned int ExperimentalConstrainedFMul = 0;
106
  static inline unsigned int ExperimentalConstrainedFPExt = 0;
107
  static inline unsigned int ExperimentalConstrainedFPTrunc = 0;
108
  static inline unsigned int ExperimentalConstrainedFSub = 0;
109
  static inline unsigned int Fabs = 0;
110
  static inline unsigned int Floor = 0;
111
  static inline unsigned int FShl = 0;
112
  static inline unsigned int FShr = 0;
113
  static inline unsigned int MaxNum = 0;
114
  static inline unsigned int MinNum = 0;
115
  static inline unsigned int Nearbyint = 0;
116
  static inline unsigned int Roundeven = 0;
117
  static inline unsigned int SAddSat = 0;
118
  static inline unsigned int Sqrt = 0;
119
  static inline unsigned int SSubSat = 0;
120
  static inline unsigned int Trunc = 0;
121
  static inline unsigned int UAddSat = 0;
122
  static inline unsigned int USubSat = 0;
123
  static inline unsigned int Bswap = 0;
124
  static inline unsigned int SMax = 0;
125
  static inline unsigned int SMin = 0;
126
  static inline unsigned int UMax = 0;
127
  static inline unsigned int UMin = 0;
128
#if defined(__x86_64__)
129
  static inline unsigned int X86SSE2PAvgB = 0;
130
  static inline unsigned int X86SSE2PAvgW = 0;
131
  static inline unsigned int X86SSE2PMAddWd = 0;
132
  static inline unsigned int X86SSE41RoundPd = 0;
133
  static inline unsigned int X86SSE41RoundPs = 0;
134
  static inline unsigned int X86SSE41RoundSd = 0;
135
  static inline unsigned int X86SSE41RoundSs = 0;
136
  static inline unsigned int X86SSSE3PMAddUbSw128 = 0;
137
  static inline unsigned int X86SSSE3PMulHrSw128 = 0;
138
  static inline unsigned int X86SSSE3PShufB128 = 0;
139
  static inline unsigned int X86XOpVPHAddBW = 0;
140
  static inline unsigned int X86XOpVPHAddUBW = 0;
141
  static inline unsigned int X86XOpVPHAddUWD = 0;
142
  static inline unsigned int X86XOpVPHAddWD = 0;
143
#endif
144
#if defined(__aarch64__)
145
  static inline unsigned int AArch64NeonFRIntN = 0;
146
  static inline unsigned int AArch64NeonSAddLP = 0;
147
  static inline unsigned int AArch64NeonSQRDMulH = 0;
148
  static inline unsigned int AArch64NeonTbl1 = 0;
149
  static inline unsigned int AArch64NeonUAddLP = 0;
150
  static inline unsigned int AArch64NeonURHAdd = 0;
151
#endif
152
#if defined(__s390x__)
153
  static inline unsigned int S390VPerm = 0;
154
#endif
155
156
  static inline unsigned int Cold = 0;
157
  static inline unsigned int NoAlias = 0;
158
  static inline unsigned int NoInline = 0;
159
  static inline unsigned int NoReturn = 0;
160
  static inline unsigned int ReadOnly = 0;
161
  static inline unsigned int StrictFP = 0;
162
  static inline unsigned int UWTable = 0;
163
#if LLVM_VERSION_MAJOR >= 15
164
  static constexpr inline const unsigned int UWTableDefault = 2;
165
#else
166
  static constexpr inline const unsigned int UWTableDefault = 0;
167
#endif
168
169
  static inline unsigned int InvariantGroup = 0;
170
171
private:
172
  static inline std::once_flag Once;
173
1
  static inline void initOnce(LLVMContextRef C) noexcept {
174
1
    using namespace std::literals;
175
1
#if LLVM_VERSION_MAJOR < 17
176
1
    LLVMInitializeCore(LLVMGetGlobalPassRegistry());
177
1
#endif
178
1
    LLVMInitializeNativeTarget();
179
1
    LLVMInitializeNativeAsmPrinter();
180
181
1
    Abs = getIntrinsicID("llvm.abs"sv);
182
1
    Ceil = getIntrinsicID("llvm.ceil"sv);
183
1
    CopySign = getIntrinsicID("llvm.copysign"sv);
184
1
    Ctlz = getIntrinsicID("llvm.ctlz"sv);
185
1
    Cttz = getIntrinsicID("llvm.cttz"sv);
186
1
    Ctpop = getIntrinsicID("llvm.ctpop"sv);
187
1
    Expect = getIntrinsicID("llvm.expect");
188
1
    ExperimentalConstrainedFAdd =
189
1
        getIntrinsicID("llvm.experimental.constrained.fadd"sv);
190
1
    ExperimentalConstrainedFDiv =
191
1
        getIntrinsicID("llvm.experimental.constrained.fdiv"sv);
192
1
    ExperimentalConstrainedFMul =
193
1
        getIntrinsicID("llvm.experimental.constrained.fmul"sv);
194
1
    ExperimentalConstrainedFPExt =
195
1
        getIntrinsicID("llvm.experimental.constrained.fpext"sv);
196
1
    ExperimentalConstrainedFPTrunc =
197
1
        getIntrinsicID("llvm.experimental.constrained.fptrunc"sv);
198
1
    ExperimentalConstrainedFSub =
199
1
        getIntrinsicID("llvm.experimental.constrained.fsub"sv);
200
1
    Fabs = getIntrinsicID("llvm.fabs"sv);
201
1
    Floor = getIntrinsicID("llvm.floor"sv);
202
1
    FShl = getIntrinsicID("llvm.fshl"sv);
203
1
    FShr = getIntrinsicID("llvm.fshr"sv);
204
1
    MaxNum = getIntrinsicID("llvm.maxnum"sv);
205
1
    MinNum = getIntrinsicID("llvm.minnum"sv);
206
1
    Nearbyint = getIntrinsicID("llvm.nearbyint"sv);
207
1
    Roundeven = getIntrinsicID("llvm.roundeven"sv);
208
1
    SAddSat = getIntrinsicID("llvm.sadd.sat"sv);
209
1
    Sqrt = getIntrinsicID("llvm.sqrt"sv);
210
1
    SSubSat = getIntrinsicID("llvm.ssub.sat"sv);
211
1
    Trunc = getIntrinsicID("llvm.trunc"sv);
212
1
    UAddSat = getIntrinsicID("llvm.uadd.sat"sv);
213
1
    USubSat = getIntrinsicID("llvm.usub.sat"sv);
214
1
    Bswap = getIntrinsicID("llvm.bswap"sv);
215
1
    SMax = getIntrinsicID("llvm.smax"sv);
216
1
    SMin = getIntrinsicID("llvm.smin"sv);
217
1
    UMax = getIntrinsicID("llvm.umax"sv);
218
1
    UMin = getIntrinsicID("llvm.umin"sv);
219
220
1
#if defined(__x86_64__)
221
1
    X86SSE2PAvgB = getIntrinsicID("llvm.x86.sse2.pavg.b"sv);
222
1
    X86SSE2PAvgW = getIntrinsicID("llvm.x86.sse2.pavg.w"sv);
223
1
    X86SSE2PMAddWd = getIntrinsicID("llvm.x86.sse2.pmadd.wd"sv);
224
1
    X86SSE41RoundPd = getIntrinsicID("llvm.x86.sse41.round.pd"sv);
225
1
    X86SSE41RoundPs = getIntrinsicID("llvm.x86.sse41.round.ps"sv);
226
1
    X86SSE41RoundSd = getIntrinsicID("llvm.x86.sse41.round.sd"sv);
227
1
    X86SSE41RoundSs = getIntrinsicID("llvm.x86.sse41.round.ss"sv);
228
1
    X86SSSE3PMAddUbSw128 = getIntrinsicID("llvm.x86.ssse3.pmadd.ub.sw.128"sv);
229
1
    X86SSSE3PMulHrSw128 = getIntrinsicID("llvm.x86.ssse3.pmul.hr.sw.128"sv);
230
1
    X86SSSE3PShufB128 = getIntrinsicID("llvm.x86.ssse3.pshuf.b.128"sv);
231
1
    X86XOpVPHAddBW = getIntrinsicID("llvm.x86.xop.vphaddbw"sv);
232
1
    X86XOpVPHAddUBW = getIntrinsicID("llvm.x86.xop.vphaddubw"sv);
233
1
    X86XOpVPHAddUWD = getIntrinsicID("llvm.x86.xop.vphadduwd"sv);
234
1
    X86XOpVPHAddWD = getIntrinsicID("llvm.x86.xop.vphaddwd"sv);
235
1
#endif
236
#if defined(__aarch64__)
237
    AArch64NeonFRIntN = getIntrinsicID("llvm.aarch64.neon.frintn"sv);
238
    AArch64NeonSAddLP = getIntrinsicID("llvm.aarch64.neon.saddlp"sv);
239
    AArch64NeonSQRDMulH = getIntrinsicID("llvm.aarch64.neon.sqrdmulh"sv);
240
    AArch64NeonTbl1 = getIntrinsicID("llvm.aarch64.neon.tbl1"sv);
241
    AArch64NeonUAddLP = getIntrinsicID("llvm.aarch64.neon.uaddlp"sv);
242
    AArch64NeonURHAdd = getIntrinsicID("llvm.aarch64.neon.urhadd"sv);
243
#endif
244
#if defined(__s390x__)
245
    S390VPerm = getIntrinsicID("llvm.s390.vperm"sv);
246
#endif
247
248
1
    Cold = getEnumAttributeKind("cold"sv);
249
1
    NoAlias = getEnumAttributeKind("noalias"sv);
250
1
    NoInline = getEnumAttributeKind("noinline"sv);
251
1
    NoReturn = getEnumAttributeKind("noreturn"sv);
252
1
    ReadOnly = getEnumAttributeKind("readonly"sv);
253
1
    StrictFP = getEnumAttributeKind("strictfp"sv);
254
1
    UWTable = getEnumAttributeKind("uwtable"sv);
255
256
1
    InvariantGroup = getMetadataKind(C, "invariant.group"sv);
257
1
  }
258
259
  template <typename... ArgsT>
260
  static unsigned int getIntrinsicID(std::string_view Name,
261
46
                                     ArgsT &&...Args) noexcept {
262
46
    const auto Value = LLVMLookupIntrinsicID(Name.data(), Name.size());
263
46
    if constexpr (sizeof...(Args) == 0) {
264
46
      return Value;
265
    } else {
266
      if (Value == NotIntrinsic) {
267
        return getIntrinsicID(std::forward<ArgsT>(Args)...);
268
      }
269
    }
270
46
  }
271
7
  static unsigned int getEnumAttributeKind(std::string_view Name) noexcept {
272
7
    return LLVMGetEnumAttributeKindForName(Name.data(), Name.size());
273
7
  }
274
  static unsigned int getMetadataKind(LLVMContextRef C,
275
1
                                      std::string_view Name) noexcept {
276
1
    return LLVMGetMDKindIDInContext(C, Name.data(),
277
1
                                    static_cast<unsigned int>(Name.size()));
278
1
  }
279
};
280
281
class Attribute;
282
class Message;
283
class Metadata;
284
class PassManager;
285
class Type;
286
class Value;
287
class Builder;
288
class BasicBlock;
289
290
class Context {
291
public:
292
6.68k
  constexpr Context(LLVMContextRef R) noexcept : Ref(R) {}
293
  Context(const Context &) = default;
294
  Context &operator=(const Context &) = default;
295
296
0
  static Context create() noexcept { return Context(LLVMContextCreate()); }
297
298
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
299
2.23k
  constexpr auto &unwrap() const noexcept { return Ref; }
300
204k
  constexpr auto &unwrap() noexcept { return Ref; }
301
0
  LLVMContextRef release() noexcept { return std::exchange(Ref, nullptr); }
302
0
  friend void swap(Context &LHS, Context &RHS) noexcept {
303
0
    using std::swap;
304
0
    swap(LHS.Ref, RHS.Ref);
305
0
  }
306
307
  inline Type getVoidTy() noexcept;
308
  inline Type getInt1Ty() noexcept;
309
  inline Type getInt8Ty() noexcept;
310
  inline Type getInt16Ty() noexcept;
311
  inline Type getInt32Ty() noexcept;
312
  inline Type getInt64Ty() noexcept;
313
  inline Type getInt128Ty() noexcept;
314
  inline Type getIntNTy(unsigned int NumBits) noexcept;
315
  inline Type getFloatTy() noexcept;
316
  inline Type getDoubleTy() noexcept;
317
318
  inline Value getFalse() noexcept;
319
  inline Value getTrue() noexcept;
320
  inline Value getInt8(uint8_t C) noexcept;
321
  inline Value getInt16(uint16_t C) noexcept;
322
  inline Value getInt32(uint32_t C) noexcept;
323
  inline Value getInt64(uint64_t C) noexcept;
324
  inline Value getFloat(float C) noexcept;
325
  inline Value getDouble(double C) noexcept;
326
327
private:
328
  LLVMContextRef Ref = nullptr;
329
};
330
331
class Module {
332
public:
333
  constexpr Module() noexcept = default;
334
0
  constexpr Module(LLVMModuleRef R) noexcept : Ref(R) {}
335
  Module(const Module &) = delete;
336
  Module &operator=(const Module &) = delete;
337
0
  Module(Module &&M) noexcept : Module() { swap(*this, M); }
338
0
  Module &operator=(Module &&M) noexcept {
339
0
    swap(*this, M);
340
0
    return *this;
341
0
  }
342
343
  Module(const Context &C, const char *Name) noexcept
344
2.23k
      : Ref(LLVMModuleCreateWithNameInContext(Name, C.unwrap())) {}
345
2.23k
  ~Module() noexcept { LLVMDisposeModule(Ref); }
346
347
2.22k
  const char *getTarget() noexcept { return LLVMGetTarget(Ref); }
348
2.23k
  void setTarget(const char *Triple) noexcept { LLVMSetTarget(Ref, Triple); }
349
  inline Value addFunction(Type Ty, LLVMLinkage Linkage,
350
                           const char *Name = "") noexcept;
351
  inline Value addGlobal(Type Ty, bool IsConstant, LLVMLinkage Linkage,
352
                         Value Initializer, const char *Name = "") noexcept;
353
  inline Value getNamedGlobal(const char *Name) noexcept;
354
  inline Value addAlias(Type Ty, Value V, const char *Name,
355
                        unsigned int AddrSpace = 0) noexcept;
356
  inline void addFlag(LLVMModuleFlagBehavior Behavior, std::string_view Key,
357
                      const Metadata &Val) noexcept;
358
  inline void addFlag(LLVMModuleFlagBehavior Behavior, std::string_view Key,
359
                      const Value &Val) noexcept;
360
  inline void addFlag(LLVMModuleFlagBehavior Behavior, std::string_view Key,
361
                      uint32_t Val) noexcept;
362
  inline Value getFirstGlobal() noexcept;
363
  inline Value getFirstFunction() noexcept;
364
  inline Value getNamedFunction(const char *Name) noexcept;
365
  inline Message printModuleToFile(const char *File) noexcept;
366
  inline Message verify(LLVMVerifierFailureAction Action) noexcept;
367
368
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
369
0
  constexpr auto &unwrap() const noexcept { return Ref; }
370
6.66k
  constexpr auto &unwrap() noexcept { return Ref; }
371
0
  LLVMModuleRef release() noexcept { return std::exchange(Ref, nullptr); }
372
0
  friend void swap(Module &LHS, Module &RHS) noexcept {
373
0
    using std::swap;
374
0
    swap(LHS.Ref, RHS.Ref);
375
0
  }
376
377
private:
378
  LLVMModuleRef Ref = nullptr;
379
};
380
381
class ErrorMessage {
382
public:
383
  constexpr ErrorMessage() noexcept = default;
384
0
  constexpr ErrorMessage(char *M) noexcept : Data(M) {}
385
  ErrorMessage(const ErrorMessage &) = delete;
386
  ErrorMessage &operator=(const ErrorMessage &) = delete;
387
0
  ErrorMessage(ErrorMessage &&M) noexcept : ErrorMessage() { swap(*this, M); }
388
0
  ErrorMessage &operator=(ErrorMessage &&M) noexcept {
389
0
    swap(*this, M);
390
0
    return *this;
391
0
  }
392
393
0
  ~ErrorMessage() noexcept { LLVMDisposeErrorMessage(Data); }
394
395
0
  constexpr operator bool() const noexcept { return Data != nullptr; }
396
0
  constexpr auto &unwrap() const noexcept { return Data; }
397
0
  constexpr auto &unwrap() noexcept { return Data; }
398
0
  friend void swap(ErrorMessage &LHS, ErrorMessage &RHS) noexcept {
399
0
    using std::swap;
400
0
    swap(LHS.Data, RHS.Data);
401
0
  }
402
403
0
  std::string_view string_view() const noexcept { return Data; }
404
405
private:
406
  char *Data = nullptr;
407
};
408
409
class Error {
410
public:
411
  constexpr Error() noexcept = default;
412
0
  constexpr Error(LLVMErrorRef R) noexcept : Ref(R) {}
413
  Error(const Error &) = delete;
414
  Error &operator=(const Error &) = delete;
415
0
  Error(Error &&E) noexcept : Error() { swap(*this, E); }
416
0
  Error &operator=(Error &&E) noexcept {
417
0
    swap(*this, E);
418
0
    return *this;
419
0
  }
420
421
0
  ~Error() noexcept { LLVMConsumeError(Ref); }
422
423
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
424
0
  constexpr auto &unwrap() const noexcept { return Ref; }
425
0
  constexpr auto &unwrap() noexcept { return Ref; }
426
0
  LLVMErrorRef release() noexcept { return std::exchange(Ref, nullptr); }
427
0
  friend void swap(Error &LHS, Error &RHS) noexcept {
428
0
    using std::swap;
429
0
    swap(LHS.Ref, RHS.Ref);
430
0
  }
431
432
0
  ErrorMessage message() noexcept {
433
0
    return LLVMGetErrorMessage(std::exchange(Ref, nullptr));
434
0
  }
435
436
private:
437
  LLVMErrorRef Ref = nullptr;
438
};
439
440
class Message {
441
public:
442
13.3k
  constexpr Message() noexcept = default;
443
8.90k
  constexpr Message(char *M) noexcept : Data(M) {}
444
  Message(const Message &) = delete;
445
  Message &operator=(const Message &) = delete;
446
0
  Message(Message &&M) noexcept : Message() { swap(*this, M); }
447
2.23k
  Message &operator=(Message &&M) noexcept {
448
2.23k
    swap(*this, M);
449
2.23k
    return *this;
450
2.23k
  }
451
452
22.2k
  ~Message() noexcept { LLVMDisposeMessage(Data); }
453
454
8.88k
  constexpr operator bool() const noexcept { return Data != nullptr; }
455
0
  constexpr auto &unwrap() const noexcept { return Data; }
456
15.5k
  constexpr auto &unwrap() noexcept { return Data; }
457
2.23k
  friend void swap(Message &LHS, Message &RHS) noexcept {
458
2.23k
    using std::swap;
459
2.23k
    swap(LHS.Data, RHS.Data);
460
2.23k
  }
461
462
4.45k
  std::string_view string_view() const noexcept { return Data; }
463
464
private:
465
  char *Data = nullptr;
466
};
467
468
class MemoryBuffer {
469
public:
470
6.66k
  constexpr MemoryBuffer() noexcept = default;
471
0
  constexpr MemoryBuffer(LLVMMemoryBufferRef R) noexcept : Ref(R) {}
472
  MemoryBuffer(const MemoryBuffer &) = delete;
473
  MemoryBuffer &operator=(const MemoryBuffer &) = delete;
474
0
  MemoryBuffer(MemoryBuffer &&M) noexcept : MemoryBuffer() { swap(*this, M); }
475
2.22k
  MemoryBuffer &operator=(MemoryBuffer &&M) noexcept {
476
2.22k
    swap(*this, M);
477
2.22k
    return *this;
478
2.22k
  }
479
480
6.66k
  ~MemoryBuffer() noexcept { LLVMDisposeMemoryBuffer(Ref); }
481
482
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
483
0
  constexpr auto &unwrap() const noexcept { return Ref; }
484
6.66k
  constexpr auto &unwrap() noexcept { return Ref; }
485
2.22k
  friend void swap(MemoryBuffer &LHS, MemoryBuffer &RHS) noexcept {
486
2.22k
    using std::swap;
487
2.22k
    swap(LHS.Ref, RHS.Ref);
488
2.22k
  }
489
490
2.22k
  static std::pair<MemoryBuffer, Message> getFile(const char *Path) noexcept {
491
2.22k
    std::pair<MemoryBuffer, Message> Result;
492
2.22k
    LLVMCreateMemoryBufferWithContentsOfFile(Path, &Result.first.unwrap(),
493
2.22k
                                             &Result.second.unwrap());
494
2.22k
    return Result;
495
2.22k
  }
496
4.44k
  const char *data() const noexcept { return LLVMGetBufferStart(Ref); }
497
4.44k
  size_t size() const noexcept { return LLVMGetBufferSize(Ref); }
498
499
private:
500
  LLVMMemoryBufferRef Ref = nullptr;
501
};
502
503
class Type {
504
public:
505
1.12M
  constexpr Type() = default;
506
4.22M
  constexpr Type(LLVMTypeRef R) noexcept : Ref(R) {}
507
  constexpr Type(const Type &) = default;
508
  constexpr Type &operator=(const Type &) = default;
509
1.00M
  Type(Type &&T) noexcept : Type() { swap(*this, T); }
510
110k
  Type &operator=(Type &&T) noexcept {
511
110k
    swap(*this, T);
512
110k
    return *this;
513
110k
  }
514
515
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
516
0
  constexpr auto &unwrap() const noexcept { return Ref; }
517
4.85M
  constexpr auto &unwrap() noexcept { return Ref; }
518
1.11M
  friend void swap(Type &LHS, Type &RHS) noexcept {
519
1.11M
    using std::swap;
520
1.11M
    swap(LHS.Ref, RHS.Ref);
521
1.11M
  }
522
523
  static Type getFunctionType(Type ReturnType, Span<const Type> ParamTypes,
524
28.1k
                              bool IsVarArg = false) noexcept {
525
28.1k
    const auto Data = const_cast<LLVMTypeRef *>(
526
28.1k
        reinterpret_cast<const LLVMTypeRef *>(ParamTypes.data()));
527
28.1k
    const auto Size = static_cast<unsigned int>(ParamTypes.size());
528
28.1k
    return LLVMFunctionType(ReturnType.unwrap(), Data, Size, IsVarArg);
529
28.1k
  }
530
  static Type getPointerType(Type ElementType,
531
0
                             unsigned int AddressSpace = 0) noexcept {
532
0
    return LLVMPointerType(ElementType.unwrap(), AddressSpace);
533
0
  }
534
  static Type getArrayType(Type ElementType,
535
4.46k
                           unsigned int ElementCount) noexcept {
536
4.46k
    return LLVMArrayType(ElementType.unwrap(), ElementCount);
537
4.46k
  }
538
  static Type getVectorType(Type ElementType,
539
264k
                            unsigned int ElementCount) noexcept {
540
264k
    return LLVMVectorType(ElementType.unwrap(), ElementCount);
541
264k
  }
542
  static Type getStructType(Span<const Type> ElementTypes,
543
708
                            bool Packed = false) noexcept {
544
708
    const auto Data = const_cast<LLVMTypeRef *>(
545
708
        reinterpret_cast<const LLVMTypeRef *>(ElementTypes.data()));
546
708
    const auto Size = static_cast<unsigned int>(ElementTypes.size());
547
708
    assuming(Size >= 1);
548
708
    return LLVMStructTypeInContext(LLVMGetTypeContext(Data[0]), Data, Size,
549
708
                                   Packed);
550
708
  }
551
  static Type getStructType(const char *Name, Span<const Type> ElementTypes,
552
2.23k
                            bool Packed = false) noexcept {
553
2.23k
    const auto Data = const_cast<LLVMTypeRef *>(
554
2.23k
        reinterpret_cast<const LLVMTypeRef *>(ElementTypes.data()));
555
2.23k
    const auto Size = static_cast<unsigned int>(ElementTypes.size());
556
2.23k
    assuming(Size >= 1);
557
2.23k
    Type Ty = LLVMStructCreateNamed(LLVMGetTypeContext(Data[0]), Name);
558
2.23k
    LLVMStructSetBody(Ty.unwrap(), Data, Size, Packed);
559
2.23k
    return Ty;
560
2.23k
  }
561
562
20.4k
  bool isVoidTy() const noexcept {
563
20.4k
    return LLVMGetTypeKind(Ref) == LLVMVoidTypeKind;
564
20.4k
  }
565
42.2k
  bool isFloatTy() const noexcept {
566
42.2k
    return LLVMGetTypeKind(Ref) == LLVMFloatTypeKind;
567
42.2k
  }
568
18.4k
  bool isDoubleTy() const noexcept {
569
18.4k
    return LLVMGetTypeKind(Ref) == LLVMDoubleTypeKind;
570
18.4k
  }
571
4.57k
  bool isIntegerTy() const noexcept {
572
4.57k
    return LLVMGetTypeKind(Ref) == LLVMIntegerTypeKind;
573
4.57k
  }
574
13.4k
  bool isStructTy() const noexcept {
575
13.4k
    return LLVMGetTypeKind(Ref) == LLVMStructTypeKind;
576
13.4k
  }
577
0
  bool isVectorTy() const noexcept {
578
0
    return LLVMGetTypeKind(Ref) == LLVMVectorTypeKind;
579
0
  }
580
581
4.57k
  unsigned int getPrimitiveSizeInBits() const noexcept {
582
4.57k
    switch (LLVMGetTypeKind(Ref)) {
583
0
    case LLVMBFloatTypeKind:
584
0
      return 16;
585
0
    case LLVMHalfTypeKind:
586
0
      return 16;
587
0
    case LLVMFloatTypeKind:
588
0
      return 32;
589
0
    case LLVMDoubleTypeKind:
590
0
      return 64;
591
0
    case LLVMX86_FP80TypeKind:
592
0
      return 80;
593
0
    case LLVMFP128TypeKind:
594
0
      return 128;
595
0
    case LLVMPPC_FP128TypeKind:
596
0
      return 128;
597
0
#if LLVM_VERSION_MAJOR < 20
598
0
    case LLVMX86_MMXTypeKind:
599
0
      return 64;
600
0
#endif
601
4.57k
    case LLVMIntegerTypeKind:
602
4.57k
      return getIntegerBitWidth();
603
0
    case LLVMVectorTypeKind:
604
0
      return getElementType().getPrimitiveSizeInBits() * getVectorSize();
605
0
    default:
606
0
      return 0;
607
4.57k
    }
608
4.57k
  }
609
7.30k
  unsigned int getFPMantissaWidth() const noexcept {
610
7.30k
    switch (LLVMGetTypeKind(Ref)) {
611
0
    case LLVMBFloatTypeKind:
612
0
      return 8;
613
0
    case LLVMHalfTypeKind:
614
0
      return 11;
615
3.33k
    case LLVMFloatTypeKind:
616
3.33k
      return 24;
617
3.96k
    case LLVMDoubleTypeKind:
618
3.96k
      return 53;
619
0
    case LLVMX86_FP80TypeKind:
620
0
      return 64;
621
0
    case LLVMFP128TypeKind:
622
0
      return 113;
623
0
    default:
624
0
      return 0;
625
7.30k
    }
626
7.30k
  }
627
628
83.1k
  Type getElementType() const noexcept { return LLVMGetElementType(Ref); }
629
33.0k
  unsigned int getIntegerBitWidth() const noexcept {
630
33.0k
    return LLVMGetIntTypeWidth(Ref);
631
33.0k
  }
632
11.1k
  Type getIntegerExtendedType() const noexcept {
633
11.1k
    return LLVMIntTypeInContext(LLVMGetTypeContext(Ref),
634
11.1k
                                getIntegerBitWidth() * 2);
635
11.1k
  }
636
683
  Type getIntegerTruncatedType() const noexcept {
637
683
    return LLVMIntTypeInContext(LLVMGetTypeContext(Ref),
638
683
                                getIntegerBitWidth() / 2);
639
683
  }
640
785
  unsigned int getStructNumElements() const noexcept {
641
785
    return LLVMCountStructElementTypes(Ref);
642
785
  }
643
158
  Type getStructElementType(unsigned int Index) const noexcept {
644
158
    return LLVMStructGetTypeAtIndex(Ref, Index);
645
158
  }
646
92.9k
  Type getPointerTo(unsigned int AddressSpace = 0) const noexcept {
647
92.9k
    return LLVMPointerType(Ref, AddressSpace);
648
92.9k
  }
649
16.9k
  Type getReturnType() const noexcept { return LLVMGetReturnType(Ref); }
650
8.58k
  unsigned int getNumParams() const noexcept {
651
8.58k
    return LLVMCountParamTypes(Ref);
652
8.58k
  }
653
4.29k
  void getParamTypes(Span<Type> Types) const noexcept {
654
4.29k
    LLVMGetParamTypes(Ref, reinterpret_cast<LLVMTypeRef *>(Types.data()));
655
4.29k
  }
656
88.1k
  unsigned int getVectorSize() const noexcept { return LLVMGetVectorSize(Ref); }
657
11.1k
  Type getExtendedElementVectorType() const noexcept {
658
11.1k
    return getVectorType(getElementType().getIntegerExtendedType(),
659
11.1k
                         getVectorSize());
660
11.1k
  }
661
683
  Type getTruncatedElementVectorType() const noexcept {
662
683
    return getVectorType(getElementType().getIntegerTruncatedType(),
663
683
                         getVectorSize());
664
683
  }
665
2.85k
  Type getHalfElementsVectorType() const noexcept {
666
2.85k
    return getVectorType(getElementType(), getVectorSize() / 2);
667
2.85k
  }
668
669
private:
670
  LLVMTypeRef Ref = nullptr;
671
};
672
673
class Value {
674
public:
675
1.98M
  constexpr Value() = default;
676
6.08M
  constexpr Value(LLVMValueRef R) noexcept : Ref(R) {}
677
  constexpr Value(const Value &) = default;
678
  constexpr Value &operator=(const Value &) = default;
679
1.83M
  Value(Value &&V) noexcept : Value() { swap(*this, V); }
680
427k
  Value &operator=(Value &&V) noexcept {
681
427k
    swap(*this, V);
682
427k
    return *this;
683
427k
  }
684
685
3.10M
  constexpr operator bool() const noexcept { return Ref != nullptr; }
686
0
  constexpr auto &unwrap() const noexcept { return Ref; }
687
4.77M
  constexpr auto &unwrap() noexcept { return Ref; }
688
689
2.25M
  friend void swap(Value &LHS, Value &RHS) noexcept {
690
2.25M
    using std::swap;
691
2.25M
    swap(LHS.Ref, RHS.Ref);
692
2.25M
  }
693
694
659k
  static Value getConstNull(Type Ty) noexcept {
695
659k
    return LLVMConstNull(Ty.unwrap());
696
659k
  }
697
105
  static Value getConstAllOnes(Type Ty) noexcept {
698
105
    return LLVMConstAllOnes(Ty.unwrap());
699
105
  }
700
103k
  static Value getUndef(Type Ty) noexcept { return LLVMGetUndef(Ty.unwrap()); }
701
1.50k
  static Value getConstPointerNull(Type Ty) noexcept {
702
1.50k
    return LLVMConstPointerNull(Ty.unwrap());
703
1.50k
  }
704
  static Value getConstInt(Type IntTy, unsigned long long N,
705
2.13M
                           bool SignExtend = false) noexcept {
706
2.13M
    return LLVMConstInt(IntTy.unwrap(), N, SignExtend);
707
2.13M
  }
708
34.9k
  template <typename T> static Value getConstReal(Type Ty, T N) noexcept {
709
34.9k
    if (Ty.isFloatTy()) {
710
20.4k
      const auto V = static_cast<float>(N);
711
20.4k
      uint32_t Raw;
712
20.4k
      static_assert(sizeof(V) == sizeof(Raw));
713
20.4k
      std::memcpy(&Raw, &V, sizeof(V));
714
20.4k
      Type Int32Ty = LLVMInt32TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
715
20.4k
      Value Ret = getConstInt(Int32Ty, Raw);
716
20.4k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
717
20.4k
    }
718
14.4k
    if (Ty.isDoubleTy()) {
719
14.4k
      const auto V = static_cast<double>(N);
720
14.4k
      uint64_t Raw;
721
14.4k
      static_assert(sizeof(V) == sizeof(Raw));
722
14.4k
      std::memcpy(&Raw, &V, sizeof(V));
723
14.4k
      Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
724
14.4k
      Value Ret = getConstInt(Int64Ty, Raw);
725
14.4k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
726
14.4k
    }
727
14.4k
    assumingUnreachable();
728
14.4k
  }
WasmEdge::LLVM::Value WasmEdge::LLVM::Value::getConstReal<float>(WasmEdge::LLVM::Type, float)
Line
Count
Source
708
13.8k
  template <typename T> static Value getConstReal(Type Ty, T N) noexcept {
709
13.8k
    if (Ty.isFloatTy()) {
710
13.8k
      const auto V = static_cast<float>(N);
711
13.8k
      uint32_t Raw;
712
13.8k
      static_assert(sizeof(V) == sizeof(Raw));
713
13.8k
      std::memcpy(&Raw, &V, sizeof(V));
714
13.8k
      Type Int32Ty = LLVMInt32TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
715
13.8k
      Value Ret = getConstInt(Int32Ty, Raw);
716
13.8k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
717
13.8k
    }
718
0
    if (Ty.isDoubleTy()) {
719
0
      const auto V = static_cast<double>(N);
720
0
      uint64_t Raw;
721
0
      static_assert(sizeof(V) == sizeof(Raw));
722
0
      std::memcpy(&Raw, &V, sizeof(V));
723
0
      Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
724
0
      Value Ret = getConstInt(Int64Ty, Raw);
725
0
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
726
0
    }
727
0
    assumingUnreachable();
728
0
  }
WasmEdge::LLVM::Value WasmEdge::LLVM::Value::getConstReal<double>(WasmEdge::LLVM::Type, double)
Line
Count
Source
708
6.56k
  template <typename T> static Value getConstReal(Type Ty, T N) noexcept {
709
6.56k
    if (Ty.isFloatTy()) {
710
0
      const auto V = static_cast<float>(N);
711
0
      uint32_t Raw;
712
0
      static_assert(sizeof(V) == sizeof(Raw));
713
0
      std::memcpy(&Raw, &V, sizeof(V));
714
0
      Type Int32Ty = LLVMInt32TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
715
0
      Value Ret = getConstInt(Int32Ty, Raw);
716
0
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
717
0
    }
718
6.56k
    if (Ty.isDoubleTy()) {
719
6.56k
      const auto V = static_cast<double>(N);
720
6.56k
      uint64_t Raw;
721
6.56k
      static_assert(sizeof(V) == sizeof(Raw));
722
6.56k
      std::memcpy(&Raw, &V, sizeof(V));
723
6.56k
      Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
724
6.56k
      Value Ret = getConstInt(Int64Ty, Raw);
725
6.56k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
726
6.56k
    }
727
0
    assumingUnreachable();
728
6.56k
  }
WasmEdge::LLVM::Value WasmEdge::LLVM::Value::getConstReal<long>(WasmEdge::LLVM::Type, long)
Line
Count
Source
708
6.35k
  template <typename T> static Value getConstReal(Type Ty, T N) noexcept {
709
6.35k
    if (Ty.isFloatTy()) {
710
3.90k
      const auto V = static_cast<float>(N);
711
3.90k
      uint32_t Raw;
712
3.90k
      static_assert(sizeof(V) == sizeof(Raw));
713
3.90k
      std::memcpy(&Raw, &V, sizeof(V));
714
3.90k
      Type Int32Ty = LLVMInt32TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
715
3.90k
      Value Ret = getConstInt(Int32Ty, Raw);
716
3.90k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
717
3.90k
    }
718
2.45k
    if (Ty.isDoubleTy()) {
719
2.45k
      const auto V = static_cast<double>(N);
720
2.45k
      uint64_t Raw;
721
2.45k
      static_assert(sizeof(V) == sizeof(Raw));
722
2.45k
      std::memcpy(&Raw, &V, sizeof(V));
723
2.45k
      Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
724
2.45k
      Value Ret = getConstInt(Int64Ty, Raw);
725
2.45k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
726
2.45k
    }
727
0
    assumingUnreachable();
728
2.45k
  }
WasmEdge::LLVM::Value WasmEdge::LLVM::Value::getConstReal<unsigned long>(WasmEdge::LLVM::Type, unsigned long)
Line
Count
Source
708
8.24k
  template <typename T> static Value getConstReal(Type Ty, T N) noexcept {
709
8.24k
    if (Ty.isFloatTy()) {
710
2.76k
      const auto V = static_cast<float>(N);
711
2.76k
      uint32_t Raw;
712
2.76k
      static_assert(sizeof(V) == sizeof(Raw));
713
2.76k
      std::memcpy(&Raw, &V, sizeof(V));
714
2.76k
      Type Int32Ty = LLVMInt32TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
715
2.76k
      Value Ret = getConstInt(Int32Ty, Raw);
716
2.76k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
717
2.76k
    }
718
5.48k
    if (Ty.isDoubleTy()) {
719
5.48k
      const auto V = static_cast<double>(N);
720
5.48k
      uint64_t Raw;
721
5.48k
      static_assert(sizeof(V) == sizeof(Raw));
722
5.48k
      std::memcpy(&Raw, &V, sizeof(V));
723
5.48k
      Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
724
5.48k
      Value Ret = getConstInt(Int64Ty, Raw);
725
5.48k
      return LLVMConstBitCast(Ret.unwrap(), Ty.unwrap());
726
5.48k
    }
727
0
    assumingUnreachable();
728
5.48k
  }
729
  static Value getConstString(Context &C, std::string_view Str,
730
0
                              bool DontNullTerminate) noexcept {
731
0
    return LLVMConstStringInContext(C.unwrap(), Str.data(),
732
0
                                    static_cast<unsigned int>(Str.size()),
733
0
                                    DontNullTerminate);
734
0
  }
735
  static Value getConstInBoundsGEP(Type Ty, Value ConstantVal,
736
0
                                   Span<const Value> ConstantIndices) noexcept {
737
0
    const auto Data = const_cast<LLVMValueRef *>(
738
0
        reinterpret_cast<const LLVMValueRef *>(ConstantIndices.data()));
739
0
    const auto Size = static_cast<unsigned int>(ConstantIndices.size());
740
0
    return LLVMConstInBoundsGEP2(Ty.unwrap(), ConstantVal.unwrap(), Data, Size);
741
0
  }
742
  static Value getConstInBoundsGEP1_64(Type Ty, Value ConstantVal,
743
0
                                       uint64_t Idx0) noexcept {
744
0
    return getConstInBoundsGEP(
745
0
        Ty, ConstantVal,
746
0
        {LLVM::Value::getConstInt(
747
0
            LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap())), Idx0)});
748
0
  }
749
  static Value getConstInBoundsGEP2_64(Type Ty, Value ConstantVal,
750
0
                                       uint64_t Idx0, uint64_t Idx1) noexcept {
751
0
    return getConstInBoundsGEP(
752
0
        Ty, ConstantVal,
753
0
        {LLVM::Value::getConstInt(
754
0
            LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap())), Idx0,
755
0
            Idx1)});
756
0
  }
757
38.3k
  static Value getConstVector(Span<const Value> ScalarConstantVals) noexcept {
758
38.3k
    const auto Data = const_cast<LLVMValueRef *>(
759
38.3k
        reinterpret_cast<const LLVMValueRef *>(ScalarConstantVals.data()));
760
38.3k
    const auto Size = static_cast<unsigned int>(ScalarConstantVals.size());
761
38.3k
    return LLVMConstVector(Data, Size);
762
38.3k
  }
763
  static Value getConstVector8(Context &C,
764
67.2k
                               Span<const uint8_t> Elements) noexcept {
765
67.2k
    std::vector<LLVMValueRef> Data(Elements.size());
766
67.2k
    std::transform(
767
67.2k
        Elements.begin(), Elements.end(), Data.begin(),
768
1.07M
        [&C](const uint8_t Element) { return C.getInt8(Element).unwrap(); });
769
67.2k
    return LLVMConstVector(Data.data(), static_cast<unsigned int>(Data.size()));
770
67.2k
  }
771
  static Value getConstVector16(Context &C,
772
0
                                Span<const uint16_t> Elements) noexcept {
773
0
    std::vector<LLVMValueRef> Data(Elements.size());
774
0
    std::transform(
775
0
        Elements.begin(), Elements.end(), Data.begin(),
776
0
        [&C](const uint16_t Element) { return C.getInt16(Element).unwrap(); });
777
0
    return LLVMConstVector(Data.data(), static_cast<unsigned int>(Data.size()));
778
0
  }
779
  static Value getConstVector32(Context &C,
780
16.7k
                                Span<const uint32_t> Elements) noexcept {
781
16.7k
    std::vector<LLVMValueRef> Data(Elements.size());
782
16.7k
    std::transform(
783
16.7k
        Elements.begin(), Elements.end(), Data.begin(),
784
73.0k
        [&C](const uint32_t Element) { return C.getInt32(Element).unwrap(); });
785
16.7k
    return LLVMConstVector(Data.data(), static_cast<unsigned int>(Data.size()));
786
16.7k
  }
787
  static Value getConstVector64(Context &C,
788
353
                                Span<const uint64_t> Elements) noexcept {
789
353
    std::vector<LLVMValueRef> Data(Elements.size());
790
353
    std::transform(
791
353
        Elements.begin(), Elements.end(), Data.begin(),
792
706
        [&C](const uint64_t Element) { return C.getInt64(Element).unwrap(); });
793
353
    return LLVMConstVector(Data.data(), static_cast<unsigned int>(Data.size()));
794
353
  }
795
796
#define DECLARE_VALUE_CHECK(name)                                              \
797
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
798
  LLVM_FOR_EACH_VALUE_SUBCLASS(DECLARE_VALUE_CHECK)
799
#undef DECLARE_VALUE_CHECK
800
801
0
  std::string_view getValueName() noexcept {
802
0
    size_t Size;
803
0
    const auto Ptr = LLVMGetValueName2(Ref, &Size);
804
0
    return {Ptr, Size};
805
0
  }
806
  inline void addFnAttr(const Attribute &A) noexcept;
807
  inline void addParamAttr(unsigned Index, const Attribute &A) noexcept;
808
  inline void addCallSiteAttribute(const Attribute &A) noexcept;
809
  inline void setMetadata(Context &C, unsigned int KindID,
810
                          Metadata Node) noexcept;
811
  inline void setMustTailCall() noexcept;
812
813
32.5k
  Value getFirstParam() noexcept { return LLVMGetFirstParam(Ref); }
814
37.2k
  Value getNextParam() noexcept { return LLVMGetNextParam(Ref); }
815
4.44k
  Value getNextGlobal() noexcept { return LLVMGetNextGlobal(Ref); }
816
39.2k
  Value getNextFunction() noexcept { return LLVMGetNextFunction(Ref); }
817
10.5k
  unsigned int countBasicBlocks() noexcept { return LLVMCountBasicBlocks(Ref); }
818
819
131k
  Type getType() const noexcept { return LLVMTypeOf(Ref); }
820
0
  Value getInitializer() noexcept { return LLVMGetInitializer(Ref); }
821
4.45k
  void setInitializer(Value ConstantVal) noexcept {
822
4.45k
    LLVMSetInitializer(Ref, ConstantVal.unwrap());
823
4.45k
  }
824
6.68k
  void setGlobalConstant(bool IsConstant) noexcept {
825
6.68k
    LLVMSetGlobalConstant(Ref, IsConstant);
826
6.68k
  }
827
21.5k
  LLVMLinkage getLinkage() noexcept { return LLVMGetLinkage(Ref); }
828
23.1k
  void setLinkage(LLVMLinkage Linkage) noexcept {
829
23.1k
    LLVMSetLinkage(Ref, Linkage);
830
23.1k
  }
831
19.6k
  void setVisibility(LLVMVisibility Viz) noexcept {
832
19.6k
    LLVMSetVisibility(Ref, Viz);
833
19.6k
  }
834
  void setDSOLocal(bool Local) noexcept;
835
19.6k
  void setDLLStorageClass(LLVMDLLStorageClass Class) noexcept {
836
19.6k
    LLVMSetDLLStorageClass(Ref, Class);
837
19.6k
  }
838
0
  bool getVolatile() noexcept { return LLVMGetVolatile(Ref); }
839
0
  void setVolatile(bool IsVolatile) noexcept {
840
0
    LLVMSetVolatile(Ref, IsVolatile);
841
0
  }
842
0
  bool getWeak() noexcept { return LLVMGetWeak(Ref); }
843
0
  void setWeak(bool IsWeak) noexcept { LLVMSetWeak(Ref, IsWeak); }
844
0
  unsigned int getAlignment() noexcept { return LLVMGetAlignment(Ref); }
845
23.1k
  void setAlignment(unsigned int Bytes) noexcept {
846
23.1k
    LLVMSetAlignment(Ref, Bytes);
847
23.1k
  }
848
0
  LLVMAtomicOrdering getOrdering() noexcept { return LLVMGetOrdering(Ref); }
849
0
  void setOrdering(LLVMAtomicOrdering Ordering) noexcept {
850
0
    LLVMSetOrdering(Ref, Ordering);
851
0
  }
852
0
  std::string_view getName() noexcept {
853
0
    size_t Length;
854
0
    auto Data = LLVMGetValueName2(Ref, &Length);
855
0
    return {Data, Length};
856
0
  }
857
858
  inline void addCase(Value OnVal, BasicBlock Dest) noexcept;
859
  inline void addDestination(BasicBlock Dest) noexcept;
860
  inline void addIncoming(Value IncomingValue,
861
                          BasicBlock IncomingBlocks) noexcept;
862
  inline void addIncoming(Span<const Value> IncomingValue,
863
                          Span<const BasicBlock> IncomingBlocks) noexcept;
864
  void eliminateUnreachableBlocks() noexcept;
865
866
private:
867
  LLVMValueRef Ref = nullptr;
868
};
869
870
struct FunctionCallee {
871
110k
  FunctionCallee() = default;
872
24.5k
  FunctionCallee(Type T, Value F) : Ty(T), Fn(F) {}
873
  Type Ty;
874
  Value Fn;
875
};
876
877
class Metadata {
878
public:
879
0
  constexpr Metadata(LLVMMetadataRef R) noexcept : Ref(R) {}
880
  Metadata(const Metadata &) = delete;
881
  Metadata &operator=(const Metadata &) = delete;
882
0
  Metadata(Metadata &&M) noexcept : Metadata() { swap(*this, M); }
883
0
  Metadata &operator=(Metadata &&M) noexcept {
884
0
    swap(*this, M);
885
0
    return *this;
886
0
  }
887
31.8k
  Metadata(Context &C, Span<Metadata> M) noexcept {
888
31.8k
    const auto Data = const_cast<LLVMMetadataRef *>(
889
31.8k
        reinterpret_cast<const LLVMMetadataRef *>(M.data()));
890
31.8k
    const auto Size = static_cast<unsigned int>(M.size());
891
31.8k
    Ref = LLVMMDNodeInContext2(C.unwrap(), Data, Size);
892
31.8k
  }
893
2.23k
  Metadata(Value V) noexcept : Ref(LLVMValueAsMetadata(V.unwrap())) {}
894
895
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
896
0
  constexpr auto &unwrap() const noexcept { return Ref; }
897
34.0k
  constexpr auto unwrap() noexcept { return Ref; }
898
0
  friend void swap(Metadata &LHS, Metadata &RHS) noexcept {
899
0
    using std::swap;
900
0
    swap(LHS.Ref, RHS.Ref);
901
0
  }
902
903
private:
904
  constexpr Metadata() noexcept = default;
905
  LLVMMetadataRef Ref = nullptr;
906
};
907
908
class Attribute {
909
public:
910
153k
  constexpr Attribute(LLVMAttributeRef R) noexcept : Ref(R) {}
911
  Attribute(const Attribute &) = delete;
912
  Attribute &operator=(const Attribute &) = delete;
913
0
  Attribute(Attribute &&M) noexcept : Attribute() { swap(*this, M); }
914
0
  Attribute &operator=(Attribute &&M) noexcept {
915
0
    swap(*this, M);
916
0
    return *this;
917
0
  }
918
919
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
920
243k
  constexpr auto &unwrap() const noexcept { return Ref; }
921
0
  constexpr auto unwrap() noexcept { return Ref; }
922
0
  friend void swap(Attribute &LHS, Attribute &RHS) noexcept {
923
0
    using std::swap;
924
0
    swap(LHS.Ref, RHS.Ref);
925
0
  }
926
927
  static Attribute createEnum(Context &C, unsigned int KindID,
928
15.6k
                              uint64_t Val) noexcept {
929
15.6k
    return LLVMCreateEnumAttribute(C.unwrap(), KindID, Val);
930
15.6k
  }
931
  static Attribute createString(Context &C, std::string_view Kind,
932
2.23k
                                std::string_view Val) noexcept {
933
2.23k
    return LLVMCreateStringAttribute(
934
2.23k
        C.unwrap(), Kind.data(), static_cast<unsigned int>(Kind.size()),
935
2.23k
        Val.data(), static_cast<unsigned int>(Val.size()));
936
2.23k
  }
937
938
private:
939
  constexpr Attribute() noexcept = default;
940
  LLVMAttributeRef Ref = nullptr;
941
};
942
943
Value Module::addFunction(Type Ty, LLVMLinkage Linkage,
944
17.5k
                          const char *Name) noexcept {
945
17.5k
  Value Fn = LLVMAddFunction(Ref, Name, Ty.unwrap());
946
17.5k
  Fn.setLinkage(Linkage);
947
17.5k
  return Fn;
948
17.5k
}
949
950
Value Module::addGlobal(Type Ty, bool IsConstant, LLVMLinkage Linkage,
951
5.40k
                        Value Initializer, const char *Name) noexcept {
952
5.40k
  Value G = LLVMAddGlobal(Ref, Ty.unwrap(), Name);
953
5.40k
  G.setLinkage(Linkage);
954
5.40k
  G.setGlobalConstant(IsConstant);
955
5.40k
  if (Initializer) {
956
3.17k
    G.setInitializer(Initializer);
957
3.17k
  }
958
5.40k
  return G;
959
5.40k
}
960
961
2.22k
Value Module::getNamedGlobal(const char *Name) noexcept {
962
2.22k
  return LLVMGetNamedGlobal(Ref, Name);
963
2.22k
}
964
965
Value Module::addAlias(Type Ty, Value V, const char *Name,
966
186
                       unsigned int AddrSpace [[maybe_unused]]) noexcept {
967
#if LLVM_VERSION_MAJOR >= 14
968
  return LLVMAddAlias2(Ref, Ty.unwrap(), AddrSpace, V.unwrap(), Name);
969
#else
970
186
  return LLVMAddAlias(Ref, Ty.unwrap(), V.unwrap(), Name);
971
186
#endif
972
186
}
973
974
void Module::addFlag(LLVMModuleFlagBehavior Behavior, std::string_view Key,
975
0
                     const Metadata &Val) noexcept {
976
0
  LLVMAddModuleFlag(Ref, Behavior, Key.data(), Key.size(), Val.unwrap());
977
0
}
978
979
void Module::addFlag(LLVMModuleFlagBehavior Behavior, std::string_view Key,
980
0
                     const Value &Val) noexcept {
981
0
  LLVMAddModuleFlag(Ref, Behavior, Key.data(), Key.size(),
982
0
                    Metadata(Val).unwrap());
983
0
}
984
985
void Module::addFlag(LLVMModuleFlagBehavior Behavior, std::string_view Key,
986
2.23k
                     uint32_t Val) noexcept {
987
2.23k
  Type Int32Ty = LLVMInt32TypeInContext(LLVMGetModuleContext(Ref));
988
2.23k
  LLVMAddModuleFlag(Ref, Behavior, Key.data(), Key.size(),
989
2.23k
                    Metadata(Value::getConstInt(Int32Ty, Val)).unwrap());
990
2.23k
}
991
992
2.22k
Value Module::getFirstGlobal() noexcept { return LLVMGetFirstGlobal(Ref); }
993
4.44k
Value Module::getFirstFunction() noexcept { return LLVMGetFirstFunction(Ref); }
994
995
0
Value Module::getNamedFunction(const char *Name) noexcept {
996
0
  return LLVMGetNamedFunction(Ref, Name);
997
0
}
998
999
0
Message Module::printModuleToFile(const char *Filename) noexcept {
1000
0
  Message M;
1001
0
  LLVMPrintModuleToFile(Ref, Filename, &M.unwrap());
1002
0
  return M;
1003
0
}
1004
1005
2.22k
Message Module::verify(LLVMVerifierFailureAction Action) noexcept {
1006
2.22k
  Message M;
1007
2.22k
  LLVMVerifyModule(Ref, Action, &M.unwrap());
1008
2.22k
  return M;
1009
2.22k
}
1010
1011
6.43k
Type Context::getVoidTy() noexcept { return LLVMVoidTypeInContext(Ref); }
1012
7.95k
Type Context::getInt1Ty() noexcept { return LLVMInt1TypeInContext(Ref); }
1013
1.08M
Type Context::getInt8Ty() noexcept { return LLVMInt8TypeInContext(Ref); }
1014
6.10k
Type Context::getInt16Ty() noexcept { return LLVMInt16TypeInContext(Ref); }
1015
799k
Type Context::getInt32Ty() noexcept { return LLVMInt32TypeInContext(Ref); }
1016
728k
Type Context::getInt64Ty() noexcept { return LLVMInt64TypeInContext(Ref); }
1017
2.23k
Type Context::getInt128Ty() noexcept { return LLVMInt128TypeInContext(Ref); }
1018
2.03k
Type Context::getIntNTy(unsigned int NumBits) noexcept {
1019
2.03k
  return LLVMIntTypeInContext(Ref, NumBits);
1020
2.03k
}
1021
82.4k
Type Context::getFloatTy() noexcept { return LLVMFloatTypeInContext(Ref); }
1022
636k
Type Context::getDoubleTy() noexcept { return LLVMDoubleTypeInContext(Ref); }
1023
1024
7.18k
Value Context::getFalse() noexcept {
1025
7.18k
  return Value::getConstInt(getInt1Ty(), 0);
1026
7.18k
}
1027
0
Value Context::getTrue() noexcept { return Value::getConstInt(getInt1Ty(), 1); }
1028
1.07M
Value Context::getInt8(uint8_t C) noexcept {
1029
1.07M
  return Value::getConstInt(getInt8Ty(), C);
1030
1.07M
}
1031
3.87k
Value Context::getInt16(uint16_t C) noexcept {
1032
3.87k
  return Value::getConstInt(getInt16Ty(), C);
1033
3.87k
}
1034
694k
Value Context::getInt32(uint32_t C) noexcept {
1035
694k
  return Value::getConstInt(getInt32Ty(), C);
1036
694k
}
1037
211k
Value Context::getInt64(uint64_t C) noexcept {
1038
211k
  return Value::getConstInt(getInt64Ty(), C);
1039
211k
}
1040
13.8k
Value Context::getFloat(float C) noexcept {
1041
13.8k
  return Value::getConstReal(getFloatTy(), C);
1042
13.8k
}
1043
6.56k
Value Context::getDouble(double C) noexcept {
1044
6.56k
  return Value::getConstReal(getDoubleTy(), C);
1045
6.56k
}
1046
1047
59.2k
void Value::addFnAttr(const Attribute &A) noexcept {
1048
59.2k
  LLVMAddAttributeAtIndex(
1049
59.2k
      Ref, static_cast<unsigned int>(LLVMAttributeFunctionIndex), A.unwrap());
1050
59.2k
}
1051
43.9k
void Value::addParamAttr(unsigned Index, const Attribute &A) noexcept {
1052
43.9k
  LLVMAddAttributeAtIndex(Ref, 1 + Index, A.unwrap());
1053
43.9k
}
1054
140k
void Value::addCallSiteAttribute(const Attribute &A) noexcept {
1055
140k
  LLVMAddCallSiteAttribute(
1056
140k
      Ref, static_cast<unsigned int>(LLVMAttributeFunctionIndex), A.unwrap());
1057
140k
}
1058
void Value::setMetadata(Context &C, unsigned int KindID,
1059
31.8k
                        Metadata Node) noexcept {
1060
31.8k
  LLVMSetMetadata(Ref, KindID, LLVMMetadataAsValue(C.unwrap(), Node.unwrap()));
1061
31.8k
}
1062
1063
233
void Value::setMustTailCall() noexcept {
1064
233
  LLVMSetTailCallKind(Ref, LLVMTailCallKindMustTail);
1065
233
}
1066
1067
2.23k
static inline Message getDefaultTargetTriple() noexcept {
1068
2.23k
  return LLVMGetDefaultTargetTriple();
1069
2.23k
}
compiler.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Line
Count
Source
1067
2.23k
static inline Message getDefaultTargetTriple() noexcept {
1068
2.23k
  return LLVMGetDefaultTargetTriple();
1069
2.23k
}
Unexecuted instantiation: context.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Unexecuted instantiation: function_compiler.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Unexecuted instantiation: memoryInstr.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Unexecuted instantiation: numericInstr.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Unexecuted instantiation: refInstr.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Unexecuted instantiation: threadInstr.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Unexecuted instantiation: vectorInstr.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Unexecuted instantiation: codegen.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Unexecuted instantiation: data.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Unexecuted instantiation: jit.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
Unexecuted instantiation: llvm.cpp:WasmEdge::LLVM::getDefaultTargetTriple()
1070
2.22k
static inline Message getHostCPUName() noexcept { return LLVMGetHostCPUName(); }
compiler.cpp:WasmEdge::LLVM::getHostCPUName()
Line
Count
Source
1070
2.22k
static inline Message getHostCPUName() noexcept { return LLVMGetHostCPUName(); }
Unexecuted instantiation: context.cpp:WasmEdge::LLVM::getHostCPUName()
Unexecuted instantiation: function_compiler.cpp:WasmEdge::LLVM::getHostCPUName()
Unexecuted instantiation: memoryInstr.cpp:WasmEdge::LLVM::getHostCPUName()
Unexecuted instantiation: numericInstr.cpp:WasmEdge::LLVM::getHostCPUName()
Unexecuted instantiation: refInstr.cpp:WasmEdge::LLVM::getHostCPUName()
Unexecuted instantiation: threadInstr.cpp:WasmEdge::LLVM::getHostCPUName()
Unexecuted instantiation: vectorInstr.cpp:WasmEdge::LLVM::getHostCPUName()
Unexecuted instantiation: codegen.cpp:WasmEdge::LLVM::getHostCPUName()
Unexecuted instantiation: data.cpp:WasmEdge::LLVM::getHostCPUName()
Unexecuted instantiation: jit.cpp:WasmEdge::LLVM::getHostCPUName()
Unexecuted instantiation: llvm.cpp:WasmEdge::LLVM::getHostCPUName()
1071
4.45k
static inline Message getHostCPUFeatures() noexcept {
1072
4.45k
  return LLVMGetHostCPUFeatures();
1073
4.45k
}
compiler.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Line
Count
Source
1071
2.22k
static inline Message getHostCPUFeatures() noexcept {
1072
2.22k
  return LLVMGetHostCPUFeatures();
1073
2.22k
}
context.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Line
Count
Source
1071
2.23k
static inline Message getHostCPUFeatures() noexcept {
1072
2.23k
  return LLVMGetHostCPUFeatures();
1073
2.23k
}
Unexecuted instantiation: function_compiler.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Unexecuted instantiation: memoryInstr.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Unexecuted instantiation: numericInstr.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Unexecuted instantiation: refInstr.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Unexecuted instantiation: threadInstr.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Unexecuted instantiation: vectorInstr.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Unexecuted instantiation: codegen.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Unexecuted instantiation: data.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Unexecuted instantiation: jit.cpp:WasmEdge::LLVM::getHostCPUFeatures()
Unexecuted instantiation: llvm.cpp:WasmEdge::LLVM::getHostCPUFeatures()
1074
1075
class BasicBlock {
1076
public:
1077
130k
  constexpr BasicBlock() noexcept = default;
1078
121k
  constexpr BasicBlock(LLVMBasicBlockRef R) noexcept : Ref(R) {}
1079
  BasicBlock(const BasicBlock &) = default;
1080
  BasicBlock &operator=(const BasicBlock &) = default;
1081
92.6k
  BasicBlock(BasicBlock &&B) noexcept : BasicBlock() { swap(*this, B); }
1082
3.82k
  BasicBlock &operator=(BasicBlock &&B) noexcept {
1083
3.82k
    swap(*this, B);
1084
3.82k
    return *this;
1085
3.82k
  }
1086
1087
61.2k
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1088
0
  constexpr auto &unwrap() const noexcept { return Ref; }
1089
253k
  constexpr auto &unwrap() noexcept { return Ref; }
1090
96.4k
  friend void swap(BasicBlock &LHS, BasicBlock &RHS) noexcept {
1091
96.4k
    using std::swap;
1092
96.4k
    swap(LHS.Ref, RHS.Ref);
1093
96.4k
  }
1094
1095
100k
  static BasicBlock create(Context &C, Value F, const char *Name) noexcept {
1096
100k
    return LLVMAppendBasicBlockInContext(C.unwrap(), F.unwrap(), Name);
1097
100k
  }
1098
0
  void erase() noexcept { LLVMDeleteBasicBlock(Ref); }
1099
1100
private:
1101
  LLVMBasicBlockRef Ref = nullptr;
1102
};
1103
1104
19.3k
void Value::addCase(Value OnVal, BasicBlock Dest) noexcept {
1105
19.3k
  LLVMAddCase(Ref, OnVal.unwrap(), Dest.unwrap());
1106
19.3k
}
1107
1108
0
void Value::addDestination(BasicBlock Dest) noexcept {
1109
0
  LLVMAddDestination(Ref, Dest.unwrap());
1110
0
}
1111
1112
void Value::addIncoming(Value IncomingValue,
1113
20.1k
                        BasicBlock IncomingBlocks) noexcept {
1114
20.1k
  LLVMAddIncoming(Ref, &IncomingValue.unwrap(), &IncomingBlocks.unwrap(), 1);
1115
20.1k
}
1116
1117
void Value::addIncoming(Span<const Value> IncomingValue,
1118
0
                        Span<const BasicBlock> IncomingBlocks) noexcept {
1119
0
  assuming(IncomingBlocks.size() == IncomingValue.size());
1120
0
  const auto ValueData = const_cast<LLVMValueRef *>(
1121
0
      reinterpret_cast<const LLVMValueRef *>(IncomingValue.data()));
1122
0
  const auto BlockData = const_cast<LLVMBasicBlockRef *>(
1123
0
      reinterpret_cast<const LLVMBasicBlockRef *>(IncomingBlocks.data()));
1124
0
  const auto Size = static_cast<unsigned int>(IncomingValue.size());
1125
0
  LLVMAddIncoming(Ref, ValueData, BlockData, Size);
1126
0
}
1127
1128
class Builder {
1129
private:
1130
445k
  LLVMValueRef getFn() noexcept {
1131
445k
    return LLVMGetBasicBlockParent(LLVMGetInsertBlock(Ref));
1132
445k
  }
1133
445k
  LLVMModuleRef getMod() noexcept { return LLVMGetGlobalParent(getFn()); }
1134
337k
  LLVMContextRef getCtx() noexcept { return LLVMGetModuleContext(getMod()); }
1135
1136
public:
1137
  constexpr Builder() noexcept = default;
1138
0
  constexpr Builder(LLVMBuilderRef R) noexcept : Ref(R) {}
1139
  Builder(const Builder &) = delete;
1140
  Builder &operator=(const Builder &) = delete;
1141
0
  Builder(Builder &&B) noexcept : Builder() { swap(*this, B); }
1142
0
  Builder &operator=(Builder &&B) noexcept {
1143
0
    swap(*this, B);
1144
0
    return *this;
1145
0
  }
1146
17.5k
  ~Builder() noexcept { LLVMDisposeBuilder(Ref); }
1147
1148
17.5k
  Builder(Context &C) noexcept : Ref(LLVMCreateBuilderInContext(C.unwrap())) {}
1149
1150
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1151
0
  constexpr auto &unwrap() const noexcept { return Ref; }
1152
0
  constexpr auto &unwrap() noexcept { return Ref; }
1153
0
  friend void swap(Builder &LHS, Builder &RHS) noexcept {
1154
0
    using std::swap;
1155
0
    swap(LHS.Ref, RHS.Ref);
1156
0
  }
1157
1158
103k
  void positionAtEnd(BasicBlock B) noexcept {
1159
103k
    LLVMPositionBuilderAtEnd(Ref, B.unwrap());
1160
103k
  }
1161
21.2k
  BasicBlock getInsertBlock() noexcept { return LLVMGetInsertBlock(Ref); }
1162
1163
6.96k
  Value createRetVoid() noexcept { return LLVMBuildRetVoid(Ref); }
1164
9.00k
  Value createRet(Value V) noexcept { return LLVMBuildRet(Ref, V.unwrap()); }
1165
386
  Value createAggregateRet(Span<const Value> RetVals) noexcept {
1166
386
    const auto Data = const_cast<LLVMValueRef *>(
1167
386
        reinterpret_cast<const LLVMValueRef *>(RetVals.data()));
1168
386
    const auto Size = static_cast<unsigned int>(RetVals.size());
1169
386
    return LLVMBuildAggregateRet(Ref, Data, Size);
1170
386
  }
1171
28.9k
  Value createBr(BasicBlock Dest) noexcept {
1172
28.9k
    return LLVMBuildBr(Ref, Dest.unwrap());
1173
28.9k
  }
1174
40.5k
  Value createCondBr(Value If, BasicBlock Then, BasicBlock Else) noexcept {
1175
40.5k
    return LLVMBuildCondBr(Ref, If.unwrap(), Then.unwrap(), Else.unwrap());
1176
40.5k
  }
1177
929
  Value createSwitch(Value V, BasicBlock Else, unsigned int NumCases) noexcept {
1178
929
    return LLVMBuildSwitch(Ref, V.unwrap(), Else.unwrap(), NumCases);
1179
929
  }
1180
0
  Value createIndirectBr(Value Addr, unsigned int NumDests) noexcept {
1181
0
    return LLVMBuildIndirectBr(Ref, Addr.unwrap(), NumDests);
1182
0
  }
1183
13.8k
  Value createUnreachable() noexcept { return LLVMBuildUnreachable(Ref); }
1184
1185
17.0k
  Value createAdd(Value LHS, Value RHS, const char *Name = "") noexcept {
1186
17.0k
    return LLVMBuildAdd(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1187
17.0k
  }
1188
0
  Value createNSWAdd(Value LHS, Value RHS, const char *Name = "") noexcept {
1189
0
    return LLVMBuildNSWAdd(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1190
0
  }
1191
0
  Value createNUWAdd(Value LHS, Value RHS, const char *Name = "") noexcept {
1192
0
    return LLVMBuildNUWAdd(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1193
0
  }
1194
2.31k
  Value createFAdd(Value LHS, Value RHS, const char *Name = "") noexcept {
1195
2.31k
    Value Ret = createIntrinsic(
1196
2.31k
        Core::ExperimentalConstrainedFAdd, {LHS.getType()},
1197
2.31k
        {LHS, RHS, getConstrainedFPRounding(), getConstrainedFPExcept()}, Name);
1198
2.31k
    Ret.addCallSiteAttribute(
1199
2.31k
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1200
2.31k
    return Ret;
1201
2.31k
  }
1202
3.12k
  Value createSub(Value LHS, Value RHS, const char *Name = "") noexcept {
1203
3.12k
    return LLVMBuildSub(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1204
3.12k
  }
1205
0
  Value createNSWSub(Value LHS, Value RHS, const char *Name = "") noexcept {
1206
0
    return LLVMBuildNSWSub(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1207
0
  }
1208
0
  Value createNUWSub(Value LHS, Value RHS, const char *Name = "") noexcept {
1209
0
    return LLVMBuildNUWSub(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1210
0
  }
1211
954
  Value createFSub(Value LHS, Value RHS, const char *Name = "") noexcept {
1212
954
    Value Ret = createIntrinsic(
1213
954
        Core::ExperimentalConstrainedFSub, {LHS.getType()},
1214
954
        {LHS, RHS, getConstrainedFPRounding(), getConstrainedFPExcept()}, Name);
1215
954
    Ret.addCallSiteAttribute(
1216
954
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1217
954
    return Ret;
1218
954
  }
1219
3.43k
  Value createMul(Value LHS, Value RHS, const char *Name = "") noexcept {
1220
3.43k
    return LLVMBuildMul(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1221
3.43k
  }
1222
0
  Value createNSWMul(Value LHS, Value RHS, const char *Name = "") noexcept {
1223
0
    return LLVMBuildNSWMul(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1224
0
  }
1225
0
  Value createNUWMul(Value LHS, Value RHS, const char *Name = "") noexcept {
1226
0
    return LLVMBuildNUWMul(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1227
0
  }
1228
945
  Value createFMul(Value LHS, Value RHS, const char *Name = "") noexcept {
1229
945
    Value Ret = createIntrinsic(
1230
945
        Core::ExperimentalConstrainedFMul, {LHS.getType()},
1231
945
        {LHS, RHS, getConstrainedFPRounding(), getConstrainedFPExcept()}, Name);
1232
945
    Ret.addCallSiteAttribute(
1233
945
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1234
945
    return Ret;
1235
945
  }
1236
3.40k
  Value createUDiv(Value LHS, Value RHS, const char *Name = "") noexcept {
1237
3.40k
    return LLVMBuildUDiv(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1238
3.40k
  }
1239
0
  Value createExactUDiv(Value LHS, Value RHS, const char *Name = "") noexcept {
1240
0
    return LLVMBuildExactUDiv(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1241
0
  }
1242
1.42k
  Value createSDiv(Value LHS, Value RHS, const char *Name = "") noexcept {
1243
1.42k
    return LLVMBuildSDiv(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1244
1.42k
  }
1245
0
  Value createExactSDiv(Value LHS, Value RHS, const char *Name = "") noexcept {
1246
0
    return LLVMBuildExactSDiv(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1247
0
  }
1248
672
  Value createFDiv(Value LHS, Value RHS, const char *Name = "") noexcept {
1249
672
    Value Ret = createIntrinsic(
1250
672
        Core::ExperimentalConstrainedFDiv, {LHS.getType()},
1251
672
        {LHS, RHS, getConstrainedFPRounding(), getConstrainedFPExcept()}, Name);
1252
672
    Ret.addCallSiteAttribute(
1253
672
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1254
672
    return Ret;
1255
672
  }
1256
2.65k
  Value createURem(Value LHS, Value RHS, const char *Name = "") noexcept {
1257
2.65k
    return LLVMBuildURem(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1258
2.65k
  }
1259
1.64k
  Value createSRem(Value LHS, Value RHS, const char *Name = "") noexcept {
1260
1.64k
    return LLVMBuildSRem(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1261
1.64k
  }
1262
3.63k
  Value createShl(Value LHS, Value RHS, const char *Name = "") noexcept {
1263
3.63k
    return LLVMBuildShl(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1264
3.63k
  }
1265
4.75k
  Value createLShr(Value LHS, Value RHS, const char *Name = "") noexcept {
1266
4.75k
    return LLVMBuildLShr(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1267
4.75k
  }
1268
4.86k
  Value createAShr(Value LHS, Value RHS, const char *Name = "") noexcept {
1269
4.86k
    return LLVMBuildAShr(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1270
4.86k
  }
1271
18.4k
  Value createAnd(Value LHS, Value RHS, const char *Name = "") noexcept {
1272
18.4k
    return LLVMBuildAnd(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1273
18.4k
  }
1274
5.78k
  Value createOr(Value LHS, Value RHS, const char *Name = "") noexcept {
1275
5.78k
    return LLVMBuildOr(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1276
5.78k
  }
1277
3.64k
  Value createXor(Value LHS, Value RHS, const char *Name = "") noexcept {
1278
3.64k
    return LLVMBuildXor(Ref, LHS.unwrap(), RHS.unwrap(), Name);
1279
3.64k
  }
1280
3.19k
  Value createNeg(Value V, const char *Name = "") noexcept {
1281
3.19k
    return LLVMBuildNeg(Ref, V.unwrap(), Name);
1282
3.19k
  }
1283
2.32k
  Value createFNeg(Value V, const char *Name = "") noexcept {
1284
2.32k
    return LLVMBuildFNeg(Ref, V.unwrap(), Name);
1285
2.32k
  }
1286
2.39k
  Value createNot(Value V, const char *Name = "") noexcept {
1287
2.39k
    return LLVMBuildNot(Ref, V.unwrap(), Name);
1288
2.39k
  }
1289
675k
  Value createAlloca(Type Ty, const char *Name = "") noexcept {
1290
675k
    return LLVMBuildAlloca(Ref, Ty.unwrap(), Name);
1291
675k
  }
1292
1.58k
  Value createArrayAlloca(Type Ty, Value Val, const char *Name = "") noexcept {
1293
1.58k
    return LLVMBuildArrayAlloca(Ref, Ty.unwrap(), Val.unwrap(), Name);
1294
1.58k
  }
1295
  Value createLoad(Type Ty, Value PointerVal, bool Volatile = false,
1296
112k
                   const char *Name = "") noexcept {
1297
112k
    auto Ret = LLVMBuildLoad2(Ref, Ty.unwrap(), PointerVal.unwrap(), Name);
1298
112k
    if (Volatile) {
1299
18.2k
      LLVMSetVolatile(Ret, true);
1300
18.2k
    }
1301
112k
    return Ret;
1302
112k
  }
1303
687k
  Value createStore(Value Val, Value Ptr, bool Volatile = false) noexcept {
1304
687k
    auto Ret = LLVMBuildStore(Ref, Val.unwrap(), Ptr.unwrap());
1305
687k
    if (Volatile) {
1306
5.35k
      LLVMSetVolatile(Ret, true);
1307
5.35k
    }
1308
687k
    return Ret;
1309
687k
  }
1310
1311
  Value createInBoundsGEP1(Type Ty, Value Pointer, Value Idx0,
1312
71.5k
                           const char *Name = "") noexcept {
1313
71.5k
    LLVMValueRef Data[1] = {Idx0.unwrap()};
1314
71.5k
    return LLVMBuildInBoundsGEP2(Ref, Ty.unwrap(), Pointer.unwrap(), Data,
1315
71.5k
                                 static_cast<unsigned>(std::size(Data)), Name);
1316
71.5k
  }
1317
  Value createInBoundsGEP2(Type Ty, Value Pointer, Value Idx0, Value Idx1,
1318
7.43k
                           const char *Name = "") noexcept {
1319
7.43k
    LLVMValueRef Data[2] = {Idx0.unwrap(), Idx1.unwrap()};
1320
7.43k
    return LLVMBuildInBoundsGEP2(Ref, Ty.unwrap(), Pointer.unwrap(), Data,
1321
7.43k
                                 static_cast<unsigned>(std::size(Data)), Name);
1322
7.43k
  }
1323
  Value createConstInBoundsGEP1_64(Type Ty, Value Pointer, uint64_t Idx0,
1324
10.7k
                                   const char *Name = "") noexcept {
1325
10.7k
    Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
1326
10.7k
    LLVMValueRef Data[1] = {Value::getConstInt(Int64Ty, Idx0).unwrap()};
1327
10.7k
    return LLVMBuildInBoundsGEP2(Ref, Ty.unwrap(), Pointer.unwrap(), Data,
1328
10.7k
                                 static_cast<unsigned>(std::size(Data)), Name);
1329
10.7k
  }
1330
1331
  Value createConstInBoundsGEP2_64(Type Ty, Value Pointer, uint64_t Idx0,
1332
                                   uint64_t Idx1,
1333
0
                                   const char *Name = "") noexcept {
1334
0
    Type Int64Ty = LLVMInt64TypeInContext(LLVMGetTypeContext(Ty.unwrap()));
1335
0
    LLVMValueRef Data[2] = {Value::getConstInt(Int64Ty, Idx0).unwrap(),
1336
0
                            Value::getConstInt(Int64Ty, Idx1).unwrap()};
1337
0
    return LLVMBuildInBoundsGEP2(Ref, Ty.unwrap(), Pointer.unwrap(), Data,
1338
0
                                 static_cast<unsigned>(std::size(Data)), Name);
1339
0
  }
1340
1341
62.8k
  Value createTrunc(Value Val, Type DestTy, const char *Name = "") noexcept {
1342
62.8k
    return LLVMBuildTrunc(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1343
62.8k
  }
1344
76.8k
  Value createZExt(Value Val, Type DestTy, const char *Name = "") noexcept {
1345
76.8k
    return LLVMBuildZExt(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1346
76.8k
  }
1347
27.4k
  Value createSExt(Value Val, Type DestTy, const char *Name = "") noexcept {
1348
27.4k
    return LLVMBuildSExt(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1349
27.4k
  }
1350
10.0k
  Value createFPToUI(Value Val, Type DestTy, const char *Name = "") noexcept {
1351
10.0k
    return LLVMBuildFPToUI(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1352
10.0k
  }
1353
4.13k
  Value createFPToSI(Value Val, Type DestTy, const char *Name = "") noexcept {
1354
4.13k
    return LLVMBuildFPToSI(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1355
4.13k
  }
1356
17.1k
  Value createUIToFP(Value Val, Type DestTy, const char *Name = "") noexcept {
1357
17.1k
    return LLVMBuildUIToFP(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1358
17.1k
  }
1359
9.43k
  Value createSIToFP(Value Val, Type DestTy, const char *Name = "") noexcept {
1360
9.43k
    return LLVMBuildSIToFP(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1361
9.43k
  }
1362
969
  Value createFPTrunc(Value Val, Type DestTy, const char *Name = "") noexcept {
1363
969
    Value Ret = createIntrinsic(
1364
969
        Core::ExperimentalConstrainedFPTrunc, {DestTy, Val.getType()},
1365
969
        {Val, getConstrainedFPRounding(), getConstrainedFPExcept()}, Name);
1366
969
    Ret.addCallSiteAttribute(
1367
969
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1368
969
    return Ret;
1369
969
  }
1370
875
  Value createFPExt(Value Val, Type DestTy, const char *Name = "") noexcept {
1371
875
    Value Ret = createIntrinsic(Core::ExperimentalConstrainedFPExt,
1372
875
                                {DestTy, Val.getType()},
1373
875
                                {Val, getConstrainedFPExcept()}, Name);
1374
875
    Ret.addCallSiteAttribute(
1375
875
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1376
875
    return Ret;
1377
875
  }
1378
0
  Value createPtrToInt(Value Val, Type DestTy, const char *Name = "") noexcept {
1379
0
    return LLVMBuildPtrToInt(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1380
0
  }
1381
795
  Value createIntToPtr(Value Val, Type DestTy, const char *Name = "") noexcept {
1382
795
    return LLVMBuildIntToPtr(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1383
795
  }
1384
286k
  Value createBitCast(Value Val, Type DestTy, const char *Name = "") noexcept {
1385
286k
    return LLVMBuildBitCast(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1386
286k
  }
1387
  Value createZExtOrBitCast(Value Val, Type DestTy,
1388
0
                            const char *Name = "") noexcept {
1389
0
    return LLVMBuildZExtOrBitCast(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1390
0
  }
1391
  Value createSExtOrBitCast(Value Val, Type DestTy,
1392
0
                            const char *Name = "") noexcept {
1393
0
    return LLVMBuildSExtOrBitCast(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1394
0
  }
1395
  Value createTruncOrBitCast(Value Val, Type DestTy,
1396
0
                             const char *Name = "") noexcept {
1397
0
    return LLVMBuildTruncOrBitCast(Ref, Val.unwrap(), DestTy.unwrap(), Name);
1398
0
  }
1399
  Value createZExtOrTrunc(Value Val, Type DestTy,
1400
2.28k
                          const char *Name = "") noexcept {
1401
2.28k
    const auto VTy = Val.getType();
1402
2.28k
    assuming(DestTy.isIntegerTy() || DestTy.isVectorTy());
1403
2.28k
    assuming(VTy.isIntegerTy() || VTy.isVectorTy());
1404
2.28k
    const auto VTySize = VTy.getPrimitiveSizeInBits();
1405
2.28k
    const auto DestTySize = DestTy.getPrimitiveSizeInBits();
1406
2.28k
    if (VTySize < DestTySize) {
1407
518
      return createZExt(Val, DestTy, Name);
1408
518
    }
1409
1.76k
    if (VTySize > DestTySize) {
1410
0
      return createTrunc(Val, DestTy, Name);
1411
0
    }
1412
1.76k
    return Val;
1413
1.76k
  }
1414
  Value createSExtOrTrunc(Value Val, Type DestTy,
1415
0
                          const char *Name = "") noexcept {
1416
0
    const auto VTy = Val.getType();
1417
0
    assuming(DestTy.isIntegerTy() || DestTy.isVectorTy());
1418
0
    assuming(VTy.isIntegerTy() || VTy.isVectorTy());
1419
0
    const auto VTySize = VTy.getPrimitiveSizeInBits();
1420
0
    const auto DestTySize = DestTy.getPrimitiveSizeInBits();
1421
0
    if (VTySize < DestTySize) {
1422
0
      return createSExt(Val, DestTy, Name);
1423
0
    }
1424
0
    if (VTySize > DestTySize) {
1425
0
      return createTrunc(Val, DestTy, Name);
1426
0
    }
1427
0
    return Val;
1428
0
  }
1429
1430
  Value createICmp(LLVMIntPredicate Op, Value LHS, Value RHS,
1431
71.0k
                   const char *Name = "") noexcept {
1432
71.0k
    return LLVMBuildICmp(Ref, Op, LHS.unwrap(), RHS.unwrap(), Name);
1433
71.0k
  }
1434
16.0k
  Value createICmpEQ(Value LHS, Value RHS, const char *Name = "") noexcept {
1435
16.0k
    return createICmp(LLVMIntEQ, LHS, RHS, Name);
1436
16.0k
  }
1437
21.1k
  Value createICmpNE(Value LHS, Value RHS, const char *Name = "") noexcept {
1438
21.1k
    return createICmp(LLVMIntNE, LHS, RHS, Name);
1439
21.1k
  }
1440
6.10k
  Value createICmpUGT(Value LHS, Value RHS, const char *Name = "") noexcept {
1441
6.10k
    return createICmp(LLVMIntUGT, LHS, RHS, Name);
1442
6.10k
  }
1443
1.54k
  Value createICmpUGE(Value LHS, Value RHS, const char *Name = "") noexcept {
1444
1.54k
    return createICmp(LLVMIntUGE, LHS, RHS, Name);
1445
1.54k
  }
1446
6.95k
  Value createICmpULT(Value LHS, Value RHS, const char *Name = "") noexcept {
1447
6.95k
    return createICmp(LLVMIntULT, LHS, RHS, Name);
1448
6.95k
  }
1449
1.74k
  Value createICmpULE(Value LHS, Value RHS, const char *Name = "") noexcept {
1450
1.74k
    return createICmp(LLVMIntULE, LHS, RHS, Name);
1451
1.74k
  }
1452
2.78k
  Value createICmpSGT(Value LHS, Value RHS, const char *Name = "") noexcept {
1453
2.78k
    return createICmp(LLVMIntSGT, LHS, RHS, Name);
1454
2.78k
  }
1455
1.15k
  Value createICmpSGE(Value LHS, Value RHS, const char *Name = "") noexcept {
1456
1.15k
    return createICmp(LLVMIntSGE, LHS, RHS, Name);
1457
1.15k
  }
1458
5.74k
  Value createICmpSLT(Value LHS, Value RHS, const char *Name = "") noexcept {
1459
5.74k
    return createICmp(LLVMIntSLT, LHS, RHS, Name);
1460
5.74k
  }
1461
2.61k
  Value createICmpSLE(Value LHS, Value RHS, const char *Name = "") noexcept {
1462
2.61k
    return createICmp(LLVMIntSLE, LHS, RHS, Name);
1463
2.61k
  }
1464
  Value createFCmp(LLVMRealPredicate Op, Value LHS, Value RHS,
1465
10.5k
                   const char *Name = "") noexcept {
1466
10.5k
    return LLVMBuildFCmp(Ref, Op, LHS.unwrap(), RHS.unwrap(), Name);
1467
10.5k
  }
1468
215
  Value createFCmpOEQ(Value LHS, Value RHS, const char *Name = "") noexcept {
1469
215
    return LLVMBuildFCmp(Ref, LLVMRealOEQ, LHS.unwrap(), RHS.unwrap(), Name);
1470
215
  }
1471
1.05k
  Value createFCmpOGT(Value LHS, Value RHS, const char *Name = "") noexcept {
1472
1.05k
    return LLVMBuildFCmp(Ref, LLVMRealOGT, LHS.unwrap(), RHS.unwrap(), Name);
1473
1.05k
  }
1474
13.5k
  Value createFCmpOGE(Value LHS, Value RHS, const char *Name = "") noexcept {
1475
13.5k
    return LLVMBuildFCmp(Ref, LLVMRealOGE, LHS.unwrap(), RHS.unwrap(), Name);
1476
13.5k
  }
1477
1.17k
  Value createFCmpOLT(Value LHS, Value RHS, const char *Name = "") noexcept {
1478
1.17k
    return LLVMBuildFCmp(Ref, LLVMRealOLT, LHS.unwrap(), RHS.unwrap(), Name);
1479
1.17k
  }
1480
179
  Value createFCmpOLE(Value LHS, Value RHS, const char *Name = "") noexcept {
1481
179
    return LLVMBuildFCmp(Ref, LLVMRealOLE, LHS.unwrap(), RHS.unwrap(), Name);
1482
179
  }
1483
0
  Value createFCmpONE(Value LHS, Value RHS, const char *Name = "") noexcept {
1484
0
    return LLVMBuildFCmp(Ref, LLVMRealONE, LHS.unwrap(), RHS.unwrap(), Name);
1485
0
  }
1486
7.15k
  Value createFCmpORD(Value LHS, Value RHS, const char *Name = "") noexcept {
1487
7.15k
    return LLVMBuildFCmp(Ref, LLVMRealORD, LHS.unwrap(), RHS.unwrap(), Name);
1488
7.15k
  }
1489
2.54k
  Value createFCmpUNO(Value LHS, Value RHS, const char *Name = "") noexcept {
1490
2.54k
    return LLVMBuildFCmp(Ref, LLVMRealUNO, LHS.unwrap(), RHS.unwrap(), Name);
1491
2.54k
  }
1492
1.44k
  Value createFCmpUEQ(Value LHS, Value RHS, const char *Name = "") noexcept {
1493
1.44k
    return LLVMBuildFCmp(Ref, LLVMRealUEQ, LHS.unwrap(), RHS.unwrap(), Name);
1494
1.44k
  }
1495
0
  Value createFCmpUGT(Value LHS, Value RHS, const char *Name = "") noexcept {
1496
0
    return LLVMBuildFCmp(Ref, LLVMRealUGT, LHS.unwrap(), RHS.unwrap(), Name);
1497
0
  }
1498
955
  Value createFCmpUGE(Value LHS, Value RHS, const char *Name = "") noexcept {
1499
955
    return LLVMBuildFCmp(Ref, LLVMRealUGE, LHS.unwrap(), RHS.unwrap(), Name);
1500
955
  }
1501
6.92k
  Value createFCmpULT(Value LHS, Value RHS, const char *Name = "") noexcept {
1502
6.92k
    return LLVMBuildFCmp(Ref, LLVMRealULT, LHS.unwrap(), RHS.unwrap(), Name);
1503
6.92k
  }
1504
0
  Value createFCmpULE(Value LHS, Value RHS, const char *Name = "") noexcept {
1505
0
    return LLVMBuildFCmp(Ref, LLVMRealULE, LHS.unwrap(), RHS.unwrap(), Name);
1506
0
  }
1507
107
  Value createFCmpUNE(Value LHS, Value RHS, const char *Name = "") noexcept {
1508
107
    return LLVMBuildFCmp(Ref, LLVMRealUNE, LHS.unwrap(), RHS.unwrap(), Name);
1509
107
  }
1510
6.95k
  Value createPHI(Type Ty, const char *Name = "") noexcept {
1511
6.95k
    return LLVMBuildPhi(Ref, Ty.unwrap(), Name);
1512
6.95k
  }
1513
  Value createCall(FunctionCallee Callee, Span<const Value> Args,
1514
128k
                   const char *Name = "") noexcept {
1515
128k
    const auto Data = const_cast<LLVMValueRef *>(
1516
128k
        reinterpret_cast<const LLVMValueRef *>(Args.data()));
1517
128k
    const auto Size = static_cast<unsigned int>(Args.size());
1518
128k
    Value Ret = LLVMBuildCall2(Ref, Callee.Ty.unwrap(), Callee.Fn.unwrap(),
1519
128k
                               Data, Size, Name);
1520
128k
    Ret.addCallSiteAttribute(
1521
128k
        LLVMCreateEnumAttribute(getCtx(), LLVM::Core::StrictFP, 0));
1522
128k
    return Ret;
1523
128k
  }
1524
  Value createSelect(Value If, Value Then, Value Else,
1525
24.5k
                     const char *Name = "") noexcept {
1526
24.5k
    return LLVMBuildSelect(Ref, If.unwrap(), Then.unwrap(), Else.unwrap(),
1527
24.5k
                           Name);
1528
24.5k
  }
1529
  Value createExtractElement(Value VecVal, Value Index,
1530
5.64k
                             const char *Name = "") noexcept {
1531
5.64k
    return LLVMBuildExtractElement(Ref, VecVal.unwrap(), Index.unwrap(), Name);
1532
5.64k
  }
1533
  Value createInsertElement(Value VecVal, Value EltVal, Value Index,
1534
87.1k
                            const char *Name = "") noexcept {
1535
87.1k
    return LLVMBuildInsertElement(Ref, VecVal.unwrap(), EltVal.unwrap(),
1536
87.1k
                                  Index.unwrap(), Name);
1537
87.1k
  }
1538
  Value createShuffleVector(Value V1, Value V2, Value Mask,
1539
102k
                            const char *Name = "") noexcept {
1540
102k
    return LLVMBuildShuffleVector(Ref, V1.unwrap(), V2.unwrap(), Mask.unwrap(),
1541
102k
                                  Name);
1542
102k
  }
1543
  Value createExtractValue(Value AggVal, unsigned int Index,
1544
26.4k
                           const char *Name = "") noexcept {
1545
26.4k
    return LLVMBuildExtractValue(Ref, AggVal.unwrap(), Index, Name);
1546
26.4k
  }
1547
  Value createInsertValue(Value AggVal, Value EltVal, unsigned int Index,
1548
0
                          const char *Name = "") noexcept {
1549
0
    return LLVMBuildInsertValue(Ref, AggVal.unwrap(), EltVal.unwrap(), Index,
1550
0
                                Name);
1551
0
  }
1552
1553
1.95k
  Value createIsNull(Value Val, const char *Name = "") noexcept {
1554
1.95k
    return LLVMBuildIsNull(Ref, Val.unwrap(), Name);
1555
1.95k
  }
1556
0
  Value createIsNotNull(Value Val, const char *Name = "") noexcept {
1557
0
    return LLVMBuildIsNotNull(Ref, Val.unwrap(), Name);
1558
0
  }
1559
  Value createFence(LLVMAtomicOrdering Ordering, bool SingleThread = false,
1560
192
                    const char *Name = "") noexcept {
1561
192
    return LLVMBuildFence(Ref, Ordering, SingleThread, Name);
1562
192
  }
1563
  Value createAtomicRMW(LLVMAtomicRMWBinOp Op, Value Ptr, Value Val,
1564
                        LLVMAtomicOrdering Ordering,
1565
0
                        bool SingleThread = false) noexcept {
1566
0
    return LLVMBuildAtomicRMW(Ref, Op, Ptr.unwrap(), Val.unwrap(), Ordering,
1567
0
                              SingleThread);
1568
0
  }
1569
  Value createAtomicCmpXchg(Value Ptr, Value Cmp, Value New,
1570
                            LLVMAtomicOrdering SuccessOrdering,
1571
                            LLVMAtomicOrdering FailureOrdering,
1572
0
                            bool SingleThread = false) noexcept {
1573
0
    return LLVMBuildAtomicCmpXchg(Ref, Ptr.unwrap(), Cmp.unwrap(), New.unwrap(),
1574
0
                                  SuccessOrdering, FailureOrdering,
1575
0
                                  SingleThread);
1576
0
  }
1577
1578
  Value createIntrinsic(unsigned int ID, Span<const Type> Types,
1579
                        Span<const Value> Args,
1580
65.5k
                        const char *Name = "") noexcept {
1581
65.5k
    FunctionCallee C;
1582
65.5k
    {
1583
65.5k
      const auto Data = const_cast<LLVMTypeRef *>(
1584
65.5k
          reinterpret_cast<const LLVMTypeRef *>(Types.data()));
1585
65.5k
      const auto Size = static_cast<unsigned int>(Types.size());
1586
65.5k
      C.Fn = LLVMGetIntrinsicDeclaration(getMod(), ID, Data, Size);
1587
65.5k
      C.Ty = LLVMIntrinsicGetType(getCtx(), ID, Data, Size);
1588
65.5k
    }
1589
65.5k
    return createCall(C, Args, Name);
1590
65.5k
  }
1591
  Value createUnaryIntrinsic(unsigned int ID, Value V,
1592
42.6k
                             const char *Name = "") noexcept {
1593
42.6k
    FunctionCallee C;
1594
42.6k
    {
1595
42.6k
      LLVMTypeRef ParamTypes[1] = {V.getType().unwrap()};
1596
42.6k
      C.Fn = LLVMGetIntrinsicDeclaration(getMod(), ID, ParamTypes, 1);
1597
42.6k
      C.Ty = LLVMIntrinsicGetType(getCtx(), ID, ParamTypes, 1);
1598
42.6k
    }
1599
42.6k
    return createCall(C, {V}, Name);
1600
42.6k
  }
1601
  Value createBinaryIntrinsic(unsigned int ID, Value LHS, Value RHS,
1602
0
                              const char *Name = "") noexcept {
1603
0
    FunctionCallee C;
1604
0
    {
1605
0
      LLVMTypeRef ParamTypes[2] = {LHS.getType().unwrap(),
1606
0
                                   RHS.getType().unwrap()};
1607
0
      C.Fn = LLVMGetIntrinsicDeclaration(getMod(), ID, ParamTypes, 2);
1608
0
      C.Ty = LLVMIntrinsicGetType(getCtx(), ID, ParamTypes, 2);
1609
0
    }
1610
0
    return createCall(C, {LHS, RHS}, Name);
1611
0
  }
1612
1613
  Value createVectorSplat(unsigned int ElementCount, Value V,
1614
38.3k
                          const char *Name = "") noexcept {
1615
38.3k
    Value Zero = Value::getConstInt(LLVMInt32TypeInContext(getCtx()), 0);
1616
38.3k
    auto Empty =
1617
38.3k
        Value::getUndef(Type::getVectorType(V.getType(), ElementCount));
1618
38.3k
    auto One = createInsertElement(Empty, V, Zero);
1619
38.3k
    std::vector<Value> Mask(ElementCount, Zero);
1620
38.3k
    return createShuffleVector(One, Empty, Value::getConstVector(Mask), Name);
1621
38.3k
  }
1622
1623
37.3k
  Value createLikely(Value V) noexcept {
1624
37.3k
    Type Int1Ty = LLVMInt1TypeInContext(getCtx());
1625
37.3k
    return createIntrinsic(LLVM::Core::Expect, {Int1Ty},
1626
37.3k
                           {V, Value::getConstInt(Int1Ty, 1)});
1627
37.3k
  }
1628
1629
5.85k
  Value getConstrainedFPRounding() noexcept {
1630
5.85k
    using namespace std::literals;
1631
5.85k
    auto Ctx = getCtx();
1632
5.85k
    auto RoundingStr = "round.tonearest"sv;
1633
5.85k
    auto RoundingMDS =
1634
5.85k
        LLVMMDStringInContext2(Ctx, RoundingStr.data(), RoundingStr.size());
1635
5.85k
    return LLVMMetadataAsValue(Ctx, RoundingMDS);
1636
5.85k
  }
1637
6.72k
  Value getConstrainedFPExcept() noexcept {
1638
6.72k
    using namespace std::literals;
1639
6.72k
    auto Ctx = getCtx();
1640
6.72k
    auto ExceptStr = "fpexcept.strict"sv;
1641
6.72k
    auto ExceptMDS =
1642
6.72k
        LLVMMDStringInContext2(Ctx, ExceptStr.data(), ExceptStr.size());
1643
6.72k
    return LLVMMetadataAsValue(Ctx, ExceptMDS);
1644
6.72k
  }
1645
1646
3.00k
  Value createArray(size_t Num, uint32_t Align) noexcept {
1647
3.00k
    Value Size = Value::getConstInt(LLVMInt64TypeInContext(getCtx()),
1648
3.00k
                                    static_cast<uint64_t>(Num) * Align);
1649
3.00k
    Type Int8Ty = LLVMInt8TypeInContext(getCtx());
1650
3.00k
    if (Num > 0) {
1651
1.58k
      auto Arr = createArrayAlloca(Int8Ty, Size);
1652
1.58k
      Arr.setAlignment(Align);
1653
1.58k
      return Arr;
1654
1.58k
    }
1655
1.41k
    return Value::getConstPointerNull(Int8Ty.getPointerTo());
1656
3.00k
  }
1657
1658
  Value createValuePtrLoad(Type Ty, Value Ptr, Type PtrTy, uint64_t Idx0 = 0,
1659
5.70k
                           const char *Name = "") noexcept {
1660
5.70k
    auto VPtr = createConstInBoundsGEP1_64(PtrTy, Ptr, Idx0, Name);
1661
5.70k
    return createLoad(Ty, createBitCast(VPtr, Ty.getPointerTo()));
1662
5.70k
  }
1663
1664
  void createValuePtrStore(Value V, Value Ptr, Type PtrTy, uint64_t Idx0 = 0,
1665
2.85k
                           const char *Name = "") noexcept {
1666
2.85k
    auto VPtr = createConstInBoundsGEP1_64(PtrTy, Ptr, Idx0, Name);
1667
2.85k
    createStore(V, createBitCast(VPtr, V.getType().getPointerTo(), Name));
1668
2.85k
  }
1669
1670
  std::vector<Value> createArrayPtrLoad(size_t RetSize, Type Ty, Value Ptr,
1671
                                        Type PtrTy, uint32_t Align = 1,
1672
71
                                        const char *Name = "") noexcept {
1673
71
    std::vector<Value> ValVec;
1674
71
    ValVec.reserve(RetSize);
1675
229
    for (size_t I = 0; I < RetSize; ++I) {
1676
158
      auto VPtr = createConstInBoundsGEP1_64(PtrTy, Ptr, I * Align, Name);
1677
158
      auto TargetTy = Ty.getStructElementType(static_cast<unsigned int>(I));
1678
158
      ValVec.push_back(
1679
158
          createLoad(TargetTy, createBitCast(VPtr, TargetTy.getPointerTo())));
1680
158
    }
1681
71
    return ValVec;
1682
71
  }
1683
1684
  void createArrayPtrStore(Span<const Value> Vals, Value Ptr, Type PtrTy,
1685
1.55k
                           uint32_t Align = 1, const char *Name = "") noexcept {
1686
3.61k
    for (size_t I = 0; I < Vals.size(); ++I) {
1687
2.06k
      auto VPtr = createConstInBoundsGEP1_64(PtrTy, Ptr, I * Align, Name);
1688
2.06k
      auto Val = Vals[I];
1689
2.06k
      createStore(Val, createBitCast(VPtr, Val.getType().getPointerTo()), Name);
1690
2.06k
    }
1691
1.55k
  }
1692
1693
private:
1694
  LLVMBuilderRef Ref = nullptr;
1695
};
1696
1697
class Target {
1698
public:
1699
2.22k
  constexpr Target() noexcept = default;
1700
0
  constexpr Target(LLVMTargetRef R) noexcept : Ref(R) {}
1701
  Target(const Target &) = delete;
1702
  Target &operator=(const Target &) = delete;
1703
0
  Target(Target &&M) noexcept : Target() { swap(*this, M); }
1704
0
  Target &operator=(Target &&M) noexcept {
1705
0
    swap(*this, M);
1706
0
    return *this;
1707
0
  }
1708
1709
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1710
4.44k
  constexpr auto &unwrap() noexcept { return Ref; }
1711
0
  friend void swap(Target &LHS, Target &RHS) noexcept {
1712
0
    using std::swap;
1713
0
    swap(LHS.Ref, RHS.Ref);
1714
0
  }
1715
1716
2.22k
  static std::pair<Target, Message> getFromTriple(const char *Triple) noexcept {
1717
2.22k
    std::pair<Target, Message> Result;
1718
2.22k
    LLVMGetTargetFromTriple(Triple, &Result.first.unwrap(),
1719
2.22k
                            &Result.second.unwrap());
1720
2.22k
    return Result;
1721
2.22k
  }
1722
1723
private:
1724
  LLVMTargetRef Ref = nullptr;
1725
};
1726
1727
#if LLVM_VERSION_MAJOR < 13
1728
class PassManager {
1729
public:
1730
  constexpr PassManager() noexcept = default;
1731
4.44k
  constexpr PassManager(LLVMPassManagerRef R) noexcept : Ref(R) {}
1732
  PassManager(const PassManager &) = delete;
1733
  PassManager &operator=(const PassManager &) = delete;
1734
0
  PassManager(PassManager &&M) noexcept : PassManager() { swap(*this, M); }
1735
0
  PassManager &operator=(PassManager &&M) noexcept {
1736
0
    swap(*this, M);
1737
0
    return *this;
1738
0
  }
1739
1740
4.44k
  ~PassManager() noexcept { LLVMDisposePassManager(Ref); }
1741
1742
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1743
0
  constexpr auto &unwrap() const noexcept { return Ref; }
1744
8.88k
  constexpr auto &unwrap() noexcept { return Ref; }
1745
0
  friend void swap(PassManager &LHS, PassManager &RHS) noexcept {
1746
0
    using std::swap;
1747
0
    swap(LHS.Ref, RHS.Ref);
1748
0
  }
1749
1750
2.22k
  static PassManager create() noexcept { return LLVMCreatePassManager(); }
1751
1752
2.22k
  static PassManager createForModule(Module &M) noexcept {
1753
2.22k
    return LLVMCreateFunctionPassManagerForModule(M.unwrap());
1754
2.22k
  }
1755
1756
0
  void addTailCallEliminationPass() noexcept {
1757
0
    LLVMAddTailCallEliminationPass(Ref);
1758
0
  }
1759
0
  void addAlwaysInlinerPass() noexcept { LLVMAddAlwaysInlinerPass(Ref); }
1760
1761
2.22k
  void initializeFunctionPassManager() noexcept {
1762
2.22k
    LLVMInitializeFunctionPassManager(Ref);
1763
2.22k
  }
1764
2.22k
  void finalizeFunctionPassManager() noexcept {
1765
2.22k
    LLVMFinalizeFunctionPassManager(Ref);
1766
2.22k
  }
1767
22.1k
  void runFunctionPassManager(Value F) noexcept {
1768
22.1k
    LLVMRunFunctionPassManager(Ref, F.unwrap());
1769
22.1k
  }
1770
2.22k
  void runPassManager(Module &M) noexcept {
1771
2.22k
    LLVMRunPassManager(Ref, M.unwrap());
1772
2.22k
  }
1773
1774
private:
1775
  LLVMPassManagerRef Ref = nullptr;
1776
};
1777
1778
class PassManagerBuilder {
1779
public:
1780
  constexpr PassManagerBuilder() noexcept = default;
1781
2.22k
  constexpr PassManagerBuilder(LLVMPassManagerBuilderRef R) noexcept : Ref(R) {}
1782
  PassManagerBuilder(const PassManagerBuilder &) = delete;
1783
  PassManagerBuilder &operator=(const PassManagerBuilder &) = delete;
1784
0
  PassManagerBuilder(PassManagerBuilder &&M) noexcept : PassManagerBuilder() {
1785
0
    swap(*this, M);
1786
0
  }
1787
0
  PassManagerBuilder &operator=(PassManagerBuilder &&M) noexcept {
1788
0
    swap(*this, M);
1789
0
    return *this;
1790
0
  }
1791
1792
2.22k
  ~PassManagerBuilder() noexcept { LLVMPassManagerBuilderDispose(Ref); }
1793
1794
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1795
0
  constexpr auto &unwrap() const noexcept { return Ref; }
1796
0
  constexpr auto &unwrap() noexcept { return Ref; }
1797
0
  friend void swap(PassManagerBuilder &LHS, PassManagerBuilder &RHS) noexcept {
1798
0
    using std::swap;
1799
0
    swap(LHS.Ref, RHS.Ref);
1800
0
  }
1801
1802
2.22k
  static PassManagerBuilder create() noexcept {
1803
2.22k
    return LLVMPassManagerBuilderCreate();
1804
2.22k
  }
1805
2.22k
  void setOptLevel(unsigned int OptLevel) noexcept {
1806
2.22k
    LLVMPassManagerBuilderSetOptLevel(Ref, OptLevel);
1807
2.22k
  }
1808
2.22k
  void setSizeLevel(unsigned int SizeLevel) noexcept {
1809
2.22k
    LLVMPassManagerBuilderSetSizeLevel(Ref, SizeLevel);
1810
2.22k
  }
1811
2.22k
  void populateFunctionPassManager(PassManager &P) noexcept {
1812
2.22k
    LLVMPassManagerBuilderPopulateFunctionPassManager(Ref, P.unwrap());
1813
2.22k
  }
1814
2.22k
  void populateModulePassManager(PassManager &P) noexcept {
1815
2.22k
    LLVMPassManagerBuilderPopulateModulePassManager(Ref, P.unwrap());
1816
2.22k
  }
1817
1818
private:
1819
  LLVMPassManagerBuilderRef Ref = nullptr;
1820
};
1821
#endif
1822
1823
class TargetMachine {
1824
public:
1825
2.23k
  constexpr TargetMachine() noexcept = default;
1826
2.22k
  constexpr TargetMachine(LLVMTargetMachineRef R) noexcept : Ref(R) {}
1827
  TargetMachine(const TargetMachine &) = delete;
1828
  TargetMachine &operator=(const TargetMachine &) = delete;
1829
0
  TargetMachine(TargetMachine &&M) noexcept : TargetMachine() {
1830
0
    swap(*this, M);
1831
0
  }
1832
2.22k
  TargetMachine &operator=(TargetMachine &&M) noexcept {
1833
2.22k
    swap(*this, M);
1834
2.22k
    return *this;
1835
2.22k
  }
1836
1837
4.45k
  ~TargetMachine() noexcept { LLVMDisposeTargetMachine(Ref); }
1838
1839
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1840
0
  constexpr auto &unwrap() const noexcept { return Ref; }
1841
0
  constexpr auto &unwrap() noexcept { return Ref; }
1842
2.22k
  friend void swap(TargetMachine &LHS, TargetMachine &RHS) noexcept {
1843
2.22k
    using std::swap;
1844
2.22k
    swap(LHS.Ref, RHS.Ref);
1845
2.22k
  }
1846
1847
  static TargetMachine create(Target &T, const char *Triple, const char *CPU,
1848
                              const char *Features, LLVMCodeGenOptLevel Level,
1849
                              LLVMRelocMode Reloc,
1850
2.22k
                              LLVMCodeModel CodeModel) noexcept {
1851
2.22k
    return LLVMCreateTargetMachine(T.unwrap(), Triple, CPU, Features, Level,
1852
2.22k
                                   Reloc, CodeModel);
1853
2.22k
  }
1854
1855
#if LLVM_VERSION_MAJOR < 13
1856
4.44k
  void addAnalysisPasses(PassManager &P) noexcept {
1857
4.44k
    LLVMAddAnalysisPasses(Ref, P.unwrap());
1858
4.44k
  }
1859
#endif
1860
1861
  std::pair<MemoryBuffer, Message>
1862
2.22k
  emitToMemoryBuffer(Module &M, LLVMCodeGenFileType CodeGen) noexcept {
1863
2.22k
    std::pair<MemoryBuffer, Message> Result;
1864
2.22k
    LLVMTargetMachineEmitToMemoryBuffer(Ref, M.unwrap(), CodeGen,
1865
2.22k
                                        &Result.second.unwrap(),
1866
2.22k
                                        &Result.first.unwrap());
1867
2.22k
    return Result;
1868
2.22k
  }
1869
1870
private:
1871
  LLVMTargetMachineRef Ref = nullptr;
1872
};
1873
1874
#if LLVM_VERSION_MAJOR >= 13
1875
class PassBuilderOptions {
1876
public:
1877
  constexpr PassBuilderOptions() noexcept = default;
1878
  constexpr PassBuilderOptions(LLVMPassBuilderOptionsRef R) noexcept : Ref(R) {}
1879
  PassBuilderOptions(const PassBuilderOptions &) = delete;
1880
  PassBuilderOptions &operator=(const PassBuilderOptions &) = delete;
1881
  PassBuilderOptions(PassBuilderOptions &&O) noexcept : PassBuilderOptions() {
1882
    swap(*this, O);
1883
  }
1884
  PassBuilderOptions &operator=(PassBuilderOptions &&O) noexcept {
1885
    swap(*this, O);
1886
    return *this;
1887
  }
1888
1889
  ~PassBuilderOptions() noexcept { LLVMDisposePassBuilderOptions(Ref); }
1890
1891
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1892
  constexpr auto &unwrap() noexcept { return Ref; }
1893
  friend void swap(PassBuilderOptions &LHS, PassBuilderOptions &RHS) noexcept {
1894
    using std::swap;
1895
    swap(LHS.Ref, RHS.Ref);
1896
  }
1897
1898
  static PassBuilderOptions create() noexcept {
1899
    return LLVMCreatePassBuilderOptions();
1900
  }
1901
1902
  void setVerifyEach(bool VerifyEach) noexcept {
1903
    LLVMPassBuilderOptionsSetVerifyEach(Ref, VerifyEach);
1904
  }
1905
1906
  void setDebugLogging(bool DebugLogging) noexcept {
1907
    LLVMPassBuilderOptionsSetDebugLogging(Ref, DebugLogging);
1908
  }
1909
1910
  void setLoopInterleaving(bool LoopInterleaving) noexcept {
1911
    LLVMPassBuilderOptionsSetLoopInterleaving(Ref, LoopInterleaving);
1912
  }
1913
1914
  void setLoopVectorization(bool LoopVectorization) noexcept {
1915
    LLVMPassBuilderOptionsSetLoopVectorization(Ref, LoopVectorization);
1916
  }
1917
1918
  void setSLPVectorization(bool SLPVectorization) noexcept {
1919
    LLVMPassBuilderOptionsSetSLPVectorization(Ref, SLPVectorization);
1920
  }
1921
1922
  void setLoopUnrolling(bool LoopUnrolling) noexcept {
1923
    LLVMPassBuilderOptionsSetLoopUnrolling(Ref, LoopUnrolling);
1924
  }
1925
1926
  void setForgetAllSCEVInLoopUnroll(bool ForgetAllSCEVInLoopUnroll) noexcept {
1927
    LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll(
1928
        Ref, ForgetAllSCEVInLoopUnroll);
1929
  }
1930
1931
  void setLicmMssaOptCap(unsigned int LicmMssaOptCap) noexcept {
1932
    LLVMPassBuilderOptionsSetLicmMssaOptCap(Ref, LicmMssaOptCap);
1933
  }
1934
1935
  void setLicmMssaNoAccForPromotionCap(
1936
      unsigned int LicmMssaNoAccForPromotionCap) noexcept {
1937
    LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap(
1938
        Ref, LicmMssaNoAccForPromotionCap);
1939
  }
1940
1941
  void setCallGraphProfile(bool CallGraphProfile) noexcept {
1942
    LLVMPassBuilderOptionsSetCallGraphProfile(Ref, CallGraphProfile);
1943
  }
1944
1945
  void setMergeFunctions(bool MergeFunctions) noexcept {
1946
    LLVMPassBuilderOptionsSetMergeFunctions(Ref, MergeFunctions);
1947
  }
1948
1949
  Error runPasses(Module &M, const char *Passes,
1950
                  const TargetMachine &TM = nullptr) noexcept {
1951
    return LLVMRunPasses(M.unwrap(), Passes, TM.unwrap(), Ref);
1952
  }
1953
1954
private:
1955
  LLVMPassBuilderOptionsRef Ref = nullptr;
1956
};
1957
#endif
1958
1959
class SectionIterator {
1960
public:
1961
  constexpr SectionIterator() noexcept = default;
1962
4.44k
  constexpr SectionIterator(LLVMSectionIteratorRef R) noexcept : Ref(R) {}
1963
  SectionIterator(const SectionIterator &) = delete;
1964
  SectionIterator &operator=(const SectionIterator &) = delete;
1965
0
  SectionIterator(SectionIterator &&B) noexcept : SectionIterator() {
1966
0
    swap(*this, B);
1967
0
  }
1968
0
  SectionIterator &operator=(SectionIterator &&B) noexcept {
1969
0
    swap(*this, B);
1970
0
    return *this;
1971
0
  }
1972
1973
4.44k
  ~SectionIterator() noexcept { LLVMDisposeSectionIterator(Ref); }
1974
1975
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
1976
70.2k
  constexpr auto &unwrap() const noexcept { return Ref; }
1977
0
  constexpr auto &unwrap() noexcept { return Ref; }
1978
0
  friend void swap(SectionIterator &LHS, SectionIterator &RHS) noexcept {
1979
0
    using std::swap;
1980
0
    swap(LHS.Ref, RHS.Ref);
1981
0
  }
1982
1983
65.7k
  void next() const noexcept { LLVMMoveToNextSection(Ref); }
1984
1985
61.3k
  const char *getName() const noexcept { return LLVMGetSectionName(Ref); }
1986
10.6k
  uint64_t getAddress() const noexcept { return LLVMGetSectionAddress(Ref); }
1987
96.4k
  uint64_t getSize() const noexcept { return LLVMGetSectionSize(Ref); }
1988
28.4k
  Span<const uint8_t> getContents() const noexcept {
1989
28.4k
    return {reinterpret_cast<const uint8_t *>(LLVMGetSectionContents(Ref)),
1990
28.4k
            static_cast<size_t>(LLVMGetSectionSize(Ref))};
1991
28.4k
  }
1992
1993
  bool isText() const noexcept;
1994
  bool isData() const noexcept;
1995
  bool isBSS() const noexcept;
1996
  bool isPData() const noexcept;
1997
  bool isEHFrame() const noexcept;
1998
  bool isVirtual() const noexcept;
1999
2000
private:
2001
  LLVMSectionIteratorRef Ref = nullptr;
2002
};
2003
2004
class SymbolIterator {
2005
public:
2006
  constexpr SymbolIterator() noexcept = default;
2007
2.22k
  constexpr SymbolIterator(LLVMSymbolIteratorRef R) noexcept : Ref(R) {}
2008
  SymbolIterator(const SymbolIterator &) = delete;
2009
  SymbolIterator &operator=(const SymbolIterator &) = delete;
2010
0
  SymbolIterator(SymbolIterator &&B) noexcept : SymbolIterator() {
2011
0
    swap(*this, B);
2012
0
  }
2013
0
  SymbolIterator &operator=(SymbolIterator &&B) noexcept {
2014
0
    swap(*this, B);
2015
0
    return *this;
2016
0
  }
2017
2018
2.22k
  ~SymbolIterator() noexcept { LLVMDisposeSymbolIterator(Ref); }
2019
2020
24.0k
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2021
24.0k
  constexpr auto &unwrap() const noexcept { return Ref; }
2022
0
  constexpr auto &unwrap() noexcept { return Ref; }
2023
0
  friend void swap(SymbolIterator &LHS, SymbolIterator &RHS) noexcept {
2024
0
    using std::swap;
2025
0
    swap(LHS.Ref, RHS.Ref);
2026
0
  }
2027
2028
21.8k
  void next() const noexcept { LLVMMoveToNextSymbol(Ref); }
2029
2030
21.8k
  const char *getName() const noexcept { return LLVMGetSymbolName(Ref); }
2031
21.8k
  uint64_t getAddress() const noexcept { return LLVMGetSymbolAddress(Ref); }
2032
0
  uint64_t getSize() const noexcept { return LLVMGetSymbolSize(Ref); }
2033
2034
private:
2035
  LLVMSymbolIteratorRef Ref = nullptr;
2036
};
2037
2038
class Binary {
2039
public:
2040
4.44k
  constexpr Binary() noexcept = default;
2041
2.22k
  constexpr Binary(LLVMBinaryRef R) noexcept : Ref(R) {}
2042
  Binary(const Binary &) = delete;
2043
  Binary &operator=(const Binary &) = delete;
2044
0
  Binary(Binary &&B) noexcept : Binary() { swap(*this, B); }
2045
4.44k
  Binary &operator=(Binary &&B) noexcept {
2046
4.44k
    swap(*this, B);
2047
4.44k
    return *this;
2048
4.44k
  }
2049
2050
6.66k
  ~Binary() noexcept { LLVMDisposeBinary(Ref); }
2051
2052
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2053
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2054
0
  constexpr auto &unwrap() noexcept { return Ref; }
2055
4.44k
  friend void swap(Binary &LHS, Binary &RHS) noexcept {
2056
4.44k
    using std::swap;
2057
4.44k
    swap(LHS.Ref, RHS.Ref);
2058
4.44k
  }
2059
2060
  static std::pair<Binary, Message> create(MemoryBuffer &M,
2061
2.22k
                                           Context &C) noexcept {
2062
2.22k
    std::pair<Binary, Message> Result;
2063
2.22k
    Result.first =
2064
2.22k
        LLVMCreateBinary(M.unwrap(), C.unwrap(), &Result.second.unwrap());
2065
2.22k
    return Result;
2066
2.22k
  }
2067
2068
0
  LLVMBinaryType getType() const noexcept { return LLVMBinaryGetType(Ref); }
2069
4.44k
  SectionIterator sections() const noexcept {
2070
4.44k
    return LLVMObjectFileCopySectionIterator(Ref);
2071
4.44k
  }
2072
70.2k
  bool isSectionEnd(const SectionIterator &It) const noexcept {
2073
70.2k
    return LLVMObjectFileIsSectionIteratorAtEnd(Ref, It.unwrap());
2074
70.2k
  }
2075
2.22k
  SymbolIterator symbols() const noexcept {
2076
2.22k
    return LLVMObjectFileCopySymbolIterator(Ref);
2077
2.22k
  }
2078
24.0k
  bool isSymbolEnd(const SymbolIterator &It) const noexcept {
2079
24.0k
    return LLVMObjectFileIsSymbolIteratorAtEnd(Ref, It.unwrap());
2080
24.0k
  }
2081
2082
private:
2083
  LLVMBinaryRef Ref = nullptr;
2084
};
2085
2086
class OrcThreadSafeContext {
2087
public:
2088
  constexpr OrcThreadSafeContext(LLVMOrcThreadSafeContextRef R) noexcept
2089
0
      : Ref(R) {}
2090
  OrcThreadSafeContext(const OrcThreadSafeContext &) = delete;
2091
  OrcThreadSafeContext &operator=(const OrcThreadSafeContext &) = delete;
2092
  OrcThreadSafeContext(OrcThreadSafeContext &&B) noexcept
2093
0
      : OrcThreadSafeContext() {
2094
0
    swap(*this, B);
2095
0
  }
2096
0
  OrcThreadSafeContext &operator=(OrcThreadSafeContext &&B) noexcept {
2097
0
    swap(*this, B);
2098
0
    return *this;
2099
0
  }
2100
#if LLVM_VERSION_MAJOR >= 21
2101
  OrcThreadSafeContext(Context &C) noexcept
2102
      : Ref(LLVMOrcCreateNewThreadSafeContextFromLLVMContext(C.unwrap())) {}
2103
#else
2104
6.68k
  Context getContext() noexcept {
2105
6.68k
    return LLVMOrcThreadSafeContextGetContext(Ref);
2106
6.68k
  }
2107
#endif
2108
2109
2.23k
  OrcThreadSafeContext() noexcept : Ref(LLVMOrcCreateNewThreadSafeContext()) {}
2110
2.23k
  ~OrcThreadSafeContext() noexcept { LLVMOrcDisposeThreadSafeContext(Ref); }
2111
2112
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2113
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2114
0
  constexpr auto &unwrap() noexcept { return Ref; }
2115
0
  LLVMOrcThreadSafeContextRef release() noexcept {
2116
0
    return std::exchange(Ref, nullptr);
2117
0
  }
2118
  friend void swap(OrcThreadSafeContext &LHS,
2119
0
                   OrcThreadSafeContext &RHS) noexcept {
2120
0
    using std::swap;
2121
0
    swap(LHS.Ref, RHS.Ref);
2122
0
  }
2123
2124
private:
2125
  LLVMOrcThreadSafeContextRef Ref = nullptr;
2126
};
2127
2128
class OrcThreadSafeModule {
2129
public:
2130
  constexpr OrcThreadSafeModule() noexcept = default;
2131
  constexpr OrcThreadSafeModule(LLVMOrcThreadSafeModuleRef R) noexcept
2132
0
      : Ref(R) {}
2133
  OrcThreadSafeModule(const OrcThreadSafeModule &) = delete;
2134
  OrcThreadSafeModule &operator=(const OrcThreadSafeModule &) = delete;
2135
  OrcThreadSafeModule(OrcThreadSafeModule &&B) noexcept
2136
0
      : OrcThreadSafeModule() {
2137
0
    swap(*this, B);
2138
0
  }
2139
0
  OrcThreadSafeModule &operator=(OrcThreadSafeModule &&B) noexcept {
2140
0
    swap(*this, B);
2141
0
    return *this;
2142
0
  }
2143
2144
  OrcThreadSafeModule(Module &&M, OrcThreadSafeContext &C) noexcept
2145
0
      : Ref(LLVMOrcCreateNewThreadSafeModule(M.release(), C.unwrap())) {}
2146
0
  ~OrcThreadSafeModule() noexcept { LLVMOrcDisposeThreadSafeModule(Ref); }
2147
2148
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2149
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2150
0
  constexpr auto &unwrap() noexcept { return Ref; }
2151
0
  LLVMOrcThreadSafeModuleRef release() noexcept {
2152
0
    return std::exchange(Ref, nullptr);
2153
0
  }
2154
  friend void swap(OrcThreadSafeModule &LHS,
2155
0
                   OrcThreadSafeModule &RHS) noexcept {
2156
0
    using std::swap;
2157
0
    swap(LHS.Ref, RHS.Ref);
2158
0
  }
2159
  Error withModuleDo(LLVMOrcGenericIRModuleOperationFunction F,
2160
0
                     void *Ctx) noexcept {
2161
0
    return LLVMOrcThreadSafeModuleWithModuleDo(Ref, F, Ctx);
2162
0
  }
2163
2164
private:
2165
  LLVMOrcThreadSafeModuleRef Ref = nullptr;
2166
};
2167
2168
class OrcResourceTracker {
2169
public:
2170
  constexpr OrcResourceTracker() noexcept = default;
2171
0
  constexpr OrcResourceTracker(LLVMOrcResourceTrackerRef R) noexcept : Ref(R) {}
2172
0
  ~OrcResourceTracker() noexcept {
2173
0
    if (Ref) {
2174
0
      LLVMOrcReleaseResourceTracker(Ref);
2175
0
    }
2176
0
  }
2177
  OrcResourceTracker(const OrcResourceTracker &) = delete;
2178
  OrcResourceTracker &operator=(const OrcResourceTracker &) = delete;
2179
0
  OrcResourceTracker(OrcResourceTracker &&B) noexcept : OrcResourceTracker() {
2180
0
    swap(*this, B);
2181
0
  }
2182
0
  OrcResourceTracker &operator=(OrcResourceTracker &&B) noexcept {
2183
0
    swap(*this, B);
2184
0
    return *this;
2185
0
  }
2186
2187
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2188
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2189
0
  constexpr auto &unwrap() noexcept { return Ref; }
2190
0
  friend void swap(OrcResourceTracker &LHS, OrcResourceTracker &RHS) noexcept {
2191
0
    using std::swap;
2192
0
    swap(LHS.Ref, RHS.Ref);
2193
0
  }
2194
2195
0
  Error remove() noexcept {
2196
0
    if (Ref) {
2197
0
      return LLVMOrcResourceTrackerRemove(Ref);
2198
0
    }
2199
0
    return nullptr;
2200
0
  }
2201
2202
private:
2203
  LLVMOrcResourceTrackerRef Ref = nullptr;
2204
};
2205
2206
class OrcJITDylib {
2207
public:
2208
  constexpr OrcJITDylib() noexcept = default;
2209
0
  constexpr OrcJITDylib(LLVMOrcJITDylibRef R) noexcept : Ref(R) {}
2210
  OrcJITDylib(const OrcJITDylib &) = delete;
2211
  OrcJITDylib &operator=(const OrcJITDylib &) = delete;
2212
0
  OrcJITDylib(OrcJITDylib &&B) noexcept : OrcJITDylib() { swap(*this, B); }
2213
0
  OrcJITDylib &operator=(OrcJITDylib &&B) noexcept {
2214
0
    swap(*this, B);
2215
0
    return *this;
2216
0
  }
2217
2218
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2219
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2220
0
  constexpr auto &unwrap() noexcept { return Ref; }
2221
0
  friend void swap(OrcJITDylib &LHS, OrcJITDylib &RHS) noexcept {
2222
0
    using std::swap;
2223
0
    swap(LHS.Ref, RHS.Ref);
2224
0
  }
2225
2226
0
  OrcResourceTracker createResourceTracker() noexcept {
2227
0
    return LLVMOrcJITDylibCreateResourceTracker(Ref);
2228
0
  }
2229
2230
private:
2231
  LLVMOrcJITDylibRef Ref = nullptr;
2232
};
2233
2234
class OrcIRTransformLayer {
2235
public:
2236
  constexpr OrcIRTransformLayer() noexcept = default;
2237
  constexpr OrcIRTransformLayer(LLVMOrcIRTransformLayerRef R) noexcept
2238
0
      : Ref(R) {}
2239
  OrcIRTransformLayer(const OrcIRTransformLayer &) = delete;
2240
  OrcIRTransformLayer &operator=(const OrcIRTransformLayer &) = delete;
2241
  OrcIRTransformLayer(OrcIRTransformLayer &&B) noexcept
2242
0
      : OrcIRTransformLayer() {
2243
0
    swap(*this, B);
2244
0
  }
2245
0
  OrcIRTransformLayer &operator=(OrcIRTransformLayer &&B) noexcept {
2246
0
    swap(*this, B);
2247
0
    return *this;
2248
0
  }
2249
2250
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2251
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2252
0
  constexpr auto &unwrap() noexcept { return Ref; }
2253
  friend void swap(OrcIRTransformLayer &LHS,
2254
0
                   OrcIRTransformLayer &RHS) noexcept {
2255
0
    using std::swap;
2256
0
    swap(LHS.Ref, RHS.Ref);
2257
0
  }
2258
2259
  void setTransform(LLVMOrcIRTransformLayerTransformFunction TransformFunction,
2260
0
                    void *Ctx) noexcept {
2261
0
    LLVMOrcIRTransformLayerSetTransform(Ref, TransformFunction, Ctx);
2262
0
  }
2263
2264
private:
2265
  LLVMOrcIRTransformLayerRef Ref = nullptr;
2266
};
2267
2268
class OrcLLJIT {
2269
public:
2270
0
  constexpr OrcLLJIT() noexcept = default;
2271
0
  constexpr OrcLLJIT(LLVMOrcLLJITRef R) noexcept : Ref(R) {}
2272
  OrcLLJIT(const OrcLLJIT &) = delete;
2273
  OrcLLJIT &operator=(const OrcLLJIT &) = delete;
2274
0
  OrcLLJIT(OrcLLJIT &&B) noexcept : OrcLLJIT() { swap(*this, B); }
2275
0
  OrcLLJIT &operator=(OrcLLJIT &&B) noexcept {
2276
0
    swap(*this, B);
2277
0
    return *this;
2278
0
  }
2279
2280
0
  ~OrcLLJIT() noexcept { LLVMOrcDisposeLLJIT(Ref); }
2281
2282
0
  constexpr operator bool() const noexcept { return Ref != nullptr; }
2283
0
  constexpr auto &unwrap() const noexcept { return Ref; }
2284
0
  constexpr auto &unwrap() noexcept { return Ref; }
2285
0
  friend void swap(OrcLLJIT &LHS, OrcLLJIT &RHS) noexcept {
2286
0
    using std::swap;
2287
0
    swap(LHS.Ref, RHS.Ref);
2288
0
  }
2289
2290
0
  static cxx20::expected<OrcLLJIT, Error> create() noexcept {
2291
0
    OrcLLJIT Result;
2292
0
    if (auto Err = LLVMOrcCreateLLJIT(&Result.Ref, getBuilder())) {
2293
0
      return cxx20::unexpected(Err);
2294
0
    } else {
2295
0
      return Result;
2296
0
    }
2297
0
  }
2298
2299
0
  OrcJITDylib getMainJITDylib() noexcept {
2300
0
    return LLVMOrcLLJITGetMainJITDylib(Ref);
2301
0
  }
2302
2303
0
  Error addLLVMIRModule(const OrcJITDylib &L, OrcThreadSafeModule M) noexcept {
2304
0
    return LLVMOrcLLJITAddLLVMIRModule(Ref, L.unwrap(), M.release());
2305
0
  }
2306
2307
  Error addLLVMIRModuleWithRT(const OrcResourceTracker &RT,
2308
0
                              OrcThreadSafeModule M) noexcept {
2309
0
    return LLVMOrcLLJITAddLLVMIRModuleWithRT(Ref, RT.unwrap(), M.release());
2310
0
  }
2311
2312
  template <typename T>
2313
0
  cxx20::expected<T *, Error> lookup(const char *Name) noexcept {
2314
0
    LLVMOrcJITTargetAddress Addr;
2315
0
    if (auto Err = LLVMOrcLLJITLookup(Ref, &Addr, Name)) {
2316
0
      return cxx20::unexpected(Err);
2317
0
    }
2318
0
    return reinterpret_cast<T *>(Addr);
2319
0
  }
Unexecuted instantiation: cxx20::expected<void* const (**) [35], WasmEdge::LLVM::Error> WasmEdge::LLVM::OrcLLJIT::lookup<void* const (*) [35]>(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*)
2320
2321
0
  OrcIRTransformLayer getIRTransformLayer() noexcept {
2322
0
    return LLVMOrcLLJITGetIRTransformLayer(Ref);
2323
0
  }
2324
2325
  static LLVMOrcLLJITBuilderRef getBuilder() noexcept;
2326
2327
private:
2328
  LLVMOrcLLJITRef Ref = nullptr;
2329
};
2330
2331
} // namespace WasmEdge::LLVM