2013-12-13 Vladimir Makarov <vmakarov@redhat.com>
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Dec 2013 20:47:19 +0000 (20:47 +0000)
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Dec 2013 20:47:19 +0000 (20:47 +0000)
* ira.h (struct ira_reg_equiv): Rename to ira_reg_equiv_s.
* ira.c: Ditto.
* lra-int.h (lra_init_equiv): New prototype.
* lra-constraints.c (lra_init_equiv, update_equiv): New functions.
(loc_equivalence_callback): Use the 3rd arg.
(lra_constraints): Update equivalences.  Pass curr_insn to
simplify_replace_fn_rtx.
* lra.c (lra): Call lra_init_equiv.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205974 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ira.c
gcc/ira.h
gcc/lra-constraints.c
gcc/lra-int.h
gcc/lra.c

index e80beeb..4f7b79a 100644 (file)
@@ -1,3 +1,14 @@
+2013-12-13  Vladimir Makarov  <vmakarov@redhat.com>
+
+       * ira.h (struct ira_reg_equiv): Rename to ira_reg_equiv_s.
+       * ira.c: Ditto.
+       * lra-int.h (lra_init_equiv): New prototype.
+       * lra-constraints.c (lra_init_equiv, update_equiv): New functions.
+       (loc_equivalence_callback): Use the 3rd arg.
+       (lra_constraints): Update equivalences.  Pass curr_insn to
+       simplify_replace_fn_rtx.
+       * lra.c (lra): Call lra_init_equiv.
+
 2013-12-13  Kenneth Zadeck  <zadeck@naturalbridge.com>
 
        * genmodes.c (emit_max_int): Fixed missing parens.
index d6462ca..18e2634 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -2976,7 +2976,7 @@ mark_elimination (int from, int to)
 int ira_reg_equiv_len;
 
 /* Info about equiv. info for each register.  */
-struct ira_reg_equiv *ira_reg_equiv;
+struct ira_reg_equiv_s *ira_reg_equiv;
 
 /* Expand ira_reg_equiv if necessary.  */
 void
@@ -2988,12 +2988,12 @@ ira_expand_reg_equiv (void)
     return;
   ira_reg_equiv_len = max_reg_num () * 3 / 2 + 1;
   ira_reg_equiv
-    = (struct ira_reg_equiv *) xrealloc (ira_reg_equiv,
+    = (struct ira_reg_equiv_s *) xrealloc (ira_reg_equiv,
                                         ira_reg_equiv_len
-                                        * sizeof (struct ira_reg_equiv));
+                                        * sizeof (struct ira_reg_equiv_s));
   gcc_assert (old < ira_reg_equiv_len);
   memset (ira_reg_equiv + old, 0,
-         sizeof (struct ira_reg_equiv) * (ira_reg_equiv_len - old));
+         sizeof (struct ira_reg_equiv_s) * (ira_reg_equiv_len - old));
 }
 
 static void
index 3a1824b..49acc4a 100644 (file)
--- a/gcc/ira.h
+++ b/gcc/ira.h
@@ -154,7 +154,7 @@ extern struct target_ira *this_target_ira;
   (this_target_ira->x_ira_no_alloc_regs)
 
 /* Major structure describing equivalence info for a pseudo.  */
-struct ira_reg_equiv
+struct ira_reg_equiv_s
 {
   /* True if we can use this equivalence.  */
   bool defined_p;
@@ -173,7 +173,7 @@ struct ira_reg_equiv
 extern int ira_reg_equiv_len;
 
 /* Info about equiv. info for each register.  */
-extern struct ira_reg_equiv *ira_reg_equiv;
+extern struct ira_reg_equiv_s *ira_reg_equiv;
 
 extern void ira_init_once (void);
 extern void ira_init (void);
index 0c4eec3..7d09204 100644 (file)
@@ -317,6 +317,44 @@ in_mem_p (int regno)
   return get_reg_class (regno) == NO_REGS;
 }
 
