From 69f38ab9fd8ac5c7f5b68c01673c4c6366fd343c Mon Sep 17 00:00:00 2001 From: "J\"orn Rennecke" Date: Mon, 15 Dec 2003 17:42:43 +0000 Subject: [PATCH] reload.c (reg_overlap_mentioned_for_reload_p): When looking at a PLUS in X... * reload.c (reg_overlap_mentioned_for_reload_p): When looking at a PLUS in X, avoid spuriously returning nonzero when IN is a REG or another simple PLUS, or a MEM containing one. * loop.c (loop_invariant_p): Amend comment about where new registers might come from. From-SVN: r74638 --- gcc/ChangeLog | 9 +++++++++ gcc/loop.c | 10 ++++++++-- gcc/reload.c | 18 ++++++++++++++++-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d35a59941278..be45849cdbb3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2003-12-15 J"orn Rennecke + + * reload.c (reg_overlap_mentioned_for_reload_p): + When looking at a PLUS in X, avoid spuriously returning nonzero + when IN is a REG or another simple PLUS, or a MEM containing one. + + * loop.c (loop_invariant_p): Amend comment about where new registers + might come from. + 2003-12-15 Andreas Jaeger * config/rs6000/rs6000.c (rs6000_output_function_epilogue): Remove diff --git a/gcc/loop.c b/gcc/loop.c index 8deb398b9124..93bb328be349 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -3298,8 +3298,14 @@ loop_invariant_p (const struct loop *loop, rtx x) return 0; /* Out-of-range regs can occur when we are called from unrolling. - These have always been created by the unroller and are set in - the loop, hence are never invariant. */ + These registers created by the unroller are set in the loop, + hence are never invariant. + Other out-of-range regs can be generated by load_mems; those that + are written to in the loop are not invariant, while those that are + not written to are invariant. It would be easy for load_mems + to set n_times_set correctly for these registers, however, there + is no easy way to distinguish them from registers created by the + unroller. */ if (REGNO (x) >= (unsigned) regs->num) return 0; diff --git a/gcc/reload.c b/gcc/reload.c index fe0f04746893..13f6900ce3d5 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -6290,8 +6290,22 @@ reg_overlap_mentioned_for_reload_p (rtx x, rtx in) || GET_CODE (x) == CC0) return reg_mentioned_p (x, in); else if (GET_CODE (x) == PLUS) - return (reg_overlap_mentioned_for_reload_p (XEXP (x, 0), in) - || reg_overlap_mentioned_for_reload_p (XEXP (x, 1), in)); + { + /* We actually want to know if X is mentioned somewhere inside IN. + We must not say that (plus (sp) (const_int 124)) is in + (plus (sp) (const_int 64)), since that can lead to incorrect reload + allocation when spuriously changing a RELOAD_FOR_OUTPUT_ADDRESS + into a RELOAD_OTHER on behalf of another RELOAD_OTHER. */ + while (GET_CODE (in) == MEM) + in = XEXP (in, 0); + if (GET_CODE (in) == REG) + return 0; + else if (GET_CODE (in) == PLUS) + return (reg_overlap_mentioned_for_reload_p (x, XEXP (in, 0)) + || reg_overlap_mentioned_for_reload_p (x, XEXP (in, 1))); + else return (reg_overlap_mentioned_for_reload_p (XEXP (x, 0), in) + || reg_overlap_mentioned_for_reload_p (XEXP (x, 1), in)); + } else abort ();