https://gcc.gnu.org/g:be1fb4e87de02b8c865d0335d01bec3204c68220
commit r17-5251-gbe1fb4e87de02b8c865d0335d01bec3204c68220 Author: Kyrylo Tkachov <[email protected]> Date: Tue Oct 13 17:59:14 2026 +0200 genattrtab: build the IOR tree for a list of attribute values directly check_attr_test turns a test such as (eq_attr "type" "a,b,c") into an IOR tree by adding each value with insert_right_side. Each addition walks down the right spine of the tree and simplifies each partial tree on the way, and with insn code -2 nothing is cached. A list of N values costs O(N^4) steps. The s390 scheduling descriptions have lists of more than 300 values, and building them is most of the genattrtab run for s390. The aarch64 and arm attributes also have long lists of types. At this point simplification of an IOR of tests of one attribute only removes duplicate values: with insn code -2 no expression is marked as simplified, no EQ_ATTR is evaluated, and the tests are hash-consed, so equal tests are the same object. Build the tree directly instead, keeping the first occurrence of each value and nesting to the right. For example (eq_attr "type" "a,b,a,c") still gives (ior (eq_attr "type" "a") (ior (eq_attr "type" "b") (eq_attr "type" "c"))) A list with no values, such as (eq_attr "type" ","), is still false. The generated files do not change for 52 target configurations. genattrtab instructions, with genattrtab built at -O2: s390x -90.7%, arm -50.6%, aarch64 -39.4%, riscv64 -8.9%, x86_64 no change. Built at -g without optimization, as in stage 1 of a bootstrap, aarch64 -23.7%. gcc/ChangeLog: * genattrtab.cc (check_attr_test): Build the IOR tree for a list of values directly instead of with insert_right_side. Signed-off-by: Kyrylo Tkachov <[email protected]> Diff: --- gcc/genattrtab.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/gcc/genattrtab.cc b/gcc/genattrtab.cc index 0d0b9bce2094..db6ff529478e 100644 --- a/gcc/genattrtab.cc +++ b/gcc/genattrtab.cc @@ -781,15 +781,23 @@ check_attr_test (file_location loc, rtx exp, attr_desc *attr) } else { - /* Make an IOR tree of the possible values. */ - orexp = false_rtx; + /* Make an IOR tree of the values, nested to the right, keeping + the first occurrence of each. A list with no values is + false. */ + auto_vec<rtx> values; + hash_set<rtx> seen; name_ptr = XSTR (exp, 1); while ((p = next_comma_elt (&name_ptr)) != NULL) { newexp = attr_eq (XSTR (exp, 0), p); - orexp = insert_right_side (IOR, orexp, newexp, -2, -2); + if (!seen.add (newexp)) + values.safe_push (newexp); } + orexp = values.is_empty () ? false_rtx : values.pop (); + while (!values.is_empty ()) + orexp = attr_rtx (IOR, values.pop (), orexp); + return check_attr_test (loc, orexp, attr); } }
