Skip to content

Commit a42b72c

Browse files
Porting ApsarasX/llvm-bindings#33 to this repo.
1 parent 3add75f commit a42b72c

35 files changed

+1224
-17
lines changed

CHANGELOG.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
11
# Changelog
22

3+
## [9.1.0](https://github.com/DesignLiquido/llvm-bindings/compare/v9.0.0...v9.1.0) (2026-03-12)
4+
5+
### At a glance
6+
7+
- Adds basic code generation: compile a module directly to an object file or an in-memory buffer.
8+
- Adds `ModulePassManager` and `FunctionPassManager` wrappers over LLVM's new PassBuilder infrastructure.
9+
- Adds `CallingConv`, `Reloc`, `CodeModel`, `CodeGenOpt`, `CodeGenFileType`, `OptimizationLevel`, and `ThinOrFullLTOPhase` enum namespaces.
10+
- Extends `Function`, `StructType.create`, `APInt`, and `Target.createTargetMachine` with new parameters.
11+
12+
### Added
13+
14+
- `TargetMachine.emitToFile(module, filePath, fileType)` — compiles a module to an object or assembly file on disk.
15+
- `TargetMachine.emitToBuffer(module, fileType)` — compiles a module to an in-memory `Buffer`.
16+
- `ModulePassManager` class — wraps LLVM's new `PassBuilder` pipeline. Constructor accepts an optional `OptimizationLevel` value (default: `O0`). Methods: `run(module)`, `addVerifierPass()`, `addFunctionPasses(fpm)`, `createFunctionPassManager(ltoPhase?)`, `isEmpty()`.
17+
- `FunctionPassManager` class — function-level pass pipeline obtained via `ModulePassManager.createFunctionPassManager`. Methods: `addSROAPass()`, `addEarlyCSEPass(useSSA?)`, `addInstCombinePass()`, `isEmpty()`.
18+
- `CallingConv` namespace — all `llvm::CallingConv` IDs (C, Fast, Cold, GHC, X86_StdCall, ARM_AAPCS, AMDGPU_KERNEL, …).
19+
- `Reloc` namespace — `Static`, `PIC_`, `DynamicNoPIC`, `ROPI`, `RWPI`, `ROPI_RWPI`.
20+
- `CodeModel` namespace — `Tiny`, `Small`, `Kernel`, `Medium`, `Large`.
21+
- `CodeGenOpt` namespace — `None`, `Less`, `Default`, `Aggressive`.
22+
- `CodeGenFileType` namespace — `Assembly`, `Object`, `Null`.
23+
- `OptimizationLevel` namespace — `O0`, `O1`, `O2`, `O3`, `Os`, `Oz`.
24+
- `ThinOrFullLTOPhase` namespace — `None`, `ThinLTOPreLink`, `ThinLTOPostLink`, `FullLTOPreLink`, `FullLTOPostLink`.
25+
- `Function.getCallingConv(): number` — returns the function's current calling convention.
26+
- `Function.setCallingConv(cc: number): void` — sets the function's calling convention.
27+
- `StructType.create(context, elementTypes, name, isPacked?)` — new optional `isPacked` boolean parameter.
28+
- `APInt` constructor now also accepts a `bigint` value (in addition to `number`), enabling representation of values larger than `Number.MAX_SAFE_INTEGER`.
29+
- `Target.createTargetMachine` overloads with optional `reloc`, `codeModel`, `optLevel` (`CodeGenOpt`), and `jit` parameters.
30+
331
## [9.0.0](https://github.com/DesignLiquido/llvm-bindings/compare/v8.0.0...v9.0.0) (2026-03-11)
432

533
### At a glance

README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,94 @@ LLVM 22 introduces a source-language naming API change in debug info and bumps t
258258
- `DIBuilder.cpp`: removed the `#if LLVM_VERSION_MAJOR >= 22` conditional; the LLVM 22+ API is now the only code path.
259259
- `cmake/LLVM.cmake`: the version discovery loop and the minimum-version guard now enforce LLVM >= 22.
260260

