]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
genemit: Distribute evenly to files [PR111600].
authorRobin Dapp <rdapp@ventanamicro.com>
Thu, 21 Nov 2024 14:34:37 +0000 (15:34 +0100)
committerRobin Dapp <rdapp@ventanamicro.com>
Mon, 25 Nov 2024 15:01:48 +0000 (16:01 +0100)
currently we distribute insn patterns in genemit, partitioning them
by the number of patterns per file.  The first 100 into file 1, the
next 100 into file 2, and so on.  Depending on the patterns this
can lead to files of very uneven sizes.

Similar to the genmatch split, this patch introduces a dynamic
choose_output () which considers the size of the output files
and selects the shortest one for the next pattern.

gcc/ChangeLog:

PR target/111600

* genemit.cc (handle_arg): Use files instead of filenames.
(main): Ditto.
* gensupport.cc (SIZED_BASED_CHUNKS): Define.
(choose_output): New function.
* gensupport.h (choose_output): Declare.

gcc/genemit.cc
gcc/gensupport.cc
gcc/gensupport.h

index 5d3d10f5061ab1b664431a3a5546eb10b849ba91..ee2f06cb7c2b3061658d017f0c49982d3e4568e4 100644 (file)
@@ -905,14 +905,15 @@ from the machine description file `md'.  */\n\n");
   fprintf (file, "#include \"target.h\"\n\n");
 }
 
-auto_vec<const char *, 10> output_files;
+auto_vec<FILE *, 10> output_files;
 
 static bool
 handle_arg (const char *arg)
 {
   if (arg[1] == 'O')
     {
-      output_files.safe_push (&arg[2]);
+      FILE *file = fopen (&arg[2], "w");
+      output_files.safe_push (file);
       return true;
     }
   return false;
@@ -933,47 +934,21 @@ main (int argc, const char **argv)
   /* Assign sequential codes to all entries in the machine description
      in parallel with the tables in insn-output.cc.  */
 
-  int npatterns = count_patterns ();
   md_rtx_info info;
 
-  bool to_stdout = false;
-  int npatterns_per_file = npatterns;
-  if (!output_files.is_empty ())
-    npatterns_per_file = npatterns / output_files.length () + 1;
-  else
-    to_stdout = true;
-
-  gcc_assert (npatterns_per_file > 1);
+  if (output_files.is_empty ())
+    output_files.safe_push (stdout);
 
-  /* Reverse so we can pop the first-added element.  */
-  output_files.reverse ();
+  for (auto f : output_files)
+    print_header (f);
 
-  int count = 0;
   FILE *file = NULL;
+  unsigned file_idx;
 
   /* Read the machine description.  */
   while (read_md_rtx (&info))
     {
-      if (count == 0 || count == npatterns_per_file)
-       {
-         bool is_last = !to_stdout && output_files.is_empty ();
-         if (file && !is_last)
-           if (fclose (file) != 0)
-             return FATAL_EXIT_CODE;
-
-         if (!output_files.is_empty ())
-           {
-             const char *const filename = output_files.pop ();
-             file = fopen (filename, "w");
-           }
-         else if (to_stdout)
-           file = stdout;
-         else
-           break;
-
-         print_header (file);
-         count = 0;
-       }
+      file = choose_output (output_files, file_idx);
 
       switch (GET_CODE (info.def))
        {
@@ -999,10 +974,10 @@ main (int argc, const char **argv)
        default:
          break;
        }
-
-      count++;
     }
 
+  file = choose_output (output_files, file_idx);
+
   /* Write out the routines to add CLOBBERs to a pattern and say whether they
      clobber a hard reg.  */
   output_add_clobbers (&info, file);
@@ -1015,5 +990,10 @@ main (int argc, const char **argv)
       handle_overloaded_gen (oname, file);
     }
 
-  return (fclose (file) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
+  int ret = SUCCESS_EXIT_CODE;
+  for (FILE *f : output_files)
+    if (fclose (f) != 0)
+      ret = FATAL_EXIT_CODE;
+
+  return ret;
 }
index 3a02132c8761bc5640fa874e76bbba57c17f56b1..e0adf0c1bc54cfd6563ee355e07944fe576b7fb7 100644 (file)
@@ -3913,3 +3913,36 @@ find_optab (optab_pattern *p, const char *name)
     }
   return false;
 }
+
+/* Find the file to write into next.  We try to evenly distribute the contents
+   over the different files.  */
+
+#define SIZED_BASED_CHUNKS 1
+
+FILE *
+choose_output (const vec<FILE *> &parts, unsigned &idx)
+{
+  if (parts.length () == 0)
+    gcc_unreachable ();
+#ifdef SIZED_BASED_CHUNKS
+  FILE *shortest = NULL;
+  long min = 0;
+  idx = 0;
+  for (unsigned i = 0; i < parts.length (); i++)
+    {
+      FILE *part  = parts[i];
+      long len = ftell (part);
+      if (!shortest || min > len)
+       {
+         shortest = part;
+         min = len;
+         idx = i;
+       }
+    }
+  return shortest;
+#else
+  static int current_file;
+  idx = current_file++ % parts.length ();
+  return parts[idx];
+#endif
+}
index b7a1da34518ca8fe4ebd398132ad8aa94c628b3e..781c9e9ffcea034bd1616b6155ffaafb6fc6ab74 100644 (file)
@@ -231,5 +231,6 @@ extern file_location get_file_location (rtx);
 extern const char *get_emit_function (rtx);
 extern bool needs_barrier_p (rtx);
 extern bool find_optab (optab_pattern *, const char *);
+extern FILE *choose_output (const vec<FILE *> &, unsigned &);
 
 #endif /* GCC_GENSUPPORT_H */