Introduce support for unlimited trampolines.
[mono.git] / mono / mini / local-propagation.c
index 51bc65a0c15ca261976ac265fbb801f5cd33192e..cdcaa97abfb8eeea9a3202456d2ed4a125c53042 100644 (file)
@@ -9,6 +9,7 @@
  *   Massimiliano Mantione (massi@ximian.com)
  *
  * (C) 2006 Novell, Inc.  http://www.novell.com
+ * Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
  */
 
 
@@ -121,7 +122,7 @@ restart:
 
                                        if ((def->opcode == OP_MOVE) && (!defs [def->sreg1] || (def_index [def->sreg1] < def_index [sreg])) && !vreg_is_volatile (cfg, def->sreg1)) {
                                                int vreg = def->sreg1;
-                                               //printf ("CCOPY: R%d -> R%d\n", sreg, vreg);
+                                               if (cfg->verbose_level > 2) printf ("CCOPY: R%d -> R%d\n", sreg, vreg);
                                                ins->dreg = vreg;
                                        }
                                }
@@ -130,9 +131,9 @@ restart:
                        num_sregs = mono_inst_get_src_registers (ins, sregs);
                        for (srcindex = 0; srcindex < num_sregs; ++srcindex) {
                                MonoInst *def;
-                               int nsregs;
+                               int nregs;
 
-                               nsregs = mono_inst_get_src_registers (ins, sregs);
+                               nregs = mono_inst_get_src_registers (ins, sregs);
 
                                regtype = spec [MONO_INST_SRC1 + srcindex];
                                sreg = sregs [srcindex];
@@ -170,7 +171,7 @@ restart:
                                        (def->opcode != OP_FMOVE)) {
                                        int vreg = def->sreg1;
 
-                                       //printf ("CCOPY: R%d -> R%d\n", sreg, vreg);
+                                       if (cfg->verbose_level > 2) printf ("CCOPY/2: R%d -> R%d\n", sreg, vreg);
                                        sregs [srcindex] = vreg;
                                        mono_inst_set_src_registers (ins, sregs);
 
@@ -257,10 +258,10 @@ restart:
                                                ins->inst_basereg = def->sreg1;
                                                ins->inst_offset += def->inst_imm;
                                        }
-                               } else if ((ins->opcode == OP_ISUB_IMM) && (def->opcode == OP_IADD_IMM) && (def->next == ins)) {
+                               } else if ((ins->opcode == OP_ISUB_IMM) && (def->opcode == OP_IADD_IMM) && (def->next == ins) && (def->dreg != def->sreg1)) {
                                        ins->sreg1 = def->sreg1;
                                        ins->inst_imm -= def->inst_imm;
-                               } else if ((ins->opcode == OP_IADD_IMM) && (def->opcode == OP_ISUB_IMM) && (def->next == ins)) {
+                               } else if ((ins->opcode == OP_IADD_IMM) && (def->opcode == OP_ISUB_IMM) && (def->next == ins) && (def->dreg != def->sreg1)) {
                                        ins->sreg1 = def->sreg1;
                                        ins->inst_imm -= def->inst_imm;
                                } else if (ins->opcode == OP_STOREI1_MEMBASE_REG &&
@@ -429,6 +430,30 @@ reg_is_softreg (int reg, const char spec)
                || (spec == 'v');
 }
 
+static inline gboolean
+mono_is_simd_accessor (MonoInst *ins)
+{
+       switch (ins->opcode) {
+#ifdef MONO_ARCH_SIMD_INTRINSICS
+       case OP_INSERT_I1:
+       case OP_INSERT_I2:
+       case OP_INSERT_I4:
+       case OP_INSERT_I8:
+       case OP_INSERT_R4:
+       case OP_INSERT_R8:
+
+       case OP_INSERTX_U1_SLOW:
+       case OP_INSERTX_I4_SLOW:
+       case OP_INSERTX_R4_SLOW:
+       case OP_INSERTX_R8_SLOW:
+       case OP_INSERTX_I8_SLOW:
+               return TRUE;
+#endif
+       default:
+               return FALSE;
+       }
+}
+
 /**
  * mono_local_deadce:
  *
@@ -508,7 +533,7 @@ mono_local_deadce (MonoCompile *cfg)
                                 * This isn't copyprop, not deadce, but it can only be performed
                                 * after handle_global_vregs () has run.
                                 */
-                               if (!get_vreg_to_inst (cfg, ins->sreg1) && (spec2 [MONO_INST_DEST] != ' ') && (def->dreg == ins->sreg1) && !mono_bitset_test_fast (used, ins->sreg1) && !MONO_IS_STORE_MEMBASE (def) && reg_is_softreg (ins->sreg1, spec [MONO_INST_DEST])) {
+                               if (!get_vreg_to_inst (cfg, ins->sreg1) && (spec2 [MONO_INST_DEST] != ' ') && (def->dreg == ins->sreg1) && !mono_bitset_test_fast (used, ins->sreg1) && !MONO_IS_STORE_MEMBASE (def) && reg_is_softreg (ins->sreg1, spec [MONO_INST_DEST]) && !mono_is_simd_accessor (def)) {
                                        if (cfg->verbose_level > 2) {
                                                printf ("\tReverse copyprop in BB%d on ", bb->block_num);
                                                mono_print_ins (ins);