Define a Variable struct so that frontends don't have to.
Frontends can still use their own types with `ILBuilder` and `FunctionBuilder`. This just provides a basic `Variable` struct for frontends that want it.
This commit is contained in:
@@ -15,6 +15,10 @@ use cretonne::packed_option::PackedOption;
|
|||||||
/// In order to reduce memory reallocations when compiling multiple functions,
|
/// In order to reduce memory reallocations when compiling multiple functions,
|
||||||
/// `ILBuilder` holds various data structures which are cleared between
|
/// `ILBuilder` holds various data structures which are cleared between
|
||||||
/// functions, rather than dropped, preserving the underlying allocations.
|
/// functions, rather than dropped, preserving the underlying allocations.
|
||||||
|
///
|
||||||
|
/// The `Variable` parameter can be any index-like type that can be made to
|
||||||
|
/// implement `EntityRef`. For frontends that don't have an obvious type to
|
||||||
|
/// use here, `variable::Variable` can be used.
|
||||||
pub struct ILBuilder<Variable>
|
pub struct ILBuilder<Variable>
|
||||||
where
|
where
|
||||||
Variable: EntityRef,
|
Variable: EntityRef,
|
||||||
@@ -590,22 +594,7 @@ mod tests {
|
|||||||
use frontend::{ILBuilder, FunctionBuilder};
|
use frontend::{ILBuilder, FunctionBuilder};
|
||||||
use cretonne::verifier::verify_function;
|
use cretonne::verifier::verify_function;
|
||||||
use cretonne::settings;
|
use cretonne::settings;
|
||||||
|
use Variable;
|
||||||
use std::u32;
|
|
||||||
|
|
||||||
// An opaque reference to variable.
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
|
||||||
pub struct Variable(u32);
|
|
||||||
impl EntityRef for Variable {
|
|
||||||
fn new(index: usize) -> Self {
|
|
||||||
assert!(index < (u32::MAX as usize));
|
|
||||||
Variable(index as u32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn index(self) -> usize {
|
|
||||||
self.0 as usize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sample_function(lazy_seal: bool) {
|
fn sample_function(lazy_seal: bool) {
|
||||||
let mut sig = Signature::new(CallConv::Native);
|
let mut sig = Signature::new(CallConv::Native);
|
||||||
@@ -620,9 +609,9 @@ mod tests {
|
|||||||
let block0 = builder.create_ebb();
|
let block0 = builder.create_ebb();
|
||||||
let block1 = builder.create_ebb();
|
let block1 = builder.create_ebb();
|
||||||
let block2 = builder.create_ebb();
|
let block2 = builder.create_ebb();
|
||||||
let x = Variable(0);
|
let x = Variable::new(0);
|
||||||
let y = Variable(1);
|
let y = Variable::new(1);
|
||||||
let z = Variable(2);
|
let z = Variable::new(2);
|
||||||
builder.declare_var(x, I32);
|
builder.declare_var(x, I32);
|
||||||
builder.declare_var(y, I32);
|
builder.declare_var(y, I32);
|
||||||
builder.declare_var(z, I32);
|
builder.declare_var(z, I32);
|
||||||
|
|||||||
@@ -39,23 +39,8 @@
|
|||||||
//! use cretonne::ir::{ExternalName, CallConv, Function, Signature, AbiParam, InstBuilder};
|
//! use cretonne::ir::{ExternalName, CallConv, Function, Signature, AbiParam, InstBuilder};
|
||||||
//! use cretonne::ir::types::*;
|
//! use cretonne::ir::types::*;
|
||||||
//! use cretonne::settings;
|
//! use cretonne::settings;
|
||||||
//! use cton_frontend::{ILBuilder, FunctionBuilder};
|
//! use cton_frontend::{ILBuilder, FunctionBuilder, Variable};
|
||||||
//! use cretonne::verifier::verify_function;
|
//! use cretonne::verifier::verify_function;
|
||||||
//! use std::u32;
|
|
||||||
//!
|
|
||||||
//! // An opaque reference to variable.
|
|
||||||
//! #[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
|
||||||
//! pub struct Variable(u32);
|
|
||||||
//! impl EntityRef for Variable {
|
|
||||||
//! fn new(index: usize) -> Self {
|
|
||||||
//! assert!(index < (u32::MAX as usize));
|
|
||||||
//! Variable(index as u32)
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! fn index(self) -> usize {
|
|
||||||
//! self.0 as usize
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//!
|
//!
|
||||||
//! fn main() {
|
//! fn main() {
|
||||||
//! let mut sig = Signature::new(CallConv::Native);
|
//! let mut sig = Signature::new(CallConv::Native);
|
||||||
@@ -69,9 +54,9 @@
|
|||||||
//! let block0 = builder.create_ebb();
|
//! let block0 = builder.create_ebb();
|
||||||
//! let block1 = builder.create_ebb();
|
//! let block1 = builder.create_ebb();
|
||||||
//! let block2 = builder.create_ebb();
|
//! let block2 = builder.create_ebb();
|
||||||
//! let x = Variable(0);
|
//! let x = Variable::new(0);
|
||||||
//! let y = Variable(1);
|
//! let y = Variable::new(1);
|
||||||
//! let z = Variable(2);
|
//! let z = Variable::new(2);
|
||||||
//! builder.declare_var(x, I32);
|
//! builder.declare_var(x, I32);
|
||||||
//! builder.declare_var(y, I32);
|
//! builder.declare_var(y, I32);
|
||||||
//! builder.declare_var(z, I32);
|
//! builder.declare_var(z, I32);
|
||||||
@@ -149,6 +134,8 @@
|
|||||||
extern crate cretonne;
|
extern crate cretonne;
|
||||||
|
|
||||||
pub use frontend::{ILBuilder, FunctionBuilder};
|
pub use frontend::{ILBuilder, FunctionBuilder};
|
||||||
|
pub use variable::Variable;
|
||||||
|
|
||||||
mod frontend;
|
mod frontend;
|
||||||
mod ssa;
|
mod ssa;
|
||||||
|
mod variable;
|
||||||
|
|||||||
@@ -720,21 +720,7 @@ mod tests {
|
|||||||
use cretonne::ir::instructions::BranchInfo;
|
use cretonne::ir::instructions::BranchInfo;
|
||||||
use cretonne::settings;
|
use cretonne::settings;
|
||||||
use ssa::SSABuilder;
|
use ssa::SSABuilder;
|
||||||
use std::u32;
|
use Variable;
|
||||||
|
|
||||||
/// An opaque reference to variable.
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
|
||||||
pub struct Variable(u32);
|
|
||||||
impl EntityRef for Variable {
|
|
||||||
fn new(index: usize) -> Self {
|
|
||||||
assert!(index < (u32::MAX as usize));
|
|
||||||
Variable(index as u32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn index(self) -> usize {
|
|
||||||
self.0 as usize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn simple_block() {
|
fn simple_block() {
|
||||||
@@ -748,14 +734,14 @@ mod tests {
|
|||||||
// z = x + z;
|
// z = x + z;
|
||||||
|
|
||||||
let block = ssa.declare_ebb_header_block(ebb0);
|
let block = ssa.declare_ebb_header_block(ebb0);
|
||||||
let x_var = Variable(0);
|
let x_var = Variable::new(0);
|
||||||
let x_ssa = {
|
let x_ssa = {
|
||||||
let mut cur = FuncCursor::new(&mut func);
|
let mut cur = FuncCursor::new(&mut func);
|
||||||
cur.insert_ebb(ebb0);
|
cur.insert_ebb(ebb0);
|
||||||
cur.ins().iconst(I32, 1)
|
cur.ins().iconst(I32, 1)
|
||||||
};
|
};
|
||||||
ssa.def_var(x_var, x_ssa, block);
|
ssa.def_var(x_var, x_ssa, block);
|
||||||
let y_var = Variable(1);
|
let y_var = Variable::new(1);
|
||||||
let y_ssa = {
|
let y_ssa = {
|
||||||
let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0);
|
let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0);
|
||||||
cur.ins().iconst(I32, 2)
|
cur.ins().iconst(I32, 2)
|
||||||
@@ -764,7 +750,7 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(ssa.use_var(&mut func, x_var, I32, block).0, x_ssa);
|
assert_eq!(ssa.use_var(&mut func, x_var, I32, block).0, x_ssa);
|
||||||
assert_eq!(ssa.use_var(&mut func, y_var, I32, block).0, y_ssa);
|
assert_eq!(ssa.use_var(&mut func, y_var, I32, block).0, y_ssa);
|
||||||
let z_var = Variable(2);
|
let z_var = Variable::new(2);
|
||||||
let x_use1 = ssa.use_var(&mut func, x_var, I32, block).0;
|
let x_use1 = ssa.use_var(&mut func, x_var, I32, block).0;
|
||||||
let y_use1 = ssa.use_var(&mut func, y_var, I32, block).0;
|
let y_use1 = ssa.use_var(&mut func, y_var, I32, block).0;
|
||||||
let z1_ssa = {
|
let z1_ssa = {
|
||||||
@@ -800,7 +786,7 @@ mod tests {
|
|||||||
// y = x + y;
|
// y = x + y;
|
||||||
|
|
||||||
let block0 = ssa.declare_ebb_header_block(ebb0);
|
let block0 = ssa.declare_ebb_header_block(ebb0);
|
||||||
let x_var = Variable(0);
|
let x_var = Variable::new(0);
|
||||||
let x_ssa = {
|
let x_ssa = {
|
||||||
let mut cur = FuncCursor::new(&mut func);
|
let mut cur = FuncCursor::new(&mut func);
|
||||||
cur.insert_ebb(ebb0);
|
cur.insert_ebb(ebb0);
|
||||||
@@ -809,7 +795,7 @@ mod tests {
|
|||||||
cur.ins().iconst(I32, 1)
|
cur.ins().iconst(I32, 1)
|
||||||
};
|
};
|
||||||
ssa.def_var(x_var, x_ssa, block0);
|
ssa.def_var(x_var, x_ssa, block0);
|
||||||
let y_var = Variable(1);
|
let y_var = Variable::new(1);
|
||||||
let y_ssa = {
|
let y_ssa = {
|
||||||
let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0);
|
let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0);
|
||||||
cur.ins().iconst(I32, 2)
|
cur.ins().iconst(I32, 2)
|
||||||
@@ -817,7 +803,7 @@ mod tests {
|
|||||||
ssa.def_var(y_var, y_ssa, block0);
|
ssa.def_var(y_var, y_ssa, block0);
|
||||||
assert_eq!(ssa.use_var(&mut func, x_var, I32, block0).0, x_ssa);
|
assert_eq!(ssa.use_var(&mut func, x_var, I32, block0).0, x_ssa);
|
||||||
assert_eq!(ssa.use_var(&mut func, y_var, I32, block0).0, y_ssa);
|
assert_eq!(ssa.use_var(&mut func, y_var, I32, block0).0, y_ssa);
|
||||||
let z_var = Variable(2);
|
let z_var = Variable::new(2);
|
||||||
let x_use1 = ssa.use_var(&mut func, x_var, I32, block0).0;
|
let x_use1 = ssa.use_var(&mut func, x_var, I32, block0).0;
|
||||||
let y_use1 = ssa.use_var(&mut func, y_var, I32, block0).0;
|
let y_use1 = ssa.use_var(&mut func, y_var, I32, block0).0;
|
||||||
let z1_ssa = {
|
let z1_ssa = {
|
||||||
@@ -888,7 +874,7 @@ mod tests {
|
|||||||
|
|
||||||
let block0 = ssa.declare_ebb_header_block(ebb0);
|
let block0 = ssa.declare_ebb_header_block(ebb0);
|
||||||
ssa.seal_ebb_header_block(ebb0, &mut func);
|
ssa.seal_ebb_header_block(ebb0, &mut func);
|
||||||
let x_var = Variable(0);
|
let x_var = Variable::new(0);
|
||||||
let x1 = {
|
let x1 = {
|
||||||
let mut cur = FuncCursor::new(&mut func);
|
let mut cur = FuncCursor::new(&mut func);
|
||||||
cur.insert_ebb(ebb0);
|
cur.insert_ebb(ebb0);
|
||||||
@@ -899,14 +885,14 @@ mod tests {
|
|||||||
};
|
};
|
||||||
ssa.def_var(x_var, x1, block0);
|
ssa.def_var(x_var, x1, block0);
|
||||||
assert_eq!(ssa.use_var(&mut func, x_var, I32, block0).0, x1);
|
assert_eq!(ssa.use_var(&mut func, x_var, I32, block0).0, x1);
|
||||||
let y_var = Variable(1);
|
let y_var = Variable::new(1);
|
||||||
let y1 = {
|
let y1 = {
|
||||||
let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0);
|
let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0);
|
||||||
cur.ins().iconst(I32, 2)
|
cur.ins().iconst(I32, 2)
|
||||||
};
|
};
|
||||||
ssa.def_var(y_var, y1, block0);
|
ssa.def_var(y_var, y1, block0);
|
||||||
assert_eq!(ssa.use_var(&mut func, y_var, I32, block0).0, y1);
|
assert_eq!(ssa.use_var(&mut func, y_var, I32, block0).0, y1);
|
||||||
let z_var = Variable(2);
|
let z_var = Variable::new(2);
|
||||||
let x2 = ssa.use_var(&mut func, x_var, I32, block0).0;
|
let x2 = ssa.use_var(&mut func, x_var, I32, block0).0;
|
||||||
assert_eq!(x2, x1);
|
assert_eq!(x2, x1);
|
||||||
let y2 = ssa.use_var(&mut func, y_var, I32, block0).0;
|
let y2 = ssa.use_var(&mut func, y_var, I32, block0).0;
|
||||||
@@ -995,7 +981,7 @@ mod tests {
|
|||||||
//
|
//
|
||||||
let block0 = ssa.declare_ebb_header_block(ebb0);
|
let block0 = ssa.declare_ebb_header_block(ebb0);
|
||||||
ssa.seal_ebb_header_block(ebb0, &mut func);
|
ssa.seal_ebb_header_block(ebb0, &mut func);
|
||||||
let x_var = Variable(0);
|
let x_var = Variable::new(0);
|
||||||
let x1 = {
|
let x1 = {
|
||||||
let mut cur = FuncCursor::new(&mut func);
|
let mut cur = FuncCursor::new(&mut func);
|
||||||
cur.insert_ebb(ebb0);
|
cur.insert_ebb(ebb0);
|
||||||
@@ -1060,9 +1046,9 @@ mod tests {
|
|||||||
// jump ebb1
|
// jump ebb1
|
||||||
//
|
//
|
||||||
let block0 = ssa.declare_ebb_header_block(ebb0);
|
let block0 = ssa.declare_ebb_header_block(ebb0);
|
||||||
let x_var = Variable(0);
|
let x_var = Variable::new(0);
|
||||||
let y_var = Variable(1);
|
let y_var = Variable::new(1);
|
||||||
let z_var = Variable(2);
|
let z_var = Variable::new(2);
|
||||||
ssa.seal_ebb_header_block(ebb0, &mut func);
|
ssa.seal_ebb_header_block(ebb0, &mut func);
|
||||||
let x1 = {
|
let x1 = {
|
||||||
let mut cur = FuncCursor::new(&mut func);
|
let mut cur = FuncCursor::new(&mut func);
|
||||||
@@ -1125,11 +1111,11 @@ mod tests {
|
|||||||
let ebb0 = func.dfg.make_ebb();
|
let ebb0 = func.dfg.make_ebb();
|
||||||
let block = ssa.declare_ebb_header_block(ebb0);
|
let block = ssa.declare_ebb_header_block(ebb0);
|
||||||
ssa.seal_ebb_header_block(ebb0, &mut func);
|
ssa.seal_ebb_header_block(ebb0, &mut func);
|
||||||
let i32_var = Variable(0);
|
let i32_var = Variable::new(0);
|
||||||
let f32_var = Variable(1);
|
let f32_var = Variable::new(1);
|
||||||
let f64_var = Variable(2);
|
let f64_var = Variable::new(2);
|
||||||
let b1_var = Variable(3);
|
let b1_var = Variable::new(3);
|
||||||
let f32x4_var = Variable(4);
|
let f32x4_var = Variable::new(4);
|
||||||
ssa.use_var(&mut func, i32_var, I32, block);
|
ssa.use_var(&mut func, i32_var, I32, block);
|
||||||
ssa.use_var(&mut func, f32_var, F32, block);
|
ssa.use_var(&mut func, f32_var, F32, block);
|
||||||
ssa.use_var(&mut func, f64_var, F64, block);
|
ssa.use_var(&mut func, f64_var, F64, block);
|
||||||
@@ -1147,7 +1133,7 @@ mod tests {
|
|||||||
let ebb0 = func.dfg.make_ebb();
|
let ebb0 = func.dfg.make_ebb();
|
||||||
let block = ssa.declare_ebb_header_block(ebb0);
|
let block = ssa.declare_ebb_header_block(ebb0);
|
||||||
ssa.seal_ebb_header_block(ebb0, &mut func);
|
ssa.seal_ebb_header_block(ebb0, &mut func);
|
||||||
let x_var = Variable(0);
|
let x_var = Variable::new(0);
|
||||||
assert_eq!(func.dfg.num_ebb_params(ebb0), 0);
|
assert_eq!(func.dfg.num_ebb_params(ebb0), 0);
|
||||||
ssa.use_var(&mut func, x_var, I32, block);
|
ssa.use_var(&mut func, x_var, I32, block);
|
||||||
assert_eq!(func.dfg.num_ebb_params(ebb0), 0);
|
assert_eq!(func.dfg.num_ebb_params(ebb0), 0);
|
||||||
@@ -1166,7 +1152,7 @@ mod tests {
|
|||||||
let mut ssa: SSABuilder<Variable> = SSABuilder::new();
|
let mut ssa: SSABuilder<Variable> = SSABuilder::new();
|
||||||
let ebb0 = func.dfg.make_ebb();
|
let ebb0 = func.dfg.make_ebb();
|
||||||
let block = ssa.declare_ebb_header_block(ebb0);
|
let block = ssa.declare_ebb_header_block(ebb0);
|
||||||
let x_var = Variable(0);
|
let x_var = Variable::new(0);
|
||||||
assert_eq!(func.dfg.num_ebb_params(ebb0), 0);
|
assert_eq!(func.dfg.num_ebb_params(ebb0), 0);
|
||||||
ssa.use_var(&mut func, x_var, I32, block);
|
ssa.use_var(&mut func, x_var, I32, block);
|
||||||
assert_eq!(func.dfg.num_ebb_params(ebb0), 1);
|
assert_eq!(func.dfg.num_ebb_params(ebb0), 1);
|
||||||
@@ -1200,7 +1186,7 @@ mod tests {
|
|||||||
cur.insert_ebb(ebb1);
|
cur.insert_ebb(ebb1);
|
||||||
cur.goto_bottom(ebb0);
|
cur.goto_bottom(ebb0);
|
||||||
cur.ins().return_(&[]);
|
cur.ins().return_(&[]);
|
||||||
let x_var = Variable(0);
|
let x_var = Variable::new(0);
|
||||||
cur.goto_bottom(ebb1);
|
cur.goto_bottom(ebb1);
|
||||||
let val = ssa.use_var(&mut cur.func, x_var, I32, block1).0;
|
let val = ssa.use_var(&mut cur.func, x_var, I32, block1).0;
|
||||||
let brz = cur.ins().brz(val, ebb1, &[]);
|
let brz = cur.ins().brz(val, ebb1, &[]);
|
||||||
@@ -1237,7 +1223,7 @@ mod tests {
|
|||||||
let block2 = ssa.declare_ebb_header_block(ebb2);
|
let block2 = ssa.declare_ebb_header_block(ebb2);
|
||||||
{
|
{
|
||||||
let mut cur = FuncCursor::new(&mut func);
|
let mut cur = FuncCursor::new(&mut func);
|
||||||
let x_var = Variable(0);
|
let x_var = Variable::new(0);
|
||||||
cur.insert_ebb(ebb0);
|
cur.insert_ebb(ebb0);
|
||||||
cur.insert_ebb(ebb1);
|
cur.insert_ebb(ebb1);
|
||||||
cur.insert_ebb(ebb2);
|
cur.insert_ebb(ebb2);
|
||||||
|
|||||||
24
lib/frontend/src/variable.rs
Normal file
24
lib/frontend/src/variable.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
//! A basic `Variable` implementation.
|
||||||
|
//!
|
||||||
|
//! `ILBuilder`, `FunctionBuilder`, and related types have a `Variable`
|
||||||
|
//! type parameter, to allow frontends that identify variables with
|
||||||
|
//! their own index types to use them directly. Frontends which don't
|
||||||
|
//! can use the `Variable` defined here.
|
||||||
|
|
||||||
|
use cretonne::entity::EntityRef;
|
||||||
|
use std::u32;
|
||||||
|
|
||||||
|
///! An opaque reference to a variable.
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub struct Variable(u32);
|
||||||
|
|
||||||
|
impl EntityRef for Variable {
|
||||||
|
fn new(index: usize) -> Self {
|
||||||
|
assert!(index < (u32::MAX as usize));
|
||||||
|
Variable(index as u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn index(self) -> usize {
|
||||||
|
self.0 as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user