Coverage Report

Created: 2026-11-12 06:35

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