Commit 33156717 by Jan Hubicka Committed by Jan Hubicka

basic-block.h (scale_bbs_frequencies_int, [...]): Declare.

	* basic-block.h (scale_bbs_frequencies_int,
	scale_bbs_frequencies_gcov_type): Declare.
	* cfg.c (RDIV): New macro.
	(update_bb_frequency_for_threading): Fix.
	* basic-block.h (scale_bbs_frequencies_int,
	scale_bbs_frequencies_gcov_type): New.
	* cfgloopmanip.c (scale_bbs_frequencies): Kill.
	(scale_loop_frequencies, duplicate_loop_to_header_edge): Use
	scale_bbs_frequencies_int.
	* tree-ssa-loop-ch.c (copy_loop_headers): Fix profiling info.

Co-Authored-By: Dale Johannesen <dalej@apple.com>

From-SVN: r96700
parent 76ef0a0d
2005-03-18 Jan Hubicka <jh@suse.cz>
Dale Johannesen <dalej@apple.com>
* basic-block.h (scale_bbs_frequencies_int,
scale_bbs_frequencies_gcov_type): Declare.
* cfg.c (RDIV): New macro.
(update_bb_frequency_for_threading): Fix.
* basic-block.h (scale_bbs_frequencies_int,
scale_bbs_frequencies_gcov_type): New.
* cfgloopmanip.c (scale_bbs_frequencies): Kill.
(scale_loop_frequencies, duplicate_loop_to_header_edge): Use
scale_bbs_frequencies_int.
* tree-ssa-loop-ch.c (copy_loop_headers): Fix profiling info.
2005-03-18 Kazu Hirata <kazu@cs.umass.edu> 2005-03-18 Kazu Hirata <kazu@cs.umass.edu>
* config/m32r/m32r-protos.h: Remove the prototypes for * config/m32r/m32r-protos.h: Remove the prototypes for
......
...@@ -468,6 +468,9 @@ extern void dump_edge_info (FILE *, edge, int); ...@@ -468,6 +468,9 @@ extern void dump_edge_info (FILE *, edge, int);
extern void brief_dump_cfg (FILE *); extern void brief_dump_cfg (FILE *);
extern void clear_edges (void); extern void clear_edges (void);
extern rtx first_insn_after_basic_block_note (basic_block); extern rtx first_insn_after_basic_block_note (basic_block);
extern void scale_bbs_frequencies_int (basic_block *, int, int, int);
extern void scale_bbs_frequencies_gcov_type (basic_block *, int, gcov_type,
gcov_type);
/* Structure to group all of the information to process IF-THEN and /* Structure to group all of the information to process IF-THEN and
IF-THEN-ELSE blocks for the conditional execution support. This IF-THEN-ELSE blocks for the conditional execution support. This
......
...@@ -96,6 +96,8 @@ static void free_edge (edge); ...@@ -96,6 +96,8 @@ static void free_edge (edge);
/* Indicate the presence of the profile. */ /* Indicate the presence of the profile. */
enum profile_status profile_status; enum profile_status profile_status;
#define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
/* Called once at initialization time. */ /* Called once at initialization time. */
void void
...@@ -933,10 +935,10 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency, ...@@ -933,10 +935,10 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency,
} }
else if (prob != REG_BR_PROB_BASE) else if (prob != REG_BR_PROB_BASE)
{ {
int scale = REG_BR_PROB_BASE / prob; int scale = 65536 * REG_BR_PROB_BASE / prob;
FOR_EACH_EDGE (c, ei, bb->succs) FOR_EACH_EDGE (c, ei, bb->succs)
c->probability *= scale; c->probability *= scale / 65536;
} }
if (bb != taken_edge->src) if (bb != taken_edge->src)
...@@ -945,3 +947,40 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency, ...@@ -945,3 +947,40 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency,
if (taken_edge->count < 0) if (taken_edge->count < 0)
taken_edge->count = 0; taken_edge->count = 0;
} }
/* Multiply all frequencies of basic blocks in array BBS of length NBBS
by NUM/DEN, in int arithmetic. May lose some accuracy. */
void
scale_bbs_frequencies_int (basic_block *bbs, int nbbs, int num, int den)
{
int i;
edge e;
for (i = 0; i < nbbs; i++)
{
edge_iterator ei;
bbs[i]->frequency = (bbs[i]->frequency * num) / den;
bbs[i]->count = RDIV (bbs[i]->count * num, den);
FOR_EACH_EDGE (e, ei, bbs[i]->succs)
e->count = (e->count * num) /den;
}
}
/* Multiply all frequencies of basic blocks in array BBS of length NBBS
by NUM/DEN, in gcov_type arithmetic. More accurate than previous
function but considerably slower. */
void
scale_bbs_frequencies_gcov_type (basic_block *bbs, int nbbs, gcov_type num,
gcov_type den)
{
int i;
edge e;
for (i = 0; i < nbbs; i++)
{
edge_iterator ei;
bbs[i]->frequency = (bbs[i]->frequency * num) / den;
bbs[i]->count = RDIV (bbs[i]->count * num, den);
FOR_EACH_EDGE (e, ei, bbs[i]->succs)
e->count = (e->count * num) /den;
}
}
...@@ -45,7 +45,6 @@ static bool fix_bb_placement (struct loops *, basic_block); ...@@ -45,7 +45,6 @@ static bool fix_bb_placement (struct loops *, basic_block);
static void fix_bb_placements (struct loops *, basic_block); static void fix_bb_placements (struct loops *, basic_block);
static void place_new_loop (struct loops *, struct loop *); static void place_new_loop (struct loops *, struct loop *);
static void scale_loop_frequencies (struct loop *, int, int); static void scale_loop_frequencies (struct loop *, int, int);
static void scale_bbs_frequencies (basic_block *, int, int, int);
static basic_block create_preheader (struct loop *, int); static basic_block create_preheader (struct loop *, int);
static void fix_irreducible_loops (basic_block); static void fix_irreducible_loops (basic_block);
static void unloop (struct loops *, struct loop *); static void unloop (struct loops *, struct loop *);
...@@ -450,24 +449,6 @@ add_loop (struct loops *loops, struct loop *loop) ...@@ -450,24 +449,6 @@ add_loop (struct loops *loops, struct loop *loop)
free (bbs); free (bbs);
} }
/* Multiply all frequencies of basic blocks in array BBS of length NBBS
by NUM/DEN. */
static void
scale_bbs_frequencies (basic_block *bbs, int nbbs, int num, int den)
{
int i;
edge e;
for (i = 0; i < nbbs; i++)
{
edge_iterator ei;
bbs[i]->frequency = (bbs[i]->frequency * num) / den;
bbs[i]->count = RDIV (bbs[i]->count * num, den);
FOR_EACH_EDGE (e, ei, bbs[i]->succs)
e->count = (e->count * num) /den;
}
}
/* Multiply all frequencies in LOOP by NUM/DEN. */ /* Multiply all frequencies in LOOP by NUM/DEN. */
static void static void
scale_loop_frequencies (struct loop *loop, int num, int den) scale_loop_frequencies (struct loop *loop, int num, int den)
...@@ -475,7 +456,7 @@ scale_loop_frequencies (struct loop *loop, int num, int den) ...@@ -475,7 +456,7 @@ scale_loop_frequencies (struct loop *loop, int num, int den)
basic_block *bbs; basic_block *bbs;
bbs = get_loop_body (loop); bbs = get_loop_body (loop);
scale_bbs_frequencies (bbs, loop->num_nodes, num, den); scale_bbs_frequencies_int (bbs, loop->num_nodes, num, den);
free (bbs); free (bbs);
} }
...@@ -1059,7 +1040,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, ...@@ -1059,7 +1040,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
/* Set counts and frequencies. */ /* Set counts and frequencies. */
if (flags & DLTHE_FLAG_UPDATE_FREQ) if (flags & DLTHE_FLAG_UPDATE_FREQ)
{ {
scale_bbs_frequencies (new_bbs, n, scale_act, REG_BR_PROB_BASE); scale_bbs_frequencies_int (new_bbs, n, scale_act, REG_BR_PROB_BASE);
scale_act = RDIV (scale_act * scale_step[j], REG_BR_PROB_BASE); scale_act = RDIV (scale_act * scale_step[j], REG_BR_PROB_BASE);
} }
} }
...@@ -1071,7 +1052,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, ...@@ -1071,7 +1052,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src); set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src);
if (flags & DLTHE_FLAG_UPDATE_FREQ) if (flags & DLTHE_FLAG_UPDATE_FREQ)
{ {
scale_bbs_frequencies (bbs, n, scale_main, REG_BR_PROB_BASE); scale_bbs_frequencies_int (bbs, n, scale_main, REG_BR_PROB_BASE);
free (scale_step); free (scale_step);
} }
......
...@@ -127,9 +127,11 @@ copy_loop_headers (void) ...@@ -127,9 +127,11 @@ copy_loop_headers (void)
unsigned i; unsigned i;
struct loop *loop; struct loop *loop;
basic_block header; basic_block header;
edge exit; edge exit, entry;
basic_block *bbs; basic_block *bbs, *copied_bbs;
unsigned n_bbs; unsigned n_bbs;
unsigned bbs_size;
gcov_type entry_count, body_count, total_count;
loops = loop_optimizer_init (dump_file); loops = loop_optimizer_init (dump_file);
if (!loops) if (!loops)
...@@ -145,6 +147,8 @@ copy_loop_headers (void) ...@@ -145,6 +147,8 @@ copy_loop_headers (void)
#endif #endif
bbs = xmalloc (sizeof (basic_block) * n_basic_blocks); bbs = xmalloc (sizeof (basic_block) * n_basic_blocks);
copied_bbs = xmalloc (sizeof (basic_block) * n_basic_blocks);
bbs_size = n_basic_blocks;
for (i = 1; i < loops->num; i++) for (i = 1; i < loops->num; i++)
{ {
...@@ -180,6 +184,7 @@ copy_loop_headers (void) ...@@ -180,6 +184,7 @@ copy_loop_headers (void)
else else
exit = EDGE_SUCC (header, 1); exit = EDGE_SUCC (header, 1);
bbs[n_bbs++] = header; bbs[n_bbs++] = header;
gcc_assert (bbs_size > n_bbs);
header = exit->dest; header = exit->dest;
} }
...@@ -196,13 +201,33 @@ copy_loop_headers (void) ...@@ -196,13 +201,33 @@ copy_loop_headers (void)
if (!single_pred_p (exit->dest)) if (!single_pred_p (exit->dest))
exit = single_succ_edge (loop_split_edge_with (exit, NULL)); exit = single_succ_edge (loop_split_edge_with (exit, NULL));
if (!tree_duplicate_sese_region (loop_preheader_edge (loop), exit, entry = loop_preheader_edge (loop);
bbs, n_bbs, NULL)) entry_count = entry->src->count;
body_count = exit->dest->count;
if (!tree_duplicate_sese_region (entry, exit, bbs, n_bbs, copied_bbs))
{ {
fprintf (dump_file, "Duplication failed.\n"); fprintf (dump_file, "Duplication failed.\n");
continue; continue;
} }
/* Fix profiling info. Scaling is done in gcov_type arithmetic to
avoid losing information; this is slow, but is done at most
once per loop. We special case 0 to avoid division by 0;
probably other special cases exist. */
total_count = body_count + entry_count;
if (total_count == 0LL)
{
scale_bbs_frequencies_int (bbs, n_bbs, 0, 1);
scale_bbs_frequencies_int (copied_bbs, n_bbs, 0, 1);
}
else
{
scale_bbs_frequencies_gcov_type (bbs, n_bbs, body_count, total_count);
scale_bbs_frequencies_gcov_type (copied_bbs, n_bbs, entry_count,
total_count);
}
/* Ensure that the latch and the preheader is simple (we know that they /* Ensure that the latch and the preheader is simple (we know that they
are not now, since there was the loop exit condition. */ are not now, since there was the loop exit condition. */
loop_split_edge_with (loop_preheader_edge (loop), NULL); loop_split_edge_with (loop_preheader_edge (loop), NULL);
...@@ -210,6 +235,7 @@ copy_loop_headers (void) ...@@ -210,6 +235,7 @@ copy_loop_headers (void)
} }
free (bbs); free (bbs);
free (copied_bbs);
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
verify_loop_closed_ssa (); verify_loop_closed_ssa ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment