OSDN Git Service

2008-03-04 Rafael Espindola <espindola@google.com>
[pf3gnuchains/gcc-fork.git] / gcc / regrename.c
index 8fdc74e..74112c3 100644 (file)
@@ -6,7 +6,7 @@
 
    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)
+   the Free 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
@@ -15,9 +15,8 @@
    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"
@@ -89,7 +88,7 @@ static void scan_rtx (rtx, rtx *, enum reg_class, enum scan_actions,
                      enum op_type, int);
 static struct du_chain *build_def_use (basic_block);
 static void dump_def_use_chain (struct du_chain *);
-static void note_sets (rtx, rtx, void *);
+static void note_sets (rtx, const_rtx, void *);
 static void clear_dead_regs (HARD_REG_SET *, enum machine_mode, rtx);
 static void merge_overlapping_regs (basic_block, HARD_REG_SET *,
                                    struct du_chain *);
@@ -98,7 +97,7 @@ static void merge_overlapping_regs (basic_block, HARD_REG_SET *,
    record them in *DATA (which is actually a HARD_REG_SET *).  */
 
 static void
-note_sets (rtx x, rtx set ATTRIBUTE_UNUSED, void *data)
+note_sets (rtx x, const_rtx set ATTRIBUTE_UNUSED, void *data)
 {
   HARD_REG_SET *pset = (HARD_REG_SET *) data;
 
@@ -185,8 +184,8 @@ regrename_optimize (void)
   df_set_flags (DF_LR_RUN_DCE);
   df_note_add_problem ();
   df_analyze ();
-  df_set_flags (DF_NO_INSN_RESCAN);
-  
+  df_set_flags (DF_DEFER_INSN_RESCAN);
+
   memset (tick, 0, sizeof tick);
 
   gcc_obstack_init (&rename_obstack);
@@ -346,8 +345,6 @@ regrename_optimize (void)
     }
 
   obstack_free (&rename_obstack, NULL);
-  df_clear_flags (DF_NO_INSN_RESCAN);
-  df_insn_rescan_all ();
 
   if (dump_file)
     fputc ('\n', dump_file);
@@ -365,6 +362,7 @@ do_replace (struct du_chain *chain, int reg)
       if (regno >= FIRST_PSEUDO_REGISTER)
        ORIGINAL_REGNO (*chain->loc) = regno;
       REG_ATTRS (*chain->loc) = attr;
+      df_insn_rescan (chain->insn);
       chain = chain->next_use;
     }
 }
@@ -561,20 +559,19 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
            int index_op;
            unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
 
-           if (REGNO_OK_FOR_INDEX_P (regno0)
-               && regno_ok_for_base_p (regno1, mode, PLUS, REG))
+           if (REGNO_OK_FOR_INDEX_P (regno1)
+               && regno_ok_for_base_p (regno0, mode, PLUS, REG))
+             index_op = 1;
+           else if (REGNO_OK_FOR_INDEX_P (regno0)
+                    && regno_ok_for_base_p (regno1, mode, PLUS, REG))
              index_op = 0;
-           else if (REGNO_OK_FOR_INDEX_P (regno1)
-                    && regno_ok_for_base_p (regno0, mode, PLUS, REG))
+           else if (regno_ok_for_base_p (regno0, mode, PLUS, REG)
+                    || REGNO_OK_FOR_INDEX_P (regno1))
              index_op = 1;
            else if (regno_ok_for_base_p (regno1, mode, PLUS, REG))
              index_op = 0;
-           else if (regno_ok_for_base_p (regno0, mode, PLUS, REG))
-             index_op = 1;
-           else if (REGNO_OK_FOR_INDEX_P (regno1))
-             index_op = 1;
            else
-             index_op = 0;
+             index_op = 1;
 
            locI = &XEXP (x, index_op);
            locB = &XEXP (x, !index_op);
@@ -655,6 +652,7 @@ scan_rtx (rtx insn, rtx *loc, enum reg_class cl,
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_FIXED:
     case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
@@ -807,25 +805,19 @@ build_def_use (basic_block bb)
            }
          for (i = 0; i < recog_data.n_dups; i++)
            {
-             int dup_num = recog_data.dup_num[i];
-
              old_dups[i] = *recog_data.dup_loc[i];
              *recog_data.dup_loc[i] = cc0_rtx;
-
-             /* For match_dup of match_operator or match_parallel, share
-                them, so that we don't miss changes in the dup.  */
-             if (icode >= 0
-                 && insn_data[icode].operand[dup_num].eliminable == 0)
-               old_dups[i] = recog_data.operand[dup_num];
            }
 
          scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_all_read,
                    OP_IN, 0);
 
          for (i = 0; i < recog_data.n_dups; i++)
