使用旧Rust 2015
0.13.2 |
|
---|---|
0.12.0 |
|
0.4.1 |
|
#1 in #cretonne
69 每月下载量
在 2 crates 中使用
2MB
35K SLoC
Cretonne已重命名为Cranelift!未来版本请查看cranelift-frontend
crate。
该crate提供了一种简单的方法来创建一个Cretonne IR函数,并将其填充为从另一种语言翻译的指令。它包含一个SSA构建模块,通过use_var
和def_var
调用提供方便的方法将非SSA变量转换为SSA Cretonne IR值。
lib.rs
:
Cretonne IR构建库。
提供了一种简单的方法来创建Cretonne IR函数,并将其填充为从另一种语言翻译的指令。它包含一个SSA构建模块,允许您通过use_var
和def_var
调用将您的非SSA变量转换为SSA Cretonne IR值。
要开始,创建一个FunctionBuilderContext
并将其作为参数传递给FunctionBuilder
。
示例
这是一个我们想要转换成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
}
以下是使用FunctionBuilderContext
构建相应的Cretonne IR函数的方法
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),
}
}
依赖关系
~2MB
~45K SLoC