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]

[PATCH] Update life info after peephole2 (fix PRs middle-end/19084, rtl-optimization/19348)


Hi!

peephole2 on i?86 or x86_64 -m32 changes:

;; Start of basic block 1, registers live: 1 [dx] 2 [cx] 6 [bp] 7 [sp] 20 [frame]
(note:HI 21 14 23 1 [bb 1] NOTE_INSN_BASIC_BLOCK)

(insn:HI 23 21 24 1 (parallel [
            (set (reg/v:DI 1 dx [orig:60 x ] [60])
                (lshiftrt:DI (reg/v:DI 1 dx [orig:60 x ] [60])
                    (const_int 32 [0x20])))
            (clobber (reg:CC 17 flags))
        ]) 436 {*lshrdi3_1} (nil)
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (expr_list:REG_UNUSED (reg:SI 2 cx)
            (nil))))

(insn:HI 24 23 25 1 (set (reg/v:SI 0 ax [orig:58 u ] [58])
        (reg:SI 1 dx [orig:60 x ] [60])) 41 {*movsi_1} (insn_list:REG_DEP_TRUE 23 (nil))
    (expr_list:REG_DEAD (reg:SI 1 dx [orig:60 x ] [60])
        (nil)))
;; End of basic block 1, registers live: 0 [ax] 6 [bp] 7 [sp] 20 [frame]

into:

;; Start of basic block 1, registers live: 1 [dx] 2 [cx] 6 [bp] 7 [sp] 20 [frame]
(note:HI 21 14 63 1 [bb 1] NOTE_INSN_BASIC_BLOCK)

(insn 63 21 64 1 (set (reg:SI 1 dx [orig:60 x ] [60])
        (reg:SI 2 cx [ x+4 ])) -1 (nil)
    (expr_list:REG_DEAD (reg:SI 2 cx [ x+4 ])
        (nil)))

(insn 64 63 24 1 (parallel [
            (set (reg:SI 2 cx [ x+4 ])
                (const_int 0 [0x0]))
            (clobber (reg:CC 17 flags))
        ]) -1 (nil)
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (expr_list:REG_UNUSED (reg:SI 2 cx [ x+4 ])
            (nil))))

(insn:HI 24 64 25 1 (set (reg/v:SI 0 ax [orig:58 u ] [58])
        (reg:SI 1 dx [orig:60 x ] [60])) 41 {*movsi_1} (insn_list:REG_DEP_TRUE 23 (nil))
    (expr_list:REG_DEAD (reg:SI 1 dx [orig:60 x ] [60])
        (nil)))
;; End of basic block 1, registers live:
 0 [ax] 6 [bp] 7 [sp] 20 [frame]

This means %edx is not live at the start of this bb, but its life info has
not been updated, as peephole2_optimize only updates life info locally,
unless the cfg changed.  The following patch fixes this by doing a global
life info update if the local life info update detected some registers
that used to be live at the start of bb are no longer live.
Do you think this is the right thing to do or should we somehow make sure
this doesn't happen in peepholes?

2005-01-11  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/19084
	PR rtl-optimization/19348
	* recog.c (peephole2_optimize): Do global life update if some peephole
	decides it doesn't need at least one of its inputs and that change
	influences liveness at the start of the basic block.

	* basic-block.h (EXECUTE_IF_AND_COMPL_IN_REG_SET): Needs 2 REGSET
	arguments instead of 1.

	* gcc.dg/20050111-1.c: New test.
	* gcc.c-torture/execute/20050111-1.c: New test.

--- gcc/basic-block.h.jj	2004-12-14 12:21:48.000000000 +0100
+++ gcc/basic-block.h	2005-01-11 13:02:59.361618180 +0100
@@ -98,8 +98,8 @@ typedef bitmap_iterator reg_set_iterator
 /* Loop over all registers in REGSET1 and REGSET2, starting with MIN, setting
    REGNUM to the register number and executing CODE for all registers that are
    set in the first regset and not set in the second.  */
