diff options
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r-- | gcc/gcse.c | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/gcc/gcse.c b/gcc/gcse.c index 69f12fae9e9..cd61170a97d 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -788,6 +788,17 @@ gcse_main (rtx f, FILE *file) during this pass. */ changed = one_cprop_pass (pass + 1, 0, 0); + /* APPLE LOCAL begin div by const */ + /* div by const optimization can introduce new instructions. + All this stuff needs to be recomputed. */ + free_gcse_mem (); + max_gcse_regno = max_reg_num (); + alloc_gcse_mem (f); + free_reg_set_mem (); + alloc_reg_set_mem (max_reg_num ()); + compute_sets (f); + /* APPLE LOCAL end div by const */ + if (optimize_size) changed |= one_classic_gcse_pass (pass + 1); else @@ -4204,6 +4215,64 @@ cprop_insn (rtx insn, int alter_jumps) if (INSN_DELETED_P (insn)) return 1; } + /* APPLE LOCAL begin div by const */ + /* Look for int div by constant and expand if found. */ + if ( GET_CODE (insn) == INSN + && GET_CODE (PATTERN (insn)) == SET + && ( GET_CODE (XEXP (PATTERN (insn), 1)) == DIV + || GET_CODE (XEXP (PATTERN (insn), 1)) == UDIV) + && GET_MODE (XEXP (PATTERN (insn), 1)) == SImode + && GET_CODE (XEXP (XEXP (PATTERN (insn), 1), 1)) == CONST_INT ) + { + rtx seq, result, target; + target = XEXP (PATTERN (insn), 0); + start_sequence (); + result = expand_divmod (0, TRUNC_DIV_EXPR, SImode, + XEXP (XEXP (PATTERN (insn), 1), 0), + XEXP (XEXP (PATTERN (insn), 1), 1), + target, + GET_CODE (XEXP (PATTERN (insn), 1))==DIV ? 0 : 1); + if ( result != target ) + emit_move_insn (target, result); + seq = get_insns (); + end_sequence (); + emit_insn_after (seq, insn); + PUT_CODE (insn, NOTE); + NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (insn) = 0; + update_bb_for_insn (BLOCK_FOR_INSN (insn)); + changed = 1; + break; + } + else if ( GET_CODE (insn) == INSN + && GET_CODE (PATTERN (insn)) == SET + && (note = find_reg_equal_equiv_note (insn)) + && (GET_CODE (XEXP (note, 0)) == DIV + || GET_CODE (XEXP (note, 0)) == UDIV) + && GET_MODE (XEXP (note, 0)) == SImode + && GET_CODE (XEXP (XEXP (note, 0), 1)) == CONST_INT ) + { + rtx seq, result, target; + target = XEXP (PATTERN (insn), 0); + start_sequence (); + result = expand_divmod (0, TRUNC_DIV_EXPR, SImode, + XEXP (XEXP (note, 0), 0), + XEXP (XEXP (note, 0), 1), + target, + GET_CODE (XEXP (note, 0))==DIV ? 0 : 1); + if ( result != target ) + emit_move_insn (target, result); + seq = get_insns (); + end_sequence (); + emit_insn_after (seq, insn); + PUT_CODE (insn, NOTE); + NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (insn) = 0; + update_bb_for_insn (BLOCK_FOR_INSN (insn)); + changed = 1; + break; + } + /* APPLE LOCAL end div by const */ } else if (GET_CODE (src) == REG && REGNO (src) >= FIRST_PSEUDO_REGISTER @@ -6070,7 +6139,7 @@ delete_null_pointer_checks_1 (unsigned int *block_reg, sbitmap *nonnull_avin, delete_insn (last_insn); #ifdef HAVE_cc0 if (compare_and_branch == 2) - delete_insn (earliest); + delete_insn (earliest); #endif purge_dead_edges (bb); |