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] Fix PR optimization/7871


This is my attempt at solving the infamous regression that prevents global 
register variables from working in GCC 3.1 and later.

Let me recap, using the example from PR optimization/10684:

register int STACK __asm__("%ebx");
static void (*p) ();
void f ()
{
  STACK += 1;
  p ();
  STACK -= 1;
} 

The assignment 'STACK += 1;' is deleted at -O because life analysis put a 
REG_DEAD note for %ebx on the call to p.  Here is the chain of events in 
propagate_one_insn:
- upon arriving on the call_insn (backward), %ebx is live,
- the call is interpreted as clobbering %ebx, so that %ebx becomes dead,
- the call is interpreted as using %ebx, so that %ebx is marked live again.  
But, since it was previously dead, the REG_DEAD is issued by mark_used_reg.

The proposed fix is to use a feature of mark_used_reg: it doesn't issue the 
REG_DEAD note if the insn is setting (not merely clobbering) the register.

  /* Record and count the insns in which a reg dies.  If it is used in
     this insn and was dead below the insn then it dies in this insn.
     If it was set in this insn, we do not make a REG_DEAD note;
     likewise if we already made such a note.  */
  if ((pbi->flags & (PROP_DEATH_NOTES | PROP_REG_INFO))
      && some_was_dead
      && some_not_set)

So calls would be interpreted as both using and setting global registers, 
instead of both using and clobbering them. 

Does that make sense?  The patch is sufficient to fix PR opt/10684 (on x86) 
and PR opt/11252 (on SPARC).  I couldn't test on the testcase for PR opt/7871 
because the cross-compiler to m68k-unknown-linux-gnu doesn't build on 
mainline.


2004-02-02  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR optimization/7871
	* flow.c (propagate_one_insn): Interpret calls as setting global
	registers, not merely clobbering them.


-- 
Eric Botcazou
Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.574
diff -u -p -r1.574 flow.c
--- flow.c	29 Jan 2004 07:47:54 -0000	1.574
+++ flow.c	2 Feb 2004 21:07:45 -0000
@@ -1739,8 +1739,9 @@ propagate_one_insn (struct propagate_blo
 					      current_function_return_rtx,
 					      (rtx *) 0)))
 	      {
+		enum rtx_code code = global_regs[i] ? SET : CLOBBER;
 		/* We do not want REG_UNUSED notes for these registers.  */
-		mark_set_1 (pbi, CLOBBER, regno_reg_rtx[i], cond, insn,
+		mark_set_1 (pbi, code, regno_reg_rtx[i], cond, insn,
 			    pbi->flags & ~(PROP_DEATH_NOTES | PROP_REG_INFO));
 	      }
 	}

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