]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386: simplify cpu_feature handling
authorMartin Liska <mliska@suse.cz>
Wed, 15 Dec 2021 09:54:23 +0000 (10:54 +0100)
committerMartin Liska <mliska@suse.cz>
Fri, 9 Dec 2022 13:24:47 +0000 (14:24 +0100)
The patch removes unneeded loops for cpu_features2 and CONVERT_EXPR
that can be simplified with NOP_EXPR.

gcc/ChangeLog:

* common/config/i386/cpuinfo.h (has_cpu_feature): Directly
compute index in cpu_features2.
(set_cpu_feature): Likewise.
* config/i386/i386-builtins.cc (fold_builtin_cpu): Also remove
loop for cpu_features2 and use NOP_EXPRs.

(cherry picked from commit ef14bba0a6f3836d41d75863e6516d21aef0e936)

gcc/common/config/i386/cpuinfo.h
gcc/config/i386/i386-builtins.cc

index 4abd5480d283938fde654a8158012a3870e39491..8843f43be54a471dbbbab2e1c8b7085993549c2e 100644 (file)
@@ -55,43 +55,49 @@ struct __processor_model2
 static inline int
 has_cpu_feature (struct __processor_model *cpu_model,
                 unsigned int *cpu_features2,
-                enum processor_features f)
+                enum processor_features feature)
 {
-  unsigned int i;
+  unsigned index, offset;
+  unsigned f = feature;
+
   if (f < 32)
     {
       /* The first 32 features.  */
-      return cpu_model->__cpu_features[0] & (1U << (f & 31));
+      return cpu_model->__cpu_features[0] & (1U << f);
+    }
+  else
+    {
+      /* The rest of features.  cpu_features2[i] contains features from
+        (32 + i * 32) to (31 + 32 + i * 32), inclusively.  */
+      f -= 32;
+      index = f / 32;
+      offset = f % 32;
+      return cpu_features2[index] & (1U << offset);
     }
-  /* The rest of features.  cpu_features2[i] contains features from
-     (32 + i * 32) to (31 + 32 + i * 32), inclusively.  */
-  for (i = 0; i < SIZE_OF_CPU_FEATURES; i++)
-    if (f < (32 + 32 + i * 32))
-    return cpu_features2[i] & (1U << ((f - (32 + i * 32)) & 31));
-  gcc_unreachable ();
 }
 
 static inline void
 set_cpu_feature (struct __processor_model *cpu_model,
                 unsigned int *cpu_features2,
-                enum processor_features f)
+                enum processor_features feature)
 {
-  unsigned int i;
+  unsigned index, offset;
+  unsigned f = feature;
+
   if (f < 32)
     {
       /* The first 32 features.  */
-      cpu_model->__cpu_features[0] |= (1U << (f & 31));
-      return;
+      cpu_model->__cpu_features[0] |= (1U << f);
+    }
+  else
+    {
+      /* The rest of features.  cpu_features2[i] contains features from
+        (32 + i * 32) to (31 + 32 + i * 32), inclusively.  */
+      f -= 32;
+      index = f / 32;
+      offset = f % 32;
+      cpu_features2[index] |= (1U << offset);
     }
-  /* The rest of features.  cpu_features2[i] contains features from
-     (32 + i * 32) to (31 + 32 + i * 32), inclusively.  */
-  for (i = 0; i < SIZE_OF_CPU_FEATURES; i++)
-    if (f < (32 + 32 + i * 32))
-      {
-       cpu_features2[i] |= (1U << ((f - (32 + i * 32)) & 31));
-       return;
-      }
-  gcc_unreachable ();
 }
 
 /* Get the specific type of AMD CPU and return AMD CPU name.  Return
index 8c6d0fe96315e10cf73b4917c2470b114c870e3f..59c7da25a14dd42d866df3645f216707c6683ad3 100644 (file)
@@ -2280,7 +2280,7 @@ fold_builtin_cpu (tree fndecl, tree *args)
       /* Check the value.  */
       final = build2 (EQ_EXPR, unsigned_type_node, ref,
                      build_int_cstu (unsigned_type_node, field_val));
-      return build1 (CONVERT_EXPR, integer_type_node, final);
+      return build1 (NOP_EXPR, integer_type_node, final);
     }
   else if (fn_code == IX86_BUILTIN_CPU_SUPPORTS)
     {
@@ -2305,7 +2305,8 @@ fold_builtin_cpu (tree fndecl, tree *args)
          return integer_zero_node;
        }
 