-#define EXECUTE_IF_AND_COMPL_IN_REG_SET(REGSET, MIN, REGNUM, RSI)	\
-  EXECUTE_IF_AND_COMPL_IN_BITMAP (REGSET, MIN, REGNUM, RSI)
+#define EXECUTE_IF_AND_COMPL_IN_REG_SET(REGSET1, REGSET2, MIN, REGNUM, RSI) \
+  EXECUTE_IF_AND_COMPL_IN_BITMAP (REGSET1, REGSET2, MIN, REGNUM, RSI)
 
 /* Loop over all registers in REGSET1 and REGSET2, starting with MIN, setting
    REGNUM to the register number and executing CODE for all registers that are
--- gcc/recog.c.jj	2004-11-27 10:34:59.000000000 +0100
+++ gcc/recog.c	2005-01-11 13:49:29.000000000 +0100
@@ -2968,6 +2968,7 @@ peephole2_optimize (FILE *dump_file ATTR
   bool changed;
 #endif
   bool do_cleanup_cfg = false;
+  bool do_global_life_update = false;
   bool do_rebuild_jump_labels = false;
 
   /* Initialize the regsets we're going to use.  */
@@ -2986,6 +2987,7 @@ peephole2_optimize (FILE *dump_file ATTR
   FOR_EACH_BB_REVERSE (bb)
     {
       struct propagate_block_info *pbi;
+      reg_set_iterator rsi;
 
       /* Indicate that all slots except the last holds invalid data.  */
       for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
@@ -3207,6 +3209,15 @@ peephole2_optimize (FILE *dump_file ATTR
 	    break;
 	}
 
+      /* Some peepholes can decide the don't need one or more of their
+	 inputs.  If this happens, local life update is not enough.  */
+      EXECUTE_IF_AND_COMPL_IN_BITMAP (bb->global_live_at_start, live,
+				      0, i, rsi)
+	{
+	  do_global_life_update = true;
+	  break;
+	}
+
       free_propagate_block_info (pbi);
     }
 
@@ -3223,8 +3234,10 @@ peephole2_optimize (FILE *dump_file ATTR
   if (do_cleanup_cfg)
     {
       cleanup_cfg (0);
-      update_life_info (0, UPDATE_LIFE_GLOBAL_RM_NOTES, PROP_DEATH_NOTES);
+      do_global_life_update = true;
     }
+  if (do_global_life_update)
+    update_life_info (0, UPDATE_LIFE_GLOBAL_RM_NOTES, PROP_DEATH_NOTES);
 #ifdef HAVE_conditional_execution
   else
     {
--- gcc/testsuite/gcc.c-torture/execute/20050111-1.c.jj	2005-01-11 14:29:33.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/execute/20050111-1.c	2005-01-11 14:34:12.597789045 +0100
@@ -0,0 +1,39 @@
+/* PR middle-end/19084, rtl-optimization/19348 */
+
+unsigned int
+foo (unsigned long long x)
+{
+  unsigned int u;
+
+  if (x == 0)
+    return 0;
+  u = (unsigned int) (x >> 32);
+  return u;
+}
+
+unsigned long long
+bar (unsigned short x)
+{
+  return (unsigned long long) x << 32;
+}
+
+extern void abort (void);
+
+int
+main (void)
+{
+  if (sizeof (long long) != 8)
+    return 0;
+
+  if (foo (0) != 0)
+    abort ();
+  if (foo (0xffffffffULL) != 0)
+    abort ();
+  if (foo (0x25ff00ff00ULL) != 0x25)
+    abort ();
+  if (bar (0) != 0)
+    abort ();
+  if (bar (0x25) != 0x2500000000ULL)
+    abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.dg/20050111-1.c.jj	2005-01-11 14:29:33.566574065 +0100
+++ gcc/testsuite/gcc.dg/20050111-1.c	2005-01-11 14:34:47.242607173 +0100
@@ -0,0 +1,24 @@
+/* PR middle-end/19084, rtl-optimization/19348 */
+/* { dg-do compile } */
+/* The following ensures that this test is compiled with -O2, unless
+   on i?86 or x86_64 with -m32 option.  */
+/* { dg-options "-O2" } */
+/* { dg-options "-O2 -march=i686" { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2" { target lp64 } } */
+
+unsigned int
+foo (unsigned long long x)
+{
+  unsigned int u;
+
+  if (x == 0)
+    return 0;
+  u = (unsigned int) (x >> 32);
+  return u;
+}
+
+unsigned long long
+bar (unsigned short x)
+{
+  return (unsigned long long) x << 32;
+}

	Jakub


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