Fix bug when i128 ebb param is unused

This commit is contained in:
bjorn3
2019-06-29 14:37:05 +02:00
committed by Dan Gohman
parent 44ecc9c3d0
commit d9ee08c088
3 changed files with 90 additions and 36 deletions

View File

@@ -174,6 +174,10 @@ pub fn legalize_function(func: &mut ir::Function, cfg: &mut ControlFlowGraph, is
} }
} }
while let Some(ebb) = pos.next_ebb() {
split::split_ebb_params(pos.func, cfg, ebb);
}
// Try legalizing `isplit` and `vsplit` instructions, which could not previously be legalized. // Try legalizing `isplit` and `vsplit` instructions, which could not previously be legalized.
for inst in pending_splits { for inst in pending_splits {
//pos.goto_inst(inst); //pos.goto_inst(inst);

View File

@@ -124,6 +124,36 @@ fn split_any(
let pos = &mut FuncCursor::new(func).at_position(pos).with_srcloc(srcloc); let pos = &mut FuncCursor::new(func).at_position(pos).with_srcloc(srcloc);
let result = split_value(pos, value, concat, &mut repairs); let result = split_value(pos, value, concat, &mut repairs);
perform_repairs(pos, cfg, repairs);
result
}
pub fn split_ebb_params(
func: &mut ir::Function,
cfg: &ControlFlowGraph,
ebb: Ebb,
) {
let mut repairs = Vec::new();
let pos = &mut FuncCursor::new(func).at_top(ebb);
for (num, ebb_param) in pos.func.dfg.ebb_params(ebb).to_vec().into_iter().enumerate() {
let ty = pos.func.dfg.value_type(ebb_param);
if ty != ir::types::I128 {
continue;
}
split_ebb_param(pos, ebb, num, ebb_param, Opcode::Iconcat, &mut repairs);
}
perform_repairs(pos, cfg, repairs);
}
fn perform_repairs(
pos: &mut FuncCursor,
cfg: &ControlFlowGraph,
mut repairs: Vec<Repair>,
) {
// We have split the value requested, and now we may need to fix some EBB predecessors. // We have split the value requested, and now we may need to fix some EBB predecessors.
while let Some(repair) = repairs.pop() { while let Some(repair) = repairs.pop() {
for BasicBlock { inst, .. } in cfg.pred_iter(repair.ebb) { for BasicBlock { inst, .. } in cfg.pred_iter(repair.ebb) {
@@ -181,8 +211,6 @@ fn split_any(
pos.func.dfg[inst].put_value_list(args); pos.func.dfg[inst].put_value_list(args);
} }
} }
result
} }
/// Split a single value using the integer or vector semantics given by the `concat` opcode. /// Split a single value using the integer or vector semantics given by the `concat` opcode.
@@ -215,6 +243,33 @@ fn split_value(
// This is an EBB parameter. We can split the parameter value unless this is the entry // This is an EBB parameter. We can split the parameter value unless this is the entry
// block. // block.
if pos.func.layout.entry_block() != Some(ebb) { if pos.func.layout.entry_block() != Some(ebb) {
reuse = Some(split_ebb_param(pos, ebb, num, value, concat, repairs));
}
}
}
// Did the code above succeed in finding values we can reuse?
if let Some(pair) = reuse {
pair
} else {
// No, we'll just have to insert the requested split instruction at `pos`. Note that `pos`
// has not been moved by the EBB argument code above when `reuse` is `None`.
match concat {
Opcode::Iconcat => pos.ins().isplit(value),
Opcode::Vconcat => pos.ins().vsplit(value),
_ => panic!("Unhandled concat opcode: {}", concat),
}
}
}
fn split_ebb_param(
pos: &mut FuncCursor,
ebb: Ebb,
param_num: usize,
value: Value,
concat: Opcode,
repairs: &mut Vec<Repair>,
) -> (Value, Value) {
// We are going to replace the parameter at `num` with two new arguments. // We are going to replace the parameter at `num` with two new arguments.
// Determine the new value types. // Determine the new value types.
let ty = pos.func.dfg.value_type(value); let ty = pos.func.dfg.value_type(value);
@@ -233,7 +288,6 @@ fn split_value(
let lo = pos.func.dfg.replace_ebb_param(value, split_type); let lo = pos.func.dfg.replace_ebb_param(value, split_type);
let hi_num = pos.func.dfg.num_ebb_params(ebb); let hi_num = pos.func.dfg.num_ebb_params(ebb);
let hi = pos.func.dfg.append_ebb_param(ebb, split_type); let hi = pos.func.dfg.append_ebb_param(ebb, split_type);
reuse = Some((lo, hi));
// Now the original value is dangling. Insert a concatenation instruction that can // Now the original value is dangling. Insert a concatenation instruction that can
// compute it from the two new parameters. This also serves as a record of what we // compute it from the two new parameters. This also serves as a record of what we
@@ -248,23 +302,9 @@ fn split_value(
// Finally, splitting the EBB parameter is not enough. We also have to repair all // Finally, splitting the EBB parameter is not enough. We also have to repair all
// of the predecessor instructions that branch here. // of the predecessor instructions that branch here.
add_repair(concat, split_type, ebb, num, hi_num, repairs); add_repair(concat, split_type, ebb, param_num, hi_num, repairs);
}
}
}
// Did the code above succeed in finding values we can reuse? (lo, hi)
if let Some(pair) = reuse {
pair
} else {
// No, we'll just have to insert the requested split instruction at `pos`. Note that `pos`
// has not been moved by the EBB argument code above when `reuse` is `None`.
match concat {
Opcode::Iconcat => pos.ins().isplit(value),
Opcode::Vconcat => pos.ins().vsplit(value),
_ => panic!("Unhandled concat opcode: {}", concat),
}
}
} }
// Add a repair entry to the work list. // Add a repair entry to the work list.

View File

@@ -0,0 +1,10 @@
test compile
target x86_64
function u0:0(i128) system_v {
ebb0(v0: i128):
jump ebb1(v0)
ebb1(v1: i128):
return
}