From 01e54ef86f407385b0f2bb7afb5748f0db31bce8 Mon Sep 17 00:00:00 2001 From: Vladimir Makarov Date: Fri, 2 Aug 2013 14:23:38 +0000 Subject: [PATCH] re PR rtl-optimization/57963 (LRA S/390: esa mode failure memcpy-chk) 2013-08-02 Vladimir Makarov PR rtl-optimization/57963 * lra-constraints.c (reverse_equiv_p, contains_reloaded_insn_p): New. (lra_constraints): Use them. From-SVN: r201438 --- gcc/ChangeLog | 7 +++++++ gcc/lra-constraints.c | 49 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 489e0c7a445..94a65d2bdb5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-08-02 Vladimir Makarov + + PR rtl-optimization/57963 + * lra-constraints.c (reverse_equiv_p, contains_reloaded_insn_p): + New. + (lra_constraints): Use them. + 2013-08-02 Sofiane Naci * config/arm/types.md (define_attr "type"): Add "load_acq" and "store_rel". diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 29cf7dbe852..ced02a41356 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) -- 2.30.2