Remove the dfg::resolve_copies() method.

This method was important back when result values couldn't be moved
between instructions. Now that results can be moved, value aliases do
everything we need.

Copy instructions are still used to break interferences in the register
allocator's coalescing phase, but there isn't really any reason to use a
copy instruction over a value alias anywhere else.

After and during register allocation, copy instructions are significant,
so we never want to "see through" them like the resolve_copies()
function did.

This is related to #166, but probably doesn't fix the underlying
problem.
This commit is contained in:
Jakob Stoklund Olesen
2017-10-05 14:46:34 -07:00
parent 30aeb57083
commit b562fdcd5c
2 changed files with 3 additions and 32 deletions

View File

@@ -4,7 +4,7 @@ use entity::{PrimaryMap, EntityMap};
use isa::TargetIsa; use isa::TargetIsa;
use ir::builder::{InsertBuilder, ReplaceBuilder}; use ir::builder::{InsertBuilder, ReplaceBuilder};
use ir::extfunc::ExtFuncData; use ir::extfunc::ExtFuncData;
use ir::instructions::{Opcode, InstructionData, CallInfo}; use ir::instructions::{InstructionData, CallInfo};
use ir::layout::{Cursor, LayoutCursorInserter}; use ir::layout::{Cursor, LayoutCursorInserter};
use ir::types; use ir::types;
use ir::{Ebb, Inst, Value, Type, SigRef, Signature, FuncRef, ValueList, ValueListPool}; use ir::{Ebb, Inst, Value, Type, SigRef, Signature, FuncRef, ValueList, ValueListPool};
@@ -211,33 +211,6 @@ impl DataFlowGraph {
resolve_aliases(&self.values, value) resolve_aliases(&self.values, value)
} }
/// Resolve value copies.
///
/// Find the original definition of a value, looking through value aliases as well as
/// copy/spill/fill instructions.
pub fn resolve_copies(&self, value: Value) -> Value {
let mut v = value;
for _ in 0..self.insts.len() {
v = self.resolve_aliases(v);
v = match self.value_def(v) {
ValueDef::Res(inst, 0) => {
match self[inst] {
InstructionData::Unary { opcode, arg, .. } => {
match opcode {
Opcode::Copy | Opcode::Spill | Opcode::Fill => arg,
_ => return v,
}
}
_ => return v,
}
}
_ => return v,
};
}
panic!("Copy loop detected for {}", value);
}
/// Resolve all aliases among inst's arguments. /// Resolve all aliases among inst's arguments.
/// ///
/// For each argument of inst which is defined by an alias, replace the /// For each argument of inst which is defined by an alias, replace the
@@ -1090,7 +1063,5 @@ mod tests {
let c3 = pos.ins().copy(c); let c3 = pos.ins().copy(c);
// This does not see through copies. // This does not see through copies.
assert_eq!(pos.func.dfg.resolve_aliases(c3), c3); assert_eq!(pos.func.dfg.resolve_aliases(c3), c3);
// But this goes through both copies and aliases.
assert_eq!(pos.func.dfg.resolve_copies(c3), c2);
} }
} }

View File

@@ -190,7 +190,7 @@ fn split_value(
concat: Opcode, concat: Opcode,
repairs: &mut Vec<Repair>, repairs: &mut Vec<Repair>,
) -> (Value, Value) { ) -> (Value, Value) {
let value = pos.func.dfg.resolve_copies(value); let value = pos.func.dfg.resolve_aliases(value);
let mut reuse = None; let mut reuse = None;
match pos.func.dfg.value_def(value) { match pos.func.dfg.value_def(value) {
@@ -293,7 +293,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: &ir::DataFlowGraph, value: Value) -> Value { fn resolve_splits(dfg: &ir::DataFlowGraph, value: Value) -> Value {
let value = dfg.resolve_copies(value); let value = dfg.resolve_aliases(value);
// Deconstruct a split instruction. // Deconstruct a split instruction.
let split_res; let split_res;