[bugpoint] Remove block params
This commit is contained in:
@@ -146,22 +146,6 @@ impl ReplaceInstWithConst {
|
|||||||
inst: first_inst,
|
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 {
|
impl Mutator for ReplaceInstWithConst {
|
||||||
@@ -189,7 +173,7 @@ impl Mutator for ReplaceInstWithConst {
|
|||||||
|
|
||||||
if num_results == 1 {
|
if num_results == 1 {
|
||||||
let ty = func.dfg.value_type(func.dfg.first_result(prev_inst));
|
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 (
|
return (
|
||||||
func,
|
func,
|
||||||
format!("Replace inst {} with {}.", prev_inst, new_inst_name),
|
format!("Replace inst {} with {}.", prev_inst, new_inst_name),
|
||||||
@@ -212,7 +196,7 @@ impl Mutator for ReplaceInstWithConst {
|
|||||||
for r in results {
|
for r in results {
|
||||||
let ty = pos.func.dfg.value_type(r);
|
let ty = pos.func.dfg.value_type(r);
|
||||||
let builder = pos.ins().with_results([Some(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);
|
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.
|
/// Try to remove unused entities.
|
||||||
struct RemoveUnusedEntities {
|
struct RemoveUnusedEntities {
|
||||||
kind: u32,
|
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(
|
fn next_inst_ret_prev(
|
||||||
func: &Function,
|
func: &Function,
|
||||||
block: &mut Block,
|
block: &mut Block,
|
||||||
@@ -722,8 +799,9 @@ fn reduce(
|
|||||||
1 => Box::new(ReplaceInstWithConst::new(&func)),
|
1 => Box::new(ReplaceInstWithConst::new(&func)),
|
||||||
2 => Box::new(ReplaceInstWithTrap::new(&func)),
|
2 => Box::new(ReplaceInstWithTrap::new(&func)),
|
||||||
3 => Box::new(RemoveBlock::new(&func)),
|
3 => Box::new(RemoveBlock::new(&func)),
|
||||||
4 => Box::new(RemoveUnusedEntities::new()),
|
4 => Box::new(ReplaceBlockParamWithConst::new(&func)),
|
||||||
5 => Box::new(MergeBlocks::new(&func)),
|
5 => Box::new(RemoveUnusedEntities::new()),
|
||||||
|
6 => Box::new(MergeBlocks::new(&func)),
|
||||||
_ => break,
|
_ => 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
|
sig0 = (i64, i64, i16, i64, i64, i64, i64, i64) system_v
|
||||||
fn0 = u0:95 sig0
|
fn0 = u0:95 sig0
|
||||||
|
|
||||||
block0(v0: i64, v1: i64, v2: i64):
|
block0:
|
||||||
v113 -> v1
|
v0 = iconst.i64 0
|
||||||
v124 -> v1
|
|
||||||
v136 -> v1
|
|
||||||
v148 -> v1
|
|
||||||
v160 -> v1
|
|
||||||
v185 -> v1
|
|
||||||
v222 -> v1
|
|
||||||
v237 -> v1
|
|
||||||
v241 -> v1
|
|
||||||
v256 -> v1
|
|
||||||
v262 -> v1
|
|
||||||
v105 = iconst.i64 0
|
v105 = iconst.i64 0
|
||||||
trap user0
|
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:
|
block101:
|
||||||
v829 = iconst.i64 0
|
v829 = iconst.i64 0
|
||||||
v935 -> v829
|
v935 -> v829
|
||||||
@@ -73,4 +42,12 @@ block117:
|
|||||||
v987 = iconst.i64 0
|
v987 = iconst.i64 0
|
||||||
call fn0(v0, v105, v1052, v883, v829, v987, v951, v842)
|
call fn0(v0, v105, v1052, v883, v829, v987, v951, v842)
|
||||||
trap user0
|
trap user0
|
||||||
|
|
||||||
|
block120:
|
||||||
|
v1052 = iconst.i16 0
|
||||||
|
v960 -> v1052
|
||||||
|
v990 -> v1052
|
||||||
|
v1051 -> v1052
|
||||||
|
v1055 -> v1052
|
||||||
|
trap user0
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user