[Bug middle-end/20177] ICE in schedule-insns for -O2 -fmodulo-sched

mustafa at il dot ibm dot com gcc-bugzilla@gcc.gnu.org
Thu Mar 17 11:53:00 GMT 2005


------- Additional Comments From mustafa at il dot ibm dot com  2005-03-17 11:53 -------
The following patch should fix the Segmentation fault in gap (from SPEC2000)
mentioned in <a href="#c14">comment 14</a>. This patch is combined with the
patch from <a href="#c13">comment 13</a>. Janis can you try it out.

Index: ddg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ddg.c,v
retrieving revision 1.11
diff -c -p -r1.11 ddg.c
*** ddg.c	22 Nov 2004 12:23:47 -0000	1.11
--- ddg.c	17 Mar 2005 11:20:37 -0000
*************** create_ddg_dependence (ddg_ptr g, ddg_no
*** 187,192 ****
--- 187,194 ----
        else
  	free (e);
      }
+   else if (t == ANTI_DEP && dt == REG_DEP)
+     free (e);  /* We can fix broken anti register deps using reg-moves.  */
    else
      add_edge_to_ddg (g, e);
  }
Index: modulo-sched.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/modulo-sched.c,v
retrieving revision 1.19
diff -c -p -r1.19 modulo-sched.c
*** modulo-sched.c	1 Dec 2004 00:33:05 -0000	1.19
--- modulo-sched.c	17 Mar 2005 11:20:38 -0000
*************** const_iteration_count (rtx count_reg, ba
*** 339,344 ****
--- 339,348 ----
  {
    rtx insn;
    rtx head, tail;
+ 
+   if (! pre_header)
+     return NULL_RTX;
+ 
    get_block_head_tail (pre_header->index, &head, &tail);
  
    for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn))
*************** print_node_sched_params (FILE * dump_fil
*** 401,406 ****
--- 405,412 ----
  {
    int i;
  
+   if (! dump_file)
+     return;
    for (i = 0; i < num_nodes; i++)
      {
        node_sched_params_ptr nsp = &node_sched_params[i];
*************** calculate_maxii (ddg_ptr g)
*** 443,456 ****
    return maxii;
  }
  
! 
! /* Given the partial schedule, generate register moves when the length
!    of the register live range is more than ii; the number of moves is
!    determined according to the following equation:
! 		SCHED_TIME (use) - SCHED_TIME (def)   { 1 broken loop-carried
!    nreg_moves = ----------------------------------- - {   dependence.
! 			      ii		      { 0 if not.
!    This handles the modulo-variable-expansions (mve's) needed for the ps.  */
  static void
  generate_reg_moves (partial_schedule_ptr ps)
  {
--- 449,465 ----
    return maxii;
  }
  
! /*
!    Breaking intra-loop register anti-dependences:
!    Each intra-loop register anti-dependence implies a cross-iteration true
!    dependence of distance 1. Therefore, we can remove such false dependencies
!    and figure out if the partial schedule broke them by checking if (for a
!    true-dependence of distance 1): SCHED_TIME (def) < SCHED_TIME (use) and
!    if so generate a register move.   The number of such moves is equal to:
!               SCHED_TIME (use) - SCHED_TIME (def)       { 0 broken
!    nreg_moves = ----------------------------------- + 1 - {   dependecnce.
!                             ii                          { 1 if not.
! */
  static void
  generate_reg_moves (partial_schedule_ptr ps)
  {
*************** generate_reg_moves (partial_schedule_ptr
*** 474,479 ****
--- 483,491 ----
  	  {
  	    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
  	       will read before src writes and we can save one reg_copy.  */
  	    if (SCHED_ROW (e->dest) == SCHED_ROW (e->src)
*************** generate_reg_moves (partial_schedule_ptr
*** 497,502 ****
--- 509,517 ----
  	  {
  	    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)
  		&& SCHED_COLUMN (e->dest) < SCHED_COLUMN (e->src))
  	      dest_copy--;
*************** normalize_sched_times (partial_schedule_
*** 539,546 ****
    ddg_ptr g = ps->g;
    int amount = PS_MIN_CYCLE (ps);
    int ii = ps->ii;
! 
!   for (i = 0; i < g->num_nodes; i++)
      {
        ddg_node_ptr u = &g->nodes[i];
        int normalized_time = SCHED_TIME (u) - amount;
--- 554,561 ----
    ddg_ptr g = ps->g;
    int amount = PS_MIN_CYCLE (ps);
    int ii = ps->ii;
!   /* 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];
        int normalized_time = SCHED_TIME (u) - amount;
*************** duplicate_insns_of_cycles (partial_sched
*** 609,615 ****
  	    /* SCHED_STAGE (u_node) >= from_stage == 0.  Generate increasing
  	       number of reg_moves starting with the second occurrence of
  	       u_node, which is generated if its SCHED_STAGE <= to_stage.  */
! 	    i_reg_moves = to_stage - SCHED_STAGE (u_node);
  	    i_reg_moves = MAX (i_reg_moves, 0);
  	    i_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u_node));
  
--- 624,630 ----
  	    /* SCHED_STAGE (u_node) >= from_stage == 0.  Generate increasing
  	       number of reg_moves starting with the second occurrence of
  	       u_node, which is generated if its SCHED_STAGE <= to_stage.  */
! 	    i_reg_moves = to_stage - SCHED_STAGE (u_node) + 1;
  	    i_reg_moves = MAX (i_reg_moves, 0);
  	    i_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u_node));
  
*************** sms_schedule (FILE *dump_file)
*** 1109,1114 ****
--- 1124,1131 ----
  	     scheduling passes doesn't touch it.  */
  	  if (! flag_resched_modulo_sched)
  	    g->bb->flags |= BB_DISABLE_SCHEDULE;
+ 	  /* The life-info is not valid any more.  */
+ 	  g->bb->flags |= BB_DIRTY;
  
  	  generate_reg_moves (ps);
  	  if (dump_file)


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20177



More information about the Gcc-bugs mailing list