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 # Split instructions are not emitted with the builder, but by calling
# special functions in the `legalizer::split` module. These functions # special functions in the `legalizer::split` module. These functions
# will eliminate concat-split patterns. # will eliminate concat-split patterns.
fmt.line( fmt.line('let curpos = pos.position();')
'let {} = split::{}(dfg, cfg, pos, {});' fmt.format(
.format( 'let {} = split::{}(dfg, pos.layout, cfg, curpos, {});',
wrap_tup(node.defs), wrap_tup(node.defs),
node.expr.inst.snake_name(), node.expr.inst.snake_name(),
node.expr.args[0])) node.expr.args[0])
else: else:
if len(node.defs) == 0: if len(node.defs) == 0:
# This node doesn't define any values, so just insert the new # 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. /// Borrow a mutable reference to the function layout that this cursor is navigating.
fn layout_mut(&mut self) -> &mut Layout; 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`. /// Rebuild this cursor positioned at `inst`.
/// ///
/// This is intended to be used as a builder method: /// 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); let ty = dfg.value_type(value);
match legalize_abi_value(ty, &arg_type) { match legalize_abi_value(ty, &arg_type) {
ValueConversion::IntSplit => { 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, lo, put_arg);
convert_to_abi(dfg, cfg, pos, hi, put_arg); convert_to_abi(dfg, cfg, pos, hi, put_arg);
} }
ValueConversion::VectorSplit => { 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, lo, put_arg);
convert_to_abi(dfg, cfg, pos, hi, 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 //! 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. //! instructions. These loops will remain in the program.
use cursor::{Cursor, CursorPosition};
use flowgraph::ControlFlowGraph; use flowgraph::ControlFlowGraph;
use ir::{DataFlowGraph, Ebb, Inst, Cursor, CursorBase, Value, Type, Opcode, ValueDef, use ir::{self, Ebb, Inst, Value, Type, Opcode, ValueDef, InstructionData, InstBuilder};
InstructionData, InstBuilder};
use std::iter; use std::iter;
/// Split `value` into two values using the `isplit` semantics. Do this by reusing existing values /// Split `value` into two values using the `isplit` semantics. Do this by reusing existing values
/// if possible. /// if possible.
pub fn isplit( pub fn isplit(
dfg: &mut DataFlowGraph, dfg: &mut ir::DataFlowGraph,
layout: &mut ir::Layout,
cfg: &ControlFlowGraph, cfg: &ControlFlowGraph,
pos: &mut Cursor, pos: CursorPosition,
value: Value, value: Value,
) -> (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 /// Split `value` into halves using the `vsplit` semantics. Do this by reusing existing values if
/// possible. /// possible.
pub fn vsplit( pub fn vsplit(
dfg: &mut DataFlowGraph, dfg: &mut ir::DataFlowGraph,
layout: &mut ir::Layout,
cfg: &ControlFlowGraph, cfg: &ControlFlowGraph,
pos: &mut Cursor, pos: CursorPosition,
value: Value, value: Value,
) -> (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 /// 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. /// Generic version of `isplit` and `vsplit` controlled by the `concat` opcode.
fn split_any( fn split_any(
dfg: &mut DataFlowGraph, dfg: &mut ir::DataFlowGraph,
layout: &mut ir::Layout,
cfg: &ControlFlowGraph, cfg: &ControlFlowGraph,
pos: &mut Cursor, pos: CursorPosition,
value: Value, value: Value,
concat: Opcode, concat: Opcode,
) -> (Value, Value) { ) -> (Value, Value) {
let saved_pos = pos.position();
let mut repairs = Vec::new(); 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. // 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() {
@@ -147,7 +150,7 @@ fn split_any(
// Split the old argument, possibly causing more repairs to be scheduled. // Split the old argument, possibly causing more repairs to be scheduled.
pos.goto_inst(inst); 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. // The `lo` part replaces the original argument.
*args.get_mut(fixed_args + repair.num, &mut dfg.value_lists) *args.get_mut(fixed_args + repair.num, &mut dfg.value_lists)
@@ -173,7 +176,6 @@ fn split_any(
} }
} }
pos.set_position(saved_pos);
result result
} }
@@ -184,8 +186,8 @@ fn split_any(
/// ///
/// Return the two new values representing the parts of `value`. /// Return the two new values representing the parts of `value`.
fn split_value( fn split_value(
dfg: &mut DataFlowGraph, dfg: &mut ir::DataFlowGraph,
pos: &mut Cursor, pos: &mut ir::Cursor,
value: Value, value: Value,
concat: Opcode, concat: Opcode,
repairs: &mut Vec<Repair>, repairs: &mut Vec<Repair>,
@@ -292,7 +294,7 @@ fn add_repair(
/// ``` /// ```
/// ///
/// This function resolves `v11` to `v1` and `v12` to `v2`. /// 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); let value = dfg.resolve_copies(value);
// Deconstruct a split instruction. // 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 /// 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. /// 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(); let mut new_args = Vec::new();
for &arg in dfg.inst_args(branch) { for &arg in dfg.inst_args(branch) {