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]

More update_equiv_regs improvements


Fri Feb  5 12:34:12 1999  J"orn Rennecke <amylaar@cygnus.co.uk>

	* local-alloc.c (update_equiv_regs): Allow equivalences for
	likely-spilled regs when source and destination register classes
	are identical.

	Allow two-insn sequences that set the same register to set up
	an equivalence.

Index: local-alloc.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/local-alloc.c,v
retrieving revision 1.93.4.1
diff -p -r1.93.4.1 local-alloc.c
*** local-alloc.c	1999/02/05 09:18:49	1.93.4.1
--- local-alloc.c	1999/02/05 12:30:23
*************** update_equiv_regs ()
*** 684,689 ****
--- 684,690 ----
        rtx set;
        rtx dest, src;
        int regno;
+       rtx next;
  
        if (GET_CODE (insn) == NOTE)
  	{
*************** update_equiv_regs ()
*** 785,797 ****
  	  continue;
  	}
        /* Don't handle the equivalence if the source is in a register
! 	 class that's likely to be spilled.  */
        if (GET_CODE (src) == REG
  	  && REGNO (src) >= FIRST_PSEUDO_REGISTER
! 	  && CLASS_LIKELY_SPILLED_P (reg_preferred_class (REGNO (src))))
  	{
  	  no_equiv (dest, set);
  	  continue;
  	}
  
        note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
--- 786,838 ----
  	  continue;
  	}
        /* Don't handle the equivalence if the source is in a register
! 	 class that's likely to be spilled, and different from the
! 	 class of the destination.  */
        if (GET_CODE (src) == REG
  	  && REGNO (src) >= FIRST_PSEUDO_REGISTER
! 	  && CLASS_LIKELY_SPILLED_P (reg_preferred_class (REGNO (src)))
! 	  && (reg_preferred_class (REGNO (dest))
! 	      != reg_preferred_class (REGNO (src))))
  	{
  	  no_equiv (dest, set);
  	  continue;
+ 	}
+ 
+       /* Sometimes there are sequences like:
+ 	 (insn ... (set (reg:SI 90) (symbol_ref:SI ("x"))))
+ 	  ...
+ 	 (insn ... (set (reg:SI 91) (reg:SI 90)))
+ 
+ 	 (insn ... (set (reg:SI 91) (plus:SI (reg:SI 91) (const_int 4)))
+ 	   (expr_list:REG_EQUAL (const:SI (plus:SI (symbol_ref:SI ("x"))
+ 						   (const_int 4)))))
+ 	 Then we can ignore the first set of the second register.  */
+ 	 
+       next = next_nonnote_insn (insn);
+       if (next)
+ 	{
+ 	  rtx set2 = single_set (next);
+ 	  if (set2 && SET_DEST (set2) == dest)
+ 	    {
+ 	      rtx src2 = SET_SRC (set2);
+ 
+ 	      note = find_reg_note (next, REG_EQUAL, NULL_RTX);
+ 	      if (note)
+ 		src2 = XEXP (note, 0);
+ 
+ 	      if (function_invariant_p (src2))
+ 		{
+ 		  /* If we eventually get an equivalence, we must make sure
+ 		     that this insn is removed too.  So we give it a matching
+ 		     REG_EQUIV note for reload to find.  */
+ 		  REG_NOTES (insn)
+ 		    = gen_rtx_EXPR_LIST (REG_EQUIV, src2, REG_NOTES (insn));
+ 		  reg_equiv_init_insns[regno]
+ 		    = gen_rtx_INSN_LIST (VOIDmode, insn,
+ 					 reg_equiv_init_insns[regno]);
+ 		  continue;
+ 		}
+ 	    }
  	}
  
        note = find_reg_note (insn, REG_EQUAL, NULL_RTX);


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