diff options
author | Richard Henderson <rth@gcc.gnu.org> | 2002-10-02 13:35:49 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2002-10-02 13:35:49 -0700 |
commit | d631b80aa7ff0f81cb486863f8bdb9369b48b5e9 (patch) | |
tree | 1dfe2c0b1567ce92b07b7b8fd40f58d89decfe3b | |
parent | a6ad79e790f038417c60704d9dd7a879a3ea05ee (diff) | |
download | gcc-d631b80aa7ff0f81cb486863f8bdb9369b48b5e9.zip gcc-d631b80aa7ff0f81cb486863f8bdb9369b48b5e9.tar.gz gcc-d631b80aa7ff0f81cb486863f8bdb9369b48b5e9.tar.bz2 |
re PR rtl-optimization/7124 (-O2 -march=athlon produces ICE)
PR opt/7124
* config/i386/i386.c (ix86_register_move_cost): Increase cost
for secondary_memory_needed pairs.
From-SVN: r57751
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 30 |
2 files changed, 31 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fdf0c28..7b571cc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,11 @@ -2002-10-02 Matt Austern <austern@apple.com +2002-10-02 Richard Henderson <rth@redhat.com> + + PR opt/7124 + * config/i386/i386.c (ix86_register_move_cost): Increase cost + for secondary_memory_needed pairs. + +2002-10-02 Matt Austern <austern@apple.com> + * class.c (check_field_decls): Changed warning about const member variables so that it doesn't get issued for a class aggregate. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 28f3ac8..b018c9e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13580,17 +13580,33 @@ ix86_register_move_cost (mode, class1, class2) enum reg_class class1, class2; { /* In case we require secondary memory, compute cost of the store followed - by load. In case of copying from general_purpose_register we may emit - multiple stores followed by single load causing memory size mismatch - stall. Count this as arbitarily high cost of 20. */ + by load. In order to avoid bad register allocation choices, we need + for this to be *at least* as high as the symmetric MEMORY_MOVE_COST. */ + if (ix86_secondary_memory_needed (class1, class2, mode, 0)) { - int add_cost = 0; + int cost = 1; + + cost += MAX (MEMORY_MOVE_COST (mode, class1, 0), + MEMORY_MOVE_COST (mode, class1, 1)); + cost += MAX (MEMORY_MOVE_COST (mode, class2, 0), + MEMORY_MOVE_COST (mode, class2, 1)); + + /* In case of copying from general_purpose_register we may emit multiple + stores followed by single load causing memory size mismatch stall. + Count this as arbitarily high cost of 20. */ if (CLASS_MAX_NREGS (class1, mode) > CLASS_MAX_NREGS (class2, mode)) - add_cost = 20; - return (MEMORY_MOVE_COST (mode, class1, 0) - + MEMORY_MOVE_COST (mode, class2, 1) + add_cost); + cost += 20; + + /* In the case of FP/MMX moves, the registers actually overlap, and we + have to switch modes in order to treat them differently. */ + if ((MMX_CLASS_P (class1) && MAYBE_FLOAT_CLASS_P (class2)) + || (MMX_CLASS_P (class2) && MAYBE_FLOAT_CLASS_P (class1))) + cost += 20; + + return cost; } + /* Moves between SSE/MMX and integer unit are expensive. */ if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2) || SSE_CLASS_P (class1) != SSE_CLASS_P (class2)) |