Mercurial > hg > CbC > CbC_gcc
diff gcc/ifcvt.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | 3bfb6c00c1e0 |
children | b7f97abdc517 |
line wrap: on
line diff
--- a/gcc/ifcvt.c Sun Feb 07 18:28:00 2010 +0900 +++ b/gcc/ifcvt.c Fri Feb 12 23:39:51 2010 +0900 @@ -47,9 +47,6 @@ #include "vecprim.h" #include "dbgcnt.h" -#ifndef HAVE_conditional_execution -#define HAVE_conditional_execution 0 -#endif #ifndef HAVE_conditional_move #define HAVE_conditional_move 0 #endif @@ -62,9 +59,6 @@ #ifndef HAVE_trap #define HAVE_trap 0 #endif -#ifndef HAVE_conditional_trap -#define HAVE_conditional_trap 0 -#endif #ifndef MAX_CONDITIONAL_EXECUTE #define MAX_CONDITIONAL_EXECUTE \ @@ -197,7 +191,7 @@ insn = NEXT_INSN (insn); } - while (NOTE_P (insn)) + while (NOTE_P (insn) || DEBUG_INSN_P (insn)) { if (insn == BB_END (bb)) return NULL_RTX; @@ -220,6 +214,7 @@ while (NOTE_P (insn) || JUMP_P (insn) + || DEBUG_INSN_P (insn) || (skip_use_p && NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE)) @@ -272,7 +267,7 @@ for (insn = start; ; insn = NEXT_INSN (insn)) { - if (NOTE_P (insn)) + if (NOTE_P (insn) || DEBUG_INSN_P (insn)) goto insn_done; gcc_assert(NONJUMP_INSN_P (insn) || CALL_P (insn)); @@ -908,12 +903,12 @@ int reversep; rtx target, seq; - if (GET_CODE (if_info->b) == CONST_INT + if (CONST_INT_P (if_info->b) && INTVAL (if_info->b) == STORE_FLAG_VALUE && if_info->a == const0_rtx) reversep = 0; else if (if_info->b == const0_rtx - && GET_CODE (if_info->a) == CONST_INT + && CONST_INT_P (if_info->a) && INTVAL (if_info->a) == STORE_FLAG_VALUE && (reversed_comparison_code (if_info->cond, if_info->jump) != UNKNOWN)) @@ -955,8 +950,8 @@ int normalize, can_reverse; enum machine_mode mode; - if (GET_CODE (if_info->a) == CONST_INT - && GET_CODE (if_info->b) == CONST_INT) + if (CONST_INT_P (if_info->a) + && CONST_INT_P (if_info->b)) { mode = GET_MODE (if_info->x); ifalse = INTVAL (if_info->a); @@ -1331,11 +1326,15 @@ /* ??? FIXME: Magic number 5. */ if (cse_not_expected && MEM_P (a) && MEM_P (b) + && MEM_ADDR_SPACE (a) == MEM_ADDR_SPACE (b) && if_info->branch_cost >= 5) { + enum machine_mode address_mode + = targetm.addr_space.address_mode (MEM_ADDR_SPACE (a)); + a = XEXP (a, 0); b = XEXP (b, 0); - x = gen_reg_rtx (Pmode); + x = gen_reg_rtx (address_mode); is_mem = 1; } @@ -1484,6 +1483,9 @@ set_mem_align (tmp, MIN (MEM_ALIGN (if_info->a), MEM_ALIGN (if_info->b))); + gcc_assert (MEM_ADDR_SPACE (if_info->a) == MEM_ADDR_SPACE (if_info->b)); + set_mem_addr_space (tmp, MEM_ADDR_SPACE (if_info->a)); + noce_emit_move_insn (if_info->x, tmp); } else if (target != x) @@ -1541,7 +1543,7 @@ make equivalent types of changes) to get the constants we need if they're off by one in the right direction. */ - if (GET_CODE (target) == CONST_INT) + if (CONST_INT_P (target)) { enum rtx_code code = GET_CODE (if_info->cond); rtx op_a = XEXP (if_info->cond, 0); @@ -1558,14 +1560,14 @@ rtx src = find_reg_equal_equiv_note (prev_insn); if (!src) src = SET_SRC (PATTERN (prev_insn)); - if (GET_CODE (src) == CONST_INT) + if (CONST_INT_P (src)) { if (rtx_equal_p (op_a, SET_DEST (PATTERN (prev_insn)))) op_a = src; else if (rtx_equal_p (op_b, SET_DEST (PATTERN (prev_insn)))) op_b = src; - if (GET_CODE (op_a) == CONST_INT) + if (CONST_INT_P (op_a)) { rtx tmp = op_a; op_a = op_b; @@ -1577,7 +1579,7 @@ /* Now, look to see if we can get the right constant by adjusting the conditional. */ - if (GET_CODE (op_b) == CONST_INT) + if (CONST_INT_P (op_b)) { HOST_WIDE_INT desired_val = INTVAL (target); HOST_WIDE_INT actual_val = INTVAL (op_b); @@ -1746,13 +1748,16 @@ return TRUE; } -/* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", etc. */ +/* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", + "if (a < 0) x = ~a; else x = a;" to "x = one_cmpl_abs(a);", + etc. */ static int noce_try_abs (struct noce_if_info *if_info) { rtx cond, earliest, target, seq, a, b, c; int negate; + bool one_cmpl = false; /* Reject modes with signed zeros. */ if (HONOR_SIGNED_ZEROS (GET_MODE (if_info->x))) @@ -1770,6 +1775,17 @@ c = a; a = b; b = c; negate = 1; } + else if (GET_CODE (a) == NOT && rtx_equal_p (XEXP (a, 0), b)) + { + negate = 0; + one_cmpl = true; + } + else if (GET_CODE (b) == NOT && rtx_equal_p (XEXP (b, 0), a)) + { + c = a; a = b; b = c; + negate = 1; + one_cmpl = true; + } else return FALSE; @@ -1841,13 +1857,23 @@ } start_sequence (); - - target = expand_abs_nojump (GET_MODE (if_info->x), b, if_info->x, 1); + if (one_cmpl) + target = expand_one_cmpl_abs_nojump (GET_MODE (if_info->x), b, + if_info->x); + else + target = expand_abs_nojump (GET_MODE (if_info->x), b, if_info->x, 1); /* ??? It's a quandary whether cmove would be better here, especially for integers. Perhaps combine will clean things up. */ if (target && negate) - target = expand_simple_unop (GET_MODE (target), NEG, target, if_info->x, 0); + { + if (one_cmpl) + target = expand_simple_unop (GET_MODE (target), NOT, target, + if_info->x, 0); + else + target = expand_simple_unop (GET_MODE (target), NEG, target, + if_info->x, 0); + } if (! target) { @@ -1976,7 +2002,7 @@ if (GET_CODE (cond) == ZERO_EXTRACT) { if (XEXP (cond, 1) != const1_rtx - || GET_CODE (XEXP (cond, 2)) != CONST_INT + || !CONST_INT_P (XEXP (cond, 2)) || ! rtx_equal_p (x, XEXP (cond, 0))) return FALSE; bitnum = INTVAL (XEXP (cond, 2)); @@ -1994,7 +2020,7 @@ { /* Check for "if (X & C) x = x op C". */ if (! rtx_equal_p (x, XEXP (a, 0)) - || GET_CODE (XEXP (a, 1)) != CONST_INT + || !CONST_INT_P (XEXP (a, 1)) || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode)) != (unsigned HOST_WIDE_INT) 1 << bitnum) return FALSE; @@ -2020,7 +2046,7 @@ { /* Check for "if (X & C) x &= ~C". */ if (! rtx_equal_p (x, XEXP (a, 0)) - || GET_CODE (XEXP (a, 1)) != CONST_INT + || !CONST_INT_P (XEXP (a, 1)) || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode)) != (~((HOST_WIDE_INT) 1 << bitnum) & GET_MODE_MASK (mode))) return FALSE; @@ -2145,7 +2171,7 @@ addr = XEXP (addr, 1); break; case PLUS: - if (GET_CODE (XEXP (addr, 1)) == CONST_INT) + if (CONST_INT_P (XEXP (addr, 1))) addr = XEXP (addr, 0); else return false; @@ -2259,6 +2285,8 @@ else { insn_b = prev_nonnote_insn (if_info->cond_earliest); + while (insn_b && DEBUG_INSN_P (insn_b)) + insn_b = prev_nonnote_insn (insn_b); /* We're going to be moving the evaluation of B down from above COND_EARLIEST to JUMP. Make sure the relevant data is still intact. */ @@ -2269,14 +2297,13 @@ || ! rtx_equal_p (x, SET_DEST (set_b)) || ! noce_operand_ok (SET_SRC (set_b)) || reg_overlap_mentioned_p (x, SET_SRC (set_b)) - || modified_between_p (SET_SRC (set_b), - PREV_INSN (if_info->cond_earliest), jump) + || modified_between_p (SET_SRC (set_b), insn_b, jump) /* Likewise with X. In particular this can happen when noce_get_condition looks farther back in the instruction stream than one might expect. */ || reg_overlap_mentioned_p (x, cond) || reg_overlap_mentioned_p (x, a) - || modified_between_p (x, PREV_INSN (if_info->cond_earliest), jump)) + || modified_between_p (x, insn_b, jump)) insn_b = set_b = NULL_RTX; } @@ -2301,8 +2328,8 @@ return FALSE; if (GET_CODE (x) == ZERO_EXTRACT - && (GET_CODE (XEXP (x, 1)) != CONST_INT - || GET_CODE (XEXP (x, 2)) != CONST_INT)) + && (!CONST_INT_P (XEXP (x, 1)) + || !CONST_INT_P (XEXP (x, 2)))) return FALSE; x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART @@ -2396,7 +2423,7 @@ if (HAVE_conditional_move && noce_try_cmove (if_info)) goto success; - if (! HAVE_conditional_execution) + if (! targetm.have_conditional_execution ()) { if (noce_try_store_flag_constants (if_info)) goto success; @@ -2484,7 +2511,7 @@ { rtx set, dest, src; - if (!INSN_P (insn) || JUMP_P (insn)) + if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn)) continue; set = single_set (insn); if (!set) @@ -2562,7 +2589,8 @@ rtx set, target, dest, t, e; unsigned int regno; - if (!INSN_P (insn) || JUMP_P (insn)) + /* ??? Maybe emit conditional debug insn? */ + if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn)) continue; set = single_set (insn); gcc_assert (set && REG_P (SET_DEST (set))); @@ -3039,16 +3067,17 @@ && noce_find_if_block (test_bb, then_edge, else_edge, pass)) goto success; - if (HAVE_conditional_execution && reload_completed + if (targetm.have_conditional_execution () && reload_completed && cond_exec_find_if_block (&ce_info)) goto success; - if (HAVE_trap && HAVE_conditional_trap + if (HAVE_trap + && optab_handler (ctrap_optab, word_mode)->insn_code != CODE_FOR_nothing && find_cond_trap (test_bb, then_edge, else_edge)) goto success; if (dom_info_state (CDI_POST_DOMINATORS) >= DOM_NO_FAST_QUERY - && (! HAVE_conditional_execution || reload_completed)) + && (! targetm.have_conditional_execution () || reload_completed)) { if (find_if_case_1 (test_bb, then_edge, else_edge)) goto success; @@ -3122,6 +3151,7 @@ if (INSN_P (insn) && !JUMP_P (insn) + && !DEBUG_INSN_P (insn) && GET_CODE (PATTERN (insn)) != USE && GET_CODE (PATTERN (insn)) != CLOBBER) n_insns++; @@ -3154,7 +3184,7 @@ /* We only ever should get here after reload, and only if we have conditional execution. */ - gcc_assert (HAVE_conditional_execution && reload_completed); + gcc_assert (targetm.have_conditional_execution () && reload_completed); /* Discover if any fall through predecessors of the current test basic block were && tests (which jump to the else block) or || tests (which jump to @@ -3735,7 +3765,7 @@ test_bb->index, else_bb->index); /* ELSE is small. */ - if (! cheap_bb_rtx_cost_p (else_bb, + if (! cheap_bb_rtx_cost_p (else_bb, COSTS_N_INSNS (BRANCH_COST (optimize_bb_for_speed_p (else_edge->src), predictable_edge_p (else_edge))))) return FALSE; @@ -3782,6 +3812,8 @@ basic_block other_bb, basic_block new_dest, int reversep) { rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX; + /* Number of pending changes. */ + int n_validated_changes = 0; jump = BB_END (test_bb); @@ -3789,6 +3821,9 @@ head = BB_HEAD (merge_bb); end = BB_END (merge_bb); + while (DEBUG_INSN_P (end) && end != head) + end = PREV_INSN (end); + /* If merge_bb ends with a tablejump, predicating/moving insn's into test_bb and then deleting merge_bb will result in the jumptable that follows merge_bb being removed along with merge_bb and then we @@ -3798,6 +3833,8 @@ if (LABEL_P (head)) head = NEXT_INSN (head); + while (DEBUG_INSN_P (head) && head != end) + head = NEXT_INSN (head); if (NOTE_P (head)) { if (head == end) @@ -3806,6 +3843,8 @@ goto no_body; } head = NEXT_INSN (head); + while (DEBUG_INSN_P (head) && head != end) + head = NEXT_INSN (head); } if (JUMP_P (end)) @@ -3816,12 +3855,14 @@ goto no_body; } end = PREV_INSN (end); + while (DEBUG_INSN_P (end) && end != head) + end = PREV_INSN (end); } /* Disable handling dead code by conditional execution if the machine needs to do anything funny with the tests, etc. */ #ifndef IFCVT_MODIFY_TESTS - if (HAVE_conditional_execution) + if (targetm.have_conditional_execution ()) { /* In the conditional execution case, we have things easy. We know the condition is reversible. We don't have to check life info @@ -3850,14 +3891,17 @@ prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (prob_val)); } - if (! cond_exec_process_insns ((ce_if_block_t *)0, head, end, cond, - prob_val, 0)) - goto cancel; + if (cond_exec_process_insns (NULL, head, end, cond, prob_val, 0) + && verify_changes (0)) + n_validated_changes = num_validated_changes (); + else + cancel_changes (0); earliest = jump; } - else #endif + /* Try the NCE path if the CE path did not result in any changes. */ + if (n_validated_changes == 0) { /* In the non-conditional execution case, we have to verify that there are no trapping operations, no calls, no references to memory, and @@ -3873,7 +3917,7 @@ { if (CALL_P (insn)) return FALSE; - if (INSN_P (insn)) + if (NONDEBUG_INSN_P (insn)) { if (may_trap_p (PATTERN (insn))) return FALSE; @@ -3919,7 +3963,7 @@ FOR_BB_INSNS (merge_bb, insn) { - if (INSN_P (insn)) + if (NONDEBUG_INSN_P (insn)) { unsigned int uid = INSN_UID (insn); df_ref *def_rec; @@ -3943,11 +3987,11 @@ fail = 1; } } - + /* For TEST, we're interested in a range of insns, not a whole block. Moreover, we're interested in the insns live from OTHER_BB. */ - - /* The loop below takes the set of live registers + + /* The loop below takes the set of live registers after JUMP, and calculates the live set before EARLIEST. */ bitmap_copy (test_live, df_get_live_in (other_bb)); df_simulate_initialize_backwards (test_bb, test_live); @@ -3997,8 +4041,10 @@ goto cancel; } - if (! apply_change_group ()) - return FALSE; + if (verify_changes (n_validated_changes)) + confirm_change_group (); + else + goto cancel; if (other_bb != new_dest) { @@ -4040,8 +4086,7 @@ if (! note) continue; set = single_set (insn); - if (!set || !function_invariant_p (SET_SRC (set)) - || !function_invariant_p (XEXP (note, 0))) + if (!set || !function_invariant_p (SET_SRC (set))) remove_note (insn, note); } while (insn != end && (insn = NEXT_INSN (insn))); @@ -4112,19 +4157,14 @@ FOR_EACH_BB (bb) { basic_block new_bb; - while (!df_get_bb_dirty (bb) + while (!df_get_bb_dirty (bb) && (new_bb = find_if_header (bb, pass)) != NULL) bb = new_bb; } #ifdef IFCVT_MULTIPLE_DUMPS if (dump_file && cond_exec_changed_p) - { - if (dump_flags & TDF_SLIM) - print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags); - else - print_rtl_with_bb (dump_file, get_insns ()); - } + print_rtl_with_bb (dump_file, get_insns ()); #endif } while (cond_exec_changed_p);