summaryrefslogtreecommitdiff
path: root/gcc/predict.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2004-09-14 00:52:41 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2004-09-14 00:52:41 +0000
commitd27b0b64f68e4b90ca4a288dec295cad319e8caf (patch)
tree6c9fdd3e642a19ea5b08282b731c11537135c7af /gcc/predict.c
parent81c163fa030321cbd1514a46eefe5cde3b515414 (diff)
downloadgcc-d27b0b64f68e4b90ca4a288dec295cad319e8caf.tar.gz
* Makefile.in (predict.o): Depend on tree-scalar-evolution.h
* predict.c: Include tree-scalar-evolution.h and cfgloop.h (predict_loops): Use number_of_iterations_exit to predict number of iterations on trees. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@87473 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/predict.c')
-rw-r--r--gcc/predict.c54
1 files changed, 49 insertions, 5 deletions
diff --git a/gcc/predict.c b/gcc/predict.c
index fbbc1579b39..c19ccbe59eb 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -58,6 +58,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tree-dump.h"
#include "tree-pass.h"
#include "timevar.h"
+#include "tree-scalar-evolution.h"
+#include "cfgloop.h"
/* real constants: 0, 1, 1-1/REG_BR_PROB_BASE, REG_BR_PROB_BASE,
1/REG_BR_PROB_BASE, 0.5, BB_FREQ_MAX. */
@@ -552,13 +554,16 @@ combine_predictions_for_bb (FILE *file, basic_block bb)
}
/* Predict edge probabilities by exploiting loop structure.
- When SIMPLELOOPS is set, attempt to count number of iterations by analyzing
- RTL. */
+ When RTLSIMPLELOOPS is set, attempt to count number of iterations by analyzing
+ RTL otherwise use tree based approach. */
static void
-predict_loops (struct loops *loops_info, bool simpleloops)
+predict_loops (struct loops *loops_info, bool rtlsimpleloops)
{
unsigned i;
+ if (!rtlsimpleloops)
+ scev_initialize (loops_info);
+
/* Try to predict out blocks in a loop that are not part of a
natural loop. */
for (i = 1; i < loops_info->num; i++)
@@ -573,7 +578,7 @@ predict_loops (struct loops *loops_info, bool simpleloops)
flow_loop_scan (loop, LOOP_EXIT_EDGES);
exits = loop->num_exits;
- if (simpleloops)
+ if (rtlsimpleloops)
{
iv_analysis_loop_init (loop);
find_simple_exit (loop, &desc);
@@ -595,6 +600,42 @@ predict_loops (struct loops *loops_info, bool simpleloops)
prob);
}
}
+ 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;
+
+ if (number_of_iterations_exit (loop, exits[j], &niter_desc))
+ niter = niter_desc.niter;
+ if (!niter || TREE_CODE (niter_desc.niter) != INTEGER_CST)
+ niter = loop_niter_by_eval (loop, exits[j]);
+
+ if (TREE_CODE (niter) == INTEGER_CST)
+ {
+ int probability;
+ if (host_integerp (niter, 1)
+ && tree_int_cst_lt (niter,
+ build_int_cstu (NULL_TREE,
+ REG_BR_PROB_BASE - 1)))
+ {
+ HOST_WIDE_INT nitercst = tree_low_cst (niter, 1) + 1;
+ probability = (REG_BR_PROB_BASE + nitercst / 2) / nitercst;
+ }
+ else
+ probability = 1;
+
+ predict_edge (exits[j], PRED_LOOP_ITERATIONS, probability);
+ }
+ }
+
+ free (exits);
+ }
bbs = get_loop_body (loop);
@@ -609,7 +650,7 @@ predict_loops (struct loops *loops_info, bool simpleloops)
statements construct loops via "non-loop" constructs
in the source language and are better to be handled
separately. */
- if ((simpleloops && !can_predict_insn_p (BB_END (bb)))
+ if ((rtlsimpleloops && !can_predict_insn_p (BB_END (bb)))
|| predicted_by_p (bb, PRED_CONTINUE))
continue;
@@ -639,6 +680,9 @@ predict_loops (struct loops *loops_info, bool simpleloops)
/* Free basic blocks from get_loop_body. */
free (bbs);
}
+
+ if (!rtlsimpleloops)
+ scev_reset ();
}
/* Attempt to predict probabilities of BB outgoing edges using local