https://gcc.gnu.org/g:e17114f99c9ea754787573679b3b4d2b52434b61

commit r15-1393-ge17114f99c9ea754787573679b3b4d2b52434b61
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Jun 18 08:32:37 2024 +0200

    rs6000: Shrink rs6000_init_generated_builtins size [PR115324]
    
    While my r15-1001-g4cf2de9b5268224 PCH PIE power fix change decreased the
    .data section sizes (219792 -> 189336), it increased the size of already
    huge rs6000_init_generated_builtins generated function, from 218328
    to 228668 bytes.  That is because there are thousands of array references
    to global arrays and we keep constructing the addresses of the arrays
    again and again.
    
    Ideally some optimization would figure out we have a single function which
    has
        461   rs6000_overload_info
       1257   rs6000_builtin_info_fntype
       1768   rs6000_builtin_decls
       2548   rs6000_instance_info_fntype
    array references and that maybe it might be a good idea to just preload
    the addresses of those arrays into some register if it decreases code size
    and doesn't slow things down.
    The function actually is called just once and is huge, so code size is even
    more important than speed, which is dominated by all the GC allocations
    anyway.
    
    Until that is done, here is a slightly cleaner version of the hack, which
    makes the function noipa (so that LTO doesn't undo it) for GCC 8.1+ and
    passes the 4 arrays as arguments to the function from the caller.
    This decreases the function size from 228668 bytes to 207572 bytes.
    
    2024-06-18  Jakub Jelinek  <ja...@redhat.com>
    
            PR target/115324
            * config/rs6000/rs6000-gen-builtins.cc (write_decls): Change
            declaration of rs6000_init_generated_builtins from no arguments
            to 4 pointer arguments.
            (write_init_bif_table): Change rs6000_builtin_info_fntype to
            builtin_info_fntype and rs6000_builtin_decls to builtin_decls.
            (write_init_ovld_table): Change rs6000_instance_info_fntype to
            instance_info_fntype, rs6000_builtin_decls to builtin_decls and
            rs6000_overload_info to overload_info.
            (write_init_file): Add __noipa__ attribute to
            rs6000_init_generated_builtins for GCC 8.1+ and change the function
            from no arguments to 4 pointer arguments.  Change 
rs6000_builtin_decls
            to builtin_decls.
            * config/rs6000/rs6000-builtin.cc (rs6000_init_builtins): Adjust
            rs6000_init_generated_builtins caller.

Diff:
---
 gcc/config/rs6000/rs6000-builtin.cc      |  5 ++++-
 gcc/config/rs6000/rs6000-gen-builtins.cc | 36 ++++++++++++++++++++++----------
 2 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-builtin.cc 
b/gcc/config/rs6000/rs6000-builtin.cc
index e96d5157e4dd..bb9da68edc73 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -835,7 +835,10 @@ rs6000_init_builtins (void)
                                                TYPE_QUAL_CONST));
 
   /* Execute the autogenerated initialization code for builtins.  */
-  rs6000_init_generated_builtins ();
+  rs6000_init_generated_builtins (rs6000_builtin_info_fntype,
+                                 rs6000_instance_info_fntype,
+                                 rs6000_overload_info,
+                                 rs6000_builtin_decls);
 
   if (TARGET_DEBUG_BUILTIN)
     {
diff --git a/gcc/config/rs6000/rs6000-gen-builtins.cc 
b/gcc/config/rs6000/rs6000-gen-builtins.cc
index 7ae932220bb8..9af92cc5185d 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.cc
+++ b/gcc/config/rs6000/rs6000-gen-builtins.cc
@@ -2376,7 +2376,10 @@ write_decls (void)
           "rs6000_instance_info_fntype[RS6000_INST_MAX];\n");
   fprintf (header_file, "extern ovldrecord rs6000_overload_info[];\n\n");
 
