diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2013-08-02 14:23:38 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2013-08-02 14:23:38 +0000 |
commit | 01e54ef86f407385b0f2bb7afb5748f0db31bce8 (patch) | |
tree | a8d03ad274dd5b88c91925649ec285612f10e96a /gcc/lra-constraints.c | |
parent | e2fd7ca74819ba4db334430582c163a3efeaada4 (diff) | |
download | gcc-01e54ef86f407385b0f2bb7afb5748f0db31bce8.zip gcc-01e54ef86f407385b0f2bb7afb5748f0db31bce8.tar.gz gcc-01e54ef86f407385b0f2bb7afb5748f0db31bce8.tar.bz2 |
re PR rtl-optimization/57963 (LRA S/390: esa mode failure memcpy-chk)
2013-08-02 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/57963
* lra-constraints.c (reverse_equiv_p, contains_reloaded_insn_p):
New.
(lra_constraints): Use them.
From-SVN: r201438
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r-- | gcc/lra-constraints.c | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 29cf7db..ced02a4 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -3600,6 +3600,40 @@ init_insn_rhs_dead_pseudo_p (int regno) return false; } +/* Return TRUE if REGNO has a reverse equivalence. The equivalence is + reverse only if we have one init insn with given REGNO as a + source. */ +static bool +reverse_equiv_p (int regno) +{ + rtx insns, set; + + if ((insns = ira_reg_equiv[regno].init_insns) == NULL_RTX) + return false; + if (! INSN_P (XEXP (insns, 0)) + || XEXP (insns, 1) != NULL_RTX) + return false; + if ((set = single_set (XEXP (insns, 0))) == NULL_RTX) + return false; + return REG_P (SET_SRC (set)) && (int) REGNO (SET_SRC (set)) == regno; +} + +/* Return TRUE if REGNO was reloaded in an equivalence init insn. We + call this function only for non-reverse equivalence. */ +static bool +contains_reloaded_insn_p (int regno) +{ + rtx set; + rtx list = ira_reg_equiv[regno].init_insns; + + for (; list != NULL_RTX; list = XEXP (list, 1)) + if ((set = single_set (XEXP (list, 0))) == NULL_RTX + || ! REG_P (SET_DEST (set)) + || (int) REGNO (SET_DEST (set)) != regno) + return true; + return false; +} + /* Entry function of LRA constraint pass. Return true if the constraint pass did change the code. */ bool @@ -3643,7 +3677,6 @@ lra_constraints (bool first_p) else if ((x = get_equiv_substitution (reg)) != reg) { bool pseudo_p = contains_reg_p (x, false, false); - rtx set, insns; /* After RTL transformation, we can not guarantee that pseudo in the substitution was not reloaded which might @@ -3675,13 +3708,13 @@ lra_constraints (bool first_p) removed the insn. When the equiv can be a constant, the right hand side of the init insn can be a pseudo. */ - || (! ((insns = ira_reg_equiv[i].init_insns) != NULL_RTX - && INSN_P (XEXP (insns, 0)) - && XEXP (insns, 1) == NULL_RTX - && (set = single_set (XEXP (insns, 0))) != NULL_RTX - && REG_P (SET_SRC (set)) - && (int) REGNO (SET_SRC (set)) == i) - && init_insn_rhs_dead_pseudo_p (i)) + || (! reverse_equiv_p (i) + && (init_insn_rhs_dead_pseudo_p (i) + /* If we reloaded the pseudo in an equivalence + init insn, we can not remove the equiv init + insns and the init insns might write into + const memory in this case. */ + || contains_reloaded_insn_p (i))) /* Prevent access beyond equivalent memory for paradoxical subregs. */ || (MEM_P (x) |