OSDN Git Service

* tree-parloops.c: Change license to GPLv3.
[pf3gnuchains/gcc-fork.git] / gcc / regrename.c
index 0ed810e..2da42c3 100644 (file)
@@ -89,7 +89,7 @@ static void scan_rtx (rtx, rtx *, enum reg_class, enum scan_actions,
 static struct du_chain *build_def_use (basic_block);
 static void dump_def_use_chain (struct du_chain *);
 static void note_sets (rtx, const_rtx, void *);
-static void clear_dead_regs (HARD_REG_SET *, enum machine_mode, rtx);
+static void clear_dead_regs (HARD_REG_SET *, enum reg_note, rtx);
 static void merge_overlapping_regs (basic_block, HARD_REG_SET *,
                                    struct du_chain *);
 
@@ -114,7 +114,7 @@ note_sets (rtx x, const_rtx set ATTRIBUTE_UNUSED, void *data)
    in the list NOTES.  */
 
 static void
-clear_dead_regs (HARD_REG_SET *pset, enum machine_mode kind, rtx notes)
+clear_dead_regs (HARD_REG_SET *pset, enum reg_note kind, rtx notes)
 {
   rtx note;
   for (note = notes; note; note = XEXP (note, 1))
@@ -137,8 +137,15 @@ merge_overlapping_regs (basic_block b, HARD_REG_SET *pset,
   struct du_chain *t = chain;
   rtx insn;
   HARD_REG_SET live;
+  df_ref *def_rec;
 
   REG_SET_TO_HARD_REG_SET (live, df_get_live_in (b));
+  for (def_rec = df_get_artificial_defs (b->index); *def_rec; def_rec++)
+    {
+      df_ref def = *def_rec;
+      if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+       SET_HARD_REG_BIT (live, DF_REF_REGNO (def));
+    }
   insn = BB_HEAD (b);
   while (t)
     {
@@ -333,12 +340,12 @@ regrename_optimize (void)
              continue;
            }
 
+         if (dump_file)
+           fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
+
          do_replace (this_du, best_new_reg);
          tick[best_new_reg] = ++this_tick;
          df_set_regs_ever_live (best_new_reg, true);
-
-         if (dump_file)
-           fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
        }
 
       obstack_free (&rename_obstack, first_obj);
@@ -357,11 +364,13 @@ do_replace (struct du_chain *chain, int reg)
     {
       unsigned int regno = ORIGINAL_REGNO (*chain->loc);
       struct reg_attrs * attr = REG_ATTRS (*chain->loc);
+      int reg_ptr = REG_POINTER (*chain->loc);
 
       *chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
       if (regno >= FIRST_PSEUDO_REGISTER)
        ORIGINAL_REGNO (*chain->loc) = regno;
       REG_ATTRS (*chain->loc) = attr;
+      REG_POINTER (*chain->loc) = reg_ptr;
       df_insn_rescan (chain->insn);
       chain = chain->next_use;
     }
@@ -1314,6 +1323,10 @@ maybe_mode_change (enum machine_mode orig_mode, enum machine_mode copy_mode,
                   enum machine_mode new_mode, unsigned int regno,
                   unsigned int copy_regno ATTRIBUTE_UNUSED)
 {
+  if (GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (orig_mode)
+      && GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (new_mode))
+    return NULL_RTX;
+
   if (orig_mode == new_mode)
     return gen_rtx_raw_REG (new_mode, regno);
   else if (mode_change_ok (orig_mode, new_mode, regno))
@@ -1375,6 +1388,7 @@ find_oldest_value_reg (enum reg_class cl, rtx reg, struct value_data *vd)
        {
          ORIGINAL_REGNO (new_rtx) = ORIGINAL_REGNO (reg);
          REG_ATTRS (new_rtx) = REG_ATTRS (reg);
+         REG_POINTER (new_rtx) = REG_POINTER (reg);
          return new_rtx;
        }
     }
@@ -1673,6 +1687,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
                    {
                      ORIGINAL_REGNO (new_rtx) = ORIGINAL_REGNO (src);
                      REG_ATTRS (new_rtx) = REG_ATTRS (src);
+                     REG_POINTER (new_rtx) = REG_POINTER (src);
                      if (dump_file)
                        fprintf (dump_file,
                                 "insn %u: replaced reg %u with %u\n",
@@ -1990,4 +2005,3 @@ struct rtl_opt_pass pass_cprop_hardreg =
   TODO_dump_func | TODO_verify_rtl_sharing /* todo_flags_finish */
  }
 };
-