diff options
author | DJ Delorie <dj@redhat.com> | 2006-11-17 18:15:29 -0500 |
---|---|---|
committer | DJ Delorie <dj@gcc.gnu.org> | 2006-11-17 18:15:29 -0500 |
commit | d2c9375a6d77a910c3696f3e01e0fafafc21c345 (patch) | |
tree | cf353ee37fa3fdee81a2f7a5c7fec82e28b4a4b4 /gcc | |
parent | 036a2b7a60782739d05a48d9968cdb8e2129b683 (diff) | |
download | gcc-d2c9375a6d77a910c3696f3e01e0fafafc21c345.zip gcc-d2c9375a6d77a910c3696f3e01e0fafafc21c345.tar.gz gcc-d2c9375a6d77a910c3696f3e01e0fafafc21c345.tar.bz2 |
reload1.c (reloads_unique_chain): New.
* reload1.c (reloads_unique_chain): New.
(reloads_conflict): Call it.
From-SVN: r118953
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/reload1.c | 48 |
2 files changed, 52 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d2fbac9..f3c8b87 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2006-11-17 DJ Delorie <dj@redhat.com> + + * reload1.c (reloads_unique_chain): New. + (reloads_conflict): Call it. + 2006-11-17 Bob Wilson <bob.wilson@acm.org> * config/xtensa/predicates.md (addsubx_operand): New. diff --git a/gcc/reload1.c b/gcc/reload1.c index e644322..88b89fe 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -4794,6 +4794,51 @@ reload_reg_reaches_end_p (unsigned int regno, int opnum, enum reload_type type) } } + +/* Returns whether R1 and R2 are uniquely chained: the value of one + is used by the other, and that value is not used by any other + reload for this insn. This is used to partially undo the decision + made in find_reloads when in the case of multiple + RELOAD_FOR_OPERAND_ADDRESS reloads it converts all + RELOAD_FOR_OPADDR_ADDR reloads into RELOAD_FOR_OPERAND_ADDRESS + reloads. This code tries to avoid the conflict created by that + change. It might be cleaner to explicitly keep track of which + RELOAD_FOR_OPADDR_ADDR reload is associated with which + RELOAD_FOR_OPERAND_ADDRESS reload, rather than to try to detect + this after the fact. */ +static bool +reloads_unique_chain_p (int r1, int r2) +{ + int i; + + /* We only check input reloads. */ + if (! rld[r1].in || ! rld[r2].in) + return false; + + /* Avoid anything with output reloads. */ + if (rld[r1].out || rld[r2].out) + return false; + + /* "chained" means one reload is a component of the other reload, + not the same as the other reload. */ + if (rld[r1].opnum != rld[r2].opnum + || rtx_equal_p (rld[r1].in, rld[r2].in) + || rld[r1].optional || rld[r2].optional + || ! (reg_mentioned_p (rld[r1].in, rld[r2].in) + || reg_mentioned_p (rld[r2].in, rld[r1].in))) + return false; + + for (i = 0; i < n_reloads; i ++) + /* Look for input reloads that aren't our two */ + if (i != r1 && i != r2 && rld[i].in) + { + /* If our reload is mentioned at all, it isn't a simple chain. */ + if (reg_mentioned_p (rld[r1].in, rld[i].in)) + return false; + } + return true; +} + /* Return 1 if the reloads denoted by R1 and R2 cannot share a register. Return 0 otherwise. @@ -4842,7 +4887,8 @@ reloads_conflict (int r1, int r2) case RELOAD_FOR_OPERAND_ADDRESS: return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN - || r2_type == RELOAD_FOR_OPERAND_ADDRESS); + || (r2_type == RELOAD_FOR_OPERAND_ADDRESS + && !reloads_unique_chain_p (r1, r2))); case RELOAD_FOR_OPADDR_ADDR: return (r2_type == RELOAD_FOR_INPUT |