2009-05-11 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / local-propagation.c
index ccb7858ebd3480f1559ba1291fea6b588b5b2768..51bc65a0c15ca261976ac265fbb801f5cd33192e 100644 (file)
@@ -64,23 +64,25 @@ restart:
 
                /* Manually init the defs entries used by the bblock */
                MONO_BB_FOR_EACH_INS (bb, ins) {
+                       int sregs [MONO_MAX_SRC_REGS];
+                       int num_sregs, i;
+
                        if ((ins->dreg != -1) && (ins->dreg < max)) {
                                defs [ins->dreg] = NULL;
 #if SIZEOF_REGISTER == 4
                                defs [ins->dreg + 1] = NULL;
 #endif
                        }
-                       if ((ins->sreg1 != -1) && (ins->sreg1 < max)) {
-                               defs [ins->sreg1] = NULL;
-#if SIZEOF_REGISTER == 4
-                               defs [ins->sreg1 + 1] = NULL;
-#endif
-                       }
-                       if ((ins->sreg2 != -1) && (ins->sreg2 < max)) {
-                               defs [ins->sreg2] = NULL;
+
+                       num_sregs = mono_inst_get_src_registers (ins, sregs);
+                       for (i = 0; i < num_sregs; ++i) {
+                               int sreg = sregs [i];
+                               if (sreg < max) {
+                                       defs [sreg] = NULL;
 #if SIZEOF_REGISTER == 4
-                               defs [ins->sreg2 + 1] = NULL;
+                                       defs [sreg + 1] = NULL;
 #endif
+                               }
                        }
                }
 
@@ -89,6 +91,8 @@ restart:
                MONO_BB_FOR_EACH_INS (bb, ins) {
                        const char *spec = INS_INFO (ins->opcode);
                        int regtype, srcindex, sreg;
+                       int num_sregs;
+                       int sregs [MONO_MAX_SRC_REGS];
 
                        if (ins->opcode == OP_NOP) {
                                MONO_DELETE_INS (bb, ins);
@@ -123,11 +127,15 @@ restart:
                                }
                        }
 
-                       for (srcindex = 0; srcindex < 2; ++srcindex) {
+                       num_sregs = mono_inst_get_src_registers (ins, sregs);
+                       for (srcindex = 0; srcindex < num_sregs; ++srcindex) {
                                MonoInst *def;
+                               int nsregs;
+
+                               nsregs = mono_inst_get_src_registers (ins, sregs);
 
-                               regtype = srcindex == 0 ? spec [MONO_INST_SRC1] : spec [MONO_INST_SRC2];
-                               sreg = srcindex == 0 ? ins->sreg1 : ins->sreg2;
+                               regtype = spec [MONO_INST_SRC1 + srcindex];
+                               sreg = sregs [srcindex];
 
                                if ((regtype == ' ') || (sreg == -1) || (!defs [sreg]))
                                        continue;
@@ -163,10 +171,8 @@ restart:
                                        int vreg = def->sreg1;
 
                                        //printf ("CCOPY: R%d -> R%d\n", sreg, vreg);
-                                       if (srcindex == 0)
-                                               ins->sreg1 = vreg;
-                                       else
-                                               ins->sreg2 = vreg;
+                                       sregs [srcindex] = vreg;
+                                       mono_inst_set_src_registers (ins, sregs);
 
                                        /* Allow further iterations */
                                        srcindex = -1;
@@ -209,10 +215,8 @@ restart:
                                                } else {
                                                        ins->inst_imm = def->inst_c0;
                                                }
-                                               if (srcindex == 0)
-                                                       ins->sreg1 = -1;
-                                               else
-                                                       ins->sreg2 = -1;
+                                               sregs [srcindex] = -1;
+                                               mono_inst_set_src_registers (ins, sregs);
 
                                                if ((opcode2 == OP_VOIDCALL) || (opcode2 == OP_CALL) || (opcode2 == OP_LCALL) || (opcode2 == OP_FCALL))
                                                        ((MonoCallInst*)ins)->fptr = (gpointer)ins->inst_imm;
@@ -223,9 +227,9 @@ restart:
                                        }
                                        else {
                                                /* Special cases */
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(TARGET_X86) || defined(TARGET_AMD64)
                                                if ((ins->opcode == OP_X86_LEA) && (srcindex == 1)) {
-#if SIZEOF_VOID_P == 8
+#if SIZEOF_REGISTER == 8
                                                        /* FIXME: Use OP_PADD_IMM when the new JIT is done */
                                                        ins->opcode = OP_LADD_IMM;
 #else
@@ -260,12 +264,12 @@ restart:
                                        ins->sreg1 = def->sreg1;
                                        ins->inst_imm -= def->inst_imm;
                                } else if (ins->opcode == OP_STOREI1_MEMBASE_REG &&
-                                                  (def->opcode == OP_ICONV_TO_U1 || def->opcode == OP_ICONV_TO_I1 || def->opcode == OP_SEXT_I4 || (SIZEOF_VOID_P == 8 && def->opcode == OP_LCONV_TO_U1)) &&
+                                                  (def->opcode == OP_ICONV_TO_U1 || def->opcode == OP_ICONV_TO_I1 || def->opcode == OP_SEXT_I4 || (SIZEOF_REGISTER == 8 && def->opcode == OP_LCONV_TO_U1)) &&
                                                   (!defs [def->sreg1] || (def_index [def->sreg1] < def_index [sreg]))) {
                                        /* Avoid needless sign extension */
                                        ins->sreg1 = def->sreg1;
                                } else if (ins->opcode == OP_STOREI2_MEMBASE_REG &&
-                                                  (def->opcode == OP_ICONV_TO_U2 || def->opcode == OP_ICONV_TO_I2 || def->opcode == OP_SEXT_I4 || (SIZEOF_VOID_P == 8 && def->opcode == OP_LCONV_TO_I2)) &&
+                                                  (def->opcode == OP_ICONV_TO_U2 || def->opcode == OP_ICONV_TO_I2 || def->opcode == OP_SEXT_I4 || (SIZEOF_REGISTER == 8 && def->opcode == OP_LCONV_TO_I2)) &&
                                                   (!defs [def->sreg1] || (def_index [def->sreg1] < def_index [sreg]))) {
                                        /* Avoid needless sign extension */
                                        ins->sreg1 = def->sreg1;
@@ -406,10 +410,10 @@ restart:
 static inline gboolean
 reg_is_softreg_no_fpstack (int reg, const char spec)
 {
-       return (spec == 'i' && reg > MONO_MAX_IREGS)
-               || ((spec == 'f' && reg > MONO_MAX_FREGS) && !MONO_ARCH_USE_FPSTACK)
+       return (spec == 'i' && reg >= MONO_MAX_IREGS)
+               || ((spec == 'f' && reg >= MONO_MAX_FREGS) && !MONO_ARCH_USE_FPSTACK)
 #ifdef MONO_ARCH_SIMD_INTRINSICS
-               || (spec == 'x' && reg > MONO_MAX_XREGS)
+               || (spec == 'x' && reg >= MONO_MAX_XREGS)
 #endif
                || (spec == 'v');
 }
@@ -417,10 +421,10 @@ reg_is_softreg_no_fpstack (int reg, const char spec)
 static inline gboolean
 reg_is_softreg (int reg, const char spec)
 {
-       return (spec == 'i' && reg > MONO_MAX_IREGS)
-               || (spec == 'f' && reg > MONO_MAX_FREGS)
+       return (spec == 'i' && reg >= MONO_MAX_IREGS)
+               || (spec == 'f' && reg >= MONO_MAX_FREGS)
 #ifdef MONO_ARCH_SIMD_INTRINSICS
-               || (spec == 'x' && reg > MONO_MAX_XREGS)
+               || (spec == 'x' && reg >= MONO_MAX_XREGS)
 #endif
                || (spec == 'v');
 }
@@ -453,6 +457,8 @@ mono_local_deadce (MonoCompile *cfg)
                /* Manually init the defs entries used by the bblock */
                MONO_BB_FOR_EACH_INS (bb, ins) {
                        const char *spec = INS_INFO (ins->opcode);
+                       int sregs [MONO_MAX_SRC_REGS];
+                       int num_sregs, i;
 
                        if (spec [MONO_INST_DEST] != ' ') {
                                mono_bitset_clear_fast (used, ins->dreg);
@@ -463,16 +469,11 @@ mono_local_deadce (MonoCompile *cfg)
                                mono_bitset_clear_fast (defined, ins->dreg + 1);
 #endif
                        }
-                       if (spec [MONO_INST_SRC1] != ' ') {
-                               mono_bitset_clear_fast (used, ins->sreg1);
-#if SIZEOF_REGISTER == 4
-                               mono_bitset_clear_fast (used, ins->sreg1 + 1);
-#endif
-                       }
-                       if (spec [MONO_INST_SRC2] != ' ') {
-                               mono_bitset_clear_fast (used, ins->sreg2);
+                       num_sregs = mono_inst_get_src_registers (ins, sregs);
+                       for (i = 0; i < num_sregs; ++i) {
+                               mono_bitset_clear_fast (used, sregs [i]);
 #if SIZEOF_REGISTER == 4
-                               mono_bitset_clear_fast (used, ins->sreg2 + 1);
+                               mono_bitset_clear_fast (used, sregs [i] + 1);
 #endif
                        }
                }
@@ -482,6 +483,8 @@ mono_local_deadce (MonoCompile *cfg)
                 */
                MONO_BB_FOR_EACH_INS_REVERSE_SAFE (bb, prev, ins) {
                        const char *spec = INS_INFO (ins->opcode);
+                       int sregs [MONO_MAX_SRC_REGS];
+                       int num_sregs, i;
 
                        if (ins->opcode == OP_NOP) {
                                MONO_DELETE_INS (bb, ins);
@@ -546,10 +549,9 @@ mono_local_deadce (MonoCompile *cfg)
 
                        if (spec [MONO_INST_DEST] != ' ')
                                mono_bitset_set_fast (defined, ins->dreg);
-                       if (spec [MONO_INST_SRC1] != ' ')
-                               mono_bitset_set_fast (used, ins->sreg1);
-                       if (spec [MONO_INST_SRC2] != ' ')
-                               mono_bitset_set_fast (used, ins->sreg2);
+                       num_sregs = mono_inst_get_src_registers (ins, sregs);
+                       for (i = 0; i < num_sregs; ++i)
+                               mono_bitset_set_fast (used, sregs [i]);
                        if (MONO_IS_STORE_MEMBASE (ins))
                                mono_bitset_set_fast (used, ins->dreg);