[bugpoint] Remove block params
This commit is contained in:
@@ -146,22 +146,6 @@ impl ReplaceInstWithConst {
|
||||
inst: first_inst,
|
||||
}
|
||||
}
|
||||
|
||||
fn const_for_type<'f, T: InstBuilder<'f>>(builder: T, ty: ir::Type) -> &'static str {
|
||||
// Try to keep the result type consistent, and default to an integer type
|
||||
// otherwise: this will cover all the cases for f32/f64 and integer types, or
|
||||
// create verifier errors otherwise.
|
||||
if ty == F32 {
|
||||
builder.f32const(0.0);
|
||||
"f32const"
|
||||
} else if ty == F64 {
|
||||
builder.f64const(0.0);
|
||||
"f64const"
|
||||
} else {
|
||||
builder.iconst(ty, 0);
|
||||
"iconst"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mutator for ReplaceInstWithConst {
|
||||
@@ -189,7 +173,7 @@ impl Mutator for ReplaceInstWithConst {
|
||||
|
||||
if num_results == 1 {
|
||||
let ty = func.dfg.value_type(func.dfg.first_result(prev_inst));
|
||||
let new_inst_name = Self::const_for_type(func.dfg.replace(prev_inst), ty);
|
||||
let new_inst_name = const_for_type(func.dfg.replace(prev_inst), ty);
|
||||
return (
|
||||
func,
|
||||
format!("Replace inst {} with {}.", prev_inst, new_inst_name),
|
||||
@@ -212,7 +196,7 @@ impl Mutator for ReplaceInstWithConst {
|
||||
for r in results {
|
||||
let ty = pos.func.dfg.value_type(r);
|
||||
let builder = pos.ins().with_results([Some(r)]);
|
||||
let new_inst_name = Self::const_for_type(builder, ty);
|
||||
let new_inst_name = const_for_type(builder, ty);
|
||||
inst_names.push(new_inst_name);
|
||||
}
|
||||
|
||||
@@ -312,6 +296,80 @@ impl Mutator for RemoveBlock {
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to replace the block params with constants.
|
||||
struct ReplaceBlockParamWithConst {
|
||||
block: Block,
|
||||
params_remaining: usize,
|
||||
}
|
||||
|
||||
impl ReplaceBlockParamWithConst {
|
||||
fn new(func: &Function) -> Self {
|
||||
let first_block = func.layout.entry_block().unwrap();
|
||||
Self {
|
||||
block: first_block,
|
||||
params_remaining: func.dfg.num_block_params(first_block),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mutator for ReplaceBlockParamWithConst {
|
||||
fn name(&self) -> &'static str {
|
||||
"replace block parameter with const"
|
||||
}
|
||||
|
||||
fn mutation_count(&self, func: &Function) -> usize {
|
||||
func.layout
|
||||
.blocks()
|
||||
.map(|block| func.dfg.num_block_params(block))
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn mutate(&mut self, mut func: Function) -> Option<(Function, String, ProgressStatus)> {
|
||||
while self.params_remaining == 0 {
|
||||
self.block = func.layout.next_block(self.block)?;
|
||||
self.params_remaining = func.dfg.num_block_params(self.block);
|
||||
}
|
||||
|
||||
self.params_remaining -= 1;
|
||||
let param_index = self.params_remaining;
|
||||
|
||||
let param = func.dfg.block_params(self.block)[param_index];
|
||||
let param_type = func.dfg.value_type(param);
|
||||
func.dfg.remove_block_param(param);
|
||||
|
||||
let first_inst = func.layout.first_inst(self.block).unwrap();
|
||||
let mut pos = FuncCursor::new(&mut func).at_inst(first_inst);
|
||||
let builder = pos.ins().with_results([Some(param)]);
|
||||
let new_inst_name = const_for_type(builder, param_type);
|
||||
|
||||
let mut cfg = ControlFlowGraph::new();
|
||||
cfg.compute(&func);
|
||||
|
||||
// Remove parameters in branching instructions that point to this block
|
||||
for pred in cfg.pred_iter(self.block) {
|
||||
let inst = &mut func.dfg[pred.inst];
|
||||
let num_fixed_args = inst.opcode().constraints().num_fixed_value_arguments();
|
||||
let mut values = inst.take_value_list().unwrap();
|
||||
values.remove(num_fixed_args + param_index, &mut func.dfg.value_lists);
|
||||
func.dfg[pred.inst].put_value_list(values);
|
||||
}
|
||||
|
||||
if Some(self.block) == func.layout.entry_block() {
|
||||
// Entry block params must match function params
|
||||
func.signature.params.remove(param_index);
|
||||
}
|
||||
|
||||
Some((
|
||||
func,
|
||||
format!(
|
||||
"Replaced param {} of {} by {}",
|
||||
param, self.block, new_inst_name
|
||||
),
|
||||
ProgressStatus::ExpandedOrShrinked,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to remove unused entities.
|
||||
struct RemoveUnusedEntities {
|
||||
kind: u32,
|
||||
@@ -652,6 +710,25 @@ impl Mutator for MergeBlocks {
|
||||
}
|
||||
}
|
||||
|
||||
fn const_for_type<'f, T: InstBuilder<'f>>(builder: T, ty: ir::Type) -> &'static str {
|
||||
// Try to keep the result type consistent, and default to an integer type
|
||||
// otherwise: this will cover all the cases for f32/f64, integer and boolean types,
|
||||
// or create verifier errors otherwise.
|
||||
if ty == F32 {
|
||||
builder.f32const(0.0);
|
||||
"f32const"
|
||||
} else if ty == F64 {
|
||||
builder.f64const(0.0);
|
||||
"f64const"
|
||||
} else if ty.is_bool() {
|
||||
builder.bconst(ty, false);
|
||||
"bconst"
|
||||
} else {
|
||||
builder.iconst(ty, 0);
|
||||
"iconst"
|
||||
}
|
||||
}
|
||||
|
||||
fn next_inst_ret_prev(
|
||||
func: &Function,
|
||||
block: &mut Block,
|
||||
@@ -722,8 +799,9 @@ fn reduce(
|
||||
1 => Box::new(ReplaceInstWithConst::new(&func)),
|
||||
2 => Box::new(ReplaceInstWithTrap::new(&func)),
|
||||
3 => Box::new(RemoveBlock::new(&func)),
|
||||
4 => Box::new(RemoveUnusedEntities::new()),
|
||||
5 => Box::new(MergeBlocks::new(&func)),
|
||||
4 => Box::new(ReplaceBlockParamWithConst::new(&func)),
|
||||
5 => Box::new(RemoveUnusedEntities::new()),
|
||||
6 => Box::new(MergeBlocks::new(&func)),
|
||||
_ => break,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,43 +1,12 @@
|
||||
function u0:0(i64, i64, i64) system_v {
|
||||
function u0:0() system_v {
|
||||
sig0 = (i64, i64, i16, i64, i64, i64, i64, i64) system_v
|
||||
fn0 = u0:95 sig0
|
||||
|
||||
block0(v0: i64, v1: i64, v2: i64):
|
||||
v113 -> v1
|
||||
v124 -> v1
|
||||
v136 -> v1
|
||||
v148 -> v1
|
||||
v160 -> v1
|
||||
v185 -> v1
|
||||
v222 -> v1
|
||||
v237 -> v1
|
||||
v241 -> v1
|
||||
v256 -> v1
|
||||
v262 -> v1
|
||||
block0:
|
||||
v0 = iconst.i64 0
|
||||
v105 = iconst.i64 0
|
||||
trap user0
|
||||
|
||||
block99(v804: i64, v1035: i64, v1037: i64, v1039: i64, v1044: i64, v1052: i16, v1057: i64):
|
||||
v817 -> v1035
|
||||
v830 -> v1037
|
||||
v844 -> v1039
|
||||
v857 -> v1039
|
||||
v939 -> v1039
|
||||
v1042 -> v1039
|
||||
v1050 -> v1039
|
||||
v908 -> v1044
|
||||
v917 -> v1044
|
||||
v921 -> v1044
|
||||
v1043 -> v1044
|
||||
v960 -> v1052
|
||||
v990 -> v1052
|
||||
v1051 -> v1052
|
||||
v1055 -> v1052
|
||||
v963 -> v1057
|
||||
v1056 -> v1057
|
||||
v1060 -> v1057
|
||||
trap user0
|
||||
|
||||
block101:
|
||||
v829 = iconst.i64 0
|
||||
v935 -> v829
|
||||
@@ -73,4 +42,12 @@ block117:
|
||||
v987 = iconst.i64 0
|
||||
call fn0(v0, v105, v1052, v883, v829, v987, v951, v842)
|
||||
trap user0
|
||||
|
||||
block120:
|
||||
v1052 = iconst.i16 0
|
||||
v960 -> v1052
|
||||
v990 -> v1052
|
||||
v1051 -> v1052
|
||||
v1055 -> v1052
|
||||
trap user0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user