predict.c: Include pointer-set.h.
* predict.c: Include pointer-set.h. (bb_predictions): New variable. (tree_predicted_by_p, tree_predict_edge, remove_predictions_associated_with_edge): Use bb_predictions map instead of bb->predictions. (clear_bb_predictions, assert_is_empty): New functions. (combine_predictions_for_bb): Use bb_predictions map. Call clear_bb_predictions. (tree_estimate_probability): Create and free bb_predictions map. * Makefile.in (predict.o): Add pointer-set.h dependency. * basic-block.h (struct basic_block_def): Remove predictions field. * cfgrtl.c (rtl_verify_flow_info_1): Do not check bb->predictions. From-SVN: r124032
This commit is contained in:
parent
e919dfe284
commit
f06b0a10f9
|
@ -1,3 +1,19 @@
|
||||||
|
2007-04-21 Zdenek Dvorak <dvorakz@suse.cz>
|
||||||
|
|
||||||
|
* predict.c: Include pointer-set.h.
|
||||||
|
(bb_predictions): New variable.
|
||||||
|
(tree_predicted_by_p, tree_predict_edge,
|
||||||
|
remove_predictions_associated_with_edge): Use bb_predictions map
|
||||||
|
instead of bb->predictions.
|
||||||
|
(clear_bb_predictions, assert_is_empty): New functions.
|
||||||
|
(combine_predictions_for_bb): Use bb_predictions map. Call
|
||||||
|
clear_bb_predictions.
|
||||||
|
(tree_estimate_probability): Create and free bb_predictions map.
|
||||||
|
* Makefile.in (predict.o): Add pointer-set.h dependency.
|
||||||
|
* basic-block.h (struct basic_block_def): Remove predictions
|
||||||
|
field.
|
||||||
|
* cfgrtl.c (rtl_verify_flow_info_1): Do not check bb->predictions.
|
||||||
|
|
||||||
2007-04-21 Kaz Kojima <kkojima@gcc.gnu.org>
|
2007-04-21 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||||
|
|
||||||
PR target/31480
|
PR target/31480
|
||||||
|
|
|
@ -2685,7 +2685,7 @@ predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||||
hard-reg-set.h output.h toplev.h $(RECOG_H) $(FUNCTION_H) except.h \
|
hard-reg-set.h output.h toplev.h $(RECOG_H) $(FUNCTION_H) except.h \
|
||||||
$(TM_P_H) $(PREDICT_H) sreal.h $(PARAMS_H) $(TARGET_H) $(CFGLOOP_H) \
|
$(TM_P_H) $(PREDICT_H) sreal.h $(PARAMS_H) $(TARGET_H) $(CFGLOOP_H) \
|
||||||
$(COVERAGE_H) $(SCEV_H) $(GGC_H) predict.def $(TIMEVAR_H) $(TREE_DUMP_H) \
|
$(COVERAGE_H) $(SCEV_H) $(GGC_H) predict.def $(TIMEVAR_H) $(TREE_DUMP_H) \
|
||||||
$(TREE_FLOW_H) tree-pass.h $(EXPR_H)
|
$(TREE_FLOW_H) tree-pass.h $(EXPR_H) pointer-set.h
|
||||||
lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \
|
lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \
|
||||||
$(RTL_H) $(GGC_H) gt-lists.h
|
$(RTL_H) $(GGC_H) gt-lists.h
|
||||||
bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||||
|
|
|
@ -240,9 +240,6 @@ struct basic_block_def GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb")
|
||||||
/* Chain of PHI nodes for this block. */
|
/* Chain of PHI nodes for this block. */
|
||||||
tree phi_nodes;
|
tree phi_nodes;
|
||||||
|
|
||||||
/* A list of predictions. */
|
|
||||||
struct edge_prediction *predictions;
|
|
||||||
|
|
||||||
/* Expected number of executions: calculated in profile.c. */
|
/* Expected number of executions: calculated in profile.c. */
|
||||||
gcov_type count;
|
gcov_type count;
|
||||||
|
|
||||||
|
|
|
@ -1716,12 +1716,6 @@ rtl_verify_flow_info_1 (void)
|
||||||
bb->index);
|
bb->index);
|
||||||
err = 1;
|
err = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bb->predictions)
|
|
||||||
{
|
|
||||||
error ("bb prediction set for block %d, but it is not used in RTL land", bb->index);
|
|
||||||
err = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now check the basic blocks (boundaries etc.) */
|
/* Now check the basic blocks (boundaries etc.) */
|
||||||
|
|
146
gcc/predict.c
146
gcc/predict.c
|
@ -60,6 +60,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
#include "timevar.h"
|
#include "timevar.h"
|
||||||
#include "tree-scalar-evolution.h"
|
#include "tree-scalar-evolution.h"
|
||||||
#include "cfgloop.h"
|
#include "cfgloop.h"
|
||||||
|
#include "pointer-set.h"
|
||||||
|
|
||||||
/* real constants: 0, 1, 1-1/REG_BR_PROB_BASE, REG_BR_PROB_BASE,
|
/* real constants: 0, 1, 1-1/REG_BR_PROB_BASE, REG_BR_PROB_BASE,
|
||||||
1/REG_BR_PROB_BASE, 0.5, BB_FREQ_MAX. */
|
1/REG_BR_PROB_BASE, 0.5, BB_FREQ_MAX. */
|
||||||
|
@ -174,6 +175,11 @@ rtl_predicted_by_p (basic_block bb, enum br_predictor predictor)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This map contains for a basic block the list of predictions for the
|
||||||
|
outgoing edges. */
|
||||||
|
|
||||||
|
static struct pointer_map_t *bb_predictions;
|
||||||
|
|
||||||
/* Return true if the one of outgoing edges is already predicted by
|
/* Return true if the one of outgoing edges is already predicted by
|
||||||
PREDICTOR. */
|
PREDICTOR. */
|
||||||
|
|
||||||
|
@ -181,7 +187,12 @@ bool
|
||||||
tree_predicted_by_p (basic_block bb, enum br_predictor predictor)
|
tree_predicted_by_p (basic_block bb, enum br_predictor predictor)
|
||||||
{
|
{
|
||||||
struct edge_prediction *i;
|
struct edge_prediction *i;
|
||||||
for (i = bb->predictions; i; i = i->ep_next)
|
void **preds = pointer_map_contains (bb_predictions, bb);
|
||||||
|
|
||||||
|
if (!preds)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (i = *preds; i; i = i->ep_next)
|
||||||
if (i->ep_predictor == predictor)
|
if (i->ep_predictor == predictor)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -283,10 +294,11 @@ tree_predict_edge (edge e, enum br_predictor predictor, int probability)
|
||||||
if ((e->src != ENTRY_BLOCK_PTR && EDGE_COUNT (e->src->succs) > 1)
|
if ((e->src != ENTRY_BLOCK_PTR && EDGE_COUNT (e->src->succs) > 1)
|
||||||
&& flag_guess_branch_prob && optimize)
|
&& flag_guess_branch_prob && optimize)
|
||||||
{
|
{
|
||||||
struct edge_prediction *i = ggc_alloc (sizeof (struct edge_prediction));
|
struct edge_prediction *i = XNEW (struct edge_prediction);
|
||||||
|
void **preds = pointer_map_insert (bb_predictions, e->src);
|
||||||
|
|
||||||
i->ep_next = e->src->predictions;
|
i->ep_next = *preds;
|
||||||
e->src->predictions = i;
|
*preds = i;
|
||||||
i->ep_probability = probability;
|
i->ep_probability = probability;
|
||||||
i->ep_predictor = predictor;
|
i->ep_predictor = predictor;
|
||||||
i->ep_edge = e;
|
i->ep_edge = e;
|
||||||
|
@ -298,19 +310,51 @@ tree_predict_edge (edge e, enum br_predictor predictor, int probability)
|
||||||
void
|
void
|
||||||
remove_predictions_associated_with_edge (edge e)
|
remove_predictions_associated_with_edge (edge e)
|
||||||
{
|
{
|
||||||
if (e->src->predictions)
|
void **preds;
|
||||||
|
|
||||||
|
if (!bb_predictions)
|
||||||
|
return;
|
||||||
|
|
||||||
|
preds = pointer_map_contains (bb_predictions, e->src);
|
||||||
|
|
||||||
|
if (preds)
|
||||||
{
|
{
|
||||||
struct edge_prediction **prediction = &e->src->predictions;
|
struct edge_prediction **prediction = (struct edge_prediction **) preds;
|
||||||
|
struct edge_prediction *next;
|
||||||
|
|
||||||
while (*prediction)
|
while (*prediction)
|
||||||
{
|
{
|
||||||
if ((*prediction)->ep_edge == e)
|
if ((*prediction)->ep_edge == e)
|
||||||
*prediction = (*prediction)->ep_next;
|
{
|
||||||
|
next = (*prediction)->ep_next;
|
||||||
|
free (*prediction);
|
||||||
|
*prediction = next;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
prediction = &((*prediction)->ep_next);
|
prediction = &((*prediction)->ep_next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clears the list of predictions stored for BB. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_bb_predictions (basic_block bb)
|
||||||
|
{
|
||||||
|
void **preds = pointer_map_contains (bb_predictions, bb);
|
||||||
|
struct edge_prediction *pred, *next;
|
||||||
|
|
||||||
|
if (!preds)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (pred = *preds; pred; pred = next)
|
||||||
|
{
|
||||||
|
next = pred->ep_next;
|
||||||
|
free (pred);
|
||||||
|
}
|
||||||
|
*preds = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return true when we can store prediction on insn INSN.
|
/* Return true when we can store prediction on insn INSN.
|
||||||
At the moment we represent predictions only on conditional
|
At the moment we represent predictions only on conditional
|
||||||
jumps, not at computed jump or other complicated cases. */
|
jumps, not at computed jump or other complicated cases. */
|
||||||
|
@ -538,6 +582,7 @@ combine_predictions_for_bb (basic_block bb)
|
||||||
int nedges = 0;
|
int nedges = 0;
|
||||||
edge e, first = NULL, second = NULL;
|
edge e, first = NULL, second = NULL;
|
||||||
edge_iterator ei;
|
edge_iterator ei;
|
||||||
|
void **preds;
|
||||||
|
|
||||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||||
if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
|
if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
|
||||||
|
@ -559,7 +604,7 @@ combine_predictions_for_bb (basic_block bb)
|
||||||
{
|
{
|
||||||
if (!bb->count)
|
if (!bb->count)
|
||||||
set_even_probabilities (bb);
|
set_even_probabilities (bb);
|
||||||
bb->predictions = NULL;
|
clear_bb_predictions (bb);
|
||||||
if (dump_file)
|
if (dump_file)
|
||||||
fprintf (dump_file, "%i edges in bb %i predicted to even probabilities\n",
|
fprintf (dump_file, "%i edges in bb %i predicted to even probabilities\n",
|
||||||
nedges, bb->index);
|
nedges, bb->index);
|
||||||
|
@ -569,31 +614,36 @@ combine_predictions_for_bb (basic_block bb)
|
||||||
if (dump_file)
|
if (dump_file)
|
||||||
fprintf (dump_file, "Predictions for bb %i\n", bb->index);
|
fprintf (dump_file, "Predictions for bb %i\n", bb->index);
|
||||||
|
|
||||||
/* We implement "first match" heuristics and use probability guessed
|
preds = pointer_map_contains (bb_predictions, bb);
|
||||||
by predictor with smallest index. */
|
if (preds)
|
||||||
for (pred = bb->predictions; pred; pred = pred->ep_next)
|
|
||||||
{
|
{
|
||||||
int predictor = pred->ep_predictor;
|
/* We implement "first match" heuristics and use probability guessed
|
||||||
int probability = pred->ep_probability;
|
by predictor with smallest index. */
|
||||||
|
for (pred = *preds; pred; pred = pred->ep_next)
|
||||||
|
{
|
||||||
|
int predictor = pred->ep_predictor;
|
||||||
|
int probability = pred->ep_probability;
|
||||||
|
|
||||||
if (pred->ep_edge != first)
|
if (pred->ep_edge != first)
|
||||||
probability = REG_BR_PROB_BASE - probability;
|
probability = REG_BR_PROB_BASE - probability;
|
||||||
|
|
||||||
found = true;
|
found = true;
|
||||||
if (best_predictor > predictor)
|
if (best_predictor > predictor)
|
||||||
best_probability = probability, best_predictor = predictor;
|
best_probability = probability, best_predictor = predictor;
|
||||||
|
|
||||||
d = (combined_probability * probability
|
d = (combined_probability * probability
|
||||||
+ (REG_BR_PROB_BASE - combined_probability)
|
+ (REG_BR_PROB_BASE - combined_probability)
|
||||||
* (REG_BR_PROB_BASE - probability));
|
* (REG_BR_PROB_BASE - probability));
|
||||||
|
|
||||||
/* Use FP math to avoid overflows of 32bit integers. */
|
/* Use FP math to avoid overflows of 32bit integers. */
|
||||||
if (d == 0)
|
if (d == 0)
|
||||||
/* If one probability is 0% and one 100%, avoid division by zero. */
|
/* If one probability is 0% and one 100%, avoid division by zero. */
|
||||||
combined_probability = REG_BR_PROB_BASE / 2;
|
combined_probability = REG_BR_PROB_BASE / 2;
|
||||||
else
|
else
|
||||||
combined_probability = (((double) combined_probability) * probability
|
combined_probability = (((double) combined_probability)
|
||||||
* REG_BR_PROB_BASE / d + 0.5);
|
* probability
|
||||||
|
* REG_BR_PROB_BASE / d + 0.5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decide which heuristic to use. In case we didn't match anything,
|
/* Decide which heuristic to use. In case we didn't match anything,
|
||||||
|
@ -617,17 +667,20 @@ combine_predictions_for_bb (basic_block bb)
|
||||||
combined_probability = best_probability;
|
combined_probability = best_probability;
|
||||||
dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true);
|
dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true);
|
||||||
|
|
||||||
for (pred = bb->predictions; pred; pred = pred->ep_next)
|
if (preds)
|
||||||
{
|
{
|
||||||
int predictor = pred->ep_predictor;
|
for (pred = *preds; pred; pred = pred->ep_next)
|
||||||
int probability = pred->ep_probability;
|
{
|
||||||
|
int predictor = pred->ep_predictor;
|
||||||
|
int probability = pred->ep_probability;
|
||||||
|
|
||||||
if (pred->ep_edge != EDGE_SUCC (bb, 0))
|
if (pred->ep_edge != EDGE_SUCC (bb, 0))
|
||||||
probability = REG_BR_PROB_BASE - probability;
|
probability = REG_BR_PROB_BASE - probability;
|
||||||
dump_prediction (dump_file, predictor, probability, bb,
|
dump_prediction (dump_file, predictor, probability, bb,
|
||||||
!first_match || best_predictor == predictor);
|
!first_match || best_predictor == predictor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bb->predictions = NULL;
|
clear_bb_predictions (bb);
|
||||||
|
|
||||||
if (!bb->count)
|
if (!bb->count)
|
||||||
{
|
{
|
||||||
|
@ -1278,6 +1331,20 @@ call_expr:;
|
||||||
free (heads);
|
free (heads);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_CHECKING
|
||||||
|
|
||||||
|
/* Callback for pointer_map_traverse, asserts that the pointer map is
|
||||||
|
empty. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
assert_is_empty (void *key ATTRIBUTE_UNUSED, void **value,
|
||||||
|
void *data ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
gcc_assert (!*value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Predict branch probabilities and estimate profile of the tree CFG. */
|
/* Predict branch probabilities and estimate profile of the tree CFG. */
|
||||||
static unsigned int
|
static unsigned int
|
||||||
tree_estimate_probability (void)
|
tree_estimate_probability (void)
|
||||||
|
@ -1295,6 +1362,7 @@ tree_estimate_probability (void)
|
||||||
create_preheaders (CP_SIMPLE_PREHEADERS);
|
create_preheaders (CP_SIMPLE_PREHEADERS);
|
||||||
calculate_dominance_info (CDI_POST_DOMINATORS);
|
calculate_dominance_info (CDI_POST_DOMINATORS);
|
||||||
|
|
||||||
|
bb_predictions = pointer_map_create ();
|
||||||
tree_bb_level_predictions ();
|
tree_bb_level_predictions ();
|
||||||
|
|
||||||
mark_irreducible_loops ();
|
mark_irreducible_loops ();
|
||||||
|
@ -1383,6 +1451,12 @@ tree_estimate_probability (void)
|
||||||
FOR_EACH_BB (bb)
|
FOR_EACH_BB (bb)
|
||||||
combine_predictions_for_bb (bb);
|
combine_predictions_for_bb (bb);
|
||||||
|
|
||||||
|
#ifdef ENABLE_CHECKING
|
||||||
|
pointer_map_traverse (bb_predictions, assert_is_empty, NULL);
|
||||||
|
#endif
|
||||||
|
pointer_map_destroy (bb_predictions);
|
||||||
|
bb_predictions = NULL;
|
||||||
|
|
||||||
strip_builtin_expect ();
|
strip_builtin_expect ();
|
||||||
estimate_bb_frequencies ();
|
estimate_bb_frequencies ();
|
||||||
free_dominance_info (CDI_POST_DOMINATORS);
|
free_dominance_info (CDI_POST_DOMINATORS);
|
||||||
|
|
Loading…
Reference in New Issue