X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Flocal-propagation.c;h=3c76408f3e44ce31d0e4869c3e51aec8ba7549be;hb=430ebd1982d79a85e58be0dad04c42249b65cf56;hp=06464d1a666b7b3141706de8b7e7281e752b2663;hpb=a5e40870bd3bb18e1681afed6c71e7edfdb80534;p=mono.git diff --git a/mono/mini/local-propagation.c b/mono/mini/local-propagation.c index 06464d1a666..3c76408f3e4 100644 --- a/mono/mini/local-propagation.c +++ b/mono/mini/local-propagation.c @@ -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_VOID_P == 4 +#if SIZEOF_REGISTER == 4 defs [ins->dreg + 1] = NULL; #endif } - if ((ins->sreg1 != -1) && (ins->sreg1 < max)) { - defs [ins->sreg1] = NULL; -#if SIZEOF_VOID_P == 4 - defs [ins->sreg1 + 1] = NULL; -#endif - } - if ((ins->sreg2 != -1) && (ins->sreg2 < max)) { - defs [ins->sreg2] = NULL; -#if SIZEOF_VOID_P == 4 - defs [ins->sreg2 + 1] = 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 [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); @@ -117,17 +121,21 @@ 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; } } } - 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; - regtype = srcindex == 0 ? spec [MONO_INST_SRC1] : spec [MONO_INST_SRC2]; - sreg = srcindex == 0 ? ins->sreg1 : ins->sreg2; + nsregs = mono_inst_get_src_registers (ins, sregs); + + regtype = spec [MONO_INST_SRC1 + srcindex]; + sreg = sregs [srcindex]; if ((regtype == ' ') || (sreg == -1) || (!defs [sreg])) continue; @@ -162,11 +170,9 @@ restart: (def->opcode != OP_FMOVE)) { int vreg = def->sreg1; - //printf ("CCOPY: R%d -> R%d\n", sreg, vreg); - if (srcindex == 0) - ins->sreg1 = vreg; - else - ins->sreg2 = 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); /* 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 @@ -253,19 +257,19 @@ 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 && - (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; @@ -286,7 +290,7 @@ restart: case OP_IADD_IMM: case OP_SUB_IMM: case OP_ISUB_IMM: -#if SIZEOF_VOID_P == 8 +#if SIZEOF_REGISTER == 8 case OP_LADD_IMM: case OP_LSUB_IMM: #endif @@ -297,7 +301,7 @@ restart: break; case OP_MUL_IMM: case OP_IMUL_IMM: -#if SIZEOF_VOID_P == 8 +#if SIZEOF_REGISTER == 8 case OP_LMUL_IMM: #endif if (ins->inst_imm == 0) { @@ -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,26 +457,23 @@ 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); mono_bitset_clear_fast (defined, ins->dreg); -#if SIZEOF_VOID_P == 4 +#if SIZEOF_REGISTER == 4 /* Regpairs */ mono_bitset_clear_fast (used, ins->dreg + 1); mono_bitset_clear_fast (defined, ins->dreg + 1); #endif } - if (spec [MONO_INST_SRC1] != ' ') { - mono_bitset_clear_fast (used, ins->sreg1); -#if SIZEOF_VOID_P == 4 - mono_bitset_clear_fast (used, ins->sreg1 + 1); -#endif - } - if (spec [MONO_INST_SRC2] != ' ') { - mono_bitset_clear_fast (used, ins->sreg2); -#if SIZEOF_VOID_P == 4 - mono_bitset_clear_fast (used, ins->sreg2 + 1); + 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, 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);