mirror of git://gcc.gnu.org/git/gcc.git
rtl.h (insn_note): Remove NOTE_INSN_PREDICTION.
* rtl.h (insn_note): Remove NOTE_INSN_PREDICTION. * rtl.c (note_insn_name): Likewise. * print-rtl.c (print_rtx): Don't print it. * cfgrtl.h (can_delete_note_p): Don't handle it. (rtl_delete_block): Likewise. * passes.c (rest_of_handle_guess_branch_prob): Remove. (rest_of_compilation): Don't call it. * predict.c (process_note_predictions, process_note_prediction, note_prediction_to_br_prob): Remove. * basic-block.c (note_prediction_to_br_prob): Remove prototype. * stmt.c (return_prediction): Remove. (expand_value_return): Don't call it. Don't add prediction notes for return statements. From-SVN: r85016
This commit is contained in:
parent
d917fa8798
commit
07a236b612
|
@ -1,3 +1,19 @@
|
||||||
|
2004-07-21 Steven Bosscher <stevenb@suse.de>
|
||||||
|
|
||||||
|
* rtl.h (insn_note): Remove NOTE_INSN_PREDICTION.
|
||||||
|
* rtl.c (note_insn_name): Likewise.
|
||||||
|
* print-rtl.c (print_rtx): Don't print it.
|
||||||
|
* cfgrtl.h (can_delete_note_p): Don't handle it.
|
||||||
|
(rtl_delete_block): Likewise.
|
||||||
|
* passes.c (rest_of_handle_guess_branch_prob): Remove.
|
||||||
|
(rest_of_compilation): Don't call it.
|
||||||
|
* predict.c (process_note_predictions, process_note_prediction,
|
||||||
|
note_prediction_to_br_prob): Remove.
|
||||||
|
* basic-block.c (note_prediction_to_br_prob): Remove prototype.
|
||||||
|
* stmt.c (return_prediction): Remove.
|
||||||
|
(expand_value_return): Don't call it. Don't add prediction
|
||||||
|
notes for return statements.
|
||||||
|
|
||||||
2004-07-21 Josef Zlomek <zlomekj@suse.cz>
|
2004-07-21 Josef Zlomek <zlomekj@suse.cz>
|
||||||
|
|
||||||
* var-tracking.c (vt_find_locations): Set the in_pending bitmap at
|
* var-tracking.c (vt_find_locations): Set the in_pending bitmap at
|
||||||
|
|
|
@ -595,7 +595,6 @@ extern rtx emit_block_insn_before (rtx, rtx, basic_block);
|
||||||
|
|
||||||
/* In predict.c */
|
/* In predict.c */
|
||||||
extern void estimate_probability (struct loops *);
|
extern void estimate_probability (struct loops *);
|
||||||
extern void note_prediction_to_br_prob (void);
|
|
||||||
extern void expected_value_to_br_prob (void);
|
extern void expected_value_to_br_prob (void);
|
||||||
extern bool maybe_hot_bb_p (basic_block);
|
extern bool maybe_hot_bb_p (basic_block);
|
||||||
extern bool probably_cold_bb_p (basic_block);
|
extern bool probably_cold_bb_p (basic_block);
|
||||||
|
|
|
@ -93,8 +93,7 @@ can_delete_note_p (rtx note)
|
||||||
{
|
{
|
||||||
return (NOTE_LINE_NUMBER (note) == NOTE_INSN_DELETED
|
return (NOTE_LINE_NUMBER (note) == NOTE_INSN_DELETED
|
||||||
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_BASIC_BLOCK
|
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_BASIC_BLOCK
|
||||||
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_UNLIKELY_EXECUTED_CODE
|
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_UNLIKELY_EXECUTED_CODE);
|
||||||
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_PREDICTION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* True if a given label can be deleted. */
|
/* True if a given label can be deleted. */
|
||||||
|
@ -376,15 +375,13 @@ rtl_delete_block (basic_block b)
|
||||||
and remove the associated NOTE_INSN_EH_REGION_BEG and
|
and remove the associated NOTE_INSN_EH_REGION_BEG and
|
||||||
NOTE_INSN_EH_REGION_END notes. */
|
NOTE_INSN_EH_REGION_END notes. */
|
||||||
|
|
||||||
/* Get rid of all NOTE_INSN_PREDICTIONs and NOTE_INSN_LOOP_CONTs
|
/* Get rid of all NOTE_INSN_LOOP_CONTs hanging before the block. */
|
||||||
hanging before the block. */
|
|
||||||
|
|
||||||
for (insn = PREV_INSN (BB_HEAD (b)); insn; insn = PREV_INSN (insn))
|
for (insn = PREV_INSN (BB_HEAD (b)); insn; insn = PREV_INSN (insn))
|
||||||
{
|
{
|
||||||
if (!NOTE_P (insn))
|
if (!NOTE_P (insn))
|
||||||
break;
|
break;
|
||||||
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION
|
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT)
|
||||||
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT)
|
|
||||||
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
|
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
gcc/passes.c
13
gcc/passes.c
|
@ -1472,18 +1472,6 @@ rest_of_handle_jump (void)
|
||||||
timevar_pop (TV_JUMP);
|
timevar_pop (TV_JUMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
rest_of_handle_guess_branch_prob (void)
|
|
||||||
{
|
|
||||||
/* Turn NOTE_INSN_PREDICTIONs into branch predictions. */
|
|
||||||
if (flag_guess_branch_prob)
|
|
||||||
{
|
|
||||||
timevar_push (TV_BRANCH_PROB);
|
|
||||||
note_prediction_to_br_prob ();
|
|
||||||
timevar_pop (TV_BRANCH_PROB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rest_of_handle_eh (void)
|
rest_of_handle_eh (void)
|
||||||
{
|
{
|
||||||
|
@ -1791,7 +1779,6 @@ rest_of_compilation (void)
|
||||||
goto exit_rest_of_compilation;
|
goto exit_rest_of_compilation;
|
||||||
|
|
||||||
rest_of_handle_jump ();
|
rest_of_handle_jump ();
|
||||||
rest_of_handle_guess_branch_prob ();
|
|
||||||
|
|
||||||
if (cfun->tail_call_emit)
|
if (cfun->tail_call_emit)
|
||||||
fixup_tail_calls ();
|
fixup_tail_calls ();
|
||||||
|
|
146
gcc/predict.c
146
gcc/predict.c
|
@ -76,8 +76,6 @@ static void estimate_loops_at_level (struct loop *loop);
|
||||||
static void propagate_freq (struct loop *);
|
static void propagate_freq (struct loop *);
|
||||||
static void estimate_bb_frequencies (struct loops *);
|
static void estimate_bb_frequencies (struct loops *);
|
||||||
static int counts_to_freqs (void);
|
static int counts_to_freqs (void);
|
||||||
static void process_note_predictions (basic_block, int *);
|
|
||||||
static void process_note_prediction (basic_block, int *, int, int);
|
|
||||||
static bool last_basic_block_p (basic_block);
|
static bool last_basic_block_p (basic_block);
|
||||||
static void compute_function_frequency (void);
|
static void compute_function_frequency (void);
|
||||||
static void choose_function_section (void);
|
static void choose_function_section (void);
|
||||||
|
@ -1078,150 +1076,6 @@ last_basic_block_p (basic_block bb)
|
||||||
&& bb->succ && !bb->succ->succ_next
|
&& bb->succ && !bb->succ->succ_next
|
||||||
&& bb->succ->dest->next_bb == EXIT_BLOCK_PTR));
|
&& bb->succ->dest->next_bb == EXIT_BLOCK_PTR));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sets branch probabilities according to PREDiction and
|
|
||||||
FLAGS. HEADS[bb->index] should be index of basic block in that we
|
|
||||||
need to alter branch predictions (i.e. the first of our dominators
|
|
||||||
such that we do not post-dominate it) (but we fill this information
|
|
||||||
on demand, so -1 may be there in case this was not needed yet). */
|
|
||||||
|
|
||||||
static void
|
|
||||||
process_note_prediction (basic_block bb, int *heads, int pred, int flags)
|
|
||||||
{
|
|
||||||
edge e;
|
|
||||||
int y;
|
|
||||||
bool taken;
|
|
||||||
|
|
||||||
taken = flags & IS_TAKEN;
|
|
||||||
|
|
||||||
if (heads[bb->index] < 0)
|
|
||||||
{
|
|
||||||
/* This is first time we need this field in heads array; so
|
|
||||||
find first dominator that we do not post-dominate (we are
|
|
||||||
using already known members of heads array). */
|
|
||||||
basic_block ai = bb;
|
|
||||||
basic_block next_ai = get_immediate_dominator (CDI_DOMINATORS, bb);
|
|
||||||
int head;
|
|
||||||
|
|
||||||
while (heads[next_ai->index] < 0)
|
|
||||||
{
|
|
||||||
if (!dominated_by_p (CDI_POST_DOMINATORS, next_ai, bb))
|
|
||||||
break;
|
|
||||||
heads[next_ai->index] = ai->index;
|
|
||||||
ai = next_ai;
|
|
||||||
next_ai = get_immediate_dominator (CDI_DOMINATORS, next_ai);
|
|
||||||
}
|
|
||||||
if (!dominated_by_p (CDI_POST_DOMINATORS, next_ai, bb))
|
|
||||||
head = next_ai->index;
|
|
||||||
else
|
|
||||||
head = heads[next_ai->index];
|
|
||||||
while (next_ai != bb)
|
|
||||||
{
|
|
||||||
next_ai = ai;
|
|
||||||
if (heads[ai->index] == ENTRY_BLOCK)
|
|
||||||
ai = ENTRY_BLOCK_PTR;
|
|
||||||
else
|
|
||||||
ai = BASIC_BLOCK (heads[ai->index]);
|
|
||||||
heads[next_ai->index] = head;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
y = heads[bb->index];
|
|
||||||
|
|
||||||
/* Now find the edge that leads to our branch and aply the prediction. */
|
|
||||||
|
|
||||||
if (y == last_basic_block || !can_predict_insn_p (BB_END (BASIC_BLOCK (y))))
|
|
||||||
return;
|
|
||||||
for (e = BASIC_BLOCK (y)->succ; e; e = e->succ_next)
|
|
||||||
if (e->dest->index >= 0
|
|
||||||
&& dominated_by_p (CDI_POST_DOMINATORS, e->dest, bb))
|
|
||||||
predict_edge_def (e, pred, taken);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Gathers NOTE_INSN_PREDICTIONs in given basic block and turns them
|
|
||||||
into branch probabilities. For description of heads array, see
|
|
||||||
process_note_prediction. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
process_note_predictions (basic_block bb, int *heads)
|
|
||||||
{
|
|
||||||
rtx insn;
|
|
||||||
edge e;
|
|
||||||
|
|
||||||
/* Additionally, we check here for blocks with no successors. */
|
|
||||||
int contained_noreturn_call = 0;
|
|
||||||
int was_bb_head = 0;
|
|
||||||
int noreturn_block = 1;
|
|
||||||
|
|
||||||
for (insn = BB_END (bb); insn;
|
|
||||||
was_bb_head |= (insn == BB_HEAD (bb)), insn = PREV_INSN (insn))
|
|
||||||
{
|
|
||||||
if (!NOTE_P (insn))
|
|
||||||
{
|
|
||||||
if (was_bb_head)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Noreturn calls cause program to exit, therefore they are
|
|
||||||
always predicted as not taken. */
|
|
||||||
if (CALL_P (insn)
|
|
||||||
&& find_reg_note (insn, REG_NORETURN, NULL))
|
|
||||||
contained_noreturn_call = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION)
|
|
||||||
{
|
|
||||||
int alg = (int) NOTE_PREDICTION_ALG (insn);
|
|
||||||
/* Process single prediction note. */
|
|
||||||
process_note_prediction (bb,
|
|
||||||
heads,
|
|
||||||
alg, (int) NOTE_PREDICTION_FLAGS (insn));
|
|
||||||
delete_insn (insn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (e = bb->succ; e; e = e->succ_next)
|
|
||||||
if (!(e->flags & EDGE_FAKE))
|
|
||||||
noreturn_block = 0;
|
|
||||||
if (contained_noreturn_call)
|
|
||||||
{
|
|
||||||
/* This block ended from other reasons than because of return.
|
|
||||||
If it is because of noreturn call, this should certainly not
|
|
||||||
be taken. Otherwise it is probably some error recovery. */
|
|
||||||
process_note_prediction (bb, heads, PRED_NORETURN, NOT_TAKEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Gathers NOTE_INSN_PREDICTIONs and turns them into
|
|
||||||
branch probabilities. */
|
|
||||||
|
|
||||||
void
|
|
||||||
note_prediction_to_br_prob (void)
|
|
||||||
{
|
|
||||||
basic_block bb;
|
|
||||||
int *heads;
|
|
||||||
|
|
||||||
/* To enable handling of noreturn blocks. */
|
|
||||||
add_noreturn_fake_exit_edges ();
|
|
||||||
connect_infinite_loops_to_exit ();
|
|
||||||
|
|
||||||
calculate_dominance_info (CDI_POST_DOMINATORS);
|
|
||||||
calculate_dominance_info (CDI_DOMINATORS);
|
|
||||||
|
|
||||||
heads = xmalloc (sizeof (int) * last_basic_block);
|
|
||||||
memset (heads, -1, sizeof (int) * last_basic_block);
|
|
||||||
heads[ENTRY_BLOCK_PTR->next_bb->index] = last_basic_block;
|
|
||||||
|
|
||||||
/* Process all prediction notes. */
|
|
||||||
|
|
||||||
FOR_EACH_BB (bb)
|
|
||||||
process_note_predictions (bb, heads);
|
|
||||||
|
|
||||||
free_dominance_info (CDI_POST_DOMINATORS);
|
|
||||||
free_dominance_info (CDI_DOMINATORS);
|
|
||||||
free (heads);
|
|
||||||
|
|
||||||
remove_fake_exit_edges ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is used to carry information about basic blocks. It is
|
/* This is used to carry information about basic blocks. It is
|
||||||
attached to the AUX field of the standard CFG block. */
|
attached to the AUX field of the standard CFG block. */
|
||||||
|
|
|
@ -281,15 +281,6 @@ print_rtx (rtx in_rtx)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NOTE_INSN_PREDICTION:
|
|
||||||
if (NOTE_PREDICTION (in_rtx))
|
|
||||||
fprintf (outfile, " [ %d %d ] ",
|
|
||||||
(int)NOTE_PREDICTION_ALG (in_rtx),
|
|
||||||
(int) NOTE_PREDICTION_FLAGS (in_rtx));
|
|
||||||
else
|
|
||||||
fprintf (outfile, " [ ERROR ]");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NOTE_INSN_UNLIKELY_EXECUTED_CODE:
|
case NOTE_INSN_UNLIKELY_EXECUTED_CODE:
|
||||||
{
|
{
|
||||||
basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
|
basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
|
||||||
|
|
|
@ -122,7 +122,6 @@ const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS] =
|
||||||
"NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END",
|
"NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END",
|
||||||
"NOTE_INSN_REPEATED_LINE_NUMBER",
|
"NOTE_INSN_REPEATED_LINE_NUMBER",
|
||||||
"NOTE_INSN_BASIC_BLOCK", "NOTE_INSN_EXPECTED_VALUE",
|
"NOTE_INSN_BASIC_BLOCK", "NOTE_INSN_EXPECTED_VALUE",
|
||||||
"NOTE_INSN_PREDICTION",
|
|
||||||
"NOTE_INSN_UNLIKELY_EXECUTED_CODE",
|
"NOTE_INSN_UNLIKELY_EXECUTED_CODE",
|
||||||
"NOTE_INSN_VAR_LOCATION"
|
"NOTE_INSN_VAR_LOCATION"
|
||||||
};
|
};
|
||||||
|
|
|
@ -1029,9 +1029,6 @@ enum insn_note
|
||||||
NOTE_EXPECTED_VALUE; stored as (eq (reg) (const_int)). */
|
NOTE_EXPECTED_VALUE; stored as (eq (reg) (const_int)). */
|
||||||
NOTE_INSN_EXPECTED_VALUE,
|
NOTE_INSN_EXPECTED_VALUE,
|
||||||
|
|
||||||
/* Record a prediction. Uses NOTE_PREDICTION. */
|
|
||||||
NOTE_INSN_PREDICTION,
|
|
||||||
|
|
||||||
/* Record that the current basic block is unlikely to be executed and
|
/* Record that the current basic block is unlikely to be executed and
|
||||||
should be moved to the UNLIKELY_EXECUTED_TEXT_SECTION. */
|
should be moved to the UNLIKELY_EXECUTED_TEXT_SECTION. */
|
||||||
NOTE_INSN_UNLIKELY_EXECUTED_CODE,
|
NOTE_INSN_UNLIKELY_EXECUTED_CODE,
|
||||||
|
|
48
gcc/stmt.c
48
gcc/stmt.c
|
@ -264,7 +264,6 @@ static bool check_operand_nalternatives (tree, tree);
|
||||||
static bool check_unique_operand_names (tree, tree);
|
static bool check_unique_operand_names (tree, tree);
|
||||||
static char *resolve_operand_name_1 (char *, tree, tree);
|
static char *resolve_operand_name_1 (char *, tree, tree);
|
||||||
static void expand_null_return_1 (void);
|
static void expand_null_return_1 (void);
|
||||||
static enum br_predictor return_prediction (rtx);
|
|
||||||
static rtx shift_return_value (rtx);
|
static rtx shift_return_value (rtx);
|
||||||
static void expand_value_return (rtx);
|
static void expand_value_return (rtx);
|
||||||
static void do_jump_if_equal (rtx, rtx, rtx, int);
|
static void do_jump_if_equal (rtx, rtx, rtx, int);
|
||||||
|
@ -1811,35 +1810,6 @@ expand_naked_return (void)
|
||||||
emit_jump (end_label);
|
emit_jump (end_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to guess whether the value of return means error code. */
|
|
||||||
static enum br_predictor
|
|
||||||
return_prediction (rtx val)
|
|
||||||
{
|
|
||||||
/* Different heuristics for pointers and scalars. */
|
|
||||||
if (POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))))
|
|
||||||
{
|
|
||||||
/* NULL is usually not returned. */
|
|
||||||
if (val == const0_rtx)
|
|
||||||
return PRED_NULL_RETURN;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Negative return values are often used to indicate
|
|
||||||
errors. */
|
|
||||||
if (GET_CODE (val) == CONST_INT
|
|
||||||
&& INTVAL (val) < 0)
|
|
||||||
return PRED_NEGATIVE_RETURN;
|
|
||||||
/* Constant return values are also usually erors,
|
|
||||||
zero/one often mean booleans so exclude them from the
|
|
||||||
heuristics. */
|
|
||||||
if (CONSTANT_P (val)
|
|
||||||
&& (val != const0_rtx && val != const1_rtx))
|
|
||||||
return PRED_CONST_RETURN;
|
|
||||||
}
|
|
||||||
return PRED_NO_PREDICTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* If the current function returns values in the most significant part
|
/* If the current function returns values in the most significant part
|
||||||
of a register, shift return value VAL appropriately. The mode of
|
of a register, shift return value VAL appropriately. The mode of
|
||||||
the function's return type is known not to be BLKmode. */
|
the function's return type is known not to be BLKmode. */
|
||||||
|
@ -1872,26 +1842,10 @@ shift_return_value (rtx val)
|
||||||
static void
|
static void
|
||||||
expand_value_return (rtx val)
|
expand_value_return (rtx val)
|
||||||
{
|
{
|
||||||
rtx return_reg;
|
|
||||||
enum br_predictor pred;
|
|
||||||
|
|
||||||
if (flag_guess_branch_prob
|
|
||||||
&& (pred = return_prediction (val)) != PRED_NO_PREDICTION)
|
|
||||||
{
|
|
||||||
/* Emit information for branch prediction. */
|
|
||||||
rtx note;
|
|
||||||
|
|
||||||
note = emit_note (NOTE_INSN_PREDICTION);
|
|
||||||
|
|
||||||
NOTE_PREDICTION (note) = NOTE_PREDICT (pred, NOT_TAKEN);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return_reg = DECL_RTL (DECL_RESULT (current_function_decl));
|
|
||||||
|
|
||||||
/* Copy the value to the return location
|
/* Copy the value to the return location
|
||||||
unless it's already there. */
|
unless it's already there. */
|
||||||
|
|
||||||
|
rtx return_reg = DECL_RTL (DECL_RESULT (current_function_decl));
|
||||||
if (return_reg != val)
|
if (return_reg != val)
|
||||||
{
|
{
|
||||||
tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
|
tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
|
||||||
|
|
Loading…
Reference in New Issue