-  fprintf (header_file, "extern void rs6000_init_generated_builtins ();\n\n");
+  fprintf (header_file,
+          "extern void rs6000_init_generated_builtins (tree *, tree *,\n");
+  fprintf (header_file,
+          "\t\t\t\t\t    ovldrecord *, tree *);\n\n");
   fprintf (header_file,
           "extern bool rs6000_builtin_is_supported (rs6000_gen_builtins);\n");
   fprintf (header_file,
@@ -2651,7 +2654,7 @@ write_init_bif_table (void)
   for (int i = 0; i <= curr_bif; i++)
     {
       fprintf (init_file,
-              "  rs6000_builtin_info_fntype[RS6000_BIF_%s]"
+              "  builtin_info_fntype[RS6000_BIF_%s]"
               "\n    = %s;\n",
               bifs[i].idname, bifs[i].fndecl);
 
@@ -2678,7 +2681,7 @@ write_init_bif_table (void)
        }
 
       fprintf (init_file,
-              "  rs6000_builtin_decls[(int)RS6000_BIF_%s] = t\n",
+              "  builtin_decls[(int)RS6000_BIF_%s] = t\n",
               bifs[i].idname);
       fprintf (init_file,
               "    = add_builtin_function (\"%s\",\n",
@@ -2719,7 +2722,7 @@ write_init_bif_table (void)
          fprintf (init_file, "    }\n");
          fprintf (init_file, "  else\n");
          fprintf (init_file, "    {\n");
-         fprintf (init_file, "      rs6000_builtin_decls"
+         fprintf (init_file, "      builtin_decls"
                   "[(int)RS6000_BIF_%s] = NULL_TREE;\n", bifs[i].idname);
          fprintf (init_file, "    }\n");
        }
@@ -2740,7 +2743,7 @@ write_init_ovld_table (void)
   for (int i = 0; i <= curr_ovld; i++)
     {
       fprintf (init_file,
-              "  rs6000_instance_info_fntype[RS6000_INST_%s]"
+              "  instance_info_fntype[RS6000_INST_%s]"
               "\n    = %s;\n",
               ovlds[i].ovld_id_name, ovlds[i].fndecl);
 
@@ -2772,7 +2775,7 @@ write_init_ovld_table (void)
            }
 
          fprintf (init_file,
-                  "  rs6000_builtin_decls[(int)RS6000_OVLD_%s] = t\n",
+                  "  builtin_decls[(int)RS6000_OVLD_%s] = t\n",
                   stanza->stanza_id);
          fprintf (init_file,
                   "    = add_builtin_function (\"%s\",\n",
@@ -2793,7 +2796,7 @@ write_init_ovld_table (void)
          fprintf (init_file, "\n");
 
          fprintf (init_file,
-                  "  rs6000_overload_info[RS6000_OVLD_%s - base]"
+                  "  overload_info[RS6000_OVLD_%s - base]"
                   ".first_instance\n",
                   stanza->stanza_id);
          fprintf (init_file,
@@ -2826,19 +2829,30 @@ write_init_file (void)
   write_bif_static_init ();
   write_ovld_static_init ();
 
+  /* The reason to pass pointers to the function instead of accessing
+     the rs6000_{{builtin,instance}_info_fntype,overload_info,builtin_decls}
+     arrays directly is to decrease size of the already large function and
+     noipa prevents the compiler with LTO to undo that optimization.  */
+  fprintf (init_file, "#if GCC_VERSION >= 8001\n");
+  fprintf (init_file, "__attribute__((__noipa__))\n");
+  fprintf (init_file, "#endif\n");
   fprintf (init_file, "void\n");
-  fprintf (init_file, "rs6000_init_generated_builtins ()\n");
+  fprintf (init_file,
+          "rs6000_init_generated_builtins (tree *builtin_info_fntype,\n");
+  fprintf (init_file, "\t\t\t\ttree *instance_info_fntype,\n");
+  fprintf (init_file, "\t\t\t\tovldrecord *overload_info,\n");
+  fprintf (init_file, "\t\t\t\ttree *builtin_decls)\n");
   fprintf (init_file, "{\n");
   fprintf (init_file, "  tree t;\n");
   rbt_inorder_callback (&fntype_rbt, fntype_rbt.rbt_root, write_fntype_init);
   fprintf (init_file, "\n");
 
   fprintf (init_file,
-          "  rs6000_builtin_decls[RS6000_BIF_NONE] = NULL_TREE;\n");
+          "  builtin_decls[RS6000_BIF_NONE] = NULL_TREE;\n");
   fprintf (init_file,
-          "  rs6000_builtin_decls[RS6000_BIF_MAX] = NULL_TREE;\n");
+          "  builtin_decls[RS6000_BIF_MAX] = NULL_TREE;\n");
   fprintf (init_file,
-          "  rs6000_builtin_decls[RS6000_OVLD_NONE] = NULL_TREE;\n\n");
+          "  builtin_decls[RS6000_OVLD_NONE] = NULL_TREE;\n\n");
 
   write_init_bif_table ();
   write_init_ovld_table ();

Reply via email to