-      if (isa_names_table[i].feature >= 32)
+      unsigned feature = isa_names_table[i].feature;
+      if (feature >= INT_TYPE_SIZE)
        {
          if (ix86_cpu_features2_var == nullptr)
            {
@@ -2323,46 +2324,44 @@ fold_builtin_cpu (tree fndecl, tree *args)
              varpool_node::add (ix86_cpu_features2_var);
            }
 
-         for (unsigned int j = 0; j < SIZE_OF_CPU_FEATURES; j++)
-           if (isa_names_table[i].feature < (32 + 32 + j * 32))
-             {
-               field_val = (1U << (isa_names_table[i].feature
-                                   - (32 + j * 32)));
-               tree index = size_int (j);
-               array_elt = build4 (ARRAY_REF, unsigned_type_node,
-                                   ix86_cpu_features2_var,
-                                   index, NULL_TREE, NULL_TREE);
-               /* Return __cpu_features2[index] & field_val  */
-               final = build2 (BIT_AND_EXPR, unsigned_type_node,
-                               array_elt,
-                               build_int_cstu (unsigned_type_node,
-                                               field_val));
-               return build1 (CONVERT_EXPR, integer_type_node, final);
-             }
+         feature -= INT_TYPE_SIZE;
+         field_val = 1U << (feature % INT_TYPE_SIZE);
+         tree index = size_int (feature / INT_TYPE_SIZE);
+         array_elt = build4 (ARRAY_REF, unsigned_type_node,
+                             ix86_cpu_features2_var,
+                             index, NULL_TREE, NULL_TREE);
+         /* Return __cpu_features2[index] & field_val  */
+         final = build2 (BIT_AND_EXPR, unsigned_type_node,
+                         array_elt,
+                         build_int_cstu (unsigned_type_node,
+                                         field_val));
+         return build1 (NOP_EXPR, integer_type_node, final);
        }
-
-      field = TYPE_FIELDS (ix86_cpu_model_type_node);
-      /* Get the last field, which is __cpu_features.  */
-      while (DECL_CHAIN (field))
-        field = DECL_CHAIN (field);
-
-      /* Get the appropriate field: __cpu_model.__cpu_features  */
-      ref = build3 (COMPONENT_REF, TREE_TYPE (field), ix86_cpu_model_var,
-                   field, NULL_TREE);
-
-      /* Access the 0th element of __cpu_features array.  */
-      array_elt = build4 (ARRAY_REF, unsigned_type_node, ref,
-                         integer_zero_node, NULL_TREE, NULL_TREE);
-
-      field_val = (1U << isa_names_table[i].feature);
-      /* Return __cpu_model.__cpu_features[0] & field_val  */
-      final = build2 (BIT_AND_EXPR, unsigned_type_node, array_elt,
-                     build_int_cstu (unsigned_type_node, field_val));
-      if (isa_names_table[i].feature == (INT_TYPE_SIZE - 1))
-       return build2 (NE_EXPR, integer_type_node, final,
-                      build_int_cst (unsigned_type_node, 0));
       else
-       return build1 (CONVERT_EXPR, integer_type_node, final);
+       {
+         field = TYPE_FIELDS (ix86_cpu_model_type_node);
+         /* Get the last field, which is __cpu_features.  */
+         while (DECL_CHAIN (field))
+           field = DECL_CHAIN (field);
+
+         /* Get the appropriate field: __cpu_model.__cpu_features  */
+         ref = build3 (COMPONENT_REF, TREE_TYPE (field), ix86_cpu_model_var,
+                       field, NULL_TREE);
+
+         /* Access the 0th element of __cpu_features array.  */
+         array_elt = build4 (ARRAY_REF, unsigned_type_node, ref,
+                             integer_zero_node, NULL_TREE, NULL_TREE);
+
+         field_val = (1U << feature);
+         /* Return __cpu_model.__cpu_features[0] & field_val  */
+         final = build2 (BIT_AND_EXPR, unsigned_type_node, array_elt,
+                         build_int_cstu (unsigned_type_node, field_val));
+         if (feature == (INT_TYPE_SIZE - 1))
+           return build2 (NE_EXPR, integer_type_node, final,
+                          build_int_cst (unsigned_type_node, 0));
+         else
+           return build1 (NOP_EXPR, integer_type_node, final);
+       }
     }
   gcc_unreachable ();
 }