Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/playxe/b3-rs
JIT codegen backend with SSA IR based on B3 from WebKit
https://github.com/playxe/b3-rs
compiler graphcoloring irc jit linearscan optimizations ssa webkit
Last synced: 2 months ago
JSON representation
JIT codegen backend with SSA IR based on B3 from WebKit
- Host: GitHub
- URL: https://github.com/playxe/b3-rs
- Owner: playXE
- License: bsd-2-clause
- Created: 2023-03-18T06:09:14.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2023-10-26T17:13:06.000Z (about 1 year ago)
- Last Synced: 2024-11-08T11:47:30.565Z (3 months ago)
- Topics: compiler, graphcoloring, irc, jit, linearscan, optimizations, ssa, webkit
- Language: Rust
- Homepage:
- Size: 955 KB
- Stars: 59
- Watchers: 2
- Forks: 2
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# b3-rs
Backend based on [Bare Bones Backend](https://webkit.org/docs/b3/) from WebKit. I am making it for educational purposes.
## Usage
See examples and `src/tests.rs`.
Here's iterative factorial generator:
```rust
// imports ARGUMENT_GPR0
use b3::macroassembler::jit::gpr_info::*;fn main() {
let opts = b3::Options::default();
let mut proc = b3::Procedure::new(opts);// Create entry block. The argument to `add_block` is block frequency.
// Blocks with different frequences are ordered differently. By default
// they are recalculated before lowering to Assembly IR.
// set `opts.estimate_static_execution_counts` to `false` to use user provided frequency.
let entry = proc.add_block(1.0);let mut builder = b3::BasicBlockBuilder::new(&mut proc, entry);
// Argument management is offloaded to client code. Here we load argument from first GPR argument register,
// it is RDI on x86-64
let number = builder.argument(b3::Reg::new_gpr(ARGUMENT_GPR0), b3::Type::Int32);// Declare variables. They are automatically converted to SSA form.
let i = builder.procedure.add_variable(b3::Type::Int32);
let factorial = builder.procedure.add_variable(b3::Type::Int32);// Create blocks for `for` loop.
let for_header = builder.procedure.add_block(1.0);
let for_body = builder.procedure.add_block(1.0);
let for_exit = builder.procedure.add_block(1.0);let one = builder.const32(1);
builder.var_set(factorial, one);
builder.var_set(i, one);builder.jump(Some(for_header));
builder.block = for_header;
let i_value = builder.var_get(i);
let cmp = builder.binary(b3::Opcode::LessEqual, i_value, number);// Conditional branch.
builder.branch(cmp, for_body, (for_exit, b3::Frequency::Normal));builder.block = for_body;
let i_value = builder.var_get(i);
let factorial_value = builder.var_get(factorial);
let mul = builder.binary(b3::Opcode::Mul, i_value, factorial_value);
builder.var_set(factorial, mul);let i_value = builder.var_get(i);
let one = builder.const32(1);
let add = builder.binary(b3::Opcode::Add, i_value, one);builder.var_set(i, add);
builder.jump(Some(for_header));
builder.block = for_exit;
let factorial_value = builder.var_get(factorial);
builder.return_(Some(factorial_value));// Compiles B3 IR down to machine code.
let compilation = b3::compile(proc);
// use `entrypoint(0)` to get first entrypoint of code.
// NOTE: Multiple entrypoints are not yet supported.
let func: extern "C" fn(i32) -> i32 = unsafe { std::mem::transmute(compilation.entrypoint(0)) };assert_eq!(func(5), 120);
}
```## Contributors
- [PROMETHIA](https://github.com/PROMETHIA-27) - helped to fix UB and port B3 to stable toolchain.
## Licensing
Original B3 code belongs to WebKit and is licensed under BSD-2. Rust port of B3 because of that is also licensed with BSD-2 license.