generate better conditions after shl/shr/sar with constant shift count

This commit is contained in:
Fabian 2022-11-09 22:35:58 -06:00
parent 71d36b234f
commit 8bf7a6aac0
3 changed files with 46 additions and 5 deletions

View file

@ -1635,7 +1635,10 @@ pub fn gen_getzf(ctx: &mut JitContext, negate: ConditionNegate) {
}
}
},
Instruction::Cmp { .. } | Instruction::Sub { .. } | Instruction::Add { .. } => {
Instruction::Cmp { .. }
| Instruction::Sub { .. }
| Instruction::Add { .. }
| Instruction::NonZeroShift { .. } => {
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_OPTIMISED);
gen_get_last_result(ctx.builder, &ctx.previous_instruction);
if negate == ConditionNegate::False {
@ -1752,6 +1755,15 @@ pub fn gen_getcf(ctx: &mut JitContext, negate: ConditionNegate) {
ctx.builder
.const_i32(if negate == ConditionNegate::True { 1 } else { 0 });
},
Instruction::NonZeroShift { .. } => {
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_OPTIMISED);
gen_get_flags(ctx.builder);
ctx.builder.const_i32(FLAG_CARRY);
ctx.builder.and_i32();
if negate == ConditionNegate::True {
ctx.builder.eqz_i32();
}
},
&Instruction::Other => {
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_UNOPTIMISED);
@ -1797,7 +1809,8 @@ pub fn gen_getsf(ctx: &mut JitContext, negate: ConditionNegate) {
Instruction::Cmp { opsize, .. }
| Instruction::Sub { opsize, .. }
| Instruction::Add { opsize, .. }
| Instruction::Bitwise { opsize, .. } => {
| Instruction::Bitwise { opsize, .. }
| Instruction::NonZeroShift { opsize, .. } => {
let &opsize = opsize;
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_OPTIMISED);
gen_get_last_result(ctx.builder, &ctx.previous_instruction);
@ -1905,6 +1918,12 @@ pub fn gen_getof(ctx: &mut JitContext) {
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_OPTIMISED);
ctx.builder.const_i32(0);
},
Instruction::NonZeroShift { .. } => {
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_OPTIMISED);
gen_get_flags(ctx.builder);
ctx.builder.const_i32(FLAG_OVERFLOW);
ctx.builder.and_i32();
},
&Instruction::Other => {
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_UNOPTIMISED);
gen_get_flags_changed(ctx.builder);
@ -2051,7 +2070,7 @@ pub fn gen_test_be(ctx: &mut JitContext, negate: ConditionNegate) {
ctx.builder.eqz_i32();
}
},
&Instruction::Other => {
Instruction::Other | Instruction::NonZeroShift { .. } => {
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_UNOPTIMISED);
gen_getcf(ctx, ConditionNegate::False);
gen_getzf(ctx, ConditionNegate::False);
@ -2167,7 +2186,7 @@ pub fn gen_test_l(ctx: &mut JitContext, negate: ConditionNegate) {
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_OPTIMISED);
gen_getsf(ctx, negate);
},
&Instruction::Other | Instruction::Add { .. } => {
&Instruction::Other | Instruction::Add { .. } | Instruction::NonZeroShift { .. } => {
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_UNOPTIMISED);
if let Instruction::Add { .. } = ctx.previous_instruction {
gen_profiler_stat_increment(
@ -2297,7 +2316,7 @@ pub fn gen_test_le(ctx: &mut JitContext, negate: ConditionNegate) {
ctx.builder.eqz_i32();
}
},
Instruction::Other | Instruction::Add { .. } => {
Instruction::Other | Instruction::Add { .. } | Instruction::NonZeroShift { .. } => {
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_UNOPTIMISED);
if let Instruction::Add { .. } = ctx.previous_instruction {
gen_profiler_stat_increment(

View file

@ -274,6 +274,10 @@ pub enum Instruction {
opsize: i32,
is_inc: bool,
},
NonZeroShift {
dest: InstructionOperandDest,
opsize: i32,
},
Bitwise {
dest: InstructionOperandDest,
opsize: i32,

View file

@ -1555,6 +1555,12 @@ impl ShiftCount {
}
fn gen_shl32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
if let &LocalOrImmediate::Immediate(1..=31) = source_operand {
ctx.current_instruction = Instruction::NonZeroShift {
dest: local_to_instruction_operand(ctx, dest_operand),
opsize: OPSIZE_32,
};
}
let builder = &mut ctx.builder;
let count = match source_operand {
LocalOrImmediate::WasmLocal(l) => {
@ -1622,6 +1628,12 @@ fn gen_shl32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &Lo
}
}
fn gen_shr32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
if let &LocalOrImmediate::Immediate(1..=31) = source_operand {
ctx.current_instruction = Instruction::NonZeroShift {
dest: local_to_instruction_operand(ctx, dest_operand),
opsize: OPSIZE_32,
};
}
let builder = &mut ctx.builder;
let count = match source_operand {
LocalOrImmediate::WasmLocal(l) => {
@ -1682,6 +1694,12 @@ fn gen_shr32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &Lo
}
}
fn gen_sar32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
if let &LocalOrImmediate::Immediate(1..=31) = source_operand {
ctx.current_instruction = Instruction::NonZeroShift {
dest: local_to_instruction_operand(ctx, dest_operand),
opsize: OPSIZE_32,
};
}
let builder = &mut ctx.builder;
let count = match source_operand {
LocalOrImmediate::WasmLocal(l) => {