Commit d331e204 by Mostafa Hagog Committed by Mostafa Hagog

Fix PR middle-end/20177 and add test case.

From-SVN: r96828
parent 191dd2c9
2005-03-21 Mostafa Hagog <mustafa@il.ibm.com>
PR middle-end/20177
* ddg.c (create_ddg_dependence): Ignore reg-anti dependency.
* modulo-sched.c (const_iteration_count): Return on NULL
pre-header.
(print_node_sched_params): Return on NULL dump_file.
(generate_reg_moves): Handle reg-anti dependencies and disregard
closing branch when generating register moves.
(sms_schedule): Mark the SMSed block dirty.
* passes.c (rest_of_handle_sms): Call update_life_info for all
basic-blocks.
* testsuite/gcc.dg/20050321-1.c: New test.
2005-03-21 Bob Wilson <bob.wilson@acm.org> 2005-03-21 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/lib1funcs.asm (__mulsi3): Use symbolic name for ACCLO. * config/xtensa/lib1funcs.asm (__mulsi3): Use symbolic name for ACCLO.
......
...@@ -187,6 +187,8 @@ create_ddg_dependence (ddg_ptr g, ddg_node_ptr src_node, ...@@ -187,6 +187,8 @@ create_ddg_dependence (ddg_ptr g, ddg_node_ptr src_node,
else else
free (e); free (e);
} }
else if (t == ANTI_DEP && dt == REG_DEP)
free (e); /* We can fix broken anti register deps using reg-moves. */
else else
add_edge_to_ddg (g, e); add_edge_to_ddg (g, e);
} }
......
...@@ -337,6 +337,10 @@ const_iteration_count (rtx count_reg, basic_block pre_header, ...@@ -337,6 +337,10 @@ const_iteration_count (rtx count_reg, basic_block pre_header,
{ {
rtx insn; rtx insn;
rtx head, tail; rtx head, tail;
if (! pre_header)
return NULL_RTX;
get_block_head_tail (pre_header->index, &head, &tail); get_block_head_tail (pre_header->index, &head, &tail);
for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn)) for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn))
...@@ -399,6 +403,8 @@ print_node_sched_params (FILE * dump_file, int num_nodes) ...@@ -399,6 +403,8 @@ print_node_sched_params (FILE * dump_file, int num_nodes)
{ {
int i; int i;
if (! dump_file)
return;
for (i = 0; i < num_nodes; i++) for (i = 0; i < num_nodes; i++)
{ {
node_sched_params_ptr nsp = &node_sched_params[i]; node_sched_params_ptr nsp = &node_sched_params[i];
...@@ -441,14 +447,17 @@ calculate_maxii (ddg_ptr g) ...@@ -441,14 +447,17 @@ calculate_maxii (ddg_ptr g)
return maxii; return maxii;
} }
/*
/* Given the partial schedule, generate register moves when the length Breaking intra-loop register anti-dependences:
of the register live range is more than ii; the number of moves is Each intra-loop register anti-dependence implies a cross-iteration true
determined according to the following equation: dependence of distance 1. Therefore, we can remove such false dependencies
SCHED_TIME (use) - SCHED_TIME (def) { 1 broken loop-carried and figure out if the partial schedule broke them by checking if (for a
nreg_moves = ----------------------------------- - { dependence. true-dependence of distance 1): SCHED_TIME (def) < SCHED_TIME (use) and
ii { 0 if not. if so generate a register move. The number of such moves is equal to:
This handles the modulo-variable-expansions (mve's) needed for the ps. */ SCHED_TIME (use) - SCHED_TIME (def) { 0 broken
nreg_moves = ----------------------------------- + 1 - { dependecnce.
ii { 1 if not.
*/
static void static void
generate_reg_moves (partial_schedule_ptr ps) generate_reg_moves (partial_schedule_ptr ps)
{ {
...@@ -472,6 +481,9 @@ generate_reg_moves (partial_schedule_ptr ps) ...@@ -472,6 +481,9 @@ generate_reg_moves (partial_schedule_ptr ps)
{ {
int nreg_moves4e = (SCHED_TIME (e->dest) - SCHED_TIME (e->src)) / ii; int nreg_moves4e = (SCHED_TIME (e->dest) - SCHED_TIME (e->src)) / ii;
if (e->distance == 1)
nreg_moves4e = (SCHED_TIME (e->dest) - SCHED_TIME (e->src) + ii) / ii;
/* If dest precedes src in the schedule of the kernel, then dest /* If dest precedes src in the schedule of the kernel, then dest
will read before src writes and we can save one reg_copy. */ will read before src writes and we can save one reg_copy. */
if (SCHED_ROW (e->dest) == SCHED_ROW (e->src) if (SCHED_ROW (e->dest) == SCHED_ROW (e->src)
...@@ -495,6 +507,9 @@ generate_reg_moves (partial_schedule_ptr ps) ...@@ -495,6 +507,9 @@ generate_reg_moves (partial_schedule_ptr ps)
{ {
int dest_copy = (SCHED_TIME (e->dest) - SCHED_TIME (e->src)) / ii; int dest_copy = (SCHED_TIME (e->dest) - SCHED_TIME (e->src)) / ii;
if (e->distance == 1)
dest_copy = (SCHED_TIME (e->dest) - SCHED_TIME (e->src) + ii) / ii;
if (SCHED_ROW (e->dest) == SCHED_ROW (e->src) if (SCHED_ROW (e->dest) == SCHED_ROW (e->src)
&& SCHED_COLUMN (e->dest) < SCHED_COLUMN (e->src)) && SCHED_COLUMN (e->dest) < SCHED_COLUMN (e->src))
dest_copy--; dest_copy--;
...@@ -538,7 +553,8 @@ normalize_sched_times (partial_schedule_ptr ps) ...@@ -538,7 +553,8 @@ normalize_sched_times (partial_schedule_ptr ps)
int amount = PS_MIN_CYCLE (ps); int amount = PS_MIN_CYCLE (ps);
int ii = ps->ii; int ii = ps->ii;
for (i = 0; i < g->num_nodes; i++) /* Don't include the closing branch assuming that it is the last node. */
for (i = 0; i < g->num_nodes - 1; i++)
{ {
ddg_node_ptr u = &g->nodes[i]; ddg_node_ptr u = &g->nodes[i];
int normalized_time = SCHED_TIME (u) - amount; int normalized_time = SCHED_TIME (u) - amount;
...@@ -607,7 +623,7 @@ duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage, ...@@ -607,7 +623,7 @@ duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage,
/* SCHED_STAGE (u_node) >= from_stage == 0. Generate increasing /* SCHED_STAGE (u_node) >= from_stage == 0. Generate increasing
number of reg_moves starting with the second occurrence of number of reg_moves starting with the second occurrence of
u_node, which is generated if its SCHED_STAGE <= to_stage. */ u_node, which is generated if its SCHED_STAGE <= to_stage. */
i_reg_moves = to_stage - SCHED_STAGE (u_node); i_reg_moves = to_stage - SCHED_STAGE (u_node) + 1;
i_reg_moves = MAX (i_reg_moves, 0); i_reg_moves = MAX (i_reg_moves, 0);
i_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u_node)); i_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u_node));
...@@ -1107,6 +1123,8 @@ sms_schedule (FILE *dump_file) ...@@ -1107,6 +1123,8 @@ sms_schedule (FILE *dump_file)
scheduling passes doesn't touch it. */ scheduling passes doesn't touch it. */
if (! flag_resched_modulo_sched) if (! flag_resched_modulo_sched)
g->bb->flags |= BB_DISABLE_SCHEDULE; g->bb->flags |= BB_DISABLE_SCHEDULE;
/* The life-info is not valid any more. */
g->bb->flags |= BB_DIRTY;
generate_reg_moves (ps); generate_reg_moves (ps);
if (dump_file) if (dump_file)
......
...@@ -575,6 +575,8 @@ rest_of_handle_partition_blocks (void) ...@@ -575,6 +575,8 @@ rest_of_handle_partition_blocks (void)
static void static void
rest_of_handle_sms (void) rest_of_handle_sms (void)
{ {
sbitmap blocks;
timevar_push (TV_SMS); timevar_push (TV_SMS);
open_dump_file (DFI_sms, current_function_decl); open_dump_file (DFI_sms, current_function_decl);
...@@ -587,10 +589,14 @@ rest_of_handle_sms (void) ...@@ -587,10 +589,14 @@ rest_of_handle_sms (void)
/* Update the life information, because we add pseudos. */ /* Update the life information, because we add pseudos. */
max_regno = max_reg_num (); max_regno = max_reg_num ();
allocate_reg_info (max_regno, FALSE, FALSE); allocate_reg_info (max_regno, FALSE, FALSE);
update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES, blocks = sbitmap_alloc (last_basic_block);
(PROP_DEATH_NOTES sbitmap_ones (blocks);
| PROP_KILL_DEAD_CODE update_life_info (blocks, UPDATE_LIFE_GLOBAL_RM_NOTES,
| PROP_SCAN_DEAD_CODE)); (PROP_DEATH_NOTES
| PROP_REG_INFO
| PROP_KILL_DEAD_CODE
| PROP_SCAN_DEAD_CODE));
no_new_pseudos = 1; no_new_pseudos = 1;
ggc_collect (); ggc_collect ();
......
/* This caused an ICE on powerpc-linux-gnu due to not
up-to-date life info (PR middle-end/20177). */
/* { dg-do compile } */
/* { dg-options "-O2 -fmodulo-sched" } */
extern void * malloc (long);
struct s {
int k;
};
int n;
struct s *a1, *(*use)[];
float (*vector)[];
void
foo (float *V)
{
int i, used = 0;
vector = malloc (i * sizeof (float));
while ((*use)[used] != a1)
used += 1;
for (i = 0; i < n; i++)
*V += (*vector)[i];
}
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