Reload inheritance fix

Bernd Schmidt bernds@redhat.co.uk
Sat Sep 16 09:31:00 GMT 2000


Testing an sh-elf toolchain with a commercial C testsuite showed up a problem
with reload inheritance.  Suppose you have a situation like this:

(set (pseudo A) (foo)
[...]
(set (pseudo B) (bar)
[...]
(... (use (pseudo B)) ... (REG_DEAD pseudo B))
[...]
(... (use pseudo A) ...)
(... (use pseudo A) ... (REG_DEAD pseudo A))

where pseudo B gets allocted to hard reg X, and pseudo A fails to get a hard
reg.

For the first insn, reload chooses to reload A into hard reg X, setting
spill_reg_store etc. accordingly.  It gets replaced with

  (set (reg X) (foo))
  (set (mem some_stack_slot) (reg X))

When we reach the last insn, we see that we have inherited pseudo A, this
pseudo is dead here, and we had a spill in the first insn that stored the
pseudo into memory.  Since we inherited the pseudo, we can delete the
old output reload, right?

Not quite.  We did inherit pseudo A in the last insn, but we inherited the
input reload from the immediately preceding insn.  The original output reload
should have been long forgotten, since register X is clobbered by the set of
pseudo B.  This is recognized by forget_old_reloads_1, but for some reason
that function does not clear spill_reg_store.  The patch below changes it
to do that, which fixes the problem.

Note: there's another place in reload which looks like it attempts to fix the
same problem:

                  /* If reg_reloaded_valid is not set for this register,
                     there might be a stale spill_reg_store lying around.
                     We must clear it, since otherwise emit_reload_insns
                     might delete the store.  */
                  if (! TEST_HARD_REG_BIT (reg_reloaded_valid, regno))
                    spill_reg_store[regno] = NULL_RTX;

I have a feeling that this may be unnecessary with the patch below, but I
don't want to risk deleting it now.


Bernd

	* reload1.c (forget_old_reloads_1): If a hard reg is stored, clear
	its entry in spill_reg_store.

Index: reload1.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/reload1.c,v
retrieving revision 1.275
diff -u -p -r1.275 reload1.c
--- reload1.c	2000/09/08 02:44:11	1.275
+++ reload1.c	2000/09/16 16:21:14
@@ -4020,7 +4020,10 @@ forget_old_reloads_1 (x, ignored, data)
 	   reload reg in the current instruction.  */
 	if (n_reloads == 0
 	    || ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i))
-	  CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
+	  {
+	    CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
+	    spill_reg_store[regno + i] = 0;
+	  }
     }
 
   /* Since value of X has changed,



More information about the Gcc-patches mailing list