261+
## v9.1.0 — Basic code generation
262+
263+
v9.1.0 adds a substantial set of new APIs for compiling LLVM IR to native code.
264+
265+
**At a glance**
266+
267+
- Adds basic code generation: compile a module to an object file or an in-memory buffer.
268+
- Adds `ModulePassManager` and `FunctionPassManager` wrappers over LLVM's new PassBuilder infrastructure.
269+
- Adds `CallingConv` namespace with all calling convention IDs.
270+
- Adds `Reloc`, `CodeModel`, `CodeGenOpt`, and `CodeGenFileType` enum namespaces.
271+
- Adds `OptimizationLevel` and `ThinOrFullLTOPhase` enum namespaces.
272+
- Extends `Function` with `getCallingConv()` and `setCallingConv(cc)`.
273+
- Extends `StructType.create` with an optional `isPacked` boolean parameter.
274+
- Extends `APInt` constructor to accept a `bigint` value in addition to `number`.
275+
- Extends `Target.createTargetMachine` with optional `reloc`, `codeModel`, `optLevel`, and `jit` parameters.
276+
277+
**Code generation**
278+
279+
Initialize target backends first, then use `TargetMachine.emitToFile` or `TargetMachine.emitToBuffer`:
280+
281+
```typescript
282+
import llvm from 'llvm-bindings';
283+
284+
llvm.InitializeAllTargetInfos();
285+
llvm.InitializeAllTargets();
286+
llvm.InitializeAllTargetMCs();
287+
llvm.InitializeAllAsmPrinters();
288+
289+
const target = llvm.TargetRegistry.lookupTarget('x86_64')!;
290+
const machine = target.createTargetMachine(
291+
'x86_64-unknown-unknown',
292+
'generic',
293+
'',
294+
llvm.Reloc.PIC_,
295+
llvm.CodeModel.Small,
296+
llvm.CodeGenOpt.Default,
297+
);
298+
299+
// ... build your module ...
300+
const myModule: llvm.Module = /* ... */;
301+
myModule.setDataLayout(machine.createDataLayout());
302+
303+
// Emit to an object file on disk
304+
machine.emitToFile(myModule, '/tmp/out.o', llvm.CodeGenFileType.Object);
305+
306+
// Or emit to an in-memory Buffer
307+
const buf: Buffer = machine.emitToBuffer(myModule, llvm.CodeGenFileType.Object);
308+
```
309+
310+
**Pass manager**
311+
312+
`ModulePassManager` wraps LLVM's new PassBuilder pipeline. Pass the desired `OptimizationLevel` to its constructor:
313+
314+
```typescript
315+
const mpm = new llvm.ModulePassManager(llvm.OptimizationLevel.O2);
316+
mpm.run(myModule);
317+
```
318+
319+
`FunctionPassManager` is obtained via `ModulePassManager.createFunctionPassManager` and can be composed back into the module pipeline:
320+
321+
```typescript
322+
const fpm = mpm.createFunctionPassManager(llvm.ThinOrFullLTOPhase.None);
323+
// fpm.addSROAPass();
324+
// fpm.addEarlyCSEPass();
325+
// fpm.addInstCombinePass();
326+
mpm.addFunctionPasses(fpm);
327+
```
328+
329+
**Calling conventions**
330+
331+
```typescript
332+
func.setCallingConv(llvm.CallingConv.Fast);
333+
console.log(func.getCallingConv()); // 8
334+
```
335+
336+
**Packed structs**
337+
338+
```typescript
339+
const packed = llvm.StructType.create(context, [i8, i32], 'PackedPoint', true);
340+
console.log(packed.isPacked()); // true
341+
```
342+
343+
**BigInt support for APInt**
344+
345+
```typescript
346+
const big = new llvm.APInt(64, 9007199254740993n); // value > Number.MAX_SAFE_INTEGER
347+
```
348+
261349
## Compatibility
262350

263351
| llvm-bindings versions | compatible LLVM versions |
@@ -275,6 +363,7 @@ LLVM 22 introduces a source-language naming API change in debug info and bumps t
275363
| (@designliquido/llvm-bindings) 7.0.x | 20.1.x |
276364
| (@designliquido/llvm-bindings) 8.0.x | 21.1.x |
277365
| (@designliquido/llvm-bindings) 9.0.x | 22.1.x |
366+
| (@designliquido/llvm-bindings) 9.1.x | 22.1.x |
278367

279368
## Acknowledgments
280369

cmake/LLVM.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@ include_directories(${LLVM_INCLUDE_DIRS})
3636

3737
add_definitions(${LLVM_DEFINITIONS})
3838

