OSDN Git Service

* df-problems.c (df_byte_lr_alloc): Don't set problem_data to
[pf3gnuchains/gcc-fork.git] / gcc / dse.c
index 95a351b..534324d 100644 (file)
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -1,5 +1,5 @@
 /* RTL dead store elimination.
-   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    Contributed by Richard Sandiford <rsandifor@codesourcery.com>
    and Kenneth Zadeck <zadeck@naturalbridge.com>
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dse.h"
 #include "optabs.h"
 #include "dbgcnt.h"
+#include "target.h"
 
 /* This file contains three techniques for performing Dead Store
    Elimination (dse).  
@@ -222,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.  */
@@ -463,12 +464,20 @@ struct group_info
      canonical ordering of these that is not based on addresses.  */
   int id;
 
+  /* True if there are any positions that are to be processed
+     globally.  */
+  bool process_globally;
+
+  /* True if the base of this group is either the frame_pointer or
+     hard_frame_pointer.  */
+  bool frame_related;
+
   /* A mem wrapped around the base pointer for the group in order to
      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
@@ -493,14 +502,6 @@ struct group_info
      the positions that are occupied by stores for this group.  */
   bitmap group_kill;
 
-  /* True if there are any positions that are to be processed
-     globally.  */
-  bool process_globally;
-
-  /* True if the base of this group is either the frame_pointer or
-     hard_frame_pointer.  */
-  bool frame_related;
-
   /* The offset_map is used to map the offsets from this base into
      positions in the global bitmaps.  It is only created after all of
      the all of stores have been scanned and we know which ones we
@@ -704,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);
@@ -825,7 +826,7 @@ replace_inc_dec (rtx *r, void *d)
     case POST_INC:
       {
        rtx r1 = XEXP (x, 0);
-       rtx c = gen_int_mode (Pmode, data->size);
+       rtx c = gen_int_mode (data->size, Pmode);
        emit_insn_before (gen_rtx_SET (Pmode, r1, 
                                       gen_rtx_PLUS (Pmode, r1, c)),
                          data->insn);
@@ -836,7 +837,7 @@ replace_inc_dec (rtx *r, void *d)
     case POST_DEC:
       {
        rtx r1 = XEXP (x, 0);
-       rtx c = gen_int_mode (Pmode, -data->size);
+       rtx c = gen_int_mode (-data->size, Pmode);
        emit_insn_before (gen_rtx_SET (Pmode, r1, 
                                       gen_rtx_PLUS (Pmode, r1, c)),
                          data->insn);
@@ -1285,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;
@@ -1455,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)
     {
@@ -1546,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)
@@ -1579,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)
     {
@@ -2005,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;
@@ -2057,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.  */
@@ -2127,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)
            {
@@ -2138,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.  */
@@ -2211,6 +2245,7 @@ check_mem_read_rtx (rtx *loc, void *data)
          if (store_info->rhs
              && store_info->group_id == -1
              && store_info->cse_base == base
+             && width != -1
              && offset >= store_info->begin
              && offset + width <= store_info->end
              && all_positions_needed_p (store_info,
@@ -2223,7 +2258,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)
            {
@@ -3065,8 +3100,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);