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:
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user