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]

Re: [PATCH/RFC] [PR optimization/13567] Don't cse no-conflict block


Jim Wilson <wilson@specifixinc.com> wrote:
> This looks like the right idea.  However, it looks like you are skipping
> over the last instruction of a no-conflict block, which has the
> REG_EQUAL note.  We actually do want cse to use this note, as this may
> be useful for later optimizations.  I think skipping all of the insns
> inside the no-conflict block, but still handling the last one is right. 
> So I'd suggest clearing no_conflict (along with libcall_insn) when we
> see a REG_RETVAL note.  I think this is better if it works.

I've tried this.  Unfortunately, my testcase failed with it.
The destination of the last identity SET insn of the no-conflict
block was changed by cse.

> Another alternative is setting libcall_insn when we see a
> REG_NO_CONFLICT note, instead of setting the new no_conflict variable. 
> There is already code to suppress recording dest values set when
> libcall_insn is set.  This may be enough to solve the problem.  If so, I
> think this is an ever better fix, since simple cse of insn sources
> inside the no-conflict block may result in better code.

The original code is setting libcall_insn between the insn with
REG_LIBCALL note and the previous insn of the last one with
REG_RETVAL note.  So it seems insns with REG_NO_CONFLICT note
are processed so already.

Your suggestion means that we can avoid this problem if the last
insn of the no-conflict block was handled with a non-null libcall_insn,
doesn't it?  If so, how about this?  It passed my testcase.  If it
looks OK, I'll test it with bootstrap and regression tests.
Thanks for your suggestions.

Regards,
	kaz
--
2004-01-08  Kaz Kojima  <kkojima@gcc.gnu.org>

	PR optimization/13567
	* cse.c (cse_basic_block): Call cse_insn with a non-null
	libcall_insn for the last SET insn of a no-confilict block.

diff -u3prN ORIG/gcc/gcc/cse.c LOCAL/gcc/gcc/cse.c
--- ORIG/gcc/gcc/cse.c	Fri Dec  5 09:25:44 2003
+++ LOCAL/gcc/gcc/cse.c	Thu Jan  8 18:41:50 2004
@@ -1,6 +1,6 @@
 /* Common subexpression elimination for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
-   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -7103,6 +7103,7 @@ cse_basic_block (rtx from, rtx to, struc
   int to_usage = 0;
   rtx libcall_insn = NULL_RTX;
   int num_insns = 0;
+  int no_conflict = 0;
 
   /* This array is undefined before max_reg, so only allocate
      the space actually needed and adjust the start.  */
@@ -7182,11 +7183,26 @@ cse_basic_block (rtx from, rtx to, struc
 	      if ((p = find_reg_note (insn, REG_LIBCALL, NULL_RTX)))
 		libcall_insn = XEXP (p, 0);
 	      else if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
-		libcall_insn = 0;
+		{
+		  /* Keep libcall_insn for the last SET insn of a no-conflict
+		     block to prevent changing the destination.  */
+		  if (! no_conflict)
+		    libcall_insn = 0;
+		  else
+		    no_conflict = -1;
+		}
+	      else if (find_reg_note (insn, REG_NO_CONFLICT, NULL_RTX))
+		no_conflict = 1;
 	    }
 
 	  cse_insn (insn, libcall_insn);
 
+	  if (no_conflict == -1)
+	    {
+	      libcall_insn = 0;
+	      no_conflict = 0;
+	    }
+	    
 	  /* If we haven't already found an insn where we added a LABEL_REF,
 	     check this one.  */
 	  if (GET_CODE (insn) == INSN && ! recorded_label_ref


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