Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVlad Brezae <brezaevlad@gmail.com>2015-12-23 20:40:05 +0300
committerVlad Brezae <brezaevlad@gmail.com>2016-01-16 04:23:07 +0300
commitdbd9b34fe30bb353817fd52cf54a5e3ab72ce993 (patch)
treee0df194698311b67b9732c0949ae01e1d94bd04f
parentf60b11a873bdacc152a5dfeb063b2dd9a8650b8f (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.c41
-rw-r--r--mono/mini/local-propagation.c41
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;
}