Add ebb macro to insert a new blocks in legalization output.

This commit is contained in:
Nicolas B. Pierron
2019-09-16 15:46:20 +02:00
committed by Nicolas B. Pierron
parent 0c1f17d6dd
commit 26cfbafb32
3 changed files with 148 additions and 18 deletions

View File

@@ -1,5 +1,6 @@
use crate::cdsl::ast::{
Apply, DefIndex, DefPool, DummyDef, DummyExpr, Expr, PatternPosition, VarIndex, VarPool,
Apply, BlockPool, DefIndex, DefPool, DummyDef, DummyExpr, Expr, PatternPosition, VarIndex,
VarPool,
};
use crate::cdsl::instructions::Instruction;
use crate::cdsl::type_inference::{infer_transform, TypeEnvironment};
@@ -22,6 +23,7 @@ pub(crate) struct Transform {
pub dst: Vec<DefIndex>,
pub var_pool: VarPool,
pub def_pool: DefPool,
pub block_pool: BlockPool,
pub type_env: TypeEnvironment,
}
@@ -31,6 +33,7 @@ impl Transform {
fn new(src: DummyDef, dst: Vec<DummyDef>) -> Self {
let mut var_pool = VarPool::new();
let mut def_pool = DefPool::new();
let mut block_pool = BlockPool::new();
let mut input_vars: Vec<VarIndex> = Vec::new();
let mut defined_vars: Vec<VarIndex> = Vec::new();
@@ -47,6 +50,7 @@ impl Transform {
&mut defined_vars,
&mut var_pool,
&mut def_pool,
&mut block_pool,
)[0];
let num_src_inputs = input_vars.len();
@@ -59,6 +63,7 @@ impl Transform {
&mut defined_vars,
&mut var_pool,
&mut def_pool,
&mut block_pool,
);
// Sanity checks.
@@ -122,6 +127,7 @@ impl Transform {
dst,
var_pool,
def_pool,
block_pool,
type_env,
}
}
@@ -224,6 +230,9 @@ fn rewrite_expr(
DummyExpr::Apply(..) => {
panic!("Recursive apply is not allowed.");
}
DummyExpr::Block(_block) => {
panic!("Blocks are not valid arguments.");
}
}
}
@@ -238,8 +247,18 @@ fn rewrite_def_list(
defined_vars: &mut Vec<VarIndex>,
var_pool: &mut VarPool,
def_pool: &mut DefPool,
block_pool: &mut BlockPool,
) -> Vec<DefIndex> {
let mut new_defs = Vec::new();
// Register variable names of new blocks first as a block name can be used to jump forward. Thus
// the name has to be registered first to avoid misinterpreting it as an input-var.
for dummy_def in dummy_defs.iter() {
if let DummyExpr::Block(ref var) = dummy_def.expr {
var_index(var.name, symbol_table, defined_vars, var_pool);
}
}
// Iterate over the definitions and blocks, to map variables names to inputs or outputs.
for dummy_def in dummy_defs {
let def_index = def_pool.next_index();
@@ -251,19 +270,34 @@ fn rewrite_def_list(
defined_vars,
var_pool,
);
let new_apply = rewrite_expr(position, dummy_def.expr, symbol_table, input_vars, var_pool);
if let DummyExpr::Block(var) = dummy_def.expr {
let var_index = *symbol_table
.get(var.name)
.or_else(|| {
panic!(
"Block {} was not registered during the first visit",
var.name
)
})
.unwrap();
var_pool.get_mut(var_index).set_def(position, def_index);
block_pool.create_block(var_index, def_index);
} else {
let new_apply =
rewrite_expr(position, dummy_def.expr, symbol_table, input_vars, var_pool);
assert!(
def_pool.next_index() == def_index,
"shouldn't have created new defs in the meanwhile"
);
assert_eq!(
new_apply.inst.value_results.len(),
new_defined_vars.len(),
"number of Var results in instruction is incorrect"
);
assert!(
def_pool.next_index() == def_index,
"shouldn't have created new defs in the meanwhile"
);
assert_eq!(
new_apply.inst.value_results.len(),
new_defined_vars.len(),
"number of Var results in instruction is incorrect"
);
new_defs.push(def_pool.create(new_apply, new_defined_vars));
new_defs.push(def_pool.create_inst(new_apply, new_defined_vars));
}
}
new_defs
}