diff options
author | Jan Hubicka <jh@suse.cz> | 2007-10-09 09:07:15 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2007-10-09 07:07:15 +0000 |
commit | edbed3d31e8f6981f4bf4692c132b95081ab5112 (patch) | |
tree | 2f06dba4798e87e7c5ac176d0fe66b8e2a3dc3ec /gcc/final.c | |
parent | 8df9c702e68f7d493e39883145e03f947ce6e437 (diff) | |
download | gcc-edbed3d31e8f6981f4bf4692c132b95081ab5112.zip gcc-edbed3d31e8f6981f4bf4692c132b95081ab5112.tar.gz gcc-edbed3d31e8f6981f4bf4692c132b95081ab5112.tar.bz2 |
invoke.texi (align-threshold, [...]): Document.
* invoke.texi (align-threshold, align-loop-iterations): Document.
* final.c: Include cfgloop.h, params.h
(compute_alignments): Dump decisions and compare them with loop
structure; honor given parameters.
(pass_compute_alignments): New dump file.
* params.def (PARAM_ALIGN_THRESHOLD, PARAM_ALIGN_LOOP_ITERATIONS): New.
* Makefile.in (final.o): Add dependency on cfgloop.h and params.h
From-SVN: r129162
Diffstat (limited to 'gcc/final.c')
-rw-r--r-- | gcc/final.c | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/gcc/final.c b/gcc/final.c index b59a222..654f847 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -78,6 +78,8 @@ along with GCC; see the file COPYING3. If not see #include "df.h" #include "vecprim.h" #include "ggc.h" +#include "cfgloop.h" +#include "params.h" #ifdef XCOFF_DEBUGGING_INFO #include "xcoffout.h" /* Needed for external data @@ -673,6 +675,8 @@ compute_alignments (void) { int log, max_skip, max_log; basic_block bb; + int freq_max = 0; + int freq_threshold = 0; if (label_align) { @@ -688,6 +692,19 @@ compute_alignments (void) if (! optimize || optimize_size) return 0; + if (dump_file) + { + dump_flow_info (dump_file, TDF_DETAILS); + flow_loops_dump (dump_file, NULL, 1); + loop_optimizer_init (AVOID_CFG_MODIFICATIONS); + } + FOR_EACH_BB (bb) + if (bb->frequency > freq_max) + freq_max = bb->frequency; + freq_threshold = freq_max / PARAM_VALUE (PARAM_ALIGN_THRESHOLD); + + if (dump_file) + fprintf(dump_file, "freq_max: %i\n",freq_max); FOR_EACH_BB (bb) { rtx label = BB_HEAD (bb); @@ -697,7 +714,12 @@ compute_alignments (void) if (!LABEL_P (label) || probably_never_executed_bb_p (bb)) - continue; + { + if (dump_file) + fprintf(dump_file, "BB %4i freq %4i loop %2i loop_depth %2i skipped.\n", + bb->index, bb->frequency, bb->loop_father->num, bb->loop_depth); + continue; + } max_log = LABEL_ALIGN (label); max_skip = LABEL_ALIGN_MAX_SKIP; @@ -708,6 +730,18 @@ compute_alignments (void) else branch_frequency += EDGE_FREQUENCY (e); } + if (dump_file) + { + fprintf(dump_file, "BB %4i freq %4i loop %2i loop_depth %2i fall %4i branch %4i", + bb->index, bb->frequency, bb->loop_father->num, + bb->loop_depth, + fallthru_frequency, branch_frequency); + if (!bb->loop_father->inner && bb->loop_father->num) + fprintf (dump_file, " inner_loop"); + if (bb->loop_father->header == bb) + fprintf (dump_file, " loop_header"); + fprintf (dump_file, "\n"); + } /* There are two purposes to align block with no fallthru incoming edge: 1) to avoid fetch stalls when branch destination is near cache boundary @@ -720,12 +754,14 @@ compute_alignments (void) when function is called. */ if (!has_fallthru - && (branch_frequency > BB_FREQ_MAX / 10 + && (branch_frequency > freq_threshold || (bb->frequency > bb->prev_bb->frequency * 10 && (bb->prev_bb->frequency <= ENTRY_BLOCK_PTR->frequency / 2)))) { log = JUMP_ALIGN (label); + if (dump_file) + fprintf(dump_file, " jump alignment added.\n"); if (max_log < log) { max_log = log; @@ -736,10 +772,13 @@ compute_alignments (void) align it. It is most likely a first block of loop. */ if (has_fallthru && maybe_hot_bb_p (bb) - && branch_frequency + fallthru_frequency > BB_FREQ_MAX / 10 - && branch_frequency > fallthru_frequency * 2) + && branch_frequency + fallthru_frequency > freq_threshold + && (branch_frequency + > fallthru_frequency * PARAM_VALUE (PARAM_ALIGN_LOOP_ITERATIONS))) { log = LOOP_ALIGN (label); + if (dump_file) + fprintf(dump_file, " internal loop alignment added.\n"); if (max_log < log) { max_log = log; @@ -749,12 +788,15 @@ compute_alignments (void) LABEL_TO_ALIGNMENT (label) = max_log; LABEL_TO_MAX_SKIP (label) = max_skip; } + + if (dump_file) + loop_optimizer_finalize (); return 0; } struct tree_opt_pass pass_compute_alignments = { - NULL, /* name */ + "alignments", /* name */ NULL, /* gate */ compute_alignments, /* execute */ NULL, /* sub */ @@ -765,7 +807,8 @@ struct tree_opt_pass pass_compute_alignments = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ + TODO_dump_func | TODO_verify_rtl_sharing + | TODO_ggc_collect, /* todo_flags_finish */ 0 /* letter */ }; |