X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Flocal-propagation.c;h=29261596d93d71fd414aefac8369d43e5ffcc76e;hb=1d5f1c4760fc206f1a927e4f6066a8d97a0af901;hp=9811fc962bf9d89189d78189220ac7607dc06e29;hpb=6f2b5cd69f33daad2303e46311e7333239dadfdc;p=mono.git diff --git a/mono/mini/local-propagation.c b/mono/mini/local-propagation.c index 9811fc962bf..29261596d93 100644 --- a/mono/mini/local-propagation.c +++ b/mono/mini/local-propagation.c @@ -9,8 +9,11 @@ * Massimiliano Mantione (massi@ximian.com) * * (C) 2006 Novell, Inc. http://www.novell.com + * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) */ +#include +#ifndef DISABLE_JIT #include #include @@ -50,6 +53,7 @@ mono_local_cprop (MonoCompile *cfg) MonoInst **defs; gint32 *def_index; int max; + int filter = FILTER_IL_SEQ_POINT; restart: @@ -121,7 +125,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 +134,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]; @@ -165,12 +169,12 @@ restart: !vreg_is_volatile (cfg, def->sreg1) && /* This avoids propagating local vregs across calls */ ((get_vreg_to_inst (cfg, def->sreg1) || !defs [def->sreg1] || (def_index [def->sreg1] >= last_call_index) || (def->opcode == OP_VMOVE))) && - !(defs [def->sreg1] && defs [def->sreg1]->next == def) && + !(defs [def->sreg1] && mono_inst_next (defs [def->sreg1], filter) == def) && (!MONO_ARCH_USE_FPSTACK || (def->opcode != OP_FMOVE)) && (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); @@ -227,7 +231,7 @@ 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_REGISTER == 8 /* FIXME: Use OP_PADD_IMM when the new JIT is done */ @@ -253,14 +257,14 @@ restart: * We have to guarantee that def->sreg1 haven't changed since def->dreg * was defined. cfg->frame_reg is assumed to remain constant. */ - if ((def->sreg1 == cfg->frame_reg) || ((def->next == ins) && (def->dreg != def->sreg1))) { + if ((def->sreg1 == cfg->frame_reg) || ((mono_inst_next (def, filter) == ins) && (def->dreg != def->sreg1))) { 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) && (mono_inst_next (def, filter) == 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) && (mono_inst_next (def, filter) == 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 +433,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: * @@ -485,6 +513,7 @@ mono_local_deadce (MonoCompile *cfg) const char *spec = INS_INFO (ins->opcode); int sregs [MONO_MAX_SRC_REGS]; int num_sregs, i; + MonoInst *prev_f = mono_inst_prev (ins, FILTER_NOP | FILTER_IL_SEQ_POINT); if (ins->opcode == OP_NOP) { MONO_DELETE_INS (bb, ins); @@ -493,13 +522,11 @@ mono_local_deadce (MonoCompile *cfg) g_assert (ins->opcode > MONO_CEE_LAST); - if (MONO_IS_NON_FP_MOVE (ins) && ins->prev) { + if (MONO_IS_NON_FP_MOVE (ins) && prev_f) { MonoInst *def; const char *spec2; - def = ins->prev; - while (def->prev && (def->opcode == OP_NOP)) - def = def->prev; + def = prev_f; spec2 = INS_INFO (def->opcode); /* @@ -508,7 +535,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); @@ -530,8 +557,8 @@ mono_local_deadce (MonoCompile *cfg) (!get_vreg_to_inst (cfg, ins->dreg) || (!bb->extended && !vreg_is_volatile (cfg, ins->dreg) && mono_bitset_test_fast (defined, ins->dreg))) && MONO_INS_HAS_NO_SIDE_EFFECT (ins)) { /* Happens with CMOV instructions */ - if (ins->prev && ins->prev->opcode == OP_ICOMPARE_IMM) { - MonoInst *prev = ins->prev; + if (prev_f && prev_f->opcode == OP_ICOMPARE_IMM) { + MonoInst *prev = prev_f; /* * Can't use DELETE_INS since that would interfere with the * FOR_EACH_INS loop. @@ -586,3 +613,5 @@ mono_local_deadce (MonoCompile *cfg) //mono_print_code (cfg, "AFTER LOCAL-DEADCE"); } + +#endif /* DISABLE_JIT */