This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix bogus address costs in ivopts
- From: "Ulrich Weigand" <weigand at i1 dot informatik dot uni-erlangen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 20 Oct 2004 18:17:43 +0200 (CEST)
- Subject: [PATCH] Fix bogus address costs in ivopts
Hello,
some of the loop optimization tests (loop-2.c, loop-4.c) fail on s390x
because the reference to the arr_base symbol is not moved out of the
loop.
This turned out to be caused simply by bogus cost metrics returned
from get_address_cost, leading to suboptimal selection of iv candidates.
There were two problems in get_address_cost:
- it did not recognize that offset zero is special and may be
implemented more efficiently than any non-zero offset (even though
this is not an issue on s390, it may well be e.g. on rs6000).
- it would generate non-canonical RTL of the form
(plus (const_int) (reg))
in some cases, which caused the cost functions to return too
high costs for simple addresses
Both are fixed by the following patch. (Note that the whole concept
behind get_address_cost still appears to be too simplistic IMHO:
e.g. the assumption that every type of symbol has the same cost is
just wrong. A local static will be cheaper that a global symbol
with -fPIC, which will be cheaper than thread-local symbols etc.)
Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux,
fixes the loop-2/loop-4 test cases.
OK for mainline?
Bye,
Ulrich
ChangeLog:
* tree-ssa-loop-ivopts.c (get_address_cost): Offset zero does not
cause extra costs. Generate canonical RTL.
Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-ivopts.c,v
retrieving revision 2.20
diff -c -p -r2.20 tree-ssa-loop-ivopts.c
*** gcc/tree-ssa-loop-ivopts.c 18 Oct 2004 18:01:09 -0000 2.20
--- gcc/tree-ssa-loop-ivopts.c 20 Oct 2004 13:05:19 -0000
*************** get_address_cost (bool symbol_present, b
*** 2485,2491 ****
s_offset = offset;
cost = 0;
! offset_p = (min_offset <= s_offset && s_offset <= max_offset);
ratio_p = (ratio != 1
&& -MAX_RATIO <= ratio && ratio <= MAX_RATIO
&& TEST_BIT (valid_mult, ratio + MAX_RATIO));
--- 2485,2492 ----
s_offset = offset;
cost = 0;
! offset_p = (s_offset != 0
! && min_offset <= s_offset && s_offset <= max_offset);
ratio_p = (ratio != 1
&& -MAX_RATIO <= ratio && ratio <= MAX_RATIO
&& TEST_BIT (valid_mult, ratio + MAX_RATIO));
*************** get_address_cost (bool symbol_present, b
*** 2509,2514 ****
--- 2510,2518 ----
if (ratio_p)
addr = gen_rtx_fmt_ee (MULT, Pmode, addr, GEN_INT (rat));
+ if (var_present)
+ addr = gen_rtx_fmt_ee (PLUS, Pmode, reg1, addr);
+
if (symbol_present)
{
base = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (""));
*************** get_address_cost (bool symbol_present, b
*** 2517,2531 ****
gen_rtx_fmt_ee (PLUS, Pmode,
base,
GEN_INT (off)));
- if (var_present)
- base = gen_rtx_fmt_ee (PLUS, Pmode, reg1, base);
- }
-
- else if (var_present)
- {
- base = reg1;
- if (offset_p)
- base = gen_rtx_fmt_ee (PLUS, Pmode, base, GEN_INT (off));
}
else if (offset_p)
base = GEN_INT (off);
--- 2521,2526 ----
--
Dr. Ulrich Weigand
weigand@informatik.uni-erlangen.de