peepmatic: Do not transplant instructions whose results are potentially used elsewhere
This commit is contained in:
@@ -208,26 +208,6 @@ fn const_to_value<'a>(builder: impl InstBuilder<'a>, c: Constant, root: Inst) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_to_inst(pos: &mut FuncCursor, root: Inst, part: Part<ValueOrInst>) -> Option<Inst> {
|
|
||||||
match part {
|
|
||||||
Part::Instruction(ValueOrInst::Inst(inst)) => Some(inst),
|
|
||||||
Part::Instruction(ValueOrInst::Value(v)) => {
|
|
||||||
let inst = pos.func.dfg.value_def(v).inst()?;
|
|
||||||
if pos.func.dfg.inst_results(inst).len() == 1 {
|
|
||||||
Some(inst)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Part::Constant(c) => {
|
|
||||||
let v = const_to_value(pos.ins(), c, root);
|
|
||||||
let inst = pos.func.dfg.value_def(v).unwrap_inst();
|
|
||||||
Some(inst)
|
|
||||||
}
|
|
||||||
Part::ConditionCode(_) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn part_to_value(pos: &mut FuncCursor, root: Inst, part: Part<ValueOrInst>) -> Option<Value> {
|
fn part_to_value(pos: &mut FuncCursor, root: Inst, part: Part<ValueOrInst>) -> Option<Value> {
|
||||||
match part {
|
match part {
|
||||||
Part::Instruction(ValueOrInst::Inst(inst)) => {
|
Part::Instruction(ValueOrInst::Inst(inst)) => {
|
||||||
@@ -454,14 +434,30 @@ impl<'a, 'b> InstructionSet<'b> for &'a dyn TargetIsa {
|
|||||||
new: Part<ValueOrInst>,
|
new: Part<ValueOrInst>,
|
||||||
) -> ValueOrInst {
|
) -> ValueOrInst {
|
||||||
log::trace!("replace {:?} with {:?}", old, new);
|
log::trace!("replace {:?} with {:?}", old, new);
|
||||||
let old_inst = old.unwrap_inst();
|
let old_inst = old.resolve_inst(&pos.func.dfg).unwrap();
|
||||||
|
|
||||||
// Try to convert `new` to an instruction, because we prefer replacing
|
// Try to convert `new` to an instruction, because we prefer replacing
|
||||||
// an old instruction with a new one wholesale. However, if the
|
// an old instruction with a new one wholesale. However, if the
|
||||||
// replacement cannot be converted to an instruction (e.g. the
|
// replacement cannot be converted to an instruction (e.g. the
|
||||||
// right-hand side is a block/function parameter value) then we change
|
// right-hand side is a block/function parameter value) then we change
|
||||||
// the old instruction's result to an alias of the new value.
|
// the old instruction's result to an alias of the new value.
|
||||||
match part_to_inst(pos, old_inst, new) {
|
let new_inst = match new {
|
||||||
|
Part::Instruction(ValueOrInst::Inst(inst)) => Some(inst),
|
||||||
|
Part::Instruction(ValueOrInst::Value(_)) => {
|
||||||
|
// Do not try and follow the value definition. If we transplant
|
||||||
|
// this value's instruction, and there are other uses of this
|
||||||
|
// value, then we could mess up ordering between instructions.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
Part::Constant(c) => {
|
||||||
|
let v = const_to_value(pos.ins(), c, old_inst);
|
||||||
|
let inst = pos.func.dfg.value_def(v).unwrap_inst();
|
||||||
|
Some(inst)
|
||||||
|
}
|
||||||
|
Part::ConditionCode(_) => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
match new_inst {
|
||||||
Some(new_inst) => {
|
Some(new_inst) => {
|
||||||
pos.func.transplant_inst(old_inst, new_inst);
|
pos.func.transplant_inst(old_inst, new_inst);
|
||||||
debug_assert_eq!(pos.current_inst(), Some(old_inst));
|
debug_assert_eq!(pos.current_inst(), Some(old_inst));
|
||||||
@@ -528,7 +524,7 @@ impl<'a, 'b> InstructionSet<'b> for &'a dyn TargetIsa {
|
|||||||
) -> ValueOrInst {
|
) -> ValueOrInst {
|
||||||
log::trace!("make_inst_1: {:?}({:?})", operator, a);
|
log::trace!("make_inst_1: {:?}({:?})", operator, a);
|
||||||
|
|
||||||
let root = root.unwrap_inst();
|
let root = root.resolve_inst(&pos.func.dfg).unwrap();
|
||||||
match operator {
|
match operator {
|
||||||
Operator::AdjustSpDown => {
|
Operator::AdjustSpDown => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
@@ -541,12 +537,14 @@ impl<'a, 'b> InstructionSet<'b> for &'a dyn TargetIsa {
|
|||||||
}
|
}
|
||||||
Operator::Bconst => {
|
Operator::Bconst => {
|
||||||
let c = a.unwrap_constant();
|
let c = a.unwrap_constant();
|
||||||
const_to_value(pos.ins(), c, root).into()
|
let val = const_to_value(pos.ins(), c, root);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Bint => {
|
Operator::Bint => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let ty = peepmatic_ty_to_ir_ty(r#type, &pos.func.dfg, root);
|
let ty = peepmatic_ty_to_ir_ty(r#type, &pos.func.dfg, root);
|
||||||
pos.ins().bint(ty, a).into()
|
let val = pos.ins().bint(ty, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Brnz => {
|
Operator::Brnz => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
@@ -571,17 +569,20 @@ impl<'a, 'b> InstructionSet<'b> for &'a dyn TargetIsa {
|
|||||||
}
|
}
|
||||||
Operator::Iconst => {
|
Operator::Iconst => {
|
||||||
let a = a.unwrap_constant();
|
let a = a.unwrap_constant();
|
||||||
const_to_value(pos.ins(), a, root).into()
|
let val = const_to_value(pos.ins(), a, root);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Ireduce => {
|
Operator::Ireduce => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let ty = peepmatic_ty_to_ir_ty(r#type, &pos.func.dfg, root);
|
let ty = peepmatic_ty_to_ir_ty(r#type, &pos.func.dfg, root);
|
||||||
pos.ins().ireduce(ty, a).into()
|
let val = pos.ins().ireduce(ty, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Sextend => {
|
Operator::Sextend => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let ty = peepmatic_ty_to_ir_ty(r#type, &pos.func.dfg, root);
|
let ty = peepmatic_ty_to_ir_ty(r#type, &pos.func.dfg, root);
|
||||||
pos.ins().sextend(ty, a).into()
|
let val = pos.ins().sextend(ty, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Trapnz => {
|
Operator::Trapnz => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
@@ -604,7 +605,8 @@ impl<'a, 'b> InstructionSet<'b> for &'a dyn TargetIsa {
|
|||||||
Operator::Uextend => {
|
Operator::Uextend => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let ty = peepmatic_ty_to_ir_ty(r#type, &pos.func.dfg, root);
|
let ty = peepmatic_ty_to_ir_ty(r#type, &pos.func.dfg, root);
|
||||||
pos.ins().uextend(ty, a).into()
|
let val = pos.ins().uextend(ty, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
@@ -621,167 +623,199 @@ impl<'a, 'b> InstructionSet<'b> for &'a dyn TargetIsa {
|
|||||||
) -> ValueOrInst {
|
) -> ValueOrInst {
|
||||||
log::trace!("make_inst_2: {:?}({:?}, {:?})", operator, a, b);
|
log::trace!("make_inst_2: {:?}({:?}, {:?})", operator, a, b);
|
||||||
|
|
||||||
let root = root.unwrap_inst();
|
let root = root.resolve_inst(&pos.func.dfg).unwrap();
|
||||||
match operator {
|
match operator {
|
||||||
Operator::Band => {
|
Operator::Band => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().band(a, b).into()
|
let val = pos.ins().band(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::BandImm => {
|
Operator::BandImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().band_imm(b, a).into()
|
let val = pos.ins().band_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Bor => {
|
Operator::Bor => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().bor(a, b).into()
|
let val = pos.ins().bor(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::BorImm => {
|
Operator::BorImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().bor_imm(b, a).into()
|
let val = pos.ins().bor_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Bxor => {
|
Operator::Bxor => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().bxor(a, b).into()
|
let val = pos.ins().bxor(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::BxorImm => {
|
Operator::BxorImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().bxor_imm(b, a).into()
|
let val = pos.ins().bxor_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Iadd => {
|
Operator::Iadd => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().iadd(a, b).into()
|
let val = pos.ins().iadd(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::IaddImm => {
|
Operator::IaddImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().iadd_imm(b, a).into()
|
let val = pos.ins().iadd_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Ifcmp => {
|
Operator::Ifcmp => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().ifcmp(a, b).into()
|
let val = pos.ins().ifcmp(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::IfcmpImm => {
|
Operator::IfcmpImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().ifcmp_imm(b, a).into()
|
let val = pos.ins().ifcmp_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Imul => {
|
Operator::Imul => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().imul(a, b).into()
|
let val = pos.ins().imul(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::ImulImm => {
|
Operator::ImulImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().imul_imm(b, a).into()
|
let val = pos.ins().imul_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::IrsubImm => {
|
Operator::IrsubImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().irsub_imm(b, a).into()
|
let val = pos.ins().irsub_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Ishl => {
|
Operator::Ishl => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().ishl(a, b).into()
|
let val = pos.ins().ishl(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::IshlImm => {
|
Operator::IshlImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().ishl_imm(b, a).into()
|
let val = pos.ins().ishl_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Isub => {
|
Operator::Isub => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().isub(a, b).into()
|
let val = pos.ins().isub(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Rotl => {
|
Operator::Rotl => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().rotl(a, b).into()
|
let val = pos.ins().rotl(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::RotlImm => {
|
Operator::RotlImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().rotl_imm(b, a).into()
|
let val = pos.ins().rotl_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Rotr => {
|
Operator::Rotr => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().rotr(a, b).into()
|
let val = pos.ins().rotr(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::RotrImm => {
|
Operator::RotrImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().rotr_imm(b, a).into()
|
let val = pos.ins().rotr_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Sdiv => {
|
Operator::Sdiv => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().sdiv(a, b).into()
|
let val = pos.ins().sdiv(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::SdivImm => {
|
Operator::SdivImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().sdiv_imm(b, a).into()
|
let val = pos.ins().sdiv_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Srem => {
|
Operator::Srem => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().srem(a, b).into()
|
let val = pos.ins().srem(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::SremImm => {
|
Operator::SremImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().srem_imm(b, a).into()
|
let val = pos.ins().srem_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Sshr => {
|
Operator::Sshr => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().sshr(a, b).into()
|
let val = pos.ins().sshr(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::SshrImm => {
|
Operator::SshrImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().sshr_imm(b, a).into()
|
let val = pos.ins().sshr_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Udiv => {
|
Operator::Udiv => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().udiv(a, b).into()
|
let val = pos.ins().udiv(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::UdivImm => {
|
Operator::UdivImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().udiv_imm(b, a).into()
|
let val = pos.ins().udiv_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Urem => {
|
Operator::Urem => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().urem(a, b).into()
|
let val = pos.ins().urem(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::UremImm => {
|
Operator::UremImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().urem_imm(b, a).into()
|
let val = pos.ins().urem_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Ushr => {
|
Operator::Ushr => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().ushr(a, b).into()
|
let val = pos.ins().ushr(a, b);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::UshrImm => {
|
Operator::UshrImm => {
|
||||||
let a = part_to_imm64(pos, a);
|
let a = part_to_imm64(pos, a);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
pos.ins().ushr_imm(b, a).into()
|
let val = pos.ins().ushr_imm(b, a);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
@@ -799,27 +833,30 @@ impl<'a, 'b> InstructionSet<'b> for &'a dyn TargetIsa {
|
|||||||
) -> ValueOrInst {
|
) -> ValueOrInst {
|
||||||
log::trace!("make_inst_3: {:?}({:?}, {:?}, {:?})", operator, a, b, c);
|
log::trace!("make_inst_3: {:?}({:?}, {:?}, {:?})", operator, a, b, c);
|
||||||
|
|
||||||
let root = root.unwrap_inst();
|
let root = root.resolve_inst(&pos.func.dfg).unwrap();
|
||||||
match operator {
|
match operator {
|
||||||
Operator::Icmp => {
|
Operator::Icmp => {
|
||||||
let cond = a.unwrap_condition_code();
|
let cond = a.unwrap_condition_code();
|
||||||
let cond = peepmatic_to_intcc(cond);
|
let cond = peepmatic_to_intcc(cond);
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
let c = part_to_value(pos, root, c).unwrap();
|
let c = part_to_value(pos, root, c).unwrap();
|
||||||
pos.ins().icmp(cond, b, c).into()
|
let val = pos.ins().icmp(cond, b, c);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::IcmpImm => {
|
Operator::IcmpImm => {
|
||||||
let cond = a.unwrap_condition_code();
|
let cond = a.unwrap_condition_code();
|
||||||
let cond = peepmatic_to_intcc(cond);
|
let cond = peepmatic_to_intcc(cond);
|
||||||
let imm = part_to_imm64(pos, b);
|
let imm = part_to_imm64(pos, b);
|
||||||
let c = part_to_value(pos, root, c).unwrap();
|
let c = part_to_value(pos, root, c).unwrap();
|
||||||
pos.ins().icmp_imm(cond, c, imm).into()
|
let val = pos.ins().icmp_imm(cond, c, imm);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
Operator::Select => {
|
Operator::Select => {
|
||||||
let a = part_to_value(pos, root, a).unwrap();
|
let a = part_to_value(pos, root, a).unwrap();
|
||||||
let b = part_to_value(pos, root, b).unwrap();
|
let b = part_to_value(pos, root, b).unwrap();
|
||||||
let c = part_to_value(pos, root, c).unwrap();
|
let c = part_to_value(pos, root, c).unwrap();
|
||||||
pos.ins().select(a, b, c).into()
|
let val = pos.ins().select(a, b, c);
|
||||||
|
pos.func.dfg.value_def(val).unwrap_inst().into()
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
test simple_preopt
|
||||||
|
target x86_64
|
||||||
|
|
||||||
|
;; Test that although v5 can be replaced with v1, we don't transplant `load.i32
|
||||||
|
;; v0` on top of `iadd v3, v4`, because that would move the load past other uses
|
||||||
|
;; of its result.
|
||||||
|
|
||||||
|
function %foo(i64) -> i32 {
|
||||||
|
block0(v0: i64):
|
||||||
|
v1 = load.i32 v0
|
||||||
|
v2 = iconst.i32 16
|
||||||
|
v3 = iadd_imm v1, -16
|
||||||
|
v4 = iconst.i32 16
|
||||||
|
v5 = iadd v3, v4
|
||||||
|
; check: v1 = load.i32 v0
|
||||||
|
; nextln: v5 -> v1
|
||||||
|
; nextln: v2 = iconst.i32 16
|
||||||
|
; nextln: v3 = iadd_imm v1, -16
|
||||||
|
; nextln: v4 = iconst.i32 16
|
||||||
|
; nextln: nop
|
||||||
|
return v5
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user