diff options
author | Hans-Peter Nilsson <hp@axis.com> | 2023-03-30 00:56:13 +0200 |
---|---|---|
committer | Hans-Peter Nilsson <hp@bitrange.com> | 2023-03-30 00:56:13 +0200 |
commit | 68982b98d2a7a52cfc5aada7d35d6c493c010712 (patch) | |
tree | 079b93ce956cc6de2a9bc3f2aba453787d617dd0 /gcc | |
parent | 3be4e43a6a0f429648ea188c8e110b74268fed27 (diff) | |
download | gcc-68982b98d2a7a52cfc5aada7d35d6c493c010712.zip gcc-68982b98d2a7a52cfc5aada7d35d6c493c010712.tar.gz gcc-68982b98d2a7a52cfc5aada7d35d6c493c010712.tar.bz2 |
CRIS: Make rtx-cost 0 for many CONST_INT "quick" operands
Stepping through a gdb session inspecting costs that cause
gcc.dg/tree-ssa/slsr-13.c to fail, exposed that before this
patch, cris_rtx_costs told that a shift of 1 of a register
costs 5, while adding two registers costs 4.
Making the cost of a quick-immediate constant equal to using
a register (default 0) reflects actual performance and
size-cost better. It also happens to make
gcc.dg/tree-ssa/slsr-13.c pass with what looks like better
code being generated, and improves coremark performance by
0.4%.
But, blindly doing this for *all* valid operands that fit
the "quick-immediate" addressing mode, trips interaction
with other factors*, with the end result mixed at best. So,
do this only for MINUS and logical operations for the time
being, and only for modes that fit in one register.
*) Examples of "other factors":
- A bad default implementation of insn_cost or actually,
pattern_cost, that looks only at the set_src_cost and
furthermore sees such a cost of 0 as invalid. (Compare to
the more sane set_rtx_cost.) This naturally tripped up
combine and ifcvt, causing all sorts of changes, good and
bad.
- Having the same cost, to compare a register with 0 as with
-31..31, means a compare insn of an eliminable form no
longer looks preferable.
* config/cris/cris.cc (cris_rtx_costs) [CONST_INT]: Return 0
for many quick operands, for register-sized modes.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/cris/cris.cc | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/gcc/config/cris/cris.cc b/gcc/config/cris/cris.cc index 641e7ea..05dead9 100644 --- a/gcc/config/cris/cris.cc +++ b/gcc/config/cris/cris.cc @@ -1884,7 +1884,28 @@ cris_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, if (val == 0) *total = 0; else if (val < 32 && val >= -32) - *total = 1; + switch (outer_code) + { + /* For modes that fit in one register we tell they cost + the same as with register operands. DImode operations + needs careful consideration for more basic reasons: + shifting by a non-word-size amount needs more + operations than an addition by a register pair. + Deliberately excluding SET, PLUS and comparisons and + also not including the full -64..63 range for (PLUS + and) MINUS. */ + case MINUS: case ASHIFT: case LSHIFTRT: + case ASHIFTRT: case AND: case IOR: + if (GET_MODE_SIZE(mode) <= UNITS_PER_WORD) + { + *total = 0; + break; + } + /* FALL THROUGH. */ + default: + *total = 1; + break; + } /* Eight or 16 bits are a word and cycle more expensive. */ else if (val <= 32767 && val >= -32768) *total = 2; |