diff options
author | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2024-10-04 13:43:46 +0100 |
---|---|---|
committer | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2024-10-04 13:46:13 +0100 |
commit | 7766a2c1eb683eeee352ce117e8ed014665f392f (patch) | |
tree | ff20e324233a150c9cb11f6648c813f25b7cfcb7 /gcc/config | |
parent | 16cd00a10035992f52ed67ff77eab20039555b03 (diff) | |
download | gcc-7766a2c1eb683eeee352ce117e8ed014665f392f.zip gcc-7766a2c1eb683eeee352ce117e8ed014665f392f.tar.gz gcc-7766a2c1eb683eeee352ce117e8ed014665f392f.tar.bz2 |
arm: Fix missed CE optimization for armv8.1-m.main [PR 116444]
This patch restores missed optimizations for armv8.1-m.main targets that were
missed when the generation of csinc, csinv and csneg were enabled for the same
with patch series containing:
commit c2bb84be4a6e581bbf45891457ee632a07416982
Author: Sudi Das <sudi.das@arm.com>
Date: Fri Sep 18 15:47:46 2020 +0100
[PATCH 2/5][Arm] New pattern for CSINV instructions
The original patch series makes use of the "noce" machinery to transform RTL
into patterns that later match the Armv8.1-M Mainline, by getting the target
hook TARGET_HAVE_CONDITIONAL_EXECUTION, to return FALSE for such targets prior
to reload_completed. The same machinery however was transforming other RTL
patterns which were later on causing the "ce" pass post reload_completed to no
longer optimize conditional execution opportunities, which was causing the
regression observed in PR target/116444, a regression of 'testsuite/gcc.target/arm/thumb-ifcvt-2.c'
when ran for an Armv8.1-M Mainline target.
This patch implements the target hook TARGET_NOCE_CONVERSION_PROFITABLE_P to
only allow "noce" to generate patterns that match CSINV, CSINC and CSNEG. Thus
ensuring that the early "ce" passes do not ruin things for later ones.
gcc/ChangeLog:
PR target/116444
* config/arm/arm-protos.h (arm_noce_conversion_profitable_p): New
declaration.
* config/arm/arm.cc (arm_is_v81m_cond_insn): New helper function used
in ...
(arm_noce_conversion_profitable_p): ... here. New function to implement
...
(TARGET_NOCE_PROFITABLE_P): ... this target hook. New define.
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/arm/arm-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/arm/arm.cc | 87 |
2 files changed, 88 insertions, 0 deletions
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 50cae2b..b694589 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -210,6 +210,7 @@ extern bool arm_pad_reg_upward (machine_mode, tree, int); #endif extern int arm_apply_result_size (void); extern opt_machine_mode arm_get_mask_mode (machine_mode mode); +extern bool arm_noce_conversion_profitable_p (rtx_insn *,struct noce_if_info *); #endif /* RTX_CODE */ diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index 62eea50..077c80d 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -815,6 +815,9 @@ static const scoped_attribute_specs *const arm_attribute_table[] = #undef TARGET_MODES_TIEABLE_P #define TARGET_MODES_TIEABLE_P arm_modes_tieable_p +#undef TARGET_NOCE_CONVERSION_PROFITABLE_P +#define TARGET_NOCE_CONVERSION_PROFITABLE_P arm_noce_conversion_profitable_p + #undef TARGET_CAN_CHANGE_MODE_CLASS #define TARGET_CAN_CHANGE_MODE_CLASS arm_can_change_mode_class @@ -36089,6 +36092,90 @@ arm_get_mask_mode (machine_mode mode) return default_get_mask_mode (mode); } +/* Helper function to determine whether SEQ represents a sequence of + instructions representing the Armv8.1-M Mainline conditional arithmetic + instructions: csinc, csneg and csinv. The cinc instruction is generated + using a different mechanism. */ + +static bool +arm_is_v81m_cond_insn (rtx_insn *seq) +{ + rtx_insn *curr_insn = seq; + rtx set; + /* The pattern may start with a simple set with register operands. Skip + through any of those. */ + while (curr_insn) + { + set = single_set (curr_insn); + if (!set + || !REG_P (SET_DEST (set))) + return false; + + if (!REG_P (SET_SRC (set))) + break; + curr_insn = NEXT_INSN (curr_insn); + } + + if (!set) + return false; + + /* The next instruction should be one of: + NEG: for csneg, + PLUS: for csinc, + NOT: for csinv. */ + if (GET_CODE (SET_SRC (set)) != NEG + && GET_CODE (SET_SRC (set)) != PLUS + && GET_CODE (SET_SRC (set)) != NOT) + return false; + + curr_insn = NEXT_INSN (curr_insn); + if (!curr_insn) + return false; + + /* The next instruction should be a COMPARE. */ + set = single_set (curr_insn); + if (!set + || !REG_P (SET_DEST (set)) + || GET_CODE (SET_SRC (set)) != COMPARE) + return false; + + curr_insn = NEXT_INSN (curr_insn); + if (!curr_insn) + return false; + + /* And the last instruction should be an IF_THEN_ELSE. */ + set = single_set (curr_insn); + if (!set + || !REG_P (SET_DEST (set)) + || GET_CODE (SET_SRC (set)) != IF_THEN_ELSE) + return false; + + return !NEXT_INSN (curr_insn); +} + +/* For Armv8.1-M Mainline we have both conditional execution through IT blocks, + as well as conditional arithmetic instructions controlled by + TARGET_COND_ARITH. To generate the latter we rely on a special part of the + "ce" pass that generates code for targets that don't support conditional + execution of general instructions known as "noce". These transformations + happen before 'reload_completed'. However, "noce" also triggers for some + unwanted patterns [PR 116444] that prevent "ce" optimisations after reload. + To make sure we can get both we use the TARGET_NOCE_CONVERSION_PROFITABLE_P + hook to only allow "noce" to generate the patterns that are profitable. */ + +bool +arm_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info) +{ + if (!TARGET_COND_ARITH + || reload_completed) + return true; + + if (arm_is_v81m_cond_insn (seq)) + return true; + + return false; +} + /* Output assembly to read the thread pointer from the appropriate TPIDR register into DEST. If PRED_P also emit the %? that can be used to output the predication code. */ |