This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] S/390: optimize prologue bug


Hi,

the attached patch fixes a bug in the s390 back end.

The s390_optimize_prologue function is called during
machine dependent reorg trying to take back saving
decisions made in flow for a few special registers.

Unfortunately that function sometimes spuriously identified
a saving insn and therefore replaced the wrong insn.

The checks I've added allow replacement of insns only if the registers 
saved by the new insn are a subset of the registers saved by the former 
insn.
Otherwise the insn to be replaced can't be one of the insn we are
trying to optimize. In the flow step we make pessimistic assumptions
about the registers we need to save. So the only thing new insns
introduced by s390_optimize_prologue are allowed to do is saving 
less registers than before.

This is a 4.0 regression against 3.4 because that misbehaviour is only
revealed with the packed stack layout. With the former fixed stack
layout an insn saving more registers than necessary could never
clobber another stack area.

Bootstrapped on 4.0 and mainline on s390, s390x without testsuite regressions.

OK for 4.0 and mainline?

Bye,

-Andreas-

2005-05-17  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/s390.c (s390_optimize_prologue): Don't replace an insn
	saving less registers than the replacement.

Index: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.229
diff -p -c -r1.229 s390.c
*** gcc/config/s390/s390.c	10 May 2005 20:43:34 -0000	1.229
--- gcc/config/s390/s390.c	17 May 2005 14:56:47 -0000
*************** s390_optimize_prologue (void)
*** 7951,7956 ****
--- 7951,7960 ----
  
  	  if (GET_CODE (base) != REG || off < 0)
  	    continue;
+ 	  if (cfun_frame_layout.first_save_gpr != -1
+ 	      && (cfun_frame_layout.first_save_gpr < first
+ 		  || cfun_frame_layout.last_save_gpr > last))
+ 	    continue;
  	  if (REGNO (base) != STACK_POINTER_REGNUM
  	      && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
  	    continue;
*************** s390_optimize_prologue (void)
*** 7972,7978 ****
  	  continue;
  	}
  
!       if (GET_CODE (PATTERN (insn)) == SET
  	  && GET_CODE (SET_SRC (PATTERN (insn))) == REG
  	  && (REGNO (SET_SRC (PATTERN (insn))) == BASE_REGNUM
  	      || (!TARGET_CPU_ZARCH
--- 7976,7983 ----
  	  continue;
  	}
  
!       if (cfun_frame_layout.first_save_gpr == -1
! 	  && GET_CODE (PATTERN (insn)) == SET
  	  && GET_CODE (SET_SRC (PATTERN (insn))) == REG
  	  && (REGNO (SET_SRC (PATTERN (insn))) == BASE_REGNUM
  	      || (!TARGET_CPU_ZARCH
*************** s390_optimize_prologue (void)
*** 7990,8005 ****
  	  if (REGNO (base) != STACK_POINTER_REGNUM
  	      && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
  	    continue;
- 	  if (cfun_frame_layout.first_save_gpr != -1)
- 	    {
- 	      new_insn = save_gprs (base, 
- 				    off + (cfun_frame_layout.first_save_gpr 
- 					   - first) * UNITS_PER_WORD, 
- 				    cfun_frame_layout.first_save_gpr,
- 				    cfun_frame_layout.last_save_gpr);
- 	      new_insn = emit_insn_before (new_insn, insn);
- 	      INSN_ADDRESSES_NEW (new_insn, -1);
- 	    }
  
  	  remove_insn (insn);
  	  continue;
--- 7995,8000 ----
*************** s390_optimize_prologue (void)
*** 8017,8022 ****
--- 8012,8021 ----
  
  	  if (GET_CODE (base) != REG || off < 0)
  	    continue;
+ 	  if (cfun_frame_layout.first_restore_gpr != -1
+ 	      && (cfun_frame_layout.first_restore_gpr < first
+ 		  || cfun_frame_layout.last_restore_gpr > last))
+ 	    continue;
  	  if (REGNO (base) != STACK_POINTER_REGNUM
  	      && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
  	    continue;
*************** s390_optimize_prologue (void)
*** 8038,8044 ****
  	  continue;
  	}
  
!       if (GET_CODE (PATTERN (insn)) == SET
  	  && GET_CODE (SET_DEST (PATTERN (insn))) == REG
  	  && (REGNO (SET_DEST (PATTERN (insn))) == BASE_REGNUM
  	      || (!TARGET_CPU_ZARCH
--- 8037,8044 ----
  	  continue;
  	}
  
!       if (cfun_frame_layout.first_restore_gpr == -1
! 	  && GET_CODE (PATTERN (insn)) == SET
  	  && GET_CODE (SET_DEST (PATTERN (insn))) == REG
  	  && (REGNO (SET_DEST (PATTERN (insn))) == BASE_REGNUM
  	      || (!TARGET_CPU_ZARCH
*************** s390_optimize_prologue (void)
*** 8056,8071 ****
  	  if (REGNO (base) != STACK_POINTER_REGNUM
  	      && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
  	    continue;
- 	  if (cfun_frame_layout.first_restore_gpr != -1)
- 	    {
- 	      new_insn = restore_gprs (base, 
- 				       off + (cfun_frame_layout.first_restore_gpr 
- 					      - first) * UNITS_PER_WORD,
- 				       cfun_frame_layout.first_restore_gpr,
- 				       cfun_frame_layout.last_restore_gpr);
- 	      new_insn = emit_insn_before (new_insn, insn);
- 	      INSN_ADDRESSES_NEW (new_insn, -1);
- 	    }
  
  	  remove_insn (insn);
  	  continue;
--- 8056,8061 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]