Simple preopt: use the immediate form for adjust_sp_down/ifcmp whenever possible;

This commit is contained in:
Benjamin Bouvier
2019-07-01 17:25:11 +02:00
parent 8e33ca3055
commit dc58a5fc5c

View File

@@ -8,12 +8,14 @@ use crate::cursor::{Cursor, FuncCursor};
use crate::divconst_magic_numbers::{magic_s32, magic_s64, magic_u32, magic_u64}; use crate::divconst_magic_numbers::{magic_s32, magic_s64, magic_u32, magic_u64};
use crate::divconst_magic_numbers::{MS32, MS64, MU32, MU64}; use crate::divconst_magic_numbers::{MS32, MS64, MU32, MU64};
use crate::flowgraph::ControlFlowGraph; use crate::flowgraph::ControlFlowGraph;
use crate::ir::condcodes::{CondCode, IntCC}; use crate::ir::{
use crate::ir::dfg::ValueDef; condcodes::{CondCode, IntCC},
use crate::ir::instructions::{Opcode, ValueList}; dfg::ValueDef,
use crate::ir::types::{I32, I64}; immediates,
use crate::ir::Inst; instructions::{Opcode, ValueList},
use crate::ir::{DataFlowGraph, Ebb, Function, InstBuilder, InstructionData, Type, Value}; types::{I32, I64},
DataFlowGraph, Ebb, Function, Inst, InstBuilder, InstructionData, Type, Value,
};
use crate::timing; use crate::timing;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@@ -450,6 +452,20 @@ fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCurso
} }
} }
#[inline]
fn resolve_imm64_value(dfg: &DataFlowGraph, value: Value) -> Option<immediates::Imm64> {
if let ValueDef::Result(candidate_inst, _) = dfg.value_def(value) {
if let InstructionData::UnaryImm {
opcode: Opcode::Iconst,
imm,
} = dfg[candidate_inst]
{
return Some(imm);
}
}
None
}
/// Apply basic simplifications. /// Apply basic simplifications.
/// ///
/// This folds constants with arithmetic to form `_imm` instructions, and other /// This folds constants with arithmetic to form `_imm` instructions, and other
@@ -457,12 +473,7 @@ fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCurso
fn simplify(pos: &mut FuncCursor, inst: Inst) { fn simplify(pos: &mut FuncCursor, inst: Inst) {
match pos.func.dfg[inst] { match pos.func.dfg[inst] {
InstructionData::Binary { opcode, args } => { InstructionData::Binary { opcode, args } => {
if let ValueDef::Result(iconst_inst, _) = pos.func.dfg.value_def(args[1]) { if let Some(mut imm) = resolve_imm64_value(&pos.func.dfg, args[1]) {
if let InstructionData::UnaryImm {
opcode: Opcode::Iconst,
mut imm,
} = pos.func.dfg[iconst_inst]
{
let new_opcode = match opcode { let new_opcode = match opcode {
Opcode::Iadd => Opcode::IaddImm, Opcode::Iadd => Opcode::IaddImm,
Opcode::Imul => Opcode::ImulImm, Opcode::Imul => Opcode::ImulImm,
@@ -482,6 +493,7 @@ fn simplify(pos: &mut FuncCursor, inst: Inst) {
imm = imm.wrapping_neg(); imm = imm.wrapping_neg();
Opcode::IaddImm Opcode::IaddImm
} }
Opcode::Ifcmp => Opcode::IfcmpImm,
_ => return, _ => return,
}; };
let ty = pos.func.dfg.ctrl_typevar(inst); let ty = pos.func.dfg.ctrl_typevar(inst);
@@ -489,13 +501,7 @@ fn simplify(pos: &mut FuncCursor, inst: Inst) {
.dfg .dfg
.replace(inst) .replace(inst)
.BinaryImm(new_opcode, ty, imm, args[0]); .BinaryImm(new_opcode, ty, imm, args[0]);
} } else if let Some(imm) = resolve_imm64_value(&pos.func.dfg, args[0]) {
} else if let ValueDef::Result(iconst_inst, _) = pos.func.dfg.value_def(args[0]) {
if let InstructionData::UnaryImm {
opcode: Opcode::Iconst,
imm,
} = pos.func.dfg[iconst_inst]
{
let new_opcode = match opcode { let new_opcode = match opcode {
Opcode::Isub => Opcode::IrsubImm, Opcode::Isub => Opcode::IrsubImm,
_ => return, _ => return,
@@ -507,19 +513,24 @@ fn simplify(pos: &mut FuncCursor, inst: Inst) {
.BinaryImm(new_opcode, ty, imm, args[1]); .BinaryImm(new_opcode, ty, imm, args[1]);
} }
} }
InstructionData::Unary { opcode, arg } => match opcode {
Opcode::AdjustSpDown => {
if let Some(imm) = resolve_imm64_value(&pos.func.dfg, arg) {
// Note this works for both positive and negative immediate values.
pos.func.dfg.replace(inst).adjust_sp_down_imm(imm);
} }
}
_ => {}
},
InstructionData::IntCompare { opcode, cond, args } => { InstructionData::IntCompare { opcode, cond, args } => {
debug_assert_eq!(opcode, Opcode::Icmp); debug_assert_eq!(opcode, Opcode::Icmp);
if let ValueDef::Result(iconst_inst, _) = pos.func.dfg.value_def(args[1]) { if let Some(imm) = resolve_imm64_value(&pos.func.dfg, args[1]) {
if let InstructionData::UnaryImm {
opcode: Opcode::Iconst,
imm,
} = pos.func.dfg[iconst_inst]
{
pos.func.dfg.replace(inst).icmp_imm(cond, args[0], imm); pos.func.dfg.replace(inst).icmp_imm(cond, args[0], imm);
} }
} }
}
InstructionData::CondTrap { .. } InstructionData::CondTrap { .. }
| InstructionData::Branch { .. } | InstructionData::Branch { .. }
| InstructionData::Ternary { | InstructionData::Ternary {
@@ -542,6 +553,7 @@ fn simplify(pos: &mut FuncCursor, inst: Inst) {
} }
} }
} }
_ => {} _ => {}
} }
} }