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);
            }
        }

Reply via email to