diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2003-02-01 01:01:38 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2003-02-01 01:01:38 +0000 |
commit | 2f278625ee254d3293798efeb57003a42fc2871a (patch) | |
tree | 6695bfe875cd231e5b9de23862d2deddab1b9692 | |
parent | e4b9b5fb09bda446289e62fd40feb679187ad901 (diff) | |
download | gcc-2f278625ee254d3293798efeb57003a42fc2871a.zip gcc-2f278625ee254d3293798efeb57003a42fc2871a.tar.gz gcc-2f278625ee254d3293798efeb57003a42fc2871a.tar.bz2 |
reload.c (find_reloads): Do not use the mode specified in the insn pattern as reload mode for address...
gcc/
* reload.c (find_reloads): Do not use the mode specified in the insn
pattern as reload mode for address operands. Do not generate optional
reloads for operands where a mandatory reload was already pushed.
Generate optional reloads only in the final pass though find_reloads.
(have_replacement_p): New function.
gcc/testsuite/
* gcc.dg/20030129-1.c: New test.
From-SVN: r62225
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/reload.c | 51 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/20030129-1.c | 37 |
4 files changed, 87 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dedd614..bd9a73d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2003-01-31 Ulrich Weigand <uweigand@de.ibm.com> + + * reload.c (find_reloads): Do not use the mode specified in the insn + pattern as reload mode for address operands. Do not generate optional + reloads for operands where a mandatory reload was already pushed. + Generate optional reloads only in the final pass though find_reloads. + (have_replacement_p): New function. + 2003-01-31 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> * doc/install.texi (Testing): Remove a reference to our obsolete diff --git a/gcc/reload.c b/gcc/reload.c index 46d0d64..1a7434f 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -274,6 +274,7 @@ static void find_reloads_address_part PARAMS ((rtx, rtx *, enum reg_class, static rtx find_reloads_subreg_address PARAMS ((rtx, int, int, enum reload_type, int, rtx)); static void copy_replacements_1 PARAMS ((rtx *, rtx *, int)); +static bool have_replacement_p PARAMS ((rtx *)); static int find_inc_amount PARAMS ((rtx, rtx)); #ifdef HAVE_SECONDARY_RELOADS @@ -2689,6 +2690,10 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) recog_data.operand[i] = *recog_data.operand_loc[i]; substed_operand[i] = recog_data.operand[i]; + + /* Address operands are reloaded in their existing mode, + no matter what is specified in the machine description. */ + operand_mode[i] = GET_MODE (recog_data.operand[i]); } else if (code == MEM) { @@ -3302,10 +3307,6 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) the address into a base register. */ this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode); badop = 0; - - /* Address constraints are reloaded in Pmode, no matter - what mode is given in the machine description. */ - operand_mode[i] = Pmode; break; } @@ -3876,9 +3877,20 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) return 0; } } + + /* Generate optional reloads only when optimizing, and only + on the last pass through reload. Also, make sure we do not + make an optional reload where we already have a mandatory + one; this can happen in the case of address operands. + + To check for mandatory reloads, we use have_replacement_p. + Note that this works only on the last pass through reload. */ + else if (!optimize || !replace + || have_replacement_p (recog_data.operand_loc[i])) + ; /* Do nothing. */ + else if (goal_alternative_matched[i] < 0 - && goal_alternative_matches[i] < 0 - && optimize) + && goal_alternative_matches[i] < 0) { /* For each non-matching operand that's a MEM or a pseudo-register that didn't get a hard register, make an optional reload. @@ -3928,11 +3940,10 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) reload, check if this is actually a pseudo register reference; we then need to emit a USE and/or a CLOBBER so that reload inheritance will do the right thing. */ - else if (replace - && (GET_CODE (operand) == MEM - || (GET_CODE (operand) == REG - && REGNO (operand) >= FIRST_PSEUDO_REGISTER - && reg_renumber [REGNO (operand)] < 0))) + else if (GET_CODE (operand) == MEM + || (GET_CODE (operand) == REG + && REGNO (operand) >= FIRST_PSEUDO_REGISTER + && reg_renumber [REGNO (operand)] < 0)) { operand = *recog_data.operand_loc[i]; @@ -3955,8 +3966,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) && goal_alternative_win[goal_alternative_matches[i]] && modified[i] == RELOAD_READ && modified[goal_alternative_matches[i]] == RELOAD_WRITE - && ! no_input_reloads && ! no_output_reloads - && optimize) + && ! no_input_reloads && ! no_output_reloads) { /* Similarly, make an optional reload for a pair of matching objects that are in MEM or a pseudo that didn't get a hard reg. */ @@ -6130,6 +6140,21 @@ find_replacement (loc) return *loc; } + +/* Return true if some replacement was scheduled at LOC. */ + +static bool +have_replacement_p (loc) + rtx *loc; +{ + struct replacement *r; + + for (r = &replacements[0]; r < &replacements[n_replacements]; r++) + if (r->where == loc) + return true; + + return false; +} /* Return nonzero if register in range [REGNO, ENDREGNO) appears either explicitly or implicitly in X diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 87a814f..acf883d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-01-31 Ulrich Weigand <uweigand@de.ibm.com> + + * gcc.dg/20030129-1.c: New test. + 2003-01-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> PR c++/8849 diff --git a/gcc/testsuite/gcc.dg/20030129-1.c b/gcc/testsuite/gcc.dg/20030129-1.c new file mode 100644 index 0000000..0b745a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20030129-1.c @@ -0,0 +1,37 @@ +/* This used to ICE due to a reload bug on s390*. */ + +/* { dg-do compile { target s390*-*-* } } */ +/* { dg-options "-O2" } */ + +int f (unsigned int); +void g (void *); + +void test (void *p, void *dummy) +{ + unsigned int flags = 0; + + if (dummy) + g (dummy); + + if (p) + flags |= 0x80000000; + + asm volatile ("" : : : "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); + + if (dummy) + g (dummy); + + if (p) + { + flags |= 0x20000000|0x80000000; + + if (!f (0)) + flags &= ~0x80000000; + } + + f (flags); + + if (dummy) + g (dummy); +} + |