+/* Initiate equivalences for LRA.  As we keep original equivalences
+   before any elimination, we need to make copies otherwise any change
+   in insns might change the equivalences.  */
+void
+lra_init_equiv (void)
+{
+  ira_expand_reg_equiv ();
+  for (int i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
+    {
+      rtx res;
+
+      if ((res = ira_reg_equiv[i].memory) != NULL_RTX)
+       ira_reg_equiv[i].memory = copy_rtx (res);
+      if ((res = ira_reg_equiv[i].invariant) != NULL_RTX)
+       ira_reg_equiv[i].invariant = copy_rtx (res);
+    }
+}
+
+static rtx loc_equivalence_callback (rtx, const_rtx, void *);
+
+/* Update equivalence for REGNO.  We need to this as the equivalence
+   might contain other pseudos which are changed by their
+   equivalences.  */
+static void
+update_equiv (int regno)
+{
+  rtx x;
+  
+  if ((x = ira_reg_equiv[regno].memory) != NULL_RTX)
+    ira_reg_equiv[regno].memory
+      = simplify_replace_fn_rtx (x, NULL_RTX, loc_equivalence_callback,
+                                NULL_RTX);
+  if ((x = ira_reg_equiv[regno].invariant) != NULL_RTX)
+    ira_reg_equiv[regno].invariant
+      = simplify_replace_fn_rtx (x, NULL_RTX, loc_equivalence_callback,
+                                NULL_RTX);
+}
+
 /* If we have decided to substitute X with another value, return that
    value, otherwise return X.  */
 static rtx
@@ -3694,14 +3732,16 @@ loc_equivalence_change_p (rtx *loc)
 }
 
 /* Similar to loc_equivalence_change_p, but for use as
-   simplify_replace_fn_rtx callback.  */
+   simplify_replace_fn_rtx callback.  DATA is insn for which the
+   elimination is done.  If it null we don't do the elimination.  */
 static rtx
-loc_equivalence_callback (rtx loc, const_rtx, void *)
+loc_equivalence_callback (rtx loc, const_rtx, void *data)
 {
   if (!REG_P (loc))
     return NULL_RTX;
 
-  rtx subst = get_equiv_with_elimination (loc, curr_insn);
+  rtx subst = (data == NULL
+              ? get_equiv (loc) : get_equiv_with_elimination (loc, (rtx) data));
   if (subst != loc)
     return subst;
 
@@ -3946,6 +3986,8 @@ lra_constraints (bool first_p)
              bitmap_ior_into (&equiv_insn_bitmap, &lra_reg_info[i].insn_bitmap);
          }
       }
+  for (i = FIRST_PSEUDO_REGISTER; i < new_regno_start; i++)
+    update_equiv (i);
   /* We should add all insns containing pseudos which should be
      substituted by their equivalences.  */
   EXECUTE_IF_SET_IN_BITMAP (&equiv_insn_bitmap, 0, uid, bi)
@@ -3984,7 +4026,7 @@ lra_constraints (bool first_p)
              rtx old = *curr_id->operand_loc[0];
              *curr_id->operand_loc[0]
                = simplify_replace_fn_rtx (old, NULL_RTX,
-                                          loc_equivalence_callback, NULL);
+                                          loc_equivalence_callback, curr_insn);
              if (old != *curr_id->operand_loc[0])
                {
                  lra_update_insn_regno_info (curr_insn);
index 6d8d80f..22968e1 100644 (file)
@@ -319,6 +319,7 @@ extern int lra_constraint_new_insn_uid_start;
 
 /* lra-constraints.c: */
 
+extern void lra_init_equiv (void);
 extern int lra_constraint_offset (int, enum machine_mode);
 
 extern int lra_constraint_iter;
index 21b8af1..1491fc7 100644 (file)
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -2321,6 +2321,7 @@ lra (FILE *f)
        may be a part of the offset computation for register
        elimination.  */
     assign_stack_local (BLKmode, 0, crtl->stack_alignment_needed);
+  lra_init_equiv ();
   for (;;)
     {
       for (;;)