-           *recog_data.dup_loc[i] = old_dups[i];
+           *recog_data.dup_loc[i] = copy_rtx (old_dups[i]);
          for (i = 0; i < n_ops; i++)
            *recog_data.operand_loc[i] = old_operands[i];
+         if (recog_data.n_dups)
+           df_insn_rescan (insn);
 
          /* Step 2B: Can't rename function call argument registers.  */
          if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn))
@@ -1030,8 +1022,8 @@ static void kill_value_regno (unsigned, unsigned, struct value_data *);
 static void kill_value (rtx, struct value_data *);
 static void set_value_regno (unsigned, enum machine_mode, struct value_data *);
 static void init_value_data (struct value_data *);
-static void kill_clobbered_value (rtx, rtx, void *);
-static void kill_set_value (rtx, rtx, void *);
+static void kill_clobbered_value (rtx, const_rtx, void *);
+static void kill_set_value (rtx, const_rtx, void *);
 static int kill_autoinc_value (rtx *, void *);
 static void copy_value (rtx, rtx, struct value_data *);
 static bool mode_change_ok (enum machine_mode, enum machine_mode,
@@ -1171,7 +1163,7 @@ init_value_data (struct value_data *vd)
 /* Called through note_stores.  If X is clobbered, kill its value.  */
 
 static void
-kill_clobbered_value (rtx x, rtx set, void *data)
+kill_clobbered_value (rtx x, const_rtx set, void *data)
 {
   struct value_data *vd = data;
   if (GET_CODE (set) == CLOBBER)
@@ -1182,7 +1174,7 @@ kill_clobbered_value (rtx x, rtx set, void *data)
    current value and install it as the root of its own value list.  */
 
 static void
-kill_set_value (rtx x, rtx set, void *data)
+kill_set_value (rtx x, const_rtx set, void *data)
 {
   struct value_data *vd = data;
   if (GET_CODE (set) != CLOBBER)
@@ -1483,20 +1475,19 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl,
            int index_op;
            unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
 
-           if (REGNO_OK_FOR_INDEX_P (regno0)
-               && regno_ok_for_base_p (regno1, mode, PLUS, REG))
+           if (REGNO_OK_FOR_INDEX_P (regno1)
+               && regno_ok_for_base_p (regno0, mode, PLUS, REG))
+             index_op = 1;
+           else if (REGNO_OK_FOR_INDEX_P (regno0)
+                    && regno_ok_for_base_p (regno1, mode, PLUS, REG))
              index_op = 0;
-           else if (REGNO_OK_FOR_INDEX_P (regno1)
-                    && regno_ok_for_base_p (regno0, mode, PLUS, REG))
+           else if (regno_ok_for_base_p (regno0, mode, PLUS, REG)
+                    || REGNO_OK_FOR_INDEX_P (regno1))
              index_op = 1;
            else if (regno_ok_for_base_p (regno1, mode, PLUS, REG))
              index_op = 0;
-           else if (regno_ok_for_base_p (regno0, mode, PLUS, REG))
-             index_op = 1;
-           else if (REGNO_OK_FOR_INDEX_P (regno1))
-             index_op = 1;
            else
-             index_op = 0;
+             index_op = 1;
 
            locI = &XEXP (x, index_op);
            locB = &XEXP (x, !index_op);
@@ -1745,7 +1736,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
              recog_data.operand[i] = new;
              for (j = 0; j < recog_data.n_dups; j++)
                if (recog_data.dup_num[j] == i)
-                 validate_change (insn, recog_data.dup_loc[j], new, 1);
+                 validate_unshare_change (insn, recog_data.dup_loc[j], new, 1);
 
              any_replacements = true;
            }
@@ -1960,7 +1951,7 @@ struct tree_opt_pass pass_regrename =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_df_finish |
+  TODO_df_finish | TODO_verify_rtl_sharing |
   TODO_dump_func,                       /* todo_flags_finish */
   'n'                                   /* letter */
 };
@@ -1993,7 +1984,7 @@ struct tree_opt_pass pass_cprop_hardreg =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_dump_func,                       /* todo_flags_finish */
+  TODO_dump_func | TODO_verify_rtl_sharing, /* todo_flags_finish */
   'n'                                   /* letter */
 };