Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / mini / local-propagation.c
index 04373359fb46ead9bc1ea8d96249d33ee4c15948..923f53311c7c56f2c819ecca2ec9a8740bf8a8c6 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * local-propagation.c: Local constant, copy and tree propagation.
+/**
+ * \file
+ * Local constant, copy and tree propagation.
  *
  * To make some sense of the tree mover, read mono/docs/tree-mover.txt
  *
@@ -14,6 +15,8 @@
  */
 
 #include <config.h>
+#include <mono/utils/mono-compiler.h>
+
 #ifndef DISABLE_JIT
 
 #include <string.h>
@@ -25,6 +28,7 @@
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/mempool.h>
 #include <mono/metadata/opcodes.h>
+#include <mono/utils/unlocked.h>
 #include "mini.h"
 #include "ir-emit.h"
 
@@ -171,6 +175,8 @@ mono_strength_reduction_division (MonoCompile *cfg, MonoInst *ins)
                                ins->inst_imm = power2;
                                break;
                        }
+                       if (cfg->backend->disable_div_with_mul)
+                               break;
                        allocated_vregs = TRUE;
                        /*
                         * Replacement of unsigned division with multiplication,
@@ -206,7 +212,7 @@ mono_strength_reduction_division (MonoCompile *cfg, MonoInst *ins)
                        }
                        MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, ins->dreg, MONO_LVREG_LS (tmp_regl));
 #endif
-                       mono_jit_stats.optimized_divisions++;
+                       UnlockedIncrement (&mono_jit_stats.optimized_divisions);
                        break;
                }
                case OP_IDIV_IMM: {
@@ -243,6 +249,8 @@ mono_strength_reduction_division (MonoCompile *cfg, MonoInst *ins)
                                break;
                        }
 
+                       if (cfg->backend->disable_div_with_mul)
+                               break;
                        /*
                         * Replacement of signed division with multiplication,
                         * shifts and additions Hacker's Delight, chapter 10-6.
@@ -286,7 +294,7 @@ mono_strength_reduction_division (MonoCompile *cfg, MonoInst *ins)
                        MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHR_UN_IMM, ins->dreg, tmp_regi, SIZEOF_REGISTER * 8 - 1);
                        MONO_EMIT_NEW_BIALU (cfg, OP_IADD, ins->dreg, ins->dreg, tmp_regi);
 #endif
-                       mono_jit_stats.optimized_divisions++;
+                       UnlockedIncrement (&mono_jit_stats.optimized_divisions);
                        break;
                }
        }
@@ -635,13 +643,15 @@ mono_local_cprop (MonoCompile *cfg)
                                /* FIXME: Make is_inst_imm a macro */
                                /* FIXME: Make is_inst_imm take an opcode argument */
                                /* is_inst_imm is only needed for binops */
-                               if ((((def->opcode == OP_ICONST) || ((sizeof (gpointer) == 8) && (def->opcode == OP_I8CONST))) &&
+                               if ((((def->opcode == OP_ICONST) || ((sizeof (gpointer) == 8) && (def->opcode == OP_I8CONST)) || (def->opcode == OP_PCONST)) &&
                                         (((srcindex == 0) && (ins->sreg2 == -1)) || mono_arch_is_inst_imm (def->inst_c0))) || 
                                        (!MONO_ARCH_USE_FPSTACK && (def->opcode == OP_R8CONST))) {
                                        guint32 opcode2;
 
                                        /* srcindex == 1 -> binop, ins->sreg2 == -1 -> unop */
-                                       if ((srcindex == 1) && (ins->sreg1 != -1) && defs [ins->sreg1] && (defs [ins->sreg1]->opcode == OP_ICONST) && defs [ins->sreg2]) {
+                                       if ((srcindex == 1) && (ins->sreg1 != -1) && defs [ins->sreg1] &&
+                                               ((defs [ins->sreg1]->opcode == OP_ICONST) || defs [ins->sreg1]->opcode == OP_PCONST) &&
+                                               defs [ins->sreg2]) {
                                                /* Both arguments are constants, perform cfold */
                                                mono_constant_fold_ins (cfg, ins, defs [ins->sreg1], defs [ins->sreg2], TRUE);
                                        } else if ((srcindex == 0) && (ins->sreg2 != -1) && defs [ins->sreg2]) {
@@ -733,6 +743,9 @@ mono_local_cprop (MonoCompile *cfg)
                                        dummy_arg1.inst_c0 = 1;
 
                                        mono_constant_fold_ins (cfg, ins, &dummy_arg1, NULL, TRUE);
+                               } else if (srcindex == 0 && ins->opcode == OP_COMPARE && defs [ins->sreg1]->opcode == OP_PCONST && defs [ins->sreg2] && defs [ins->sreg2]->opcode == OP_PCONST) {
+                                       /* typeof(T) == typeof(..) */
+                                       mono_constant_fold_ins (cfg, ins, defs [ins->sreg1], defs [ins->sreg2], TRUE);
                                }
                        }
 
@@ -998,4 +1011,8 @@ mono_local_deadce (MonoCompile *cfg)
        //mono_print_code (cfg, "AFTER LOCAL-DEADCE");
 }
 
-#endif /* DISABLE_JIT */
+#else /* !DISABLE_JIT */
+
+MONO_EMPTY_SOURCE_FILE (local_propagation);
+
+#endif /* !DISABLE_JIT */