This is the mail archive of the gcc@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]

Re: alpha combine/schedule conflict


On Mon, Oct 27, 1997 at 09:27:50PM -0800, Jim Wilson wrote:
> This is a known problem.  Combine is emitting a lot of USE insns that it
> should not be.  I tried coming up with a patch, but it is known to be
> incomplete/incorrect.

It looks to me that it solved the USE problem in the test case, but
exposed a new bug also related to REG_DEAD notes.  For the test case
I posted at the beginning of this thread I get

(insn 201 199 202 (set (reg/v:DI 71)
        (const_int -1)) 252 {movdi-1} (nil)
    (nil))

(insn 202 201 205 (set (reg/v:DI 71)
        (plus:DI (reg/v:DI 71)
            (const_int 536870912))) 7 {adddi3} (insn_list 201 (nil))
    (expr_list:REG_DEAD (reg/v:DI 71)
        (expr_list:REG_EQUAL (const_int 536870911)
            (nil))))

[...]

(insn 209 207 210 (set (reg:DI 137)
        (leu:DI (reg:DI 135)
            (reg/v:DI 71))) 131 {subdf3+4} (insn_list 202 (insn_list 207 (nil)))
    (expr_list:REG_DEAD (reg/v:DI 71)
        (nil)))

It appears to be simply due to incomplete checking for elim_i1.  The
attached patch (combined with yours because I'm lazy) solves the problem
for the test case.  A sanity three-stage is still going, but I'll let
you know.


r~
Tue Oct 28 01:56:39 1997  Richard Henderson  <rth@cygnus.com>

	* combine.c (try_combine): Don't elim_i1 when it is used in i2src.

Tue Sep 23 12:57:35 1997  Jim Wilson  <wilson@cygnus.com>

        * combine.c (try_combine): When setting elim_i2, check whether newi2pat
        sets i2dest.  When calling distribute_notes for i3dest_killed, pass
        elim_i2 and elim_i1.


Index: combine.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/combine.c,v
retrieving revision 1.4
diff -u -p -d -r1.4 combine.c
--- combine.c	1997/10/16 22:06:43	1.4
+++ combine.c	1997/10/28 18:54:33
@@ -1246,6 +1246,7 @@ try_combine (i3, i2, i1)
   rtx i2pat;
   /* Indicates if I2DEST or I1DEST is in I2SRC or I1_SRC.  */
   int i2dest_in_i2src = 0, i1dest_in_i1src = 0, i2dest_in_i1src = 0;
+  int i1dest_in_i2src = 0;
   int i1_feeds_i3 = 0;
   /* Notes that must be added to REG_NOTES in I3 and I2.  */
   rtx new_i3_notes, new_i2_notes;
@@ -1431,6 +1432,7 @@ try_combine (i3, i2, i1)
   i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src);
   i1dest_in_i1src = i1 && reg_overlap_mentioned_p (i1dest, i1src);
   i2dest_in_i1src = i1 && reg_overlap_mentioned_p (i2dest, i1src);
+  i1dest_in_i2src = i1 && reg_overlap_mentioned_p (i1dest, i2src);
 
   /* See if I1 directly feeds into I3.  It does if I1DEST is not used
      in I2SRC.  */
@@ -2141,10 +2143,12 @@ try_combine (i3, i2, i1)
     rtx i3links, i2links, i1links = 0;
     rtx midnotes = 0;
     register int regno;
-    /* Compute which registers we expect to eliminate.  */
-    rtx elim_i2 = (newi2pat || i2dest_in_i2src || i2dest_in_i1src
+    /* Compute which registers we expect to eliminate.  newi2pat may be setting
+       either i3dest or i2dest, so we must check it.  */
+    rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat))
+		   || i2dest_in_i2src || i2dest_in_i1src
 		   ? 0 : i2dest);
-    rtx elim_i1 = i1 == 0 || i1dest_in_i1src ? 0 : i1dest;
+    rtx elim_i1 = i1 == 0 || i1dest_in_i1src || i1dest_in_i2src ? 0 : i1dest;
 
     /* Get the old REG_NOTES and LOG_LINKS from all our insns and
        clear them.  */
@@ -2305,7 +2309,7 @@ try_combine (i3, i2, i1)
 	distribute_notes (gen_rtx (EXPR_LIST, REG_DEAD, i3dest_killed,
 				   NULL_RTX),
 			  NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
-			  NULL_RTX, NULL_RTX);
+			  elim_i2, elim_i1);
       }
 
     /* For I2 and I1, we have to be careful.  If NEWI2PAT exists and sets

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