diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2012-11-21 22:22:11 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2012-11-21 22:22:11 +0000 |
commit | 1966c91bf487448902f93c9f54e6dab45640ca52 (patch) | |
tree | 01fb4ccba359d8ef78098a191519dd742380a9b4 /gcc/lra-constraints.c | |
parent | ecdbf2cdfa8aededf4b1027998af325b0e2ff70c (diff) | |
download | gcc-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
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r-- | gcc/lra-constraints.c | 51 |
1 files changed, 34 insertions, 17 deletions
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) |