This patch changes the targetm.rtx_costs interface to pass a mode
parameter, and removes a redundant parameter. The reason for the
change is that powerpc and other backends need the mode that a
const_int is used in to properly determine the cost. For instance,
(set (reg) (ior (reg) (const_int))) where const_int is 0xff..ffff0000
can be implemented in one instruction on powerpc if the regs and
constant are SImode, but not when DImode.
Some backends work around this problem by calculating the cost of the
entire expression under the IOR, which allows the mode of the
const_int to be inferred. This of course results in huge rtx_costs
functions since you must inspect the operands of many rtx codes that
take const_int operands. Worse, it doesn't work for all calls to
targetm.rtx_costs; gcc doesn't always pass an entire insn, or even
the complete right hand side of a SET, to rtx_costs. One place this
is seen is in expand, for example, emit_store_flag makes calls like
rtx_cost (GEN_INT (normalizep), PLUS, ...)
This sort of thing seems like a fundamental requirement in expand
where insns are being built. cse also makes similar calls. So
rtx_cost must be able to handle sub-expressions of an insn.
As to the patch itself, the bulk is mostly mechanical. I haven't made
any simplification to the arm, aarch64 and mips rtx_costs that might
be possible with this interface change. rtlanal.c:rtx_cost also needs
a machine_mode parameter to deal with the expand rtl mentioned above,
as do a few other rtx cost functions. sub-rtx's in rtx_cost are
summed in order rather than reverse order so that the mode from an
earlier operand can be used for a later operand lacking a mode. This
is for ZERO_EXTEND and similar codes where the sub-rtx mode is
different to the outer mode. Canonicalization puts const_int operands
after other operands.
I moved some inline functions in rtl.h later in the file because an
earlier patch iteration passed GET_MODE (SET_DEST (x)) as the mode in
set_rtx_cost and get_full_set_rtx_cost. That meant the inlines needed
to be after the definition of SET_DEST. Later I realized that
rtx_cost needed to provide the mode for a SET anyway, so VOIDmode
would do just as well in set_rtx_cost. That means the inlines don't
need to be moved, but their new location seems better.
The patch also doesn't contain any real changes to the powerpc
backend, and in fact produces worse code than before in cases where
rldic should be allowed by combine. A later patch will cure the
powerpc regressions.
The patch was tested by full powerpc64-linux and x86_64-linux
regression testing, and building cross-compilers for aarch64-linux,
alpha-linux, arc-elf, arm-linuxeabi, avr-elf, bfin-elf, cris-linux,
epiphany-elf, frv-linux, h8300-linux, hppa-linux, ia64-linux,
iq2000-elf, lm32-elf, m32c-elf, m32r-elf, m68k-linux, mcore-elf,
mep-elf, microblaze-linux, mips64-linux, mmix, mn10300-elf,
msp430-elf, nds32le-elf, pdp11-aout, rl78-elf, s390x-linux,
sh64-linux, sparc64-linux, spu-elf, tic6x-elf, tilegx-linux,
tilepro-linux, v850-elf, vax-linux, visium-elf, xstormy16-elf, and
xtensa-linux. I examined x86_64-linux gcc/*.o files and didn't see
any unexpected changes.
The testing showed some pre-existing bugs..
arc-elf dies on attempting to assemble first libgcc file, due to gas
not understanding the options being passed by gcc. Apparently no one
cared enough to push gas changes upstream.
ia64-linux, m68k-linux, tilegx-linux and tilepro-linux have
dependencies on include files, not solved by -Dinhibit_libc, so die
building libgcc. Can be solved by hand, but annoying.
iq2000-elf: internal compiler error: in dwarf2out_var_location, at
dwarf2out.c:22302.
mep-elf: internal compiler error: in pre_and_rev_post_order_compute,
at cfganal.c:1029
s390x-linux doesn't build as a cross-compiler. undefined reference to
`s390_host_detect_local_cpu(int, char const**)'
tic6x-elf hits gas errors: Error: inconsistent uses of .cfi_sections
vax-linux: internal compiler error: Segmentation fault. Due to trying
to find MEM_ADDR_SPACE of a SUBREG in this insn predicate
&& (REG_P (operands[1])
|| ! mode_dependent_address_p (XEXP (operands[1], 0),
MEM_ADDR_SPACE (operands[1])))"
* target.def (rtx_costs): Remove "code" param, add "mode".
* rtl.h (rtx_cost, get_full_rtx_cost): Update prototype.
(set_src_cost, get_full_set_src_cost): Likewise. Move later in file.
(set_rtx_cost, get_full_set_rtx_cost): Move later in file.
* rtlanal.c (rtx_cost): Add "mode" parameter. Update targetm.rtx_costs
call. Track mode when given in rtx.
(get_full_rtx_cost): Add "mode" parameter. Update rtx_cost calls.
(default_address_cost): Pass Pmode to rtx_cost.
(insn_rtx_cost): Pass dest mode of set to set_src_cost.
* cprop.c (try_replace_reg): Ensure set_rtx_cost is not called
with NULL set.
* cse.c (COST, COST_IN): Add MODE param. Update all uses.
(notreg_cost): Add mode param. Use it.
* gcse.c (want_to_gcse_p): Delete forward declaration. Add
mode param and pass to set_src_cost. Update all calls.
(hash_scan_set): Formatting.
* hooks.c (hook_bool_rtx_int_int_int_intp_bool_false): Delete.
(hook_bool_rtx_mode_int_int_intp_bool_false): New function.
* hooks.h: Ditto.
* expmed.c (init_expmed_one_conv, init_expmed_one_mode,
init_expmed, expand_mult, mult_by_coeff_cost, expand_smod_pow2,
emit_store_flag): Update set_src_cost and rtx_cost calls.
* auto-inc-dec.c (attempt_change): Likewise.
* calls.c (precompute_register_parameters): Likewise.
* combine.c (expand_compound_operation, make_extraction,
force_to_mode, distribute_and_simplify_rtx): Likewise.
* dojump.c (prefer_and_bit_test): Likewise.
* dse.c (find_shift_sequence): Likewise.
* expr.c (compress_float_constant): Likewise.
* fwprop.c (should_replace_address, try_fwprop_subst): Likewise.
* ifcvt.c (noce_try_sign_mask): Likewise.
* loop-doloop.c (doloop_optimize): Likewise.
* loop-invariant.c (create_new_invariant): Likewise.
* lower-subreg.c (shift_cost, compute_costs): Likewise.
* optabs.c (avoid_expensive_constant, prepare_cmp_insn,
lshift_cheap_p): Likewise.
* postreload.c (reload_cse_simplify_set, reload_cse_simplify_operands,
try_replace_in_use, reload_cse_move2add): Likewise.
* reload1.c (calculate_elim_costs_all_insns, note_reg_elim_costly):
Likewise.
* simplify-rtx.c (simplify_binary_operation_1): Likewise.
* tree-ssa-loop-ivopts.c (computation_cost): Likewise.
* tree-ssa-reassoc.c (optimize_range_tests_to_bit_test): Likewise.
* tree-switch-conversion.c (emit_case_bit_tests): Likewise.
* config/aarch64/aarch64.c (aarch64_rtx_costs): Delete "code" param,
add "mode" param. Use "mode: in place of GET_MODE (x). Pass mode
to rtx_cost calls.
* config/alpha/alpha.c (alpha_rtx_costs): Likewise.
* config/arc/arc.c (arc_rtx_costs): Likewise.
* config/arm/arm.c (arm_rtx_costs): Likewise.
* config/avr/avr.c (avr_rtx_costs, avr_rtx_costs_1): Likewise.
* config/bfin/bfin.c (bfin_rtx_costs): Likewise.
* config/c6x/c6x.c (c6x_rtx_costs): Likewise.
* config/cris/cris.c (cris_rtx_costs): Likewise.
* config/epiphany/epiphany.c (epiphany_rtx_costs): Likewise.
* config/frv/frv.c (frv_rtx_costs): Likewise.
* config/h8300/h8300.c (h8300_rtx_costs): Likewise.
* config/i386/i386.c (ix86_rtx_costs): Likewise.
* config/ia64/ia64.c (ia64_rtx_costs): Likewise.
* config/iq2000/iq2000.c (iq2000_rtx_costs): Likewise.
* config/lm32/lm32.c (lm32_rtx_costs): Likewise.
* config/m32c/m32c.c (m32c_rtx_costs): Likewise.
* config/m32r/m32r.c (m32r_rtx_costs): Likewise.
* config/m68k/m68k.c (m68k_rtx_costs): Likewise.
* config/mcore/mcore.c (mcore_rtx_costs): Likewise.
* config/mep/mep.c (mep_rtx_cost): Likewise.
* config/microblaze/microblaze.c (microblaze_rtx_costs): Likewise.
* config/mips/mips.c (mips_rtx_costs): Likewise.
* config/mmix/mmix.c (mmix_rtx_costs): Likewise.
* config/mn10300/mn10300.c (mn10300_rtx_costs): Likewise.
* config/msp430/msp430.c (msp430_rtx_costs): Likewise.
* config/nds32/nds32-cost.c (nds32_rtx_costs_impl): Likewise.
* config/nds32/nds32-protos.h (nds32_rtx_costs_impl): Likewise.
* config/nds32/nds32.c (nds32_rtx_costs): Likewise.
* config/nios2/nios2.c (nios2_rtx_costs): Likewise.
* config/pa/pa.c (hppa_rtx_costs): Likewise.
* config/pdp11/pdp11.c (pdp11_rtx_costs): Likewise.
* config/rl78/rl78.c (rl78_rtx_costs): Likewise.
* config/rs6000/rs6000.c (rs6000_rtx_costs): Likewise.
* config/s390/s390.c (s390_rtx_costs): Likewise.
* config/sh/sh.c (sh_rtx_costs): Likewise.
* config/sparc/sparc.c (sparc_rtx_costs): Likewise.
* config/spu/spu.c (spu_rtx_costs): Likewise.
* config/stormy16/stormy16.c (xstormy16_rtx_costs): Likewise.
* config/tilegx/tilegx.c (tilegx_rtx_costs): Likewise.
* config/tilepro/tilepro.c (tilepro_rtx_costs): Likewise.
* config/v850/v850.c (v850_rtx_costs): Likewise.
* config/vax/vax.c (vax_rtx_costs): Likewise.
* config/visium/visium.c (visium_rtx_costs): Likewise.
* config/xtensa/xtensa.c (xtensa_rtx_costs): Likewise.
* config/aarch64/aarch64.c (aarch64_rtx_mult_cost): Change type of
"code" param, and pass as outer_code to first rtx_cost call. Pass
mode to rtx_cost calls.
(aarch64_address_cost, aarch64_if_then_else_costs): Update rtx_cost
calls.
(aarch64_rtx_costs_wrapper): Update.
* config/arm/arm.c (arm_rtx_costs_1, arm_size_rtx_costs,
arm_unspec_cost, arm_new_rtx_costs, arm_slowmul_rtx_costs): Update
rtx_cost calls.
* config/avr/avr.c (avr_final_prescan_insn): Update set_src_cost
and rtx_cost calls.
(avr_operand_rtx_cost): Similarly.
(avr_rtx_costs_1): Correct mode passed to avr_operand_rtx_cost
for subexpressions of ZERO_EXTEND, SIGN_EXTEND and COMPARE.
* config/mips/mips.c (mips_stack_address_p): Comment typo.
(mips_binary_cost): Update rtx_cost and set_src_cost calls.
(mips_rtx_costs): Use GET_MODE (x) to detect const_int.
* config/mn10300/mn10300.c (mn10300_address_cost): Pass Pmode to
rtx_cost.
(mn10300_rtx_costs): Correct mode passed to mn10300_address_cost.
* config/rs6000/rs6000.c (rs6000_debug_rtx_costs): Update.
* config/sh/sh.c (and_xor_ior_costs): Update rtx_cost call.
* doc/tm.texi: Regenerate.