patch that caused regression PR f/9258

Jan Hubicka jh@suse.cz
Tue Jan 14 20:05:00 GMT 2003


> The regression reported in PR f/9258 ([3.2/3.3/3.4 regression] ICE in
> compensate_edge, at reg-stack.c:2589) showed up with this patch:
> 
> Sat Jun 23 01:23:59 CEST 2001  Jan Hubicka  <jh@suse.cz>
> 
>       * flow.c (mark_set_1, attempt_auto_inc, mark_used_reg,
>       try_pre_increment_1): compute REG_FREQ using bb->frequency.
> 
>       * regclass.c (loop_cost): Kill.
>       (frequency): New global variable.
>       (record_operand_costs): Replace loop_cost by frequency.
>       (scan_one_insn): Likewise.
>       (regclass): Likewise; set frequency according to bb->frequency.
> 
>       * flow.c (split_edge): Set frequency.
> 
> I used the minimized test case from the PR and got the same ICE message.
> This information has been added to the PR.
> 
> Janis

Hi,
the problem is that register allocator produces stack register live across
abnormal edge.  This is because it decides to ignore the conflict with stack
register added for this reason believing that it is just local alloc stupidity
- funny feature.
Only way around this I found is the attached patch.

      SUBROUTINE FOO (B)

   10 CALL BAR(A)
      ASSIGN 20 TO M
      IF(100.LT.A) GOTO 10
      GOTO 40
C
   20 IF(B.LT.ABS(A)) GOTO 10
      ASSIGN 30 TO M
      GOTO 40
C
   30 ASSIGN 10 TO M
   40 GOTO M,(10,20,30)
      END
Tue Jan 14 23:04:44 CET 2003  Jan Hubicka  <jh@suse.cz>

	* global.c (struct allocno): Add no_stack_reg. 
	(global_conflicts): Set no_stack_reg.
	(find_reg): Use it.

*** global.c.old	Tue Jan 14 23:04:16 2003
--- global.c	Tue Jan 14 23:04:20 2003
*************** struct allocno
*** 130,135 ****
--- 130,140 ----
    /* Set of hard registers that some later allocno has a preference for.  */
  
    HARD_REG_SET regs_someone_prefers;
+ 
+ #ifdef STACK_REGS
+   /* Set to true if allocno can't be allocated in the stack register.  */
+   bool no_stack_reg;
+ #endif
  };
  
  static struct allocno *allocno;
*************** global_conflicts ()
*** 706,713 ****
  	    if (e->flags & EDGE_ABNORMAL)
  	      break;
  	  if (e != NULL)
! 	    for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
! 	      record_one_conflict (ax);
  	}
  #endif
        }
--- 711,724 ----
  	    if (e->flags & EDGE_ABNORMAL)
  	      break;
  	  if (e != NULL)
! 	    {
! 	      EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, ax,
! 		{
! 		  allocno[ax].no_stack_reg = 1;
! 		});
! 	      for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
! 		record_one_conflict (ax);
! 	    }
  	}
  #endif
        }
*************** find_reg (num, losers, alt_regs_p, accep
*** 1206,1211 ****
--- 1217,1226 ----
  			(reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
  			 regno)))
  #endif
+ #ifdef STACK_REGS
+ 	     && (!allocno[num].no_stack_reg
+ 		 || regno < FIRST_STACK_REG || regno > LAST_STACK_REG)
+ #endif
  	      )
  	    {
  	      /* We explicitly evaluate the divide results into temporary



More information about the Gcc-patches mailing list