Uses old Rust 2015
0.13.2 |
|
---|---|
0.12.0 |
|
0.4.1 |
|
#1 in #cretonne
Used in 2 crates
2MB
35K
SLoC
Cretonne has been renamed to Cranelift! For future versions, see the
cranelift-frontend
crate.
This crate provides a straightforward way to create a
Cretonne IR function and fill it with
instructions translated from another language. It contains an SSA construction
module that provides convenient methods for translating non-SSA variables into
SSA Cretonne IR values via use_var
and def_var
calls.
lib.rs
:
Cretonne IR builder library.
Provides a straightforward way to create a Cretonne IR function and fill it with instructions
translated from another language. Contains an SSA construction module that lets you translate
your non-SSA variables into SSA Cretonne IR values via use_var
and def_var
calls.
To get started, create an FunctionBuilderContext
and
pass it as an argument to a FunctionBuilder
.
Example
Here is a pseudo-program we want to transform into Cretonne IR:
function(x) {
x, y, z : i32
block0:
y = 2;
z = x + y;
jump block1
block1:
z = z + y;
brnz y, block2;
z = z - x;
return y
block2:
y = y - x
jump block1
}
Here is how you build the corresponding Cretonne IR function using FunctionBuilderContext
:
extern crate cretonne_codegen;
extern crate cretonne_frontend;
use cretonne_codegen::entity::EntityRef;
use cretonne_codegen::ir::{ExternalName, Function, Signature, AbiParam, InstBuilder};
use cretonne_codegen::ir::types::*;
use cretonne_codegen::settings::{self, CallConv};
use cretonne_frontend::{FunctionBuilderContext, FunctionBuilder, Variable};
use cretonne_codegen::verifier::verify_function;
fn main() {
let mut sig = Signature::new(CallConv::SystemV);
sig.returns.push(AbiParam::new(I32));
sig.params.push(AbiParam::new(I32));
let mut fn_builder_ctx = FunctionBuilderContext::<Variable>::new();
let mut func = Function::with_name_signature(ExternalName::user(0, 0), sig);
{
let mut builder = FunctionBuilder::<Variable>::new(&mut func, &mut fn_builder_ctx);
let block0 = builder.create_ebb();
let block1 = builder.create_ebb();
let block2 = builder.create_ebb();
let x = Variable::new(0);
let y = Variable::new(1);
let z = Variable::new(2);
builder.declare_var(x, I32);
builder.declare_var(y, I32);
builder.declare_var(z, I32);
builder.append_ebb_params_for_function_params(block0);
builder.switch_to_block(block0);
builder.seal_block(block0);
{
let tmp = builder.ebb_params(block0)[0]; // the first function parameter
builder.def_var(x, tmp);
}
{
let tmp = builder.ins().iconst(I32, 2);
builder.def_var(y, tmp);
}
{
let arg1 = builder.use_var(x);
let arg2 = builder.use_var(y);
let tmp = builder.ins().iadd(arg1, arg2);
builder.def_var(z, tmp);
}
builder.ins().jump(block1, &[]);
builder.switch_to_block(block1);
{
let arg1 = builder.use_var(y);
let arg2 = builder.use_var(z);
let tmp = builder.ins().iadd(arg1, arg2);
builder.def_var(z, tmp);
}
{
let arg = builder.use_var(y);
builder.ins().brnz(arg, block2, &[]);
}
{
let arg1 = builder.use_var(z);
let arg2 = builder.use_var(x);
let tmp = builder.ins().isub(arg1, arg2);
builder.def_var(z, tmp);
}
{
let arg = builder.use_var(y);
builder.ins().return_(&[arg]);
}
builder.switch_to_block(block2);
builder.seal_block(block2);
{
let arg1 = builder.use_var(y);
let arg2 = builder.use_var(x);
let tmp = builder.ins().isub(arg1, arg2);
builder.def_var(y, tmp);
}
builder.ins().jump(block1, &[]);
builder.seal_block(block1);
builder.finalize();
}
let flags = settings::Flags::new(settings::builder());
let res = verify_function(&func, &flags);
println!("{}", func.display(None));
match res {
Ok(_) => {}
Err(err) => panic!("{}", err),
}
}
Dependencies
~2MB
~47K SLoC