]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c, c++: Save 8 bytes of memory in lang_type for non-ObjC*
authorJakub Jelinek <jakub@redhat.com>
Thu, 12 Jun 2025 06:33:38 +0000 (08:33 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 12 Jun 2025 06:33:38 +0000 (08:33 +0200)
For C++26 P2786R13 I'm afraid I'll need 4-6 new flags on class types
in struct lang_type (1 bit for trivially_relocatable_if_eligible,
1 for replaceable_if_eligible, 1 for not_trivially_relocatable and
1 for not_replaceable and perhaps 2 bits whether the last 2 have been
computed already) and there are just 2 bits left.

The following patch is an attempt to save 8 bytes of memory
in those structures when not compiling ObjC or ObjC++ (I think those
are used fairly rarely and the patch keeps the sizes unmodified for
those 2).  The old allocations were 32 bytes for C and 120 bytes
for C++.  The patch moves the objc_info member last in the C++ case
(it was already last in the C case), arranges for GC to skip it
for C and C++ but walk for ObjC and ObjC++ and allocates or
copies over just offsetof bytes instead of sizeof.

2025-06-12  Jakub Jelinek  <jakub@redhat.com>

gcc/c/
* c-lang.h (union lang_type::maybe_objc_info): New type.
(struct lang_type): Use union maybe_objc_info info member
instead of tree objc_info.
* c-decl.cc (finish_struct): Allocate struct lang_type using
ggc_internal_cleared_alloc instead of ggc_cleared_alloc,
and use sizeof (struct lang_type) for ObjC and otherwise
offsetof (struct lang_type, info) as size.
(finish_enum): Likewise.
gcc/cp/
* cp-tree.h (union lang_type::maybe_objc_info): New type.
(struct lang_type): Use union maybe_objc_info info member
instead of tree objc_info.
* lex.cc (copy_lang_type): Use sizeof (struct lang_type)
just for ObjC++ and otherwise offsetof (struct lang_type, info).
(maybe_add_lang_type_raw): Likewise.
(cxx_make_type): Formatting fix.
gcc/objc/
* objc-act.h (TYPE_OBJC_INFO): Define to info.objc_info
instead of objc_info.
gcc/objcp/
* objcp-decl.h (TYPE_OBJC_INFO): Define to info.objc_info
instead of objc_info.

gcc/c/c-decl.cc
gcc/c/c-lang.h
gcc/cp/cp-tree.h
gcc/cp/lex.cc
gcc/objc/objc-act.h
gcc/objcp/objcp-decl.h

index 2b0bd663ba911b7883bbb0a5ef4e3bfe15e8f98b..8bbd6ebc66ad81b1fa1b19da2cf55fbb4bf34be2 100644 (file)
@@ -9790,12 +9790,17 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
        len += list_length (x);
 
        /* Use the same allocation policy here that make_node uses, to
-         ensure that this lives as long as the rest of the struct decl.
-         All decls in an inline function need to be saved.  */
-
-       space = ggc_cleared_alloc<struct lang_type> ();
-       space2 = (sorted_fields_type *) ggc_internal_alloc
-         (sizeof (struct sorted_fields_type) + len * sizeof (tree));
+          ensure that this lives as long as the rest of the struct decl.
+          All decls in an inline function need to be saved.  */
+
+       space = ((struct lang_type *)
+                ggc_internal_cleared_alloc (c_dialect_objc ()
+                                            ? sizeof (struct lang_type)
+                                            : offsetof (struct lang_type,
+                                                        info)));
+       space2 = ((sorted_fields_type *)
+                 ggc_internal_alloc (sizeof (struct sorted_fields_type)
+                                     + len * sizeof (tree)));
 
        len = 0;
        space->s = space2;
@@ -10269,7 +10274,10 @@ finish_enum (tree enumtype, tree values, tree attributes)
 
   /* Record the min/max values so that we can warn about bit-field
      enumerations that are too small for the values.  */
-  lt = ggc_cleared_alloc<struct lang_type> ();
+  lt = ((struct lang_type *)
+       ggc_internal_cleared_alloc (c_dialect_objc ()
+                                   ? sizeof (struct lang_type)
+                                   : offsetof (struct lang_type, info)));
   lt->enum_min = minnode;
   lt->enum_max = maxnode;
   TYPE_LANG_SPECIFIC (enumtype) = lt;
index 4b93d184dbca99e414b6e194e65a247020cd1236..2e99b4d8617658d8eeda51bca7152fd3e1d79a5e 100644 (file)
@@ -35,10 +35,14 @@ struct GTY(()) lang_type {
   /* In an ENUMERAL_TYPE, the min and max values.  */
   tree enum_min;
   tree enum_max;
-  /* In a RECORD_TYPE, information specific to Objective-C, such
-     as a list of adopted protocols or a pointer to a corresponding
-     @interface.  See objc/objc-act.h for details.  */
-  tree objc_info;
+  union maybe_objc_info {
+    /* If not c_dialect_objc, this part is not even allocated.  */
+    char GTY((tag ("0"))) non_objc;
+    /* In a RECORD_TYPE, information specific to Objective-C, such
+       as a list of adopted protocols or a pointer to a corresponding
+       @interface.  See objc/objc-act.h for details.  */
+    tree GTY((tag ("1"))) objc_info;
+  } GTY ((desc ("c_dialect_objc ()"))) info;
 };
 
 struct GTY(()) lang_decl {
index 3cf4a7654b3956775ca0d38848e2b32b25f899df..d663d6ec2256deea5dba6b64cc4978c817a0b610 100644 (file)
@@ -2514,12 +2514,16 @@ struct GTY(()) lang_type {
   tree key_method;
   tree decl_list;
   tree befriending_classes;
-  /* In a RECORD_TYPE, information specific to Objective-C++, such
-     as a list of adopted protocols or a pointer to a corresponding
-     @interface.  See objc/objc-act.h for details.  */
-  tree objc_info;
   /* FIXME reuse another field?  */
   tree lambda_expr;
+  union maybe_objc_info {
+    /* If not c_dialect_objc, this part is not even allocated.  */
+    char GTY((tag ("0"))) non_objc;
+    /* In a RECORD_TYPE, information specific to Objective-C, such
+       as a list of adopted protocols or a pointer to a corresponding
+       @interface.  See objc/objc-act.h for details.  */
+    tree GTY((tag ("1"))) objc_info;
+  } GTY ((desc ("c_dialect_objc ()"))) info;
 };
 
 /* We used to have a variant type for lang_type.  Keep the name of the
index 12af81ed078cc5a496bbc31abb1f3ae7f56872a6..08a634830f52aa4f68b3f0c3c4a3f7a4104d8c7e 100644 (file)
@@ -1082,15 +1082,17 @@ copy_lang_type (tree node)
   if (! TYPE_LANG_SPECIFIC (node))
     return;
 
-  auto *lt = (struct lang_type *) ggc_internal_alloc (sizeof (struct lang_type));
+  size_t sz = (c_dialect_objc () ? sizeof (struct lang_type)
+              : offsetof (struct lang_type, info));
+  auto *lt = (struct lang_type *) ggc_internal_alloc (sz);
 
-  memcpy (lt, TYPE_LANG_SPECIFIC (node), (sizeof (struct lang_type)));
+  memcpy (lt, TYPE_LANG_SPECIFIC (node), sz);
   TYPE_LANG_SPECIFIC (node) = lt;
 
   if (GATHER_STATISTICS)
     {
       tree_node_counts[(int)lang_type] += 1;
-      tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
+      tree_node_sizes[(int)lang_type] += sz;
     }
 }
 
@@ -1114,14 +1116,15 @@ maybe_add_lang_type_raw (tree t)
   if (!RECORD_OR_UNION_CODE_P (TREE_CODE (t)))
     return false;
 
-  auto *lt = (struct lang_type *) (ggc_internal_cleared_alloc
-                                  (sizeof (struct lang_type)));
+  size_t sz = (c_dialect_objc () ? sizeof (struct lang_type)
+              : offsetof (struct lang_type, info));
+  auto *lt = (struct lang_type *) (ggc_internal_cleared_alloc (sz));
   TYPE_LANG_SPECIFIC (t) = lt;
 
   if (GATHER_STATISTICS)
     {
       tree_node_counts[(int)lang_type] += 1;
-      tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
+      tree_node_sizes[(int)lang_type] += sz;
     }
 
   return true;
@@ -1135,8 +1138,8 @@ cxx_make_type (enum tree_code code MEM_STAT_DECL)
   if (maybe_add_lang_type_raw (t))
     {
       /* Set up some flags that give proper default behavior.  */
-      struct c_fileinfo *finfo =
-       get_fileinfo (LOCATION_FILE (input_location));
+      struct c_fileinfo *finfo
+       get_fileinfo (LOCATION_FILE (input_location));
       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
       CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
     }
index 39c29893fb0f1f24dfbff1cc714c783868c49662..c7f92595d46e5349c6d43bfee722fc7c5bc3a974 100644 (file)
@@ -228,7 +228,7 @@ enum objc_property_nullability {
 
 /* The following three macros must be overridden (in objcp/objcp-decl.h)
    for Objective-C++.  */
-#define TYPE_OBJC_INFO(TYPE) TYPE_LANG_SPECIFIC (TYPE)->objc_info
+#define TYPE_OBJC_INFO(TYPE) TYPE_LANG_SPECIFIC (TYPE)->info.objc_info
 #define SIZEOF_OBJC_TYPE_LANG_SPECIFIC sizeof (struct lang_type)
 #define ALLOC_OBJC_TYPE_LANG_SPECIFIC(NODE)                            \
   do {                                                                 \
index 747fdae0dfdd1cbb1972124e6cf8eb98f6ebaa93..24896207d3dc5872d88d26193ab178ad4a3b6b6f 100644 (file)
@@ -60,7 +60,7 @@ extern tree objcp_end_compound_stmt (tree, int);
 #define OBJC_SET_TYPE_NAME(type, name) (TYPE_IDENTIFIER (type) = (name))
 
 #undef TYPE_OBJC_INFO
-#define TYPE_OBJC_INFO(TYPE) LANG_TYPE_CLASS_CHECK (TYPE)->objc_info
+#define TYPE_OBJC_INFO(TYPE) LANG_TYPE_CLASS_CHECK (TYPE)->info.objc_info
 #undef SIZEOF_OBJC_TYPE_LANG_SPECIFIC
 #define SIZEOF_OBJC_TYPE_LANG_SPECIFIC sizeof (struct lang_type)
 #undef ALLOC_OBJC_TYPE_LANG_SPECIFIC