Fix bug when i128 ebb param is unused
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user