39-
llvm_map_components_to_libnames(LLVM_LIBS core codegen irreader linker support target ${LLVM_TARGETS_TO_BUILD})
39+
llvm_map_components_to_libnames(LLVM_LIBS core codegen irreader linker passes support target ${LLVM_TARGETS_TO_BUILD})

include/IR/CallingConv.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include <napi.h>
4+
5+
namespace CallingConv {
6+
void Init(Napi::Env env, Napi::Object &exports);
7+
}

include/IR/Function.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ class Function : public Napi::ObjectWrap<Function> {
6464

6565
Napi::Value getType(const Napi::CallbackInfo &info);
6666

67+
Napi::Value getCallingConv(const Napi::CallbackInfo &info);
68+
69+
void setCallingConv(const Napi::CallbackInfo &info);
70+
6771
void addFnAttr(const Napi::CallbackInfo &info);
6872

6973
void addParamAttr(const Napi::CallbackInfo &info);

include/IR/PassManager.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#pragma once
2+
3+
#include <napi.h>
4+
#include <llvm/IR/PassManager.h>
5+
#include <llvm/Passes/PassBuilder.h>
6+
#include <llvm/Analysis/LoopAnalysisManager.h>
7+
#include <llvm/Analysis/CGSCCPassManager.h>
8+
9+
class FunctionPassManager : public Napi::ObjectWrap<FunctionPassManager> {
10+
public:
11+
static inline Napi::FunctionReference constructor; // NOLINT
12+
13+
static void Init(Napi::Env env, Napi::Object &exports);
14+
15+
static Napi::Object New(Napi::Env env, llvm::FunctionPassManager fpm);
16+
17+
static bool IsClassOf(const Napi::Value &value);
18+
19+
explicit FunctionPassManager(const Napi::CallbackInfo &info);
20+
21+
llvm::FunctionPassManager &getLLVMPrimitive();
22+
23+
private:
24+
llvm::FunctionPassManager fpm;
25+
26+
void addSROAPass(const Napi::CallbackInfo &info);
27+
void addEarlyCSEPass(const Napi::CallbackInfo &info);
28+
void addInstCombinePass(const Napi::CallbackInfo &info);
29+
Napi::Value isEmpty(const Napi::CallbackInfo &info);
30+
};
31+
32+
class ModulePassManager : public Napi::ObjectWrap<ModulePassManager> {
33+
public:
34+
static inline Napi::FunctionReference constructor; // NOLINT
35+
36+
static void Init(Napi::Env env, Napi::Object &exports);
37+
38+
explicit ModulePassManager(const Napi::CallbackInfo &info);
39+
40+
private:
41+
llvm::LoopAnalysisManager LAM;
42+
llvm::FunctionAnalysisManager FAM;
43+
llvm::CGSCCAnalysisManager CGAM;
44+
llvm::ModuleAnalysisManager MAM;
45+
llvm::PassBuilder PB;
46+
llvm::ModulePassManager MPM;
47+
llvm::OptimizationLevel optLevel;
48+
49+
Napi::Value createFunctionPassManager(const Napi::CallbackInfo &info);
50+
void addFunctionPasses(const Napi::CallbackInfo &info);
51+
void addVerifierPass(const Napi::CallbackInfo &info);
52+
Napi::Value isEmpty(const Napi::CallbackInfo &info);
53+
void run(const Napi::CallbackInfo &info);
54+
};

include/IR/index.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,7 @@
2626
#include "IR/DataLayout.h"
2727
#include "IR/Verifier.h"
2828
#include "IR/Intrinsic.h"
29+
#include "IR/CallingConv.h"
30+
#include "IR/PassManager.h"
2931

3032
void InitIR(Napi::Env env, Napi::Object &exports);

include/Passes/OptimizationLevel.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include <napi.h>
4+
5+
namespace OptimizationLevel {
6+
void Init(Napi::Env env, Napi::Object &exports);
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include <napi.h>
4+
5+
namespace ThinOrFullLTOPhase {
6+
void Init(Napi::Env env, Napi::Object &exports);
7+
}

include/Passes/index.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include <napi.h>
4+
#include "Passes/OptimizationLevel.h"
5+
#include "Passes/ThinOrFullLTOPhase.h"
6+
7+
void InitPasses(Napi::Env env, Napi::Object &exports);

0 commit comments

Comments
 (0)