diff options
author | Vlad Brezae <brezaevlad@gmail.com> | 2015-12-23 20:40:05 +0300 |
---|---|---|
committer | Vlad Brezae <brezaevlad@gmail.com> | 2016-01-16 04:23:07 +0300 |
commit | dbd9b34fe30bb353817fd52cf54a5e3ab72ce993 (patch) | |
tree | e0df194698311b67b9732c0949ae01e1d94bd04f | |
parent | f60b11a873bdacc152a5dfeb063b2dd9a8650b8f (diff) |
[jit] Move optimization to cprop in order to handle more cases
Cprop can convert more binops to their _IMM counterpart, which would otherwise not be detected at method_to_ir time, allowing us to do strength reduction.
-rw-r--r-- | mono/mini/decompose.c | 41 | ||||
-rw-r--r-- | mono/mini/local-propagation.c | 41 |
2 files changed, 41 insertions, 41 deletions
diff --git a/mono/mini/decompose.c b/mono/mini/decompose.c index fa59554351b..7eb45ddaa2b 100644 --- a/mono/mini/decompose.c +++ b/mono/mini/decompose.c @@ -472,47 +472,6 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins) } break; -#if SIZEOF_REGISTER == 8 - case OP_LREM_IMM: -#endif - case OP_IREM_IMM: { - int power = mono_is_power_of_two (ins->inst_imm); - if (ins->inst_imm == 1) { - ins->opcode = OP_ICONST; - MONO_INST_NULLIFY_SREGS (ins); - ins->inst_c0 = 0; -#if __s390__ - } -#else - } else if ((ins->inst_imm > 0) && (ins->inst_imm < (1LL << 32)) && (power != -1)) { - gboolean is_long = ins->opcode == OP_LREM_IMM; - int compensator_reg = alloc_ireg (cfg); - int intermediate_reg; - - /* Based on gcc code */ - - /* Add compensation for negative numerators */ - - if (power > 1) { - intermediate_reg = compensator_reg; - MONO_EMIT_NEW_BIALU_IMM (cfg, is_long ? OP_LSHR_IMM : OP_ISHR_IMM, intermediate_reg, ins->sreg1, is_long ? 63 : 31); - } else { - intermediate_reg = ins->sreg1; - } - - MONO_EMIT_NEW_BIALU_IMM (cfg, is_long ? OP_LSHR_UN_IMM : OP_ISHR_UN_IMM, compensator_reg, intermediate_reg, (is_long ? 64 : 32) - power); - MONO_EMIT_NEW_BIALU (cfg, is_long ? OP_LADD : OP_IADD, ins->dreg, ins->sreg1, compensator_reg); - /* Compute remainder */ - MONO_EMIT_NEW_BIALU_IMM (cfg, is_long ? OP_LAND_IMM : OP_AND_IMM, ins->dreg, ins->dreg, (1 << power) - 1); - /* Remove compensation */ - MONO_EMIT_NEW_BIALU (cfg, is_long ? OP_LSUB : OP_ISUB, ins->dreg, ins->dreg, compensator_reg); - - NULLIFY_INS (ins); - } -#endif - break; - } - default: emulate = TRUE; break; diff --git a/mono/mini/local-propagation.c b/mono/mini/local-propagation.c index e9403d0a31b..eb0749ecc11 100644 --- a/mono/mini/local-propagation.c +++ b/mono/mini/local-propagation.c @@ -140,6 +140,47 @@ mono_strength_reduction_ins (MonoCompile *cfg, MonoInst *ins, const char **spec) } break; } +#if SIZEOF_REGISTER == 8 + case OP_LREM_IMM: +#endif + case OP_IREM_IMM: { + int power = mono_is_power_of_two (ins->inst_imm); + if (ins->inst_imm == 1) { + ins->opcode = OP_ICONST; + MONO_INST_NULLIFY_SREGS (ins); + ins->inst_c0 = 0; +#if __s390__ + } +#else + } else if ((ins->inst_imm > 0) && (ins->inst_imm < (1LL << 32)) && (power != -1)) { + gboolean is_long = ins->opcode == OP_LREM_IMM; + int compensator_reg = alloc_ireg (cfg); + int intermediate_reg; + + /* Based on gcc code */ + + /* Add compensation for negative numerators */ + + if (power > 1) { + intermediate_reg = compensator_reg; + MONO_EMIT_NEW_BIALU_IMM (cfg, is_long ? OP_LSHR_IMM : OP_ISHR_IMM, intermediate_reg, ins->sreg1, is_long ? 63 : 31); + } else { + intermediate_reg = ins->sreg1; + } + + MONO_EMIT_NEW_BIALU_IMM (cfg, is_long ? OP_LSHR_UN_IMM : OP_ISHR_UN_IMM, compensator_reg, intermediate_reg, (is_long ? 64 : 32) - power); + MONO_EMIT_NEW_BIALU (cfg, is_long ? OP_LADD : OP_IADD, ins->dreg, ins->sreg1, compensator_reg); + /* Compute remainder */ + MONO_EMIT_NEW_BIALU_IMM (cfg, is_long ? OP_LAND_IMM : OP_AND_IMM, ins->dreg, ins->dreg, (1 << power) - 1); + /* Remove compensation */ + MONO_EMIT_NEW_BIALU (cfg, is_long ? OP_LSUB : OP_ISUB, ins->dreg, ins->dreg, compensator_reg); + + allocated_vregs = TRUE; + } +#endif + break; + } + default: break; } |