https://gcc.gnu.org/g:4f0f87b0e5460855868b1fed4c16e2a890f5b760
commit r17-5250-g4f0f87b0e5460855868b1fed4c16e2a890f5b760 Author: Kyrylo Tkachov <[email protected]> Date: Tue Oct 13 17:59:14 2026 +0200 genattrtab: clear all simplification marks between insns optimize_attrs simplifies the attribute values of one insn code at a time. ATTR_CURR_SIMPLIFIED_P marks an expression as already simplified for the current insn, and before each insn clear_struct_flag clears the flag on the expressions that the insn's attribute values reach. Simplification also marks expressions that those values do not reach, for example NOT and EQ_ATTR_ALT nodes that attr_rtx returns from its hash table. Such a mark survives into later insns and into the output phase, and stops the simplification of that expression there. The result of simplifying an insn therefore depends on the insns before it. Record the expressions that copy_rtx_unchanging marks, and clear them before each insn and at the end of optimize_attrs. copy_rtx_unchanging is the only function that sets the flag, so this clears every mark and clear_struct_flag is no longer necessary. Simplification of an insn then depends only on its own attribute values and alternatives. The next patches rely on that. The generated files do not change for 52 target configurations, with at least one for each backend. A stale mark only stops simplification, so where the output can change it becomes more simplified, not different in meaning. Without the walks of clear_struct_flag, genattrtab built at -O2 executes fewer instructions: riscv64 -13.0%, x86_64 -11.2%, aarch64 -8.0%, arm -5.4%, s390x -0.7%. Built at -g without optimization, as in stage 1 of a bootstrap, aarch64 -4.2%. gcc/ChangeLog: * genattrtab.cc (curr_simplified): New. (clear_curr_simplified): New. (clear_struct_flag): Delete. (copy_rtx_unchanging): Record the expressions it marks. (optimize_attrs): Use clear_curr_simplified instead of clear_struct_flag before each insn. Also call it at the end. Signed-off-by: Kyrylo Tkachov <[email protected]> Diff: --- gcc/genattrtab.cc | 77 +++++++++++++++---------------------------------------- 1 file changed, 20 insertions(+), 57 deletions(-) diff --git a/gcc/genattrtab.cc b/gcc/genattrtab.cc index 966f5f9aaab3..0d0b9bce2094 100644 --- a/gcc/genattrtab.cc +++ b/gcc/genattrtab.cc @@ -249,6 +249,10 @@ static alternative_mask *insn_alternatives; static rtx true_rtx, false_rtx; +/* The expressions that copy_rtx_unchanging has marked with + ATTR_CURR_SIMPLIFIED_P since the last call to clear_curr_simplified. */ +static vec<rtx> curr_simplified; + /* Used to reduce calls to `strcmp' */ static const char *alternative_name; @@ -287,7 +291,7 @@ static rtx simplify_test_exp_in_temp (rtx, int, int); static rtx copy_rtx_unchanging (rtx); static bool attr_alt_subset_p (rtx, rtx); static bool attr_alt_subset_of_compl_p (rtx, rtx); -static void clear_struct_flag (rtx); +static void clear_curr_simplified (void); static void write_attr_valueq (FILE *, class attr_desc *, const char *); static struct attr_value *find_most_used (class attr_desc *); static void write_attr_set (FILE *, class attr_desc *, int, rtx, @@ -3193,10 +3197,9 @@ optimize_attrs (int num_insn_codes) /* Process one insn code at a time. */ for (i = -2; i < num_insn_codes; i++) { - /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant. + /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere. We use it to mean "already simplified for this insn". */ - for (iv = insn_code_values[i]; iv; iv = iv->next) - clear_struct_flag (iv->av->value); + clear_curr_simplified (); for (iv = insn_code_values[i]; iv; iv = iv->next) { @@ -3239,64 +3242,12 @@ optimize_attrs (int num_insn_codes) } } + clear_curr_simplified (); free (ivbuf); free (insn_code_values - 2); insn_code_values = NULL; } -/* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */ - -static void -clear_struct_flag (rtx x) -{ - int i; - int j; - enum rtx_code code; - const char *fmt; - - ATTR_CURR_SIMPLIFIED_P (x) = 0; - if (ATTR_IND_SIMPLIFIED_P (x)) - return; - - code = GET_CODE (x); - - switch (code) - { - case REG: - CASE_CONST_ANY: - case MATCH_TEST: - case SYMBOL_REF: - case CODE_LABEL: - case PC: - case EQ_ATTR: - case ATTR_FLAG: - return; - - default: - break; - } - - /* Compare the elements. If any pair of corresponding elements - fail to match, return 0 for the whole things. */ - - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - switch (fmt[i]) - { - case 'V': - case 'E': - for (j = 0; j < XVECLEN (x, i); j++) - clear_struct_flag (XVECEXP (x, i, j)); - break; - - case 'e': - clear_struct_flag (XEXP (x, i)); - break; - } - } -} - /* Add attribute value NAME to the beginning of ATTR's list. */ static void @@ -5006,9 +4957,21 @@ copy_rtx_unchanging (rtx orig) return orig; ATTR_CURR_SIMPLIFIED_P (orig) = 1; + curr_simplified.safe_push (orig); return orig; } +/* Clear ATTR_CURR_SIMPLIFIED_P on every expression that copy_rtx_unchanging + has marked since the last call. */ + +static void +clear_curr_simplified (void) +{ + for (rtx x : curr_simplified) + ATTR_CURR_SIMPLIFIED_P (x) = 0; + curr_simplified.truncate (0); +} + /* Determine if an insn has a constant number of delay slots, i.e., the number of delay slots is not a function of the length of the insn. */
