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]

[RFC] Don't emit REG_DEAD for clobbers if reg stays live


Hello,

> Just as an FYI, Kenny and I have replaced the global liveness analyzer
> with one from df.c, and removed the need for make_accurate_live_analysis
> (ie df.c now does the partial avail liveness stuff).
> 
> We are currently in the process of changing all the other users of life
> analysis to use the df.c liveness, which should solve this problem
> (since they will all then use the accurate life analysis).

Good to hear! Unfortunately this will come too late to fix the bug in gcc 
4.1. What about the following workaround? This one could be fine for 
the 4.1.0 release:

Remember the situation after reload. r1 is used for an uninitialized variable
hence it is live from the beginning to the read of the variable.
The special liveness analyzer in global alloc not considering uninitialized 
quantities to conflict with others assigns r1 also to a local pseudo.

bb 1 start: r1 dead
  insn 1: r1 = 0;
  insn 2: use r1; clobber r1; REG_DEAD (r1) !!!
bb 1 end: r1 live

Due to the REG_DEAD note regrename assumes it is safe to rename r1 locally to r5
resulting in:

bb 1 start: r1 live !!!
  insn 1: r5 = 0;
  insn 2: use r5; clobber r5; REG_DEAD (r5)
bb 1 end: r1 live

Because live at start has changed due to a local change an assertion in flow is
triggered.

The cause of the problem is that we already enter regrename with wrong liveness
info which in turn is caused by using a different liveness analyzer in global alloc
than elsewhere.  We have the register r1 live at the end of the basic block but the
last rtx writing this value is a clobber.  This situation should only occur if we had 
overlapping live ranges which were assigned to the same hard reg. Under normal
circumstances this should be considered a bug and an assertion would be the right
choice. But knowing that this could only be caused by the global alloc liveness 
analyzer the flow analyzer should avoid emitting a REG_DEAD note. That way the
value of the uninitialized variable (which is undefined anyway) would be clobbered
what should not cause any trouble.

The attached patch modifies mark_set_1 to consider a CLOBBER a normal SET if the
clobbered register is live afterwards.

So as a rfc what do you (or anybody else) think about the attached patch for 
mainline gcc.

Bootstrapped on i686, s390 and s390x without testsuite regressions.

This patch fixes the 920501-4.c regression on s390x.

Bye,

-Andreas-


2005-10-13  Andreas Krebbel  <krebbel1@de.ibm.com>

	* flow.c (mark_set_1): Handle CLOBBERs like SETs if the register
	is live afterwards.


Index: gcc/flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.635
diff -p -c -r1.635 flow.c
*** gcc/flow.c	22 Aug 2005 16:58:46 -0000	1.635
--- gcc/flow.c	13 Oct 2005 09:25:51 -0000
*************** mark_set_1 (struct propagate_block_info 
*** 2819,2825 ****
  	      else
  		SET_REGNO_REG_SET (pbi->local_set, i);
  	    }
! 	  if (code != CLOBBER)
  	    SET_REGNO_REG_SET (pbi->new_set, i);
  
  	  some_was_live |= needed_regno;
--- 2819,2825 ----
  	      else
  		SET_REGNO_REG_SET (pbi->local_set, i);
  	    }
! 	  if (code != CLOBBER || needed_regno)
  	    SET_REGNO_REG_SET (pbi->new_set, i);
  
  	  some_was_live |= needed_regno;


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