Removed "Variable" parametricity for SSABuilder and related code too.
This commit is contained in:
@@ -23,7 +23,7 @@ use variable::Variable;
|
|||||||
/// implement `EntityRef`. For frontends that don't have an obvious type to
|
/// implement `EntityRef`. For frontends that don't have an obvious type to
|
||||||
/// use here, `variable::Variable` can be used.
|
/// use here, `variable::Variable` can be used.
|
||||||
pub struct FunctionBuilderContext {
|
pub struct FunctionBuilderContext {
|
||||||
ssa: SSABuilder<Variable>,
|
ssa: SSABuilder,
|
||||||
ebbs: EntityMap<Ebb, EbbData>,
|
ebbs: EntityMap<Ebb, EbbData>,
|
||||||
types: EntityMap<Variable, Type>,
|
types: EntityMap<Variable, Type>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use cranelift_codegen::packed_option::ReservedValue;
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
use Variable;
|
||||||
|
|
||||||
/// Structure containing the data relevant the construction of SSA for a given function.
|
/// Structure containing the data relevant the construction of SSA for a given function.
|
||||||
///
|
///
|
||||||
@@ -32,17 +33,14 @@ use std::vec::Vec;
|
|||||||
/// A basic block is said _filled_ if all the instruction that it contains have been translated,
|
/// A basic block is said _filled_ if all the instruction that it contains have been translated,
|
||||||
/// and it is said _sealed_ if all of its predecessors have been declared. Only filled predecessors
|
/// and it is said _sealed_ if all of its predecessors have been declared. Only filled predecessors
|
||||||
/// can be declared.
|
/// can be declared.
|
||||||
pub struct SSABuilder<Variable>
|
pub struct SSABuilder {
|
||||||
where
|
|
||||||
Variable: EntityRef,
|
|
||||||
{
|
|
||||||
// Records for every variable and for every relevant block, the last definition of
|
// Records for every variable and for every relevant block, the last definition of
|
||||||
// the variable in the block.
|
// the variable in the block.
|
||||||
// TODO: Consider a sparse representation rather than EntityMap-of-EntityMap.
|
// TODO: Consider a sparse representation rather than EntityMap-of-EntityMap.
|
||||||
variables: EntityMap<Variable, EntityMap<Block, PackedOption<Value>>>,
|
variables: EntityMap<Variable, EntityMap<Block, PackedOption<Value>>>,
|
||||||
// Records the position of the basic blocks and the list of values used but not defined in the
|
// Records the position of the basic blocks and the list of values used but not defined in the
|
||||||
// block.
|
// block.
|
||||||
blocks: PrimaryMap<Block, BlockData<Variable>>,
|
blocks: PrimaryMap<Block, BlockData>,
|
||||||
// Records the basic blocks at the beginning of the `Ebb`s.
|
// Records the basic blocks at the beginning of the `Ebb`s.
|
||||||
ebb_headers: EntityMap<Ebb, PackedOption<Block>>,
|
ebb_headers: EntityMap<Ebb, PackedOption<Block>>,
|
||||||
|
|
||||||
@@ -79,15 +77,15 @@ impl SideEffects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Describes the current position of a basic block in the control flow graph.
|
/// Describes the current position of a basic block in the control flow graph.
|
||||||
enum BlockData<Variable> {
|
enum BlockData {
|
||||||
/// A block at the top of an `Ebb`.
|
/// A block at the top of an `Ebb`.
|
||||||
EbbHeader(EbbHeaderBlockData<Variable>),
|
EbbHeader(EbbHeaderBlockData),
|
||||||
/// A block inside an `Ebb` with an unique other block as its predecessor.
|
/// A block inside an `Ebb` with an unique other block as its predecessor.
|
||||||
/// The block is implicitly sealed at creation.
|
/// The block is implicitly sealed at creation.
|
||||||
EbbBody { predecessor: Block },
|
EbbBody { predecessor: Block },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Variable> BlockData<Variable> {
|
impl BlockData {
|
||||||
fn add_predecessor(&mut self, pred: Block, inst: Inst) {
|
fn add_predecessor(&mut self, pred: Block, inst: Inst) {
|
||||||
match *self {
|
match *self {
|
||||||
BlockData::EbbBody { .. } => panic!("you can't add a predecessor to a body block"),
|
BlockData::EbbBody { .. } => panic!("you can't add a predecessor to a body block"),
|
||||||
@@ -125,7 +123,7 @@ impl PredBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EbbHeaderBlockData<Variable> {
|
struct EbbHeaderBlockData {
|
||||||
// The predecessors of the Ebb header block, with the block and branch instruction.
|
// The predecessors of the Ebb header block, with the block and branch instruction.
|
||||||
predecessors: Vec<PredBlock>,
|
predecessors: Vec<PredBlock>,
|
||||||
// A ebb header block is sealed if all of its predecessors have been declared.
|
// A ebb header block is sealed if all of its predecessors have been declared.
|
||||||
@@ -156,10 +154,7 @@ impl ReservedValue for Block {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Variable> SSABuilder<Variable>
|
impl SSABuilder {
|
||||||
where
|
|
||||||
Variable: EntityRef,
|
|
||||||
{
|
|
||||||
/// Allocate a new blank SSA builder struct. Use the API function to interact with the struct.
|
/// Allocate a new blank SSA builder struct. Use the API function to interact with the struct.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -266,10 +261,7 @@ fn emit_zero(ty: Type, mut cur: FuncCursor) -> Value {
|
|||||||
/// as well as modify the jump instruction and `Ebb` headers parameters to account for the SSA
|
/// as well as modify the jump instruction and `Ebb` headers parameters to account for the SSA
|
||||||
/// Phi functions.
|
/// Phi functions.
|
||||||
///
|
///
|
||||||
impl<Variable> SSABuilder<Variable>
|
impl SSABuilder {
|
||||||
where
|
|
||||||
Variable: EntityRef,
|
|
||||||
{
|
|
||||||
/// Declares a new definition of a variable in a given basic block.
|
/// Declares a new definition of a variable in a given basic block.
|
||||||
/// The SSA value is passed as an argument because it should be created with
|
/// The SSA value is passed as an argument because it should be created with
|
||||||
/// `ir::DataFlowGraph::append_result`.
|
/// `ir::DataFlowGraph::append_result`.
|
||||||
@@ -751,7 +743,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn simple_block() {
|
fn simple_block() {
|
||||||
let mut func = Function::new();
|
let mut func = Function::new();
|
||||||
let mut ssa: SSABuilder<Variable> = SSABuilder::new();
|
let mut ssa = SSABuilder::new();
|
||||||
let ebb0 = func.dfg.make_ebb();
|
let ebb0 = func.dfg.make_ebb();
|
||||||
// Here is the pseudo-program we want to translate:
|
// Here is the pseudo-program we want to translate:
|
||||||
// x = 1;
|
// x = 1;
|
||||||
@@ -798,7 +790,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn sequence_of_blocks() {
|
fn sequence_of_blocks() {
|
||||||
let mut func = Function::new();
|
let mut func = Function::new();
|
||||||
let mut ssa: SSABuilder<Variable> = SSABuilder::new();
|
let mut ssa = SSABuilder::new();
|
||||||
let ebb0 = func.dfg.make_ebb();
|
let ebb0 = func.dfg.make_ebb();
|
||||||
let ebb1 = func.dfg.make_ebb();
|
let ebb1 = func.dfg.make_ebb();
|
||||||
// Here is the pseudo-program we want to translate:
|
// Here is the pseudo-program we want to translate:
|
||||||
@@ -879,7 +871,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn program_with_loop() {
|
fn program_with_loop() {
|
||||||
let mut func = Function::new();
|
let mut func = Function::new();
|
||||||
let mut ssa: SSABuilder<Variable> = SSABuilder::new();
|
let mut ssa = SSABuilder::new();
|
||||||
let ebb0 = func.dfg.make_ebb();
|
let ebb0 = func.dfg.make_ebb();
|
||||||
let ebb1 = func.dfg.make_ebb();
|
let ebb1 = func.dfg.make_ebb();
|
||||||
let ebb2 = func.dfg.make_ebb();
|
let ebb2 = func.dfg.make_ebb();
|
||||||
@@ -991,7 +983,7 @@ mod tests {
|
|||||||
fn br_table_with_args() {
|
fn br_table_with_args() {
|
||||||
// This tests the on-demand splitting of critical edges for br_table with jump arguments
|
// This tests the on-demand splitting of critical edges for br_table with jump arguments
|
||||||
let mut func = Function::new();
|
let mut func = Function::new();
|
||||||
let mut ssa: SSABuilder<Variable> = SSABuilder::new();
|
let mut ssa = SSABuilder::new();
|
||||||
let ebb0 = func.dfg.make_ebb();
|
let ebb0 = func.dfg.make_ebb();
|
||||||
let ebb1 = func.dfg.make_ebb();
|
let ebb1 = func.dfg.make_ebb();
|
||||||
// Here is the pseudo-program we want to translate:
|
// Here is the pseudo-program we want to translate:
|
||||||
@@ -1061,7 +1053,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn undef_values_reordering() {
|
fn undef_values_reordering() {
|
||||||
let mut func = Function::new();
|
let mut func = Function::new();
|
||||||
let mut ssa: SSABuilder<Variable> = SSABuilder::new();
|
let mut ssa = SSABuilder::new();
|
||||||
let ebb0 = func.dfg.make_ebb();
|
let ebb0 = func.dfg.make_ebb();
|
||||||
let ebb1 = func.dfg.make_ebb();
|
let ebb1 = func.dfg.make_ebb();
|
||||||
// Here is the pseudo-program we want to translate:
|
// Here is the pseudo-program we want to translate:
|
||||||
@@ -1137,7 +1129,7 @@ mod tests {
|
|||||||
fn undef() {
|
fn undef() {
|
||||||
// Use vars of various types which have not been defined.
|
// Use vars of various types which have not been defined.
|
||||||
let mut func = Function::new();
|
let mut func = Function::new();
|
||||||
let mut ssa: SSABuilder<Variable> = SSABuilder::new();
|
let mut ssa = 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);
|
||||||
ssa.seal_ebb_header_block(ebb0, &mut func);
|
ssa.seal_ebb_header_block(ebb0, &mut func);
|
||||||
@@ -1159,7 +1151,7 @@ mod tests {
|
|||||||
// Use a var which has not been defined. The search should hit the
|
// Use a var which has not been defined. The search should hit the
|
||||||
// top of the entry block, and then fall back to inserting an iconst.
|
// top of the entry block, and then fall back to inserting an iconst.
|
||||||
let mut func = Function::new();
|
let mut func = Function::new();
|
||||||
let mut ssa: SSABuilder<Variable> = SSABuilder::new();
|
let mut ssa = 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);
|
||||||
ssa.seal_ebb_header_block(ebb0, &mut func);
|
ssa.seal_ebb_header_block(ebb0, &mut func);
|
||||||
@@ -1179,7 +1171,7 @@ mod tests {
|
|||||||
// until afterward. Before sealing, the SSA builder should insert an
|
// until afterward. Before sealing, the SSA builder should insert an
|
||||||
// ebb param; after sealing, it should be removed.
|
// ebb param; after sealing, it should be removed.
|
||||||
let mut func = Function::new();
|
let mut func = Function::new();
|
||||||
let mut ssa: SSABuilder<Variable> = SSABuilder::new();
|
let mut ssa = 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::new(0);
|
let x_var = Variable::new(0);
|
||||||
@@ -1197,7 +1189,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn unreachable_use() {
|
fn unreachable_use() {
|
||||||
let mut func = Function::new();
|
let mut func = Function::new();
|
||||||
let mut ssa: SSABuilder<Variable> = SSABuilder::new();
|
let mut ssa = SSABuilder::new();
|
||||||
let ebb0 = func.dfg.make_ebb();
|
let ebb0 = func.dfg.make_ebb();
|
||||||
let ebb1 = func.dfg.make_ebb();
|
let ebb1 = func.dfg.make_ebb();
|
||||||
// Here is the pseudo-program we want to translate:
|
// Here is the pseudo-program we want to translate:
|
||||||
@@ -1240,7 +1232,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn unreachable_use_with_multiple_preds() {
|
fn unreachable_use_with_multiple_preds() {
|
||||||
let mut func = Function::new();
|
let mut func = Function::new();
|
||||||
let mut ssa: SSABuilder<Variable> = SSABuilder::new();
|
let mut ssa = SSABuilder::new();
|
||||||
let ebb0 = func.dfg.make_ebb();
|
let ebb0 = func.dfg.make_ebb();
|
||||||
let ebb1 = func.dfg.make_ebb();
|
let ebb1 = func.dfg.make_ebb();
|
||||||
let ebb2 = func.dfg.make_ebb();
|
let ebb2 = func.dfg.make_ebb();
|
||||||
|
|||||||
Reference in New Issue
Block a user