Simple preopt: use the immediate form for adjust_sp_down/ifcmp whenever possible;
This commit is contained in:
@@ -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) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user