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

@@ -401,14 +401,30 @@ fn gen_transform<'a>(
// Guard the actual expansion by `predicate`.
fmt.line("if predicate {");
fmt.indent(|fmt| {
// If we are adding some blocks, we need to recall the original block, such that we can
// recompute it.
if !transform.block_pool.is_empty() {
fmt.line("let orig_ebb = pos.current_ebb().unwrap();");
}
// If we're going to delete `inst`, we need to detach its results first so they can be
// reattached during pattern expansion.
if !replace_inst {
fmt.line("pos.func.dfg.clear_results(inst);");
}
// Emit new block creation.
for block in &transform.block_pool {
let var = transform.var_pool.get(block.name);
fmtln!(fmt, "let {} = pos.func.dfg.make_ebb();", var.name);
}
// Emit the destination pattern.
for &def_index in &transform.dst {
if let Some(block) = transform.block_pool.get(def_index) {
let var = transform.var_pool.get(block.name);
fmtln!(fmt, "pos.insert_ebb({});", var.name);
}
emit_dst_inst(
transform.def_pool.get(def_index),
&transform.def_pool,
@@ -417,16 +433,32 @@ fn gen_transform<'a>(
);
}
// Insert a new block after the last instruction, if needed.
let def_next_index = transform.def_pool.next_index();
if let Some(block) = transform.block_pool.get(def_next_index) {
let var = transform.var_pool.get(block.name);
fmtln!(fmt, "pos.insert_ebb({});", var.name);
}
// Delete the original instruction if we didn't have an opportunity to replace it.
if !replace_inst {
fmt.line("let removed = pos.remove_inst();");
fmt.line("debug_assert_eq!(removed, inst);");
}
if transform.def_pool.get(transform.src).apply.inst.is_branch {
// A branch might have been legalized into multiple branches, so we need to recompute
// the cfg.
fmt.line("cfg.recompute_ebb(pos.func, pos.current_ebb().unwrap());");
if transform.block_pool.is_empty() {
if transform.def_pool.get(transform.src).apply.inst.is_branch {
// A branch might have been legalized into multiple branches, so we need to recompute
// the cfg.
fmt.line("cfg.recompute_ebb(pos.func, pos.current_ebb().unwrap());");
}
} else {
// Update CFG for the new blocks.
fmt.line("cfg.recompute_ebb(pos.func, orig_ebb);");
for block in &transform.block_pool {
let var = transform.var_pool.get(block.name);
fmtln!(fmt, "cfg.recompute_ebb(pos.func, {});", var.name);
}
}
fmt.line("return true;");