aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2013-12-13 20:47:19 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2013-12-13 20:47:19 +0000
commit4c2b2d7916bef81ed7d2e7ebe8a657635306fa15 (patch)
treec4ae803ddb3a378c23de07993d4ac2fadf41169e /gcc
parent7424147986e3c898ed50e411657c8357764aa3f8 (diff)
downloadgcc-4c2b2d7916bef81ed7d2e7ebe8a657635306fa15.zip
gcc-4c2b2d7916bef81ed7d2e7ebe8a657635306fa15.tar.gz
gcc-4c2b2d7916bef81ed7d2e7ebe8a657635306fa15.tar.bz2
ira.h (struct ira_reg_equiv): Rename to ira_reg_equiv_s.
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. From-SVN: r205974
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/ira.c8
-rw-r--r--gcc/ira.h4
-rw-r--r--gcc/lra-constraints.c50
-rw-r--r--gcc/lra-int.h1
-rw-r--r--gcc/lra.c1
6 files changed, 65 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e80beeb..4f7b79a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/ira.c b/gcc/ira.c
index d6462ca..18e2634 100644
--- 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
diff --git a/gcc/ira.h b/gcc/ira.h
index 3a1824b..49acc4a 100644
--- 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);
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 0c4eec3..7d09204 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -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);
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
index 6d8d80f..22968e1 100644
--- a/gcc/lra-int.h
+++ b/gcc/lra-int.h
@@ -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;
diff --git a/gcc/lra.c b/gcc/lra.c
index 21b8af1..1491fc7 100644
--- 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 (;;)