aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2012-11-21 22:22:11 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2012-11-21 22:22:11 +0000
commit1966c91bf487448902f93c9f54e6dab45640ca52 (patch)
tree01fb4ccba359d8ef78098a191519dd742380a9b4
parentecdbf2cdfa8aededf4b1027998af325b0e2ff70c (diff)
downloadgcc-1966c91bf487448902f93c9f54e6dab45640ca52.zip
gcc-1966c91bf487448902f93c9f54e6dab45640ca52.tar.gz
gcc-1966c91bf487448902f93c9f54e6dab45640ca52.tar.bz2
re PR rtl-optimization/55414 (spec2006 416.gamess compilation fails on LRA)
2012-11-21 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/55414 * lra-constraints.c (Index): New function. (lra_constraints): Check dead equiv init insns. From-SVN: r193712
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/lra-constraints.c51
2 files changed, 40 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fc4e5bc..7476b86 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2012-11-21 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/55414
+ * lra-constraints.c (Index): New function.
+ (lra_constraints): Check dead equiv init insns.
+
2012-11-21 Richard Henderson <rth@redhat.com>
* config/alpha/alpha.md (extvmisaligndi): Rename from extv; update
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 63ef155..7fbd3d5 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -3215,6 +3215,17 @@ multi_block_pseudo_p (int regno)
return false;
}
+/* Return true if LIST contains a deleted insn. */
+static bool
+contains_deleted_insn_p (rtx list)
+{
+ for (; list != NULL_RTX; list = XEXP (list, 1))
+ if (NOTE_P (XEXP (list, 0))
+ && NOTE_KIND (XEXP (list, 0)) == NOTE_INSN_DELETED)
+ return true;
+ return false;
+}
+
/* Return true if X contains a pseudo dying in INSN. */
static bool
dead_pseudo_p (rtx x, rtx insn)
@@ -3317,10 +3328,29 @@ lra_constraints (bool first_p)
bool pseudo_p = contains_reg_p (x, false, false);
rtx set, insn;
- /* We don't use DF for compilation speed sake. So it is
- problematic to update live info when we use an
- equivalence containing pseudos in more than one BB. */
- if ((pseudo_p && multi_block_pseudo_p (i))
+ /* After RTL transformation, we can not guarantee that
+ pseudo in the substitution was not reloaded which might
+ make equivalence invalid. For example, in reverse
+ equiv of p0
+
+ p0 <- ...
+ ...
+ equiv_mem <- p0
+
+ the memory address register was reloaded before the 2nd
+ insn. */
+ if ((! first_p && pseudo_p)
+ /* We don't use DF for compilation speed sake. So it
+ is problematic to update live info when we use an
+ equivalence containing pseudos in more than one
+ BB. */
+ || (pseudo_p && multi_block_pseudo_p (i))
+ /* If an init insn was deleted for some reason, cancel
+ the equiv. We could update the equiv insns after
+ transformations including an equiv insn deletion
+ but it is not worthy as such cases are extremely
+ rare. */
+ || contains_deleted_insn_p (ira_reg_equiv[i].init_insns)
/* If it is not a reverse equivalence, we check that a
pseudo in rhs of the init insn is not dying in the
insn. Otherwise, the live info at the beginning of
@@ -3335,19 +3365,6 @@ lra_constraints (bool first_p)
&& (int) REGNO (SET_DEST (set)) == i)
&& init_insn_rhs_dead_pseudo_p (i)))
ira_reg_equiv[i].defined_p = false;
- else if (! first_p && pseudo_p)
- /* After RTL transformation, we can not guarantee that
- pseudo in the substitution was not reloaded which
- might make equivalence invalid. For example, in
- reverse equiv of p0
-
- p0 <- ...
- ...
- equiv_mem <- p0
-
- the memory address register was reloaded before the
- 2nd insn. */
- ira_reg_equiv[i].defined_p = false;
if (contains_reg_p (x, false, true))
ira_reg_equiv[i].profitable_p = false;
if (get_equiv_substitution (reg) != reg)