Coverage Report

Created: 2026-09-28 06:22

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