X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fpredict.c;h=961a39526a15c3f6ec185c011240597892c73156;hb=ffca001431383db73c1c827b614283aaf6a9c832;hp=432e8373f3886f5c8020923501bccfc176d2a535;hpb=aa157ca4880738c17313f153d131c0a7bb65163b;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/predict.c b/gcc/predict.c index 432e8373f38..961a39526a1 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -1,5 +1,6 @@ /* Branch prediction routines for the GNU compiler. - Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 + Free Software Foundation, Inc. This file is part of GCC. @@ -66,7 +67,7 @@ static sreal real_zero, real_one, real_almost_one, real_br_prob_base, real_inv_br_prob_base, real_one_half, real_bb_freq_max; /* Random guesstimation given names. */ -#define PROB_VERY_UNLIKELY (REG_BR_PROB_BASE / 10 - 1) +#define PROB_VERY_UNLIKELY (REG_BR_PROB_BASE / 100 - 1) #define PROB_EVEN (REG_BR_PROB_BASE / 2) #define PROB_VERY_LIKELY (REG_BR_PROB_BASE - PROB_VERY_UNLIKELY) #define PROB_ALWAYS (REG_BR_PROB_BASE) @@ -180,8 +181,7 @@ tree_predicted_by_p (basic_block bb, enum br_predictor predictor) static void predict_insn (rtx insn, enum br_predictor predictor, int probability) { - if (!any_condjump_p (insn)) - abort (); + gcc_assert (any_condjump_p (insn)); if (!flag_guess_branch_prob) return; @@ -433,14 +433,14 @@ combine_predictions_for_insn (rtx insn, basic_block bb) /* Save the prediction into CFG in case we are seeing non-degenerated conditional jump. */ - if (EDGE_COUNT (bb->succs) > 1) + if (!single_succ_p (bb)) { BRANCH_EDGE (bb)->probability = combined_probability; FALLTHRU_EDGE (bb)->probability = REG_BR_PROB_BASE - combined_probability; } } - else if (EDGE_COUNT (bb->succs) > 1) + else if (!single_succ_p (bb)) { int prob = INTVAL (XEXP (prob_note, 0)); @@ -448,7 +448,7 @@ combine_predictions_for_insn (rtx insn, basic_block bb) FALLTHRU_EDGE (bb)->probability = REG_BR_PROB_BASE - prob; } else - EDGE_SUCC (bb, 0)->probability = REG_BR_PROB_BASE; + single_succ_edge (bb)->probability = REG_BR_PROB_BASE; } /* Combine predictions into single probability and store them into CFG. @@ -582,13 +582,13 @@ predict_loops (struct loops *loops_info, bool rtlsimpleloops) { basic_block bb, *bbs; unsigned j; - int exits; + unsigned n_exits; struct loop *loop = loops_info->parray[i]; struct niter_desc desc; unsigned HOST_WIDE_INT niter; + edge *exits; - flow_loop_scan (loop, LOOP_EXIT_EDGES); - exits = loop->num_exits; + exits = get_loop_exit_edges (loop, &n_exits); if (rtlsimpleloops) { @@ -614,11 +614,8 @@ predict_loops (struct loops *loops_info, bool rtlsimpleloops) } else { - edge *exits; - unsigned j, n_exits; struct tree_niter_desc niter_desc; - exits = get_loop_exit_edges (loop, &n_exits); for (j = 0; j < n_exits; j++) { tree niter = NULL; @@ -646,8 +643,8 @@ predict_loops (struct loops *loops_info, bool rtlsimpleloops) } } - free (exits); } + free (exits); bbs = get_loop_body (loop); @@ -669,13 +666,15 @@ predict_loops (struct loops *loops_info, bool rtlsimpleloops) /* Loop branch heuristics - predict an edge back to a loop's head as taken. */ - FOR_EACH_EDGE (e, ei, bb->succs) - if (e->dest == loop->header - && e->src == loop->latch) - { - header_found = 1; - predict_edge_def (e, PRED_LOOP_BRANCH, TAKEN); - } + if (bb == loop->latch) + { + e = find_edge (loop->latch, loop->header); + if (e) + { + header_found = 1; + predict_edge_def (e, PRED_LOOP_BRANCH, TAKEN); + } + } /* Loop exit heuristics - predict an edge exiting the loop if the conditional has no loop header successors as not taken. */ @@ -687,7 +686,7 @@ predict_loops (struct loops *loops_info, bool rtlsimpleloops) (e, PRED_LOOP_EXIT, (REG_BR_PROB_BASE - predictor_info [(int) PRED_LOOP_EXIT].hitrate) - / exits); + / n_exits); } /* Free basic blocks from get_loop_body. */ @@ -695,7 +694,10 @@ predict_loops (struct loops *loops_info, bool rtlsimpleloops) } if (!rtlsimpleloops) - scev_finalize (); + { + scev_finalize (); + current_loops = NULL; + } } /* Attempt to predict probabilities of BB outgoing edges using local @@ -830,8 +832,8 @@ estimate_probability (struct loops *loops_info) care for error returns and other are often used for fast paths trought function. */ if ((e->dest == EXIT_BLOCK_PTR - || (EDGE_COUNT (e->dest->succs) == 1 - && EDGE_SUCC (e->dest, 0)->dest == EXIT_BLOCK_PTR)) + || (single_succ_p (e->dest) + && single_succ (e->dest) == EXIT_BLOCK_PTR)) && !predicted_by_p (bb, PRED_NULL_RETURN) && !predicted_by_p (bb, PRED_CONST_RETURN) && !predicted_by_p (bb, PRED_NEGATIVE_RETURN) @@ -945,7 +947,8 @@ expr_expected_value (tree expr, bitmap visited) tree decl = get_callee_fndecl (expr); if (!decl) return NULL; - if (DECL_BUILT_IN (decl) && DECL_FUNCTION_CODE (decl) == BUILT_IN_EXPECT) + if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL + && DECL_FUNCTION_CODE (decl) == BUILT_IN_EXPECT) { tree arglist = TREE_OPERAND (expr, 1); tree val; @@ -1004,13 +1007,13 @@ strip_builtin_expect (void) if (TREE_CODE (stmt) == MODIFY_EXPR && TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR && (fndecl = get_callee_fndecl (TREE_OPERAND (stmt, 1))) - && DECL_BUILT_IN (fndecl) + && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT && (arglist = TREE_OPERAND (TREE_OPERAND (stmt, 1), 1)) && TREE_CHAIN (arglist)) { TREE_OPERAND (stmt, 1) = TREE_VALUE (arglist); - modify_stmt (stmt); + update_stmt (stmt); } } } @@ -1039,9 +1042,9 @@ tree_predict_by_opcode (basic_block bb) return; op0 = TREE_OPERAND (cond, 0); type = TREE_TYPE (op0); - visited = BITMAP_XMALLOC (); + visited = BITMAP_ALLOC (NULL); val = expr_expected_value (cond, visited); - BITMAP_XFREE (visited); + BITMAP_FREE (visited); if (val) { if (integer_zerop (val)) @@ -1206,14 +1209,9 @@ apply_return_prediction (int *heads) || !SSA_NAME_DEF_STMT (return_val) || TREE_CODE (SSA_NAME_DEF_STMT (return_val)) != PHI_NODE) return; - phi = SSA_NAME_DEF_STMT (return_val); - while (phi) - { - tree next = PHI_CHAIN (phi); - if (PHI_RESULT (phi) == return_val) - break; - phi = next; - } + for (phi = SSA_NAME_DEF_STMT (return_val); phi; phi = PHI_CHAIN (phi)) + if (PHI_RESULT (phi) == return_val) + break; if (!phi) return; phi_num_args = PHI_NUM_ARGS (phi); @@ -1289,7 +1287,7 @@ tree_estimate_probability (void) basic_block bb; struct loops loops_info; - flow_loops_find (&loops_info, LOOP_TREE); + flow_loops_find (&loops_info); if (dump_file && (dump_flags & TDF_DETAILS)) flow_loops_dump (&loops_info, dump_file, NULL, 0); @@ -1315,7 +1313,7 @@ tree_estimate_probability (void) fast paths trought function. */ if (e->dest == EXIT_BLOCK_PTR && TREE_CODE (last_stmt (bb)) == RETURN_EXPR - && EDGE_COUNT (bb->preds) > 1) + && !single_pred_p (bb)) { edge e1; edge_iterator ei1; @@ -1441,8 +1439,7 @@ expected_value_to_br_prob (void) cond = simplify_rtx (cond); /* Turn the condition into a scaled branch probability. */ - if (cond != const_true_rtx && cond != const0_rtx) - abort (); + gcc_assert (cond == const_true_rtx || cond == const0_rtx); predict_insn_def (insn, PRED_BUILTIN_EXPECT, cond == const_true_rtx ? TAKEN : NOT_TAKEN); } @@ -1458,8 +1455,8 @@ last_basic_block_p (basic_block bb) return (bb->next_bb == EXIT_BLOCK_PTR || (bb->next_bb->next_bb == EXIT_BLOCK_PTR - && EDGE_COUNT (bb->succs) == 1 - && EDGE_SUCC (bb, 0)->dest->next_bb == EXIT_BLOCK_PTR)); + && single_succ_p (bb) + && single_succ (bb)->next_bb == EXIT_BLOCK_PTR)); } /* Sets branch probabilities according to PREDiction and @@ -1611,9 +1608,8 @@ propagate_freq (struct loop *loop, bitmap tovisit) { #ifdef ENABLE_CHECKING FOR_EACH_EDGE (e, ei, bb->preds) - if (bitmap_bit_p (tovisit, e->src->index) - && !(e->flags & EDGE_DFS_BACK)) - abort (); + gcc_assert (!bitmap_bit_p (tovisit, e->src->index) + || (e->flags & EDGE_DFS_BACK)); #endif FOR_EACH_EDGE (e, ei, bb->preds) @@ -1660,21 +1656,20 @@ propagate_freq (struct loop *loop, bitmap tovisit) bitmap_clear_bit (tovisit, bb->index); - /* Compute back edge frequencies. */ - FOR_EACH_EDGE (e, ei, bb->succs) - if (e->dest == head) - { - sreal tmp; + e = find_edge (bb, head); + if (e) + { + sreal tmp; - /* EDGE_INFO (e)->back_edge_prob - = ((e->probability * BLOCK_INFO (bb)->frequency) - / REG_BR_PROB_BASE); */ + /* EDGE_INFO (e)->back_edge_prob + = ((e->probability * BLOCK_INFO (bb)->frequency) + / REG_BR_PROB_BASE); */ - sreal_init (&tmp, e->probability, 0); - sreal_mul (&tmp, &tmp, &BLOCK_INFO (bb)->frequency); - sreal_mul (&EDGE_INFO (e)->back_edge_prob, - &tmp, &real_inv_br_prob_base); - } + sreal_init (&tmp, e->probability, 0); + sreal_mul (&tmp, &tmp, &BLOCK_INFO (bb)->frequency); + sreal_mul (&EDGE_INFO (e)->back_edge_prob, + &tmp, &real_inv_br_prob_base); + } /* Propagate to successor blocks. */ FOR_EACH_EDGE (e, ei, bb->succs) @@ -1758,8 +1753,7 @@ expensive_function_p (int threshold) /* We can not compute accurately for large thresholds due to scaled frequencies. */ - if (threshold > BB_FREQ_MAX) - abort (); + gcc_assert (threshold <= BB_FREQ_MAX); /* Frequencies are out of range. This either means that function contains internal loop executing more than BB_FREQ_MAX times or profile feedback @@ -1813,10 +1807,10 @@ estimate_bb_frequencies (struct loops *loops) mark_dfs_back_edges (); - EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->probability = REG_BR_PROB_BASE; + single_succ_edge (ENTRY_BLOCK_PTR)->probability = REG_BR_PROB_BASE; /* Set up block info for each basic block. */ - tovisit = BITMAP_XMALLOC (); + tovisit = BITMAP_ALLOC (NULL); alloc_aux_for_blocks (sizeof (struct block_info_def)); alloc_aux_for_edges (sizeof (struct edge_info_def)); FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb) @@ -1854,7 +1848,7 @@ estimate_bb_frequencies (struct loops *loops) free_aux_for_blocks (); free_aux_for_edges (); - BITMAP_XFREE (tovisit); + BITMAP_FREE (tovisit); } compute_function_frequency (); if (flag_reorder_functions)