This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR optimization/7871
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 2 Feb 2004 22:25:35 +0100
- Subject: [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));
}
}