Coverage Report

Created: 2025-09-27 06:27

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