diff mbox series

[v2] gcn/mkoffload.cc: Use #embed for including the generated ELF file

Message ID 4723211d-6c9e-4226-8950-531ed1b8dec1@baylibre.com
State New
Headers show
Series [v2] gcn/mkoffload.cc: Use #embed for including the generated ELF file | expand

Commit Message

Tobias Burnus June 21, 2024, 3:30 p.m. UTC
[I messed up copying from the build system, picking up an old version.
Changes to v1 (bottom of the diff): fopen is no longer required.]

Tobias Burnus wrote:
> mkoffload's generated .c file looks much nicer with '#embed'.
>
> This patch depends on Jakub's #embed patch at
> https://gcc.gnu.org/pipermail/gcc-patches/2024-June/655012.html
>
> It might be a tiny bit faster than currently (or not); however,
> once #embed has a large-file mode, it should also speed up
> the offloading compilation quit a bit.
>
> OK for mainline, once '#embed' support is in?
Tobias

Comments

Andrew Stubbs June 21, 2024, 3:55 p.m. UTC | #1
On 21/06/2024 16:30, Tobias Burnus wrote:
> [I messed up copying from the build system, picking up an old version.
> Changes to v1 (bottom of the diff): fopen is no longer required.]
> 
> Tobias Burnus wrote:
>> mkoffload's generated .c file looks much nicer with '#embed'.
>>
>> This patch depends on Jakub's #embed patch at
>> https://gcc.gnu.org/pipermail/gcc-patches/2024-June/655012.html
>>
>> It might be a tiny bit faster than currently (or not); however,
>> once #embed has a large-file mode, it should also speed up
>> the offloading compilation quit a bit.
>>
>> OK for mainline, once '#embed' support is in?
> Tobias


>    /* Dump out an array containing the binary.
>       FIXME: do this with objcopy.  */

Please adjust that comment; the FIXME can be removed completely.

Otherwise LGTM, thanks. :-)

Andrew
Jakub Jelinek July 19, 2024, 10:33 a.m. UTC | #2
On Fri, Jun 21, 2024 at 05:30:02PM +0200, Tobias Burnus wrote:
> gcc/ChangeLog:
> 
> 	* config/gcn/mkoffload.cc (read_file): Remove.
> 	(process_obj): Generate C file that uses #embed.
> 	(main): Update call to it; remove no longer needed file I/O.

> +  fprintf (cfile,
> +	   "static unsigned char gcn_code[] = {\n"
> +	   "#if defined(__STDC_EMBED_FOUND__) && __has_embed (\"%s\") == __STDC_EMBED_FOUND__\n"

If this was an attempt to deal gracefully with no #embed support, then
the above would be wrong and should have been
#if defined(__STDC_EMBED_FOUND__) && defined(__has_embed)
#if __has_embed ("whatever") == __STDC_EMBED_FOUND__
or so, because in a compiler which will not support __has_embed
you'll get error like
error: missing binary operator before token "("
on
#if defined(__STDC_EMBED_FOUND__) && __has_embed ("whatever") == __STDC_EMBED_FOUND__
as it is handled like
#if 0 && 0 ("whatever") == 0

Now, if all you want is an error if the file doesn't exist, then
#embed "whatever"
will do that too (though, in the patchset currently posted that is
still a fatal error, rather than just a normal one, perhaps we should
change that).

If you want an error not just when it doesn't exist, but also when it
is empty, then you could do
#embed "whatever" if_empty (%%%)
(or whatever is syntactically not valid there).

	Jakub
diff mbox series

Patch

gcn/mkoffload.cc: Use #embed for including the generated ELF file

gcc/ChangeLog:

	* config/gcn/mkoffload.cc (read_file): Remove.
	(process_obj): Generate C file that uses #embed.
	(main): Update call to it; remove no longer needed file I/O.

 gcc/config/gcn/mkoffload.cc | 72 ++++++++-------------------------------------
 1 file changed, 12 insertions(+), 60 deletions(-)

diff --git a/gcc/config/gcn/mkoffload.cc b/gcc/config/gcn/mkoffload.cc
index 810298a799b..0c840318b2d 100644
--- a/gcc/config/gcn/mkoffload.cc
+++ b/gcc/config/gcn/mkoffload.cc
@@ -182,44 +182,6 @@  xputenv (const char *string)
   putenv (CONST_CAST (char *, string));
 }
 
-/* Read the whole input file.  It will be NUL terminated (but
-   remember, there could be a NUL in the file itself.  */
-
-static const char *
-read_file (FILE *stream, size_t *plen)
-{
-  size_t alloc = 16384;
-  size_t base = 0;
-  char *buffer;
-
-  if (!fseek (stream, 0, SEEK_END))
-    {
-      /* Get the file size.  */
-      long s = ftell (stream);
-      if (s >= 0)
-	alloc = s + 100;
-      fseek (stream, 0, SEEK_SET);
-    }
-  buffer = XNEWVEC (char, alloc);
-
-  for (;;)
-    {
-      size_t n = fread (buffer + base, 1, alloc - base - 1, stream);
-
-      if (!n)
-	break;
-      base += n;
-      if (base + 1 == alloc)
-	{
-	  alloc *= 2;
-	  buffer = XRESIZEVEC (char, buffer, alloc);
-	}
-    }
-  buffer[base] = 0;
-  *plen = base;
-  return buffer;
-}
-
 /* Parse STR, saving found tokens into PVALUES and return their number.
    Tokens are assumed to be delimited by ':'.  */
 
@@ -725,31 +687,27 @@  process_asm (FILE *in, FILE *out, FILE *cfile)
 /* Embed an object file into a C source file.  */
 
 static void
-process_obj (FILE *in, FILE *cfile, uint32_t omp_requires)
+process_obj (const char *fname_in, FILE *cfile, uint32_t omp_requires)
 {
-  size_t len = 0;
-  const char *input = read_file (in, &len);
-
   /* Dump out an array containing the binary.
      FIXME: do this with objcopy.  */
-  fprintf (cfile, "static unsigned char gcn_code[] = {");
-  for (size_t i = 0; i < len; i += 17)
-    {
-      fprintf (cfile, "\n\t");
-      for (size_t j = i; j < i + 17 && j < len; j++)
-	fprintf (cfile, "%3u,", (unsigned char) input[j]);
-    }
-  fprintf (cfile, "\n};\n\n");
+  fprintf (cfile,
+	   "static unsigned char gcn_code[] = {\n"
+	   "#if defined(__STDC_EMBED_FOUND__) && __has_embed (\"%s\") == __STDC_EMBED_FOUND__\n"
+	   "#embed \"%s\"\n"
+	   "#else\n"
+	   "#error \"#embed '%s' failed\"\n"
+	   "#endif\n"
+	   "};\n\n", fname_in, fname_in, fname_in);
 
   fprintf (cfile,
 	   "static const struct gcn_image {\n"
 	   "  size_t size;\n"
 	   "  void *image;\n"
 	   "} gcn_image = {\n"
-	   "  %zu,\n"
+	   "  sizeof(gcn_code),\n"
 	   "  gcn_code\n"
-	   "};\n\n",
-	   len);
+	   "};\n\n");
 
   fprintf (cfile,
 	   "static const struct gcn_data {\n"
@@ -1312,13 +1270,7 @@  main (int argc, char **argv)
       fork_execute (ld_argv[0], CONST_CAST (char **, ld_argv), true, ".ld_args");
       obstack_free (&ld_argv_obstack, NULL);
 
-      in = fopen (gcn_o_name, "r");
-      if (!in)
-	fatal_error (input_location, "cannot open intermediate gcn obj file");
-
-      process_obj (in, cfile, omp_requires);
-
-      fclose (in);
+      process_obj (gcn_o_name, cfile, omp_requires);
 
       xputenv (concat ("GCC_EXEC_PREFIX=", execpath, NULL));
       xputenv (concat ("COMPILER_PATH=", cpath, NULL));