OSDN Git Service

2010-04-30 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / postreload-gcse.c
index fdf5b04..5da9f62 100644 (file)
@@ -1,12 +1,12 @@
 /* Post reload partially redundant load elimination
-   Copyright (C) 2004, 2005, 2006, 2007
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,9 +15,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -31,7 +30,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "regs.h"
 #include "hard-reg-set.h"
 #include "flags.h"
-#include "real.h"
 #include "insn-config.h"
 #include "recog.h"
 #include "basic-block.h"
@@ -176,12 +174,13 @@ static void free_mem (void);
 
 /* Support for hash table construction and transformations.  */
 static bool oprs_unchanged_p (rtx, rtx, bool);
-static void record_last_reg_set_info (rtx, int);
+static void record_last_reg_set_info (rtx, rtx);
+static void record_last_reg_set_info_regno (rtx, int);
 static void record_last_mem_set_info (rtx);
-static void record_last_set_info (rtx, rtx, void *);
+static void record_last_set_info (rtx, const_rtx, void *);
 static void record_opr_changes (rtx);
 
-static void find_mem_conflicts (rtx, rtx, void *);
+static void find_mem_conflicts (rtx, const_rtx, void *);
 static int load_killed_in_block_p (int, rtx, bool);
 static void reset_opr_set_tables (void);
 
@@ -297,7 +296,7 @@ hash_expr (rtx x, int *do_not_record_p)
 static hashval_t
 hash_expr_for_htab (const void *expp)
 {
-  struct expr *exp = (struct expr *) expp;
+  const struct expr *const exp = (const struct expr *) expp;
   return exp->hash;
 }
 
@@ -307,10 +306,10 @@ hash_expr_for_htab (const void *expp)
 static int
 expr_equiv_p (const void *exp1p, const void *exp2p)
 {
-  struct expr *exp1 = (struct expr *) exp1p;
-  struct expr *exp2 = (struct expr *) exp2p;
+  const struct expr *const exp1 = (const struct expr *) exp1p;
+  const struct expr *const exp2 = (const struct expr *) exp2p;
   int equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true);
-  
+
   gcc_assert (!equiv_p || exp1->hash == exp2->hash);
   return equiv_p;
 }
@@ -349,7 +348,7 @@ insert_expr_in_table (rtx x, rtx insn)
 
   slot = (struct expr **) htab_find_slot_with_hash (expr_table, cur_expr,
                                                    hash, INSERT);
-  
+
   if (! (*slot))
     /* The expression isn't found, so insert it.  */
     *slot = cur_expr;
@@ -363,7 +362,8 @@ insert_expr_in_table (rtx x, rtx insn)
 
   /* Search for another occurrence in the same basic block.  */
   avail_occr = cur_expr->avail_occr;
-  while (avail_occr && BLOCK_NUM (avail_occr->insn) != BLOCK_NUM (insn))
+  while (avail_occr
+        && BLOCK_FOR_INSN (avail_occr->insn) != BLOCK_FOR_INSN (insn))
     {
       /* If an occurrence isn't found, save a pointer to the end of
         the list.  */
@@ -523,6 +523,7 @@ oprs_unchanged_p (rtx x, rtx insn, bool after_insn)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_FIXED:
     case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
@@ -572,7 +573,7 @@ static int mems_conflict_p;
    to a nonzero value.  */
 
 static void
-find_mem_conflicts (rtx dest, rtx setter ATTRIBUTE_UNUSED,
+find_mem_conflicts (rtx dest, const_rtx setter ATTRIBUTE_UNUSED,
                    void *data)
 {
   rtx mem_op = (rtx) data;
@@ -645,7 +646,19 @@ load_killed_in_block_p (int uid_limit, rtx x, bool after_insn)
 /* Record register first/last/block set information for REGNO in INSN.  */
 
 static inline void
-record_last_reg_set_info (rtx insn, int regno)
+record_last_reg_set_info (rtx insn, rtx reg)
+{
+  unsigned int regno, end_regno;
+
+  regno = REGNO (reg);
+  end_regno = END_HARD_REGNO (reg);
+  do
+    reg_avail_info[regno] = INSN_CUID (insn);
+  while (++regno < end_regno);
+}
+
+static inline void
+record_last_reg_set_info_regno (rtx insn, int regno)
 {
   reg_avail_info[regno] = INSN_CUID (insn);
 }
@@ -672,7 +685,7 @@ record_last_mem_set_info (rtx insn)
    the SET is taking place.  */
 
 static void
-record_last_set_info (rtx dest, rtx setter ATTRIBUTE_UNUSED, void *data)
+record_last_set_info (rtx dest, const_rtx setter ATTRIBUTE_UNUSED, void *data)
 {
   rtx last_set_insn = (rtx) data;
 
@@ -680,7 +693,7 @@ record_last_set_info (rtx dest, rtx setter ATTRIBUTE_UNUSED, void *data)
     dest = SUBREG_REG (dest);
 
   if (REG_P (dest))
-    record_last_reg_set_info (last_set_insn, REGNO (dest));
+    record_last_reg_set_info (last_set_insn, dest);
   else if (MEM_P (dest))
     {
       /* Ignore pushes, they don't clobber memory.  They may still
@@ -691,7 +704,7 @@ record_last_set_info (rtx dest, rtx setter ATTRIBUTE_UNUSED, void *data)
       if (! push_operand (dest, GET_MODE (dest)))
        record_last_mem_set_info (last_set_insn);
       else
-       record_last_reg_set_info (last_set_insn, STACK_POINTER_REGNUM);
+       record_last_reg_set_info_regno (last_set_insn, STACK_POINTER_REGNUM);
     }
 }
 
@@ -722,17 +735,17 @@ record_opr_changes (rtx insn)
   /* Also record autoincremented REGs for this insn as changed.  */
   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
     if (REG_NOTE_KIND (note) == REG_INC)
-      record_last_reg_set_info (insn, REGNO (XEXP (note, 0)));
+      record_last_reg_set_info (insn, XEXP (note, 0));
 
   /* Finally, if this is a call, record all call clobbers.  */
   if (CALL_P (insn))
     {
-      unsigned int regno, end_regno;
+      unsigned int regno;
       rtx link, x;
 
       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
        if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
-         record_last_reg_set_info (insn, regno);
+         record_last_reg_set_info_regno (insn, regno);
 
       for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
        if (GET_CODE (XEXP (link, 0)) == CLOBBER)
@@ -741,15 +754,11 @@ record_opr_changes (rtx insn)
            if (REG_P (x))
              {
                gcc_assert (HARD_REGISTER_P (x));
-               regno = REGNO (x);
-               end_regno = END_HARD_REGNO (x);
-               do
-                 record_last_reg_set_info (insn, regno);
-               while (++regno < end_regno);
+               record_last_reg_set_info (insn, x);
              }
          }
 
-      if (! CONST_OR_PURE_CALL_P (insn))
+      if (! RTL_CONST_OR_PURE_CALL_P (insn))
        record_last_mem_set_info (insn);
     }
 }
@@ -993,7 +1002,7 @@ eliminate_partially_redundant_load (basic_block bb, rtx insn,
          avail_insn = a_occr->insn;
          avail_reg = get_avail_load_store_reg (avail_insn);
          gcc_assert (avail_reg);
-         
+
          /* Make sure we can generate a move from register avail_reg to
             dest.  */
          extract_insn (gen_move_insn (copy_rtx (dest),
@@ -1056,9 +1065,9 @@ eliminate_partially_redundant_load (basic_block bb, rtx insn,
 
   if (/* No load can be replaced by copy.  */
       npred_ok == 0
-      /* Prevent exploding the code.  */ 
-      || (optimize_size && npred_ok > 1)
-      /* If we don't have profile information we cannot tell if splitting 
+      /* Prevent exploding the code.  */
+      || (optimize_bb_for_size_p (bb) && npred_ok > 1)
+      /* If we don't have profile information we cannot tell if splitting
          a critical edge is profitable or not so don't do it.  */
       || ((! profile_info || ! flag_branch_probabilities
           || targetm.cannot_modify_jumps_p ())
@@ -1164,7 +1173,7 @@ eliminate_partially_redundant_loads (void)
        continue;
 
       /* Do not try anything on cold basic blocks.  */
-      if (probably_cold_bb_p (bb))
+      if (optimize_bb_for_size_p (bb))
        continue;
 
       /* Reset the table of things changed since the start of the current
@@ -1260,7 +1269,7 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
 
   memset (&stats, 0, sizeof (stats));
 
-  /* Allocate ememory for this pass.
+  /* Allocate memory for this pass.
      Also computes and initializes the insns' CUIDs.  */
   alloc_mem ();
 
@@ -1286,7 +1295,7 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
          fprintf (dump_file, "\n\n");
        }
     }
-    
+
   /* We are finished with alias.  */
   end_alias_analysis ();
 
@@ -1297,7 +1306,8 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
 static bool
 gate_handle_gcse2 (void)
 {
-  return (optimize > 0 && flag_gcse_after_reload);
+  return (optimize > 0 && flag_gcse_after_reload
+         && optimize_function_for_speed_p (cfun));
 }
 
 
@@ -1309,8 +1319,10 @@ rest_of_handle_gcse2 (void)
   return 0;
 }
 
-struct tree_opt_pass pass_gcse2 =
+struct rtl_opt_pass pass_gcse2 =
 {
+ {
+  RTL_PASS,
   "gcse2",                              /* name */
   gate_handle_gcse2,                    /* gate */
   rest_of_handle_gcse2,                 /* execute */
@@ -1322,8 +1334,8 @@ struct tree_opt_pass pass_gcse2 =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_dump_func |
-  TODO_verify_flow | TODO_ggc_collect,  /* todo_flags_finish */
-  'J'                                   /* letter */
+  TODO_dump_func | TODO_verify_rtl_sharing
+  | TODO_verify_flow | TODO_ggc_collect /* todo_flags_finish */
+ }
 };