[PATCH 1/4] Add mkoffload for Intel MIC
Jakub Jelinek
jakub@redhat.com
Wed Oct 22 08:27:00 GMT 2014
On Tue, Oct 21, 2014 at 09:16:02PM +0400, Ilya Verbin wrote:
> --- a/gcc/Makefile.in
> +++ b/gcc/Makefile.in
> @@ -3895,3 +3895,14 @@ DEPFILES = \
> $(foreach obj,$(ALL_HOST_OBJS),\
> $(dir $(obj))$(DEPDIR)/$(patsubst %.o,%.Po,$(notdir $(obj))))
> -include $(DEPFILES)
> +
> +
> +mkoffload.o: $(srcdir)/config/intelmic/mkoffload.c | insn-modes.h
> + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
> + -I$(srcdir)/../libgomp \
> + -DDEFAULT_REAL_TARGET_MACHINE=\"$(real_target_noncanonical)\" \
> + -DDEFAULT_TARGET_MACHINE=\"$(target_noncanonical)\" \
> + $< $(OUTPUT_OPTION)
> +
> +mkoffload$(exeext): mkoffload.o collect-utils.o libcommon-target.a $(LIBIBERTY) $(LIBDEPS)
> + $(COMPILER) -o $@ mkoffload.o collect-utils.o libcommon-target.a $(LIBIBERTY) $(LIBS)
I don't like this. I thought every offloading target will have its own
mkoffload binary, so hardcoding a particular mkoffload implementation in
the generic Makefile.in looks very much wrong. The rules should come from
some config/i386/t-intelmic target snippet enabled by config.gcc.
Also, is there a reason why do you want to use config/intelmic/
subdirectory? Is there any plan to make intelmic offloading for different
ISA than x86_64? I mean, even K10M would use i386/ backend, if it got
added, right?
So, I'd use config/i386/t-intelmic and config/i386/intelmic-mkoffload.c .
> +
> +/* Delete tempfiles and exit function. */
> +void
> +tool_cleanup (__attribute__((unused)) bool from_signal)
boo from_signal ATTRIBUTE_UNUSED ?
> + values = (char**) xmalloc (num * sizeof (char*));
Formatting, spaces before *, so char ** and char *.
> + curval = str;
> + nextval = strchrnul (curval, ':');
> +
> + for (i = 0; i < num; i++)
> + {
> + int l = nextval - curval;
> + values[i] = (char*) xmalloc (l + 1);
Idem.
> + /* Objcopy has created symbols, containing the input file name with
> + special characters replaced with '_'. We are going to rename these
> + new symbols. */
> + char *symbol_name = XALLOCAVEC (char, strlen (target_so_filename) + 1);
> + int i = 0;
> + while (target_so_filename[i])
> + {
> + char c = target_so_filename[i];
> + if ((c == '/') || (c == '.'))
> + c = '_';
> + symbol_name[i] = c;
> + i++;
> + }
> + symbol_name[i] = 0;
So, you certainly know strlen (symbol_name) here.
> + char *opt_for_objcopy[3];
> + opt_for_objcopy[0] = XALLOCAVEC (char, sizeof ("_binary__start=")
> + + strlen (symbol_name)
Thus you can use it here etc. (or rename i to symbol_name_len).
> + + strlen (symbols[0]));
> + opt_for_objcopy[1] = XALLOCAVEC (char, sizeof ("_binary__end=")
> + + strlen (symbol_name)
Likewise.
> + + strlen (symbols[1]));
> + opt_for_objcopy[2] = XALLOCAVEC (char, sizeof ("_binary__size=")
> + + strlen (symbol_name)
Likewise.
> + + strlen (symbols[2]));
> + sprintf (opt_for_objcopy[0], "_binary_%s_start=%s", symbol_name, symbols[0]);
> + sprintf (opt_for_objcopy[1], "_binary_%s_end=%s", symbol_name, symbols[1]);
> + sprintf (opt_for_objcopy[2], "_binary_%s_size=%s", symbol_name, symbols[2]);
> +
> + obstack_init (&argv_obstack);
> + obstack_ptr_grow (&argv_obstack, "objcopy");
> + obstack_ptr_grow (&argv_obstack, target_so_filename);
> + obstack_ptr_grow (&argv_obstack, "--redefine-sym");
> + obstack_ptr_grow (&argv_obstack, opt_for_objcopy[0]);
> + obstack_ptr_grow (&argv_obstack, "--redefine-sym");
> + obstack_ptr_grow (&argv_obstack, opt_for_objcopy[1]);
> + obstack_ptr_grow (&argv_obstack, "--redefine-sym");
> + obstack_ptr_grow (&argv_obstack, opt_for_objcopy[2]);
> + obstack_ptr_grow (&argv_obstack, NULL);
> + new_argv = XOBFINISH (&argv_obstack, char **);
Why do you use an obstack for an array of pointers where you know
you have exactly 9 pointers? Wouldn't
char *new_argv[9];
and just pointer assignments be better?
> + fork_execute (new_argv[0], new_argv, false);
> + obstack_free (&argv_obstack, NULL);
> +
> + return target_so_filename;
> +}
> +
> +int
> +main (int argc, char **argv)
> +{
> + progname = "mkoffload-intelmic";
> + gcc_init_libintl ();
> + diagnostic_initialize (global_dc, 0);
> +
> + if (atexit (mkoffload_atexit) != 0)
> + fatal_error ("atexit failed");
> +
> + const char *host_compiler = getenv ("COLLECT_GCC");
> + if (!host_compiler)
> + fatal_error ("COLLECT_GCC must be set.");
> +
> + const char *target_driver_name
> + = DEFAULT_REAL_TARGET_MACHINE "-accel-" DEFAULT_TARGET_MACHINE "-gcc";
> + char *target_compiler = find_target_compiler (target_driver_name);
> + if (target_compiler == NULL)
> + fatal_error ("offload compiler %s not found.", target_driver_name);
> +
> + /* We may be called with all the arguments stored in some file and
> + passed with @file. Expand them into argv before processing. */
> + expandargv (&argc, &argv);
> +
> + /* Find out whether we should compile binaries for i386 or x86-64. */
> + for (int i = argc - 1; i > 0; i--)
> + if (strncmp (argv[i], "-foffload-abi=", strlen ("-foffload-abi=")) == 0)
> + {
> + if (strstr (argv[i], "ilp32"))
> + target_ilp32 = true;
> + else if (!strstr (argv[i], "lp64"))
> + fatal_error ("unrecognizable argument of option -foffload-abi");
> + break;
> + }
> +
> + const char *target_so_filename
> + = prepare_target_image (target_compiler, argc, argv);
> +
> + const char *host_descr_filename = generate_host_descr_file (host_compiler);
> +
> + /* Perform partial linking for the target image and host side descriptor.
> + As a result we'll get a finalized object file with all offload data. */
> + struct obstack argv_obstack;
> + obstack_init (&argv_obstack);
> + obstack_ptr_grow (&argv_obstack, "ld");
> + if (target_ilp32)
> + {
> + obstack_ptr_grow (&argv_obstack, "-m");
> + obstack_ptr_grow (&argv_obstack, "elf_i386");
> + }
> + obstack_ptr_grow (&argv_obstack, "-r");
> + obstack_ptr_grow (&argv_obstack, host_descr_filename);
> + obstack_ptr_grow (&argv_obstack, target_so_filename);
> + obstack_ptr_grow (&argv_obstack, "-o");
> + obstack_ptr_grow (&argv_obstack, out_obj_filename);
> + obstack_ptr_grow (&argv_obstack, NULL);
> + char **new_argv = XOBFINISH (&argv_obstack, char **);
Similarly (well, here it is not constant, still, you know small upper bound
and can just use some int index you ++ in each assignment.
> + /* Run objcopy on the resultant object file to localize generated symbols
> + to avoid conflicting between different DSO and an executable. */
> + obstack_init (&argv_obstack);
> + obstack_ptr_grow (&argv_obstack, "objcopy");
> + obstack_ptr_grow (&argv_obstack, "-L");
> + obstack_ptr_grow (&argv_obstack, symbols[0]);
> + obstack_ptr_grow (&argv_obstack, "-L");
> + obstack_ptr_grow (&argv_obstack, symbols[1]);
> + obstack_ptr_grow (&argv_obstack, "-L");
> + obstack_ptr_grow (&argv_obstack, symbols[2]);
> + obstack_ptr_grow (&argv_obstack, out_obj_filename);
> + obstack_ptr_grow (&argv_obstack, NULL);
> + new_argv = XOBFINISH (&argv_obstack, char **);
> + fork_execute (new_argv[0], new_argv, false);
> + obstack_free (&argv_obstack, NULL);
Likewise.
Jakub
More information about the Gcc-patches
mailing list