diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2025-03-15 20:53:52 +0100 |
---|---|---|
committer | Georg-Johann Lay <avr@gjlay.de> | 2025-03-22 17:49:57 +0100 |
commit | 94355acc2debe03eb3b0a85229e340675a1ff6bd (patch) | |
tree | 4d2f00b9f3b407b26093570ad3b2c7216df36c93 /gcc/common | |
parent | 8736edca77a59157a3dae5b3aa5ca59f4fe4b4a4 (diff) | |
download | gcc-94355acc2debe03eb3b0a85229e340675a1ff6bd.zip gcc-94355acc2debe03eb3b0a85229e340675a1ff6bd.tar.gz gcc-94355acc2debe03eb3b0a85229e340675a1ff6bd.tar.bz2 |
AVR: target/119421 Better optimize some bit operations.
There are occasions where knowledge about nonzero bits makes some
optimizations possible. For example,
Rd |= Rn << Off
can be implemented as
SBRC Rn, 0
ORI Rd, 1 << Off
when Rn in { 0, 1 }, i.e. nonzero_bits (Rn) == 1. This patch adds some
patterns that exploit nonzero_bits() in some combiner patterns.
As insn conditions are not supposed to contain nonzero_bits(), the patch
splits such insns right after pass insn combine.
PR target/119421
gcc/
* config/avr/avr.opt (-muse-nonzero-bits): New option.
* config/avr/avr-protos.h (avr_nonzero_bits_lsr_operands_p): New.
(make_avr_pass_split_nzb): New.
* config/avr/avr.cc (avr_nonzero_bits_lsr_operands_p): New function.
(avr_rtx_costs_1): Return costs for the new insns.
* config/avr/avr.md (nzb): New insn attribute.
(*nzb=1.<code>...): New insns to better support some bit
operations for <code> in AND, IOR, XOR.
* config/avr/avr-passes.def (avr_pass_split_nzb): Insert pass
atfer combine.
* config/avr/avr-passes.cc (avr_pass_data_split_nzb). New pass data.
(avr_pass_split_nzb): New pass.
(make_avr_pass_split_nzb): New function.
* common/config/avr/avr-common.cc (avr_option_optimization_table):
Enable -muse-nonzero-bits for -O2 and higher.
* doc/invoke.texi (AVR Options): Document -muse-nonzero-bits.
gcc/testsuite/
* gcc.target/avr/torture/pr119421-sreg.c: New test.
Diffstat (limited to 'gcc/common')
-rw-r--r-- | gcc/common/config/avr/avr-common.cc | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/gcc/common/config/avr/avr-common.cc b/gcc/common/config/avr/avr-common.cc index 06c6cc8..203a965 100644 --- a/gcc/common/config/avr/avr-common.cc +++ b/gcc/common/config/avr/avr-common.cc @@ -42,6 +42,7 @@ static const struct default_options avr_option_optimization_table[] = { OPT_LEVELS_2_PLUS, OPT_mfuse_move_, NULL, 23 }, { OPT_LEVELS_2_PLUS, OPT_msplit_bit_shift, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_msplit_ldst, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_muse_nonzero_bits, NULL, 1 }, // Stick to the "old" placement of the subreg lowering pass. { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types_early, NULL, 1 }, /* Allow optimizer to introduce store data races. This used to be the |