Cilk

CircleCI

Toy Compiler Infrastructure influenced by LLVM written in Rust.

Do not expect too much stuff!

To Do

Build

Requirement: Rust nightly

sh cargo test --features x86_64 # build for x86_64 cargo test brainfuxk --features x86_64 -- --nocapture # this is fun. just try it. cargo test --features riscv64 # build for riscv64. very few features are implemented.

Example

```rust use cilk::{ codegen::x64::{exec}, exec::interpreter::interp, ir::{builder::Builder, module::Module, value::{Value, ImmediateValue}, types::Type}, };

let mut m = Module::new("cilk"); let fibo = m.create_function( "fibo", Type::Int32, vec![Type::Int32] ); let mut builder = Builder::new(&mut m, fibo);

{ let entry = builder.appendbasicblock(); let br1 = builder.appendbasicblock(); let br2 = builder.appendbasicblock();

builder.setinsertpoint(entry); let arg0 = builder.getparam(0).unwrap(); let eq1 = builder.buildicmp( ICmpKind::Le, arg0, Value::Immediate(ImmediateValue::Int32(2)), ); builder.buildcondbr(eq1, br1, br2);

builder.setinsertpoint(br1); builder.build_ret(Value::Immediate(ImmediateValue::Int32(1)));

builder.setinsertpoint(br2); let fibo1arg = builder.buildsub( arg0, Value::Immediate(ImmediateValue::Int32(1)), ); let fibo1 = builder.buildcall(Value::Function(fibo), vec![fibo1arg]); let fibo2arg = builder.buildsub( arg0, Value::Immediate(ImmediateValue::Int32(2)), ); let fibo2 = builder.buildcall(Value::Function(fibo), vec![fibo2arg]); let add = builder.buildadd(fibo1, fibo2); builder.buildret(add);

println!("Function dump:\n{}", m.dump(fibo)); }

// Function dump: // define i32 fibo(i32) {
// label.0:
// %0 = icmp le i32 %arg.0, i32 2 // br i1 %0 %label.1, %label.2 //
// label.1:
// ret i32 1 //
// label.2:
// %3 = sub i32 %arg.0, i32 1 // %4 = call i32 fibo(i32 %3, ) // %5 = sub i32 %arg.0, i32 2
// %6 = call i32 fibo(i32 %5, ) // %7 = add i32 %4, i32 %6 // ret i32 %7 //
// }

// In this branch, this may not work correctly. let mut interp = interp::Interpreter::new(&m); let ret = interp.run_function(fibo, vec![interp::ConcreteValue::Int32(10)]); println!("fibo(10) = {:?}", ret); // fibo(10) = Int32(55)

// JIT suppports for only x86_64

let mut jit = exec::jit::JITExecutor::new(&m); let func = jit.findfunctionby_name("func").unwrap(); println!( "fibo(10) = {:?}", jit.run(func, vec![exec::jit::GenericValue::Int32(10)])); // fibo(10) = 55 ```

rust let fibo = cilk_ir!(m; define [i32] f (i32) { entry: cond = icmp le (%arg.0), (i32 2); br (%cond) l1, l2; l1: ret (i32 1); l2: a1 = sub (%arg.0), (i32 1); r1 = call f [(%a1)]; a2 = sub (%arg.0), (i32 2); r2 = call f [(%a2)]; r3 = add (%r1), (%r2); ret (%r3); });