aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@gcc.gnu.org>2002-10-02 13:35:49 -0700
committerRichard Henderson <rth@gcc.gnu.org>2002-10-02 13:35:49 -0700
commitd631b80aa7ff0f81cb486863f8bdb9369b48b5e9 (patch)
tree1dfe2c0b1567ce92b07b7b8fd40f58d89decfe3b
parenta6ad79e790f038417c60704d9dd7a879a3ea05ee (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/config/i386/i386.c30
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))