OSDN Git Service

PR rtl-optimization/39794
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Apr 2009 06:58:02 +0000 (06:58 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Apr 2009 06:58:02 +0000 (06:58 +0000)
* alias.c (canon_true_dependence): Add x_addr argument.
* rtl.h (canon_true_dependence): Adjust prototype.
* cse.c (check_dependence): Adjust canon_true_dependence callers.
* cselib.c (cselib_invalidate_mem): Likewise.
* gcse.c (compute_transp): Likewise.
* dse.c (scan_reads_nospill): Likewise.
(record_store, check_mem_read_rtx): Likewise.  For non-const-or-frame
addresses pass base->val_rtx as mem_addr, for const-or-frame addresses
canon_base_addr of the group, plus optional offset.
(struct group_info): Rename canon_base_mem to
canon_base_addr.
(get_group_info): Set canon_base_addr to canon_rtx of base, not
canon_rtx of base_mem.

* gcc.dg/pr39794.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146669 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/alias.c
gcc/cse.c
gcc/cselib.c
gcc/dse.c
gcc/gcse.c
gcc/rtl.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr39794.c [new file with mode: 0644]

index 042c56c..a96520a 100644 (file)
@@ -1,3 +1,20 @@
+2009-04-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/39794
+       * alias.c (canon_true_dependence): Add x_addr argument.
+       * rtl.h (canon_true_dependence): Adjust prototype.
+       * cse.c (check_dependence): Adjust canon_true_dependence callers.
+       * cselib.c (cselib_invalidate_mem): Likewise.
+       * gcse.c (compute_transp): Likewise.
+       * dse.c (scan_reads_nospill): Likewise.
+       (record_store, check_mem_read_rtx): Likewise.  For non-const-or-frame
+       addresses pass base->val_rtx as mem_addr, for const-or-frame addresses
+       canon_base_addr of the group, plus optional offset.
+       (struct group_info): Rename canon_base_mem to
+       canon_base_addr.
+       (get_group_info): Set canon_base_addr to canon_rtx of base, not
+       canon_rtx of base_mem.
+
 2009-04-23  Paolo Bonzini  <bonzini@gnu.org>
 
        * config/sh/sh.c (sh_expand_prologue, sh_expand_epilogue):
index acfd934..8a20f46 100644 (file)
@@ -2287,14 +2287,13 @@ true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x,
    Variant of true_dependence which assumes MEM has already been
    canonicalized (hence we no longer do that here).
    The mem_addr argument has been added, since true_dependence computed
-   this value prior to canonicalizing.  */
+   this value prior to canonicalizing.
+   If x_addr is non-NULL, it is used in preference of XEXP (x, 0).  */
 
 int
 canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
-                      const_rtx x, bool (*varies) (const_rtx, bool))
+                      const_rtx x, rtx x_addr, bool (*varies) (const_rtx, bool))
 {
-  rtx x_addr;
-
   if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
     return 1;
 
@@ -2320,7 +2319,8 @@ canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
   if (nonoverlapping_memrefs_p (x, mem))
     return 0;
 
-  x_addr = get_addr (XEXP (x, 0));
+  if (! x_addr)
+    x_addr = get_addr (XEXP (x, 0));
 
   if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode))
     return 0;
index c238efd..3f36a1c 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -1658,7 +1658,7 @@ check_dependence (rtx *x, void *data)
 {
   struct check_dependence_data *d = (struct check_dependence_data *) data;
   if (*x && MEM_P (*x))
-    return canon_true_dependence (d->exp, d->mode, d->addr, *x,
+    return canon_true_dependence (d->exp, d->mode, d->addr, *x, NULL_RTX,
                                  cse_rtx_varies_p);
   else
     return 0;
index 945a4a1..b040231 100644 (file)
@@ -1,6 +1,6 @@
 /* Common subexpression elimination library for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008
+   1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -1483,7 +1483,7 @@ cselib_invalidate_mem (rtx mem_rtx)
            }
          if (num_mems < PARAM_VALUE (PARAM_MAX_CSELIB_MEMORY_LOCATIONS)
              && ! canon_true_dependence (mem_rtx, GET_MODE (mem_rtx), mem_addr,
-                                         x, cselib_rtx_varies_p))
+                                         x, NULL_RTX, cselib_rtx_varies_p))
            {
              has_mem = true;
              num_mems++;
index e0e685b..5ac898c 100644 (file)
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -223,7 +223,7 @@ struct store_info
   /* This canonized mem.  */
   rtx mem;
 
-  /* The result of get_addr on mem.  */
+  /* Canonized MEM address for use by canon_true_dependence.  */
   rtx mem_addr;
 
   /* If this is non-zero, it is the alias set of a spill location.  */
@@ -476,8 +476,8 @@ struct group_info
      do read dependency.  */
   rtx base_mem;
   
-  /* Canonized version of base_mem, most likely the same thing.  */
-  rtx canon_base_mem;
+  /* Canonized version of base_mem's address.  */
+  rtx canon_base_addr;
 
   /* These two sets of two bitmaps are used to keep track of how many
      stores are actually referencing that position from this base.  We
@@ -705,7 +705,7 @@ get_group_info (rtx base)
       gi->rtx_base = base;
       gi->id = rtx_group_next_id++;
       gi->base_mem = gen_rtx_MEM (QImode, base);
-      gi->canon_base_mem = canon_rtx (gi->base_mem);
+      gi->canon_base_addr = canon_rtx (base);
       gi->store1_n = BITMAP_ALLOC (NULL);
       gi->store1_p = BITMAP_ALLOC (NULL);
       gi->store2_n = BITMAP_ALLOC (NULL);
@@ -1286,7 +1286,7 @@ static rtx get_stored_val (store_info_t, enum machine_mode, HOST_WIDE_INT,
 static int
 record_store (rtx body, bb_info_t bb_info)
 {
-  rtx mem, rhs, const_rhs;
+  rtx mem, rhs, const_rhs, mem_addr;
   HOST_WIDE_INT offset = 0;
   HOST_WIDE_INT width = 0;
   alias_set_type spill_alias_set;
@@ -1456,6 +1456,23 @@ record_store (rtx body, bb_info_t bb_info)
   ptr = active_local_stores;
   last = NULL;
   redundant_reason = NULL;
+  mem = canon_rtx (mem);
+  /* For alias_set != 0 canon_true_dependence should be never called.  */
+  if (spill_alias_set)
+    mem_addr = NULL_RTX;
+  else
+    {
+      if (group_id < 0)
+       mem_addr = base->val_rtx;
+      else
+       {
+         group_info_t group
+           = VEC_index (group_info_t, rtx_group_vec, group_id);
+         mem_addr = group->canon_base_addr;
+       }
+      if (offset)
+       mem_addr = plus_constant (mem_addr, offset);
+    }
 
   while (ptr)
     {
@@ -1547,13 +1564,13 @@ record_store (rtx body, bb_info_t bb_info)
          if (canon_true_dependence (s_info->mem, 
                                     GET_MODE (s_info->mem),
                                     s_info->mem_addr,
-                                    mem, rtx_varies_p))
+                                    mem, mem_addr, rtx_varies_p))
            {
              s_info->rhs = NULL;
              s_info->const_rhs = NULL;
            }
        }
-      
+
       /* An insn can be deleted if every position of every one of
         its s_infos is zero.  */
       if (any_positions_needed_p (s_info)
@@ -1580,9 +1597,9 @@ record_store (rtx body, bb_info_t bb_info)
   /* Finish filling in the store_info.  */
   store_info->next = insn_info->store_rec;
   insn_info->store_rec = store_info;
-  store_info->mem = canon_rtx (mem);
+  store_info->mem = mem;
   store_info->alias_set = spill_alias_set;
-  store_info->mem_addr = get_addr (XEXP (mem, 0));
+  store_info->mem_addr = mem_addr;
   store_info->cse_base = base;
   if (width > HOST_BITS_PER_WIDE_INT)
     {
@@ -2006,7 +2023,7 @@ replace_read (store_info_t store_info, insn_info_t store_insn,
 static int
 check_mem_read_rtx (rtx *loc, void *data)
 {
-  rtx mem = *loc;
+  rtx mem = *loc, mem_addr;
   bb_info_t bb_info;
   insn_info_t insn_info;
   HOST_WIDE_INT offset = 0;
@@ -2058,6 +2075,22 @@ check_mem_read_rtx (rtx *loc, void *data)
   read_info->end = offset + width;
   read_info->next = insn_info->read_rec;
   insn_info->read_rec = read_info;
+  /* For alias_set != 0 canon_true_dependence should be never called.  */
+  if (spill_alias_set)
+    mem_addr = NULL_RTX;
+  else
+    {
+      if (group_id < 0)
+       mem_addr = base->val_rtx;
+      else
+       {
+         group_info_t group
+           = VEC_index (group_info_t, rtx_group_vec, group_id);
+         mem_addr = group->canon_base_addr;
+       }
+      if (offset)
+       mem_addr = plus_constant (mem_addr, offset);
+    }
 
   /* We ignore the clobbers in store_info.  The is mildly aggressive,
      but there really should not be a clobber followed by a read.  */
@@ -2128,7 +2161,7 @@ check_mem_read_rtx (rtx *loc, void *data)
              = canon_true_dependence (store_info->mem, 
                                       GET_MODE (store_info->mem),
                                       store_info->mem_addr,
-                                      mem, rtx_varies_p);
+                                      mem, mem_addr, rtx_varies_p);
          
          else if (group_id == store_info->group_id)
            {
@@ -2139,7 +2172,7 @@ check_mem_read_rtx (rtx *loc, void *data)
                  = canon_true_dependence (store_info->mem, 
                                           GET_MODE (store_info->mem),
                                           store_info->mem_addr,
-                                          mem, rtx_varies_p);
+                                          mem, mem_addr, rtx_varies_p);
              
              /* If this read is just reading back something that we just
                 stored, rewrite the read.  */
@@ -2224,7 +2257,7 @@ check_mem_read_rtx (rtx *loc, void *data)
            remove = canon_true_dependence (store_info->mem, 
                                            GET_MODE (store_info->mem),
                                            store_info->mem_addr,
-                                           mem, rtx_varies_p);
+                                           mem, mem_addr, rtx_varies_p);
          
          if (remove)
            {
@@ -3066,8 +3099,9 @@ scan_reads_nospill (insn_info_t insn_info, bitmap gen, bitmap kill)
                  if ((read_info->group_id < 0)
                      && canon_true_dependence (group->base_mem, 
                                                QImode,
-                                               group->canon_base_mem,
-                                               read_info->mem, rtx_varies_p))
+                                               group->canon_base_addr,
+                                               read_info->mem, NULL_RTX,
+                                               rtx_varies_p))
                    {
                      if (kill)
                        bitmap_ior_into (kill, group->group_kill);
index 00f0986..3195c98 100644 (file)
@@ -1,7 +1,7 @@
 /* Global common subexpression elimination/Partial redundancy elimination
    and global constant/copy propagation for GNU compiler.
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008 Free Software Foundation, Inc.
+   2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -2512,7 +2512,7 @@ compute_transp (const_rtx x, int indx, sbitmap *bmap, int set_p)
                    dest_addr = XEXP (list_entry, 0);
 
                    if (canon_true_dependence (dest, GET_MODE (dest), dest_addr,
-                                              x, rtx_addr_varies_p))
+                                              x, NULL_RTX, rtx_addr_varies_p))
                      {
                        if (set_p)
                          SET_BIT (bmap[bb_index], indx);
index 06b0cae..b93c129 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2290,7 +2290,7 @@ extern rtx canon_rtx (rtx);
 extern int true_dependence (const_rtx, enum machine_mode, const_rtx, bool (*)(const_rtx, bool));
 extern rtx get_addr (rtx);
 extern int canon_true_dependence (const_rtx, enum machine_mode, rtx, const_rtx,
-                                 bool (*)(const_rtx, bool));
+                                 rtx, bool (*)(const_rtx, bool));
 extern int read_dependence (const_rtx, const_rtx);
 extern int anti_dependence (const_rtx, const_rtx);
 extern int output_dependence (const_rtx, const_rtx);
index 47f4a80..bb5ffce 100644 (file)
@@ -1,3 +1,8 @@
+2009-04-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/39794
+       * gcc.dg/pr39794.c: New test.
+
 2009-04-23  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/atomic1.adb: New test.
diff --git a/gcc/testsuite/gcc.dg/pr39794.c b/gcc/testsuite/gcc.dg/pr39794.c
new file mode 100644 (file)
index 0000000..2702ba7
--- /dev/null
@@ -0,0 +1,33 @@
+/* PR rtl-optimization/39794 */
+/* { dg-do run } */
+/* { dg-options "-O2 -funroll-loops" } */
+
+extern void abort ();
+
+void
+foo (int *a, int n)
+{
+  int i;
+  for (i = 0; i < n; i++)
+    {
+      a[i] *= 2;
+      a[i + 1] = a[i - 1] + a[i - 2];
+    }
+}
+
+int a[16];
+int ref[16] = { 0, 1, 4, 2, 10, 12, 24, 44,
+               72, 136, 232, 416, 736, 1296, 2304, 2032 };
+
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 16; i++)
+    a[i] = i;
+  foo (a + 2, 16 - 3);
+  for (i = 0; i < 16; i++)
+    if (ref[i] != a[i])
+      abort ();
+  return 0;
+}