OSDN Git Service

* gnatvsn.adb (Gnat_Version_String): Don't overrun Ver_Len_Max.
[pf3gnuchains/gcc-fork.git] / gcc / postreload-gcse.c
index 3e3f805..7eeecf4 100644 (file)
@@ -1,12 +1,12 @@
 /* Post reload partially redundant load elimination
 /* Post reload partially redundant load elimination
-   Copyright (C) 2004, 2005
+   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
    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
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,15 +15,14 @@ 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
 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"
 #include "coretypes.h"
 #include "tm.h"
 
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
-#include "toplev.h"
+#include "diagnostic-core.h"
 
 #include "rtl.h"
 #include "tree.h"
 
 #include "rtl.h"
 #include "tree.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 "regs.h"
 #include "hard-reg-set.h"
 #include "flags.h"
-#include "real.h"
 #include "insn-config.h"
 #include "recog.h"
 #include "basic-block.h"
 #include "insn-config.h"
 #include "recog.h"
 #include "basic-block.h"
@@ -46,6 +44,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "target.h"
 #include "timevar.h"
 #include "tree-pass.h"
 #include "target.h"
 #include "timevar.h"
 #include "tree-pass.h"
+#include "dbgcnt.h"
 
 /* The following code implements gcse after reload, the purpose of this
    pass is to cleanup redundant loads generated by reload and other
 
 /* The following code implements gcse after reload, the purpose of this
    pass is to cleanup redundant loads generated by reload and other
@@ -175,12 +174,13 @@ static void free_mem (void);
 
 /* Support for hash table construction and transformations.  */
 static bool oprs_unchanged_p (rtx, rtx, bool);
 
 /* 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_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 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);
 
 static int load_killed_in_block_p (int, rtx, bool);
 static void reset_opr_set_tables (void);
 
@@ -296,7 +296,7 @@ hash_expr (rtx x, int *do_not_record_p)
 static hashval_t
 hash_expr_for_htab (const void *expp)
 {
 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;
 }
 
   return exp->hash;
 }
 
@@ -306,10 +306,10 @@ hash_expr_for_htab (const void *expp)
 static int
 expr_equiv_p (const void *exp1p, const void *exp2p)
 {
 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);
   int equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true);
-  
+
   gcc_assert (!equiv_p || exp1->hash == exp2->hash);
   return equiv_p;
 }
   gcc_assert (!equiv_p || exp1->hash == exp2->hash);
   return equiv_p;
 }
@@ -348,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);
 
   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;
   if (! (*slot))
     /* The expression isn't found, so insert it.  */
     *slot = cur_expr;
@@ -362,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;
 
   /* 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.  */
     {
       /* If an occurrence isn't found, save a pointer to the end of
         the list.  */
@@ -522,6 +523,7 @@ oprs_unchanged_p (rtx x, rtx insn, bool after_insn)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_FIXED:
     case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
     case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
@@ -571,7 +573,7 @@ static int mems_conflict_p;
    to a nonzero value.  */
 
 static void
    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;
                    void *data)
 {
   rtx mem_op = (rtx) data;
@@ -644,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 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);
 }
 {
   reg_avail_info[regno] = INSN_CUID (insn);
 }
@@ -671,7 +685,7 @@ record_last_mem_set_info (rtx insn)
    the SET is taking place.  */
 
 static void
    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;
 
 {
   rtx last_set_insn = (rtx) data;
 
@@ -679,7 +693,7 @@ record_last_set_info (rtx dest, rtx setter ATTRIBUTE_UNUSED, void *data)
     dest = SUBREG_REG (dest);
 
   if (REG_P (dest))
     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
   else if (MEM_P (dest))
     {
       /* Ignore pushes, they don't clobber memory.  They may still
@@ -690,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
       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);
     }
 }
 
     }
 }
 
@@ -721,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)
   /* 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))
     {
 
   /* 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))
       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)
 
       for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
        if (GET_CODE (XEXP (link, 0)) == CLOBBER)
@@ -740,15 +754,11 @@ record_opr_changes (rtx insn)
            if (REG_P (x))
              {
                gcc_assert (HARD_REGISTER_P (x));
            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);
     }
 }
        record_last_mem_set_info (insn);
     }
 }
@@ -992,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);
          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),
          /* Make sure we can generate a move from register avail_reg to
             dest.  */
          extract_insn (gen_move_insn (copy_rtx (dest),
@@ -1055,9 +1065,9 @@ eliminate_partially_redundant_load (basic_block bb, rtx insn,
 
   if (/* No load can be replaced by copy.  */
       npred_ok == 0
 
   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 ())
          a critical edge is profitable or not so don't do it.  */
       || ((! profile_info || ! flag_branch_probabilities
           || targetm.cannot_modify_jumps_p ())
@@ -1163,7 +1173,7 @@ eliminate_partially_redundant_loads (void)
        continue;
 
       /* Do not try anything on cold basic blocks.  */
        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
        continue;
 
       /* Reset the table of things changed since the start of the current
@@ -1190,7 +1200,7 @@ eliminate_partially_redundant_loads (void)
                  /* Are the operands unchanged since the start of the
                     block?  */
                  && oprs_unchanged_p (src, insn, false)
                  /* Are the operands unchanged since the start of the
                     block?  */
                  && oprs_unchanged_p (src, insn, false)
-                 && !(flag_non_call_exceptions && may_trap_p (src))
+                 && !(cfun->can_throw_non_call_exceptions && may_trap_p (src))
                  && !side_effects_p (src)
                  /* Is the expression recorded?  */
                  && (expr = lookup_expr_in_table (src)) != NULL)
                  && !side_effects_p (src)
                  /* Is the expression recorded?  */
                  && (expr = lookup_expr_in_table (src)) != NULL)
@@ -1225,7 +1235,7 @@ delete_redundant_insns_1 (void **slot, void *data ATTRIBUTE_UNUSED)
 
   for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
     {
 
   for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
     {
-      if (occr->deleted_p)
+      if (occr->deleted_p && dbg_cnt (gcse2_delete))
        {
          delete_insn (occr->insn);
          stats.insns_deleted++;
        {
          delete_insn (occr->insn);
          stats.insns_deleted++;
@@ -1259,7 +1269,7 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
 
   memset (&stats, 0, sizeof (stats));
 
 
   memset (&stats, 0, sizeof (stats));
 
-  /* Allocate ememory for this pass.
+  /* Allocate memory for this pass.
      Also computes and initializes the insns' CUIDs.  */
   alloc_mem ();
 
      Also computes and initializes the insns' CUIDs.  */
   alloc_mem ();
 
@@ -1285,7 +1295,7 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
          fprintf (dump_file, "\n\n");
        }
     }
          fprintf (dump_file, "\n\n");
        }
     }
-    
+
   /* We are finished with alias.  */
   end_alias_analysis ();
 
   /* We are finished with alias.  */
   end_alias_analysis ();
 
@@ -1296,7 +1306,8 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
 static bool
 gate_handle_gcse2 (void)
 {
 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));
 }
 
 
 }
 
 
@@ -1305,12 +1316,13 @@ rest_of_handle_gcse2 (void)
 {
   gcse_after_reload_main (get_insns ());
   rebuild_jump_labels (get_insns ());
 {
   gcse_after_reload_main (get_insns ());
   rebuild_jump_labels (get_insns ());
-  delete_trivially_dead_insns (get_insns (), max_reg_num ());
   return 0;
 }
 
   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 */
   "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 */
   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 */
+ }
 };
 
 };