Coverage Report

Created: 2026-06-30 06:10

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