fix for 930621-1.c failure

Geoff Keating geoffk@cygnus.com
Mon Oct 23 11:34:00 GMT 2000


This fixes the recent compile/930621-1.c failure introduced by

Fri Oct 20 00:57:00 EDT 2000  John Wehle  (john@feith.com)

       * local-alloc.c (equivalence): New structure.
       (reg_equiv): Define.
       (contains_replace_regs): Remove array and use
       field in reg_equiv.
       (memref_referenced_p): Likewise.
       (no_equiv): Likewise.
       (update_equiv_regs): Likewise.

       (equiv_init_varies_p,
       equiv_init_movable_p): New functions.
       (update_equiv_regs): Use them.  Use rtx_varies_p
       instead of function_invariant_p.  Process insns
       from end to beginning.  Allow a REG_EQUIV insn
       within the same loop as a use to be moved, also
       allow it to be moved out of a loop.  Update
       REG_DEAD notes when substituting into an insn.

and spotted by the regression tester.

I didn't look into the actual sequence of execution the bug causes,
since from inspection of the loop it's obvious that there's at least
one way it can process the same insn twice.

Bootstrapped and tested on powerpc-linux.

-- 
- Geoffrey Keating <geoffk@cygnus.com>

===File ~/patches/cygnus/gcc-localalloc.patch===============
2000-10-23  Geoff Keating  <geoffk@cygnus.com>

	* local-alloc.c (update_equiv_regs): Add an abort().  When
	deleting or moving insns, update reg_equiv[regno].init_insns.

Index: local-alloc.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/local-alloc.c,v
retrieving revision 1.71
diff -p -u -u -p -r1.71 local-alloc.c
--- local-alloc.c	2000/10/20 04:56:21	1.71
+++ local-alloc.c	2000/10/23 18:27:19
@@ -1088,6 +1088,9 @@ update_equiv_regs ()
 		 once and used once.  (If it were only set, but not used,
 		 flow would have deleted the setting insns.)  Hence
 		 there can only be one insn in reg_equiv[REGNO].init_insns.  */
+	      if (reg_equiv[regno].init_insns == NULL_RTX
+		  || XEXP (reg_equiv[regno].init_insns, 1) != NULL_RTX)
+		abort ();
 	      equiv_insn = XEXP (reg_equiv[regno].init_insns, 0);
 
 	      if (asm_noperands (PATTERN (equiv_insn)) < 0
@@ -1123,20 +1126,27 @@ update_equiv_regs ()
 		  PUT_CODE (equiv_insn, NOTE);
 		  NOTE_LINE_NUMBER (equiv_insn) = NOTE_INSN_DELETED;
 		  NOTE_SOURCE_FILE (equiv_insn) = 0;
+		  
+		  reg_equiv[regno].init_insns = 
+		    XEXP (reg_equiv[regno].init_insns, 1);
 		}
 	      /* Move the initialization of the register to just before
 		 INSN.  Update the flow information.  */
 	      else if (PREV_INSN (insn) != equiv_insn)
 		{
 		  int l;
+		  rtx new_insn;
 
-		  emit_insn_before (copy_rtx (PATTERN (equiv_insn)), insn);
+		  new_insn = emit_insn_before (copy_rtx (PATTERN (equiv_insn)),
+					       insn);
 		  REG_NOTES (PREV_INSN (insn)) = REG_NOTES (equiv_insn);
 		  REG_NOTES (equiv_insn) = 0;
 
 		  PUT_CODE (equiv_insn, NOTE);
 		  NOTE_LINE_NUMBER (equiv_insn) = NOTE_INSN_DELETED;
 		  NOTE_SOURCE_FILE (equiv_insn) = 0;
+
+		  XEXP (reg_equiv[regno].init_insns, 0) = new_insn;
 
 		  REG_BASIC_BLOCK (regno) = block >= 0 ? block : 0;
 		  REG_N_CALLS_CROSSED (regno) = 0;
============================================================


More information about the Gcc-patches mailing list