OSDN Git Service

PR testsuite/37241
[pf3gnuchains/gcc-fork.git] / gcc / dse.c
index 4394600..0a3ebb4 100644 (file)
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -1,5 +1,5 @@
 /* RTL dead store elimination.
-   Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
    Contributed by Richard Sandiford <rsandifor@codesourcery.com>
    and Kenneth Zadeck <zadeck@naturalbridge.com>
@@ -345,7 +345,7 @@ struct insn_info
   /* The linked list of insns that are in consideration for removal in
      the forwards pass thru the basic block.  This pointer may be
      trash as it is not cleared when a wild read occurs.  The only
-     time it is guaranteed to be correct is when the traveral starts
+     time it is guaranteed to be correct is when the traversal starts
      at active_local_stores.  */
   struct insn_info * next_local_store;
 };
@@ -531,7 +531,7 @@ struct clear_alias_mode_holder
 
 static alloc_pool clear_alias_mode_pool;
 
-/* This is true except if current_function_stdarg -- i.e. we cannot do
+/* This is true except if cfun->stdarg -- i.e. we cannot do
    this for vararg functions because they play games with the frame.  */
 static bool stores_off_frame_dead_at_return;
 
@@ -592,7 +592,7 @@ clear_alias_set_lookup (alias_set_type alias_set)
   slot = htab_find_slot (clear_alias_mode_table, &tmp_holder, NO_INSERT);
   gcc_assert (*slot);
   
-  return *slot;
+  return (struct clear_alias_mode_holder *) *slot;
 }
 
 
@@ -638,7 +638,8 @@ get_group_info (rtx base)
     {
       if (!clear_alias_group)
        {
-         clear_alias_group = gi = pool_alloc (rtx_group_info_pool);
+         clear_alias_group = gi =
+           (group_info_t) pool_alloc (rtx_group_info_pool);
          memset (gi, 0, sizeof (struct group_info));
          gi->id = rtx_group_next_id++;
          gi->store1_n = BITMAP_ALLOC (NULL);
@@ -658,7 +659,7 @@ get_group_info (rtx base)
 
   if (gi == NULL)
     {
-      *slot = gi = pool_alloc (rtx_group_info_pool);
+      *slot = gi = (group_info_t) pool_alloc (rtx_group_info_pool);
       gi->rtx_base = base;
       gi->id = rtx_group_next_id++;
       gi->base_mem = gen_rtx_MEM (QImode, base);
@@ -718,7 +719,7 @@ dse_step0 (void)
   bb_table = XCNEWVEC (bb_info_t, last_basic_block);
   rtx_group_next_id = 0;
 
-  stores_off_frame_dead_at_return = !current_function_stdarg;
+  stores_off_frame_dead_at_return = !cfun->stdarg;
 
   init_alias_analysis ();
   
@@ -782,10 +783,9 @@ replace_inc_dec (rtx *r, void *d)
       {
        rtx r1 = XEXP (x, 0);
        rtx c = gen_int_mode (Pmode, data->size);
-       add_insn_before (data->insn, 
-                        gen_rtx_SET (Pmode, r1, 
-                                     gen_rtx_PLUS (Pmode, r1, c)),
-                        NULL);
+       emit_insn_before (gen_rtx_SET (Pmode, r1, 
+                                      gen_rtx_PLUS (Pmode, r1, c)),
+                         data->insn);
        return -1;
       }
                 
@@ -794,10 +794,9 @@ replace_inc_dec (rtx *r, void *d)
       {
        rtx r1 = XEXP (x, 0);
        rtx c = gen_int_mode (Pmode, -data->size);
-       add_insn_before (data->insn, 
-                        gen_rtx_SET (Pmode, r1, 
-                                     gen_rtx_PLUS (Pmode, r1, c)),
-                        NULL);
+       emit_insn_before (gen_rtx_SET (Pmode, r1, 
+                                      gen_rtx_PLUS (Pmode, r1, c)),
+                         data->insn);
        return -1;
       }
        
@@ -808,8 +807,7 @@ replace_inc_dec (rtx *r, void *d)
           insn that contained it.  */
        rtx add = XEXP (x, 0);
        rtx r1 = XEXP (add, 0);
-       add_insn_before (data->insn, 
-                        gen_rtx_SET (Pmode, r1, add), NULL);
+       emit_insn_before (gen_rtx_SET (Pmode, r1, add), data->insn);
        return -1;
       }
 
@@ -826,12 +824,12 @@ static int
 replace_inc_dec_mem (rtx *r, void *d)
 {
   rtx x = *r;
-  if (GET_CODE (x) == MEM)
+  if (x != NULL_RTX && MEM_P (x))
     {
       struct insn_size data;
 
       data.size = GET_MODE_SIZE (GET_MODE (x));
-      data.insn = (rtx)d;
+      data.insn = (rtx) d;
 
       for_each_rtx (&XEXP (x, 0), replace_inc_dec, &data);
        
@@ -1246,7 +1244,7 @@ record_store (rtx body, bb_info_t bb_info)
       if (clear_alias_group->offset_map_size_p < spill_alias_set)
        clear_alias_group->offset_map_size_p = spill_alias_set;
   
-      store_info = pool_alloc (rtx_store_info_pool);
+      store_info = (store_info_t) pool_alloc (rtx_store_info_pool);
 
       if (dump_file)
        fprintf (dump_file, " processing spill store %d(%s)\n",
@@ -1260,7 +1258,7 @@ record_store (rtx body, bb_info_t bb_info)
       group_info_t group 
        = VEC_index (group_info_t, rtx_group_vec, group_id);
       
-      store_info = pool_alloc (rtx_store_info_pool);
+      store_info = (store_info_t) pool_alloc (rtx_store_info_pool);
       set_usage_bits (group, offset, width);
 
       if (dump_file)
@@ -1277,7 +1275,7 @@ record_store (rtx body, bb_info_t bb_info)
        insn_info->stack_pointer_based = true;
       insn_info->contains_cselib_groups = true;
 
-      store_info = pool_alloc (cse_store_info_pool);
+      store_info = (store_info_t) pool_alloc (cse_store_info_pool);
       group_id = -1;
 
       if (dump_file)
@@ -1294,7 +1292,7 @@ record_store (rtx body, bb_info_t bb_info)
     {
       insn_info_t next = ptr->next_local_store;
       store_info_t s_info = ptr->store_rec;
-      bool delete = true;
+      bool del = true;
 
       /* Skip the clobbers. We delete the active insn if this insn
         shadows the set.  To have been put on the active list, it
@@ -1303,7 +1301,7 @@ record_store (rtx body, bb_info_t bb_info)
        s_info = s_info->next;
 
       if (s_info->alias_set != spill_alias_set)
-       delete = false;
+       del = false;
       else if (s_info->alias_set)
        {
          struct clear_alias_mode_holder *entry 
@@ -1316,7 +1314,7 @@ record_store (rtx body, bb_info_t bb_info)
          if ((GET_MODE (mem) == GET_MODE (s_info->mem))
              && (GET_MODE (mem) == entry->mode))
            {
-             delete = true;
+             del = true;
              s_info->positions_needed = (unsigned HOST_WIDE_INT) 0;
            }
          if (dump_file)
@@ -1351,9 +1349,9 @@ record_store (rtx body, bb_info_t bb_info)
       /* An insn can be deleted if every position of every one of
         its s_infos is zero.  */
       if (s_info->positions_needed != (unsigned HOST_WIDE_INT) 0)
-       delete = false;
+       del = false;
       
-      if (delete)
+      if (del)
        {
          insn_info_t insn_to_delete = ptr;
          
@@ -1370,8 +1368,7 @@ record_store (rtx body, bb_info_t bb_info)
       ptr = next;
     }
   
-  gcc_assert ((unsigned) width
-             <= sizeof (store_info->positions_needed) * CHAR_BIT);
+  gcc_assert ((unsigned) width <= HOST_BITS_PER_WIDE_INT);
   
   /* Finish filling in the store_info.  */
   store_info->next = insn_info->store_rec;
@@ -1427,7 +1424,8 @@ static rtx
 find_shift_sequence (int access_size,
                     store_info_t store_info,
                     read_info_t read_info,
-                    int shift)
+                    int shift,
+                    bool speed)
 {
   enum machine_mode store_mode = GET_MODE (store_info->mem);
   enum machine_mode read_mode = GET_MODE (read_info->mem);
@@ -1461,10 +1459,6 @@ find_shift_sequence (int access_size,
       if (!CONSTANT_P (store_info->rhs)
          && !MODES_TIEABLE_P (new_mode, store_mode))
        continue;
-      new_lhs = simplify_gen_subreg (new_mode, copy_rtx (store_info->rhs),
-                                    store_mode, 0);
-      if (new_lhs == NULL_RTX)
-       continue;
 
       new_reg = gen_reg_rtx (new_mode);
 
@@ -1485,7 +1479,7 @@ find_shift_sequence (int access_size,
       cost = 0;
       for (insn = shift_seq; insn != NULL_RTX; insn = NEXT_INSN (insn))
        if (INSN_P (insn))
-         cost += insn_rtx_cost (PATTERN (insn));
+         cost += insn_rtx_cost (PATTERN (insn), speed);
 
       /* The computation up to here is essentially independent
         of the arguments and could be precomputed.  It may
@@ -1497,6 +1491,11 @@ find_shift_sequence (int access_size,
       if (cost > COSTS_N_INSNS (1))
        continue;
 
+      new_lhs = extract_low_bits (new_mode, store_mode,
+                                 copy_rtx (store_info->rhs));
+      if (new_lhs == NULL_RTX)
+       continue;
+
       /* We found an acceptable shift.  Generate a move to
         take the value from the store and put it into the
         shift pseudo, then shift it, then generate another
@@ -1584,7 +1583,8 @@ replace_read (store_info_t store_info, insn_info_t store_insn,
             GET_MODE_NAME (store_mode), INSN_UID (store_insn->insn));
   start_sequence ();
   if (shift)
-    read_reg = find_shift_sequence (access_size, store_info, read_info, shift);
+    read_reg = find_shift_sequence (access_size, store_info, read_info, shift,
+                                   optimize_bb_for_speed_p (BLOCK_FOR_INSN (read_insn->insn)));
   else
     read_reg = extract_low_bits (read_mode, store_mode,
                                 copy_rtx (store_info->rhs));
@@ -1603,7 +1603,8 @@ replace_read (store_info_t store_info, insn_info_t store_insn,
 
   if (validate_change (read_insn->insn, loc, read_reg, 0))
     {
-      deferred_change_t deferred_change = pool_alloc (deferred_change_pool);
+      deferred_change_t deferred_change =
+       (deferred_change_t) pool_alloc (deferred_change_pool);
       
       /* Insert this right before the store insn where it will be safe
         from later insns that might change it before the read.  */
@@ -1713,7 +1714,7 @@ check_mem_read_rtx (rtx *loc, void *data)
   else
     width = GET_MODE_SIZE (GET_MODE (mem));
 
-  read_info = pool_alloc (read_info_pool);
+  read_info = (read_info_t) pool_alloc (read_info_pool);
   read_info->group_id = group_id;
   read_info->mem = mem;
   read_info->alias_set = spill_alias_set;
@@ -1933,7 +1934,7 @@ static void
 scan_insn (bb_info_t bb_info, rtx insn)
 {
   rtx body;
-  insn_info_t insn_info = pool_alloc (insn_info_pool);
+  insn_info_t insn_info = (insn_info_t) pool_alloc (insn_info_pool);
   int mems_found = 0;
   memset (insn_info, 0, sizeof (struct insn_info));
 
@@ -1967,7 +1968,7 @@ scan_insn (bb_info_t bb_info, rtx insn)
       /* Const functions cannot do anything bad i.e. read memory,
         however, they can read their parameters which may have
         been pushed onto the stack.  */
-      if (CONST_OR_PURE_CALL_P (insn) && !pure_call_p (insn))
+      if (RTL_CONST_CALL_P (insn))
        {
          insn_info_t i_ptr = active_local_stores;
          insn_info_t last = NULL;
@@ -2078,7 +2079,7 @@ remove_useless_values (cselib_val *base)
   while (insn_info)
     {
       store_info_t store_info = insn_info->store_rec;
-      bool delete = false;
+      bool del = false;
 
       /* If ANY of the store_infos match the cselib group that is
         being deleted, then the insn can not be deleted.  */
@@ -2087,13 +2088,13 @@ remove_useless_values (cselib_val *base)
          if ((store_info->group_id == -1) 
              && (store_info->cse_base == base))
            {
-             delete = true;
+             del = true;
              break;
            }
          store_info = store_info->next;
        }
 
-      if (delete)
+      if (del)
        {
          if (last)
            last->next_local_store = insn_info->next_local_store;
@@ -2124,7 +2125,7 @@ dse_step1 (void)
   FOR_ALL_BB (bb)
     {
       insn_info_t ptr;
-      bb_info_t bb_info = pool_alloc (bb_info_pool);
+      bb_info_t bb_info = (bb_info_t) pool_alloc (bb_info_pool);
 
       memset (bb_info, 0, sizeof (struct bb_info));
       bitmap_set_bit (all_blocks, bb->index);
@@ -2163,7 +2164,7 @@ dse_step1 (void)
              && (EDGE_COUNT (bb->succs) == 0
                  || (single_succ_p (bb)
                      && single_succ (bb) == EXIT_BLOCK_PTR
-                     && ! current_function_calls_eh_return)))
+                     && ! crtl->calls_eh_return)))
            {
              insn_info_t i_ptr = active_local_stores;
              while (i_ptr)
@@ -2425,7 +2426,8 @@ dse_record_singleton_alias_set (alias_set_type alias_set,
   slot = htab_find_slot (clear_alias_mode_table, &tmp_holder, INSERT);
   gcc_assert (*slot == NULL);
 
-  *slot = entry = pool_alloc (clear_alias_mode_pool);
+  *slot = entry =
+    (struct clear_alias_mode_holder *) pool_alloc (clear_alias_mode_pool);
   entry->alias_set = alias_set;
   entry->mode = mode;
 }
@@ -3153,43 +3155,30 @@ dse_step6 (bool global_done)
   group_info_t group;
   basic_block bb;
   
-  if (global_done)
-    {
-      for (i = 0; VEC_iterate (group_info_t, rtx_group_vec, i, group); i++)
-       {
-         free (group->offset_map_n);
-         free (group->offset_map_p);
-         BITMAP_FREE (group->store1_n);
-         BITMAP_FREE (group->store1_p);
-         BITMAP_FREE (group->store2_n);
-         BITMAP_FREE (group->store2_p);
-         BITMAP_FREE (group->group_kill);
-       }
-
-      FOR_ALL_BB (bb)
-       {
-         bb_info_t bb_info = bb_table[bb->index];
-         BITMAP_FREE (bb_info->gen);
-         if (bb_info->kill)
-           BITMAP_FREE (bb_info->kill);
-         if (bb_info->in)
-           BITMAP_FREE (bb_info->in);
-         if (bb_info->out)
-           BITMAP_FREE (bb_info->out);
-       }
-    }
-  else
+  for (i = 0; VEC_iterate (group_info_t, rtx_group_vec, i, group); i++)
     {
-      for (i = 0; VEC_iterate (group_info_t, rtx_group_vec, i, group); i++)
-       {
-         BITMAP_FREE (group->store1_n);
-         BITMAP_FREE (group->store1_p);
-         BITMAP_FREE (group->store2_n);
-         BITMAP_FREE (group->store2_p);
-         BITMAP_FREE (group->group_kill);
-       }
+      free (group->offset_map_n);
+      free (group->offset_map_p);
+      BITMAP_FREE (group->store1_n);
+      BITMAP_FREE (group->store1_p);
+      BITMAP_FREE (group->store2_n);
+      BITMAP_FREE (group->store2_p);
+      BITMAP_FREE (group->group_kill);
     }
 
+  if (global_done)
+    FOR_ALL_BB (bb)
+      {
+       bb_info_t bb_info = bb_table[bb->index];
+       BITMAP_FREE (bb_info->gen);
+       if (bb_info->kill)
+         BITMAP_FREE (bb_info->kill);
+       if (bb_info->in)
+         BITMAP_FREE (bb_info->in);
+       if (bb_info->out)
+         BITMAP_FREE (bb_info->out);
+      }
+
   if (clear_alias_sets)
     {
       BITMAP_FREE (clear_alias_sets);
@@ -3214,7 +3203,6 @@ dse_step6 (bool global_done)
 }
 
 
-
 /* -------------------------------------------------------------------------
    DSE
    ------------------------------------------------------------------------- */