Remove layout::Cursor from the legalizer::split API.

We still use the cursor internally, but don't require callers to use it
too.
This commit is contained in:
Jakob Stoklund Olesen
2017-09-21 13:06:28 -07:00
parent 1cd91b6f30
commit 8e93aa7ce7
4 changed files with 39 additions and 26 deletions

View File

@@ -264,12 +264,12 @@ def emit_dst_inst(node, fmt):
# Split instructions are not emitted with the builder, but by calling
# special functions in the `legalizer::split` module. These functions
# will eliminate concat-split patterns.
fmt.line(
'let {} = split::{}(dfg, cfg, pos, {});'
.format(
wrap_tup(node.defs),
node.expr.inst.snake_name(),
node.expr.args[0]))
fmt.line('let curpos = pos.position();')
fmt.format(
'let {} = split::{}(dfg, pos.layout, cfg, curpos, {});',
wrap_tup(node.defs),
node.expr.inst.snake_name(),
node.expr.args[0])
else:
if len(node.defs) == 0:
# This node doesn't define any values, so just insert the new

View File

@@ -709,6 +709,15 @@ pub trait CursorBase {
/// Borrow a mutable reference to the function layout that this cursor is navigating.
fn layout_mut(&mut self) -> &mut Layout;
/// Rebuild this cursor positioned at `pos`.
fn at_position(mut self, pos: CursorPosition) -> Self
where
Self: Sized,
{
self.set_position(pos);
self
}
/// Rebuild this cursor positioned at `inst`.
///
/// This is intended to be used as a builder method:

View File

@@ -331,12 +331,14 @@ fn convert_to_abi<PutArg>(
let ty = dfg.value_type(value);
match legalize_abi_value(ty, &arg_type) {
ValueConversion::IntSplit => {
let (lo, hi) = isplit(dfg, cfg, pos, value);
let curpos = pos.position();
let (lo, hi) = isplit(dfg, pos.layout, cfg, curpos, value);
convert_to_abi(dfg, cfg, pos, lo, put_arg);
convert_to_abi(dfg, cfg, pos, hi, put_arg);
}
ValueConversion::VectorSplit => {
let (lo, hi) = vsplit(dfg, cfg, pos, value);
let curpos = pos.position();
let (lo, hi) = vsplit(dfg, pos.layout, cfg, curpos, value);
convert_to_abi(dfg, cfg, pos, lo, put_arg);
convert_to_abi(dfg, cfg, pos, hi, put_arg);
}

View File

@@ -64,31 +64,33 @@
//! It is possible to have circular dependencies of EBB arguments that are never used by any real
//! instructions. These loops will remain in the program.
use cursor::{Cursor, CursorPosition};
use flowgraph::ControlFlowGraph;
use ir::{DataFlowGraph, Ebb, Inst, Cursor, CursorBase, Value, Type, Opcode, ValueDef,
InstructionData, InstBuilder};
use ir::{self, Ebb, Inst, Value, Type, Opcode, ValueDef, InstructionData, InstBuilder};
use std::iter;
/// Split `value` into two values using the `isplit` semantics. Do this by reusing existing values
/// if possible.
pub fn isplit(
dfg: &mut DataFlowGraph,
dfg: &mut ir::DataFlowGraph,
layout: &mut ir::Layout,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
pos: CursorPosition,
value: Value,
) -> (Value, Value) {
split_any(dfg, cfg, pos, value, Opcode::Iconcat)
split_any(dfg, layout, cfg, pos, value, Opcode::Iconcat)
}
/// Split `value` into halves using the `vsplit` semantics. Do this by reusing existing values if
/// possible.
pub fn vsplit(
dfg: &mut DataFlowGraph,
dfg: &mut ir::DataFlowGraph,
layout: &mut ir::Layout,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
pos: CursorPosition,
value: Value,
) -> (Value, Value) {
split_any(dfg, cfg, pos, value, Opcode::Vconcat)
split_any(dfg, layout, cfg, pos, value, Opcode::Vconcat)
}
/// After splitting an EBB argument, we need to go back and fix up all of the predecessor
@@ -110,15 +112,16 @@ struct Repair {
/// Generic version of `isplit` and `vsplit` controlled by the `concat` opcode.
fn split_any(
dfg: &mut DataFlowGraph,
dfg: &mut ir::DataFlowGraph,
layout: &mut ir::Layout,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
pos: CursorPosition,
value: Value,
concat: Opcode,
) -> (Value, Value) {
let saved_pos = pos.position();
let mut repairs = Vec::new();
let result = split_value(dfg, pos, value, concat, &mut repairs);
let mut pos = ir::Cursor::new(layout).at_position(pos);
let result = split_value(dfg, &mut pos, value, concat, &mut repairs);
// We have split the value requested, and now we may need to fix some EBB predecessors.
while let Some(repair) = repairs.pop() {
@@ -147,7 +150,7 @@ fn split_any(
// Split the old argument, possibly causing more repairs to be scheduled.
pos.goto_inst(inst);
let (lo, hi) = split_value(dfg, pos, old_arg, repair.concat, &mut repairs);
let (lo, hi) = split_value(dfg, &mut pos, old_arg, repair.concat, &mut repairs);
// The `lo` part replaces the original argument.
*args.get_mut(fixed_args + repair.num, &mut dfg.value_lists)
@@ -173,7 +176,6 @@ fn split_any(
}
}
pos.set_position(saved_pos);
result
}
@@ -184,8 +186,8 @@ fn split_any(
///
/// Return the two new values representing the parts of `value`.
fn split_value(
dfg: &mut DataFlowGraph,
pos: &mut Cursor,
dfg: &mut ir::DataFlowGraph,
pos: &mut ir::Cursor,
value: Value,
concat: Opcode,
repairs: &mut Vec<Repair>,
@@ -292,7 +294,7 @@ fn add_repair(
/// ```
///
/// This function resolves `v11` to `v1` and `v12` to `v2`.
fn resolve_splits(dfg: &DataFlowGraph, value: Value) -> Value {
fn resolve_splits(dfg: &ir::DataFlowGraph, value: Value) -> Value {
let value = dfg.resolve_copies(value);
// Deconstruct a split instruction.
@@ -330,7 +332,7 @@ fn resolve_splits(dfg: &DataFlowGraph, value: Value) -> Value {
///
/// After legalizing the instructions computing the value that was split, it is likely that we can
/// avoid depending on the split instruction. Its input probably comes from a concatenation.
pub fn simplify_branch_arguments(dfg: &mut DataFlowGraph, branch: Inst) {
pub fn simplify_branch_arguments(dfg: &mut ir::DataFlowGraph, branch: Inst) {
let mut new_args = Vec::new();
for &arg in dfg.inst_args(branch) {