Ilya Verbin - Re: [PATCH][OpenMP] Forbid usage of non-target functions in target regio (original) (raw)
This is the mail archive of the gcc-patches@gcc.gnu.orgmailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
- From: Ilya Verbin
- To: Jakub Jelinek , Thomas Schwinge
- Cc: gcc-patches at gcc dot gnu dot org, Kirill Yukhin
- Date: Mon, 16 Feb 2015 17:59:16 +0300
- Subject: Re: [PATCH][OpenMP] Forbid usage of non-target functions in target regions
- Authentication-results: sourceware.org; auth=none
- References: <20150109145702 dot GA45210 at msticlxl57 dot ims dot intel dot com> <20150109150212 dot GB1405 at tucnak dot redhat dot com> <20150111200652 dot GB30445 at msticlxl57 dot ims dot intel dot com> <20150202121019 dot GO1746 at tucnak dot redhat dot com>
On Mon, Feb 02, 2015 at 13:10:19 +0100, Jakub Jelinek wrote:
[...] Generally, the solution if something goes wrong during the offloading compilation should be just to give up on the offloading to the particular offloading target (i.e. fill in the sections libgomp reads in a way that will result in host fallback).
Do you mean something like this? Bootstrapped/regtested on x86_64-linux and i686-linux. Is this patch OK for stage4 or stage1?
gcc/ * collect-utils.c (do_wait, fork_execute): New argument. * collect-utils.h: Likewise. * collect2.c: Pass new argument to do_wait and fork_execute. * config/i386/intelmic-mkoffload.c: Likewise. (compile_for_target): Don't call fatal_error if compilation failed. (generate_target_descr_file, generate_target_offloadend_file) (prepare_target_image): Pass out_filename to compile_for_target. * config/nvptx/mkoffload.c: Pass new argument fork_execute. * lto-wrapper.c (num_offload_targets): New static global variable. (compile_offload_image): Return NULL if an image was not created. (compile_images_for_offload_targets): Call warning instead of fatal_error if an image was not created. (run_gcc): Do not return empty images to linker. Pass new argument to do_wait and fork_execute. libgomp/ * target.c (gomp_target_fallback): New static function. (GOMP_target): Move host fallback to the new gomp_target_fallback. Run gomp_target_fallback if tgt_fn is not present in the splay tree.
diff --git a/gcc/collect-utils.c b/gcc/collect-utils.c index 6bbe9eb..2dce3c9 100644 --- a/gcc/collect-utils.c +++ b/gcc/collect-utils.c @@ -85,10 +85,10 @@ collect_wait (const char *prog, struct pex_obj *pex) } void -do_wait (const char *prog, struct pex_obj *pex) +do_wait (const char *prog, struct pex_obj *pex, bool non_fatal) { int ret = collect_wait (prog, pex); - if (ret != 0) + if (!non_fatal && ret != 0) fatal_error (input_location, "%s returned %d exit status", prog, ret); if (response_file && !save_temps) @@ -201,13 +201,13 @@ collect_execute (const char *prog, char **argv, const char *outname, } void -fork_execute (const char *prog, char **argv, bool use_atfile) +fork_execute (const char *prog, char **argv, bool use_atfile, bool non_fatal) { struct pex_obj pex; pex = collect_execute (prog, argv, NULL, NULL, PEX_LAST | PEX_SEARCH, use_atfile); - do_wait (prog, pex); + do_wait (prog, pex, non_fatal); } / Delete tempfiles. */ diff --git a/gcc/collect-utils.h b/gcc/collect-utils.h index 2b3ed44..7b3b3da 100644 --- a/gcc/collect-utils.h +++ b/gcc/collect-utils.h @@ -29,8 +29,8 @@ extern struct pex_obj *collect_execute (const char *, char **, const char *, const char *, int, bool); extern int collect_wait (const char *, struct pex_obj *); -extern void do_wait (const char *, struct pex_obj *); -extern void fork_execute (const char *, char **, bool); +extern void do_wait (const char *, struct pex_obj *, bool); +extern void fork_execute (const char *, char **, bool, bool); extern void utils_cleanup (bool); diff --git a/gcc/collect2.c b/gcc/collect2.c index b53e151..f8be7da 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -758,7 +758,7 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char *object_lst, obstack_free (&temporary_obstack, temporary_firstobj); } - do_wait (prog, pex); + do_wait (prog, pex, false); pex = NULL; / Compute memory needed for new LD arguments. At most number of original arguemtns @@ -803,7 +803,8 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char *object_lst, / Run the linker again, this time replacing the object files optimized by the LTO with the temporary file generated by the LTO. */ - fork_execute ("ld", out_lto_ld_argv, HAVE_GNU_LD && at_file_supplied); + fork_execute ("ld", out_lto_ld_argv, HAVE_GNU_LD && at_file_supplied, + false); post_ld_pass (true); free (lto_ld_argv); @@ -813,7 +814,7 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char *object_lst, { / Our caller is relying on us to do the link even though there is no LTO back end work to be done. */ - fork_execute ("ld", lto_ld_argv, HAVE_GNU_LD && at_file_supplied); + fork_execute ("ld", lto_ld_argv, HAVE_GNU_LD && at_file_supplied, false); post_ld_pass (false); } else @@ -1706,7 +1707,7 @@ main (int argc, char **argv) strip_argv[0] = strip_file_name; strip_argv[1] = output_file; strip_argv[2] = (char *) 0; - fork_execute ("strip", real_strip_argv, false); + fork_execute ("strip", real_strip_argv, false, false); } #ifdef COLLECT_EXPORT_LIST @@ -1792,7 +1793,7 @@ main (int argc, char *argv) / Assemble the constructor and destructor tables. Link the tables in with the rest of the program. / - fork_execute ("gcc", c_argv, at_file_supplied); + fork_execute ("gcc", c_argv, at_file_supplied, false); #ifdef COLLECT_EXPORT_LIST / On AIX we must call tlink because of possible templates resolution. */ do_tlink (ld2_argv, object_lst); @@ -1805,7 +1806,7 @@ main (int argc, char **argv) maybe_run_lto_and_relink (ld2_argv, object_lst, object, true); else { - fork_execute ("ld", ld2_argv, HAVE_GNU_LD && at_file_supplied); + fork_execute ("ld", ld2_argv, HAVE_GNU_LD && at_file_supplied, false); post_ld_pass (false); } @@ -2486,7 +2487,7 @@ scan_prog_file (const char *prog_name, scanpass which_pass, if (debug) fprintf (stderr, "\n"); - do_wait (nm_file_name, pex); + do_wait (nm_file_name, pex, false); signal (SIGINT, int_handler); #ifdef SIGQUIT @@ -2606,7 +2607,7 @@ scan_libraries (const char *prog_name) if (debug) fprintf (stderr, "\n"); - do_wait (ldd_file_name, pex); + do_wait (ldd_file_name, pex, false); signal (SIGINT, int_handler); #ifdef SIGQUIT @@ -3023,7 +3024,7 @@ do_dsymutil (const char *output_file) { pex = collect_execute (dsymutil, real_argv, NULL, NULL, PEX_LAST | PEX_SEARCH, false); - do_wait (dsymutil, pex); + do_wait (dsymutil, pex, false); } static void diff --git a/gcc/config/i386/intelmic-mkoffload.c b/gcc/config/i386/intelmic-mkoffload.c index e6394e9..45d8677 100644 --- a/gcc/config/i386/intelmic-mkoffload.c +++ b/gcc/config/i386/intelmic-mkoffload.c @@ -187,12 +187,15 @@ out: } static void -compile_for_target (struct obstack *argv_obstack) +compile_for_target (struct obstack *argv_obstack, const char *out_filename) { if (target_ilp32) obstack_ptr_grow (argv_obstack, "-m32"); else obstack_ptr_grow (argv_obstack, "-m64"); + + obstack_ptr_grow (argv_obstack, "-o"); + obstack_ptr_grow (argv_obstack, out_filename); obstack_ptr_grow (argv_obstack, NULL); char **argv = XOBFINISH (argv_obstack, char **); @@ -206,7 +209,7 @@ compile_for_target (struct obstack argv_obstack) unsetenv ("LIBRARY_PATH"); unsetenv ("LD_RUN_PATH"); - fork_execute (argv[0], argv, false); + fork_execute (argv[0], argv, false, true); obstack_free (argv_obstack, NULL); / Restore environment variables. */ @@ -214,6 +217,12 @@ compile_for_target (struct obstack argv_obstack) xputenv (concat ("COMPILER_PATH=", cpath, NULL)); xputenv (concat ("LIBRARY_PATH=", lpath, NULL)); xputenv (concat ("LD_RUN_PATH=", rpath, NULL)); + + / If something went wrong during the compilation, exit mkoffload without + producing an object file. / + struct stat st; + if (stat (out_filename, &st) != 0 || st.st_size == 0) + exit (EXIT_SUCCESS); } / Generates object file with the descriptor for the target library. */ @@ -268,9 +277,7 @@ generate_target_descr_file (const char *target_compiler) obstack_ptr_grow (&argv_obstack, "-shared"); obstack_ptr_grow (&argv_obstack, "-fPIC"); obstack_ptr_grow (&argv_obstack, src_filename); - obstack_ptr_grow (&argv_obstack, "-o"); - obstack_ptr_grow (&argv_obstack, obj_filename); - compile_for_target (&argv_obstack); + compile_for_target (&argv_obstack, obj_filename); return obj_filename; } @@ -306,9 +313,7 @@ generate_target_offloadend_file (const char *target_compiler) obstack_ptr_grow (&argv_obstack, "-shared"); obstack_ptr_grow (&argv_obstack, "-fPIC"); obstack_ptr_grow (&argv_obstack, src_filename); - obstack_ptr_grow (&argv_obstack, "-o"); - obstack_ptr_grow (&argv_obstack, obj_filename); - compile_for_target (&argv_obstack); + compile_for_target (&argv_obstack, obj_filename); return obj_filename; } @@ -364,7 +369,7 @@ generate_host_descr_file (const char *host_compiler) new_argv[new_argc++] = obj_filename; new_argv[new_argc++] = NULL; - fork_execute (new_argv[0], CONST_CAST (char **, new_argv), false); + fork_execute (new_argv[0], CONST_CAST (char **, new_argv), false, false); return obj_filename; } @@ -403,9 +408,7 @@ prepare_target_image (const char *target_compiler, int argc, char *argv) if (!out_obj_filename) fatal_error (input_location, "output file not specified"); obstack_ptr_grow (&argv_obstack, opt2); - obstack_ptr_grow (&argv_obstack, "-o"); - obstack_ptr_grow (&argv_obstack, target_so_filename); - compile_for_target (&argv_obstack); + compile_for_target (&argv_obstack, target_so_filename); / Run objcopy. */ char *rename_section_opt @@ -426,7 +429,8 @@ prepare_target_image (const char *target_compiler, int argc, char **argv) objcopy_argv[8] = "--rename-section"; objcopy_argv[9] = rename_section_opt; objcopy_argv[10] = NULL; - fork_execute (objcopy_argv[0], CONST_CAST (char **, objcopy_argv), false); + fork_execute (objcopy_argv[0], CONST_CAST (char **, objcopy_argv), false, + false); /* Objcopy has created symbols, containing the input file name with special characters replaced with '_'. We are going to rename these @@ -464,7 +468,7 @@ prepare_target_image (const char *target_compiler, int argc, char **argv) objcopy_argv[6] = "--redefine-sym"; objcopy_argv[7] = opt_for_objcopy[2]; objcopy_argv[8] = NULL; - fork_execute (objcopy_argv[0], CONST_CAST (char **, objcopy_argv), false); + fork_execute (objcopy_argv[0], CONST_CAST (char **, objcopy_argv), false, false); return target_so_filename; } @@ -527,7 +531,7 @@ main (int argc, char **argv) new_argv[new_argc++] = "-o"; new_argv[new_argc++] = out_obj_filename; new_argv[new_argc++] = NULL; - fork_execute (new_argv[0], CONST_CAST (char **, new_argv), false); + fork_execute (new_argv[0], CONST_CAST (char **, new_argv), false, false); /* Run objcopy on the resultant object file to localize generated symbols to avoid conflicting between different DSO and an executable. */ @@ -540,7 +544,7 @@ main (int argc, char **argv) new_argv[6] = symbols[2]; new_argv[7] = out_obj_filename; new_argv[8] = NULL; - fork_execute (new_argv[0], CONST_CAST (char **, new_argv), false); + fork_execute (new_argv[0], CONST_CAST (char **, new_argv), false, false); return 0; } diff --git a/gcc/config/nvptx/mkoffload.c b/gcc/config/nvptx/mkoffload.c index 739aee8..67c87b9 100644 --- a/gcc/config/nvptx/mkoffload.c +++ b/gcc/config/nvptx/mkoffload.c @@ -817,7 +817,7 @@ compile_native (const char *infile, const char *outfile, const char *compiler) obstack_ptr_grow (&argv_obstack, NULL); const char **new_argv = XOBFINISH (&argv_obstack, const char **); - fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true); + fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true, false); obstack_free (&argv_obstack, NULL); } @@ -884,7 +884,7 @@ main (int argc, char **argv) unsetenv ("COMPILER_PATH"); unsetenv ("LIBRARY_PATH"); - fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true); + fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true, false); obstack_free (&argv_obstack, NULL); xputenv (concat ("GCC_EXEC_PREFIX=", execpath, NULL)); diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index 404cb68..aef077f 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -68,6 +68,7 @@ static unsigned int nr; static char **input_names; static char **output_names; static char **offload_names; +static unsigned num_offload_targets; static const char *offloadbegin, *offloadend; static char *makefile; @@ -644,6 +645,7 @@ compile_offload_image (const char *target, const char *compiler_path, struct cl_decoded_option *linker_opts, unsigned int linker_opt_count) { + struct stat st; char *filename = NULL; char **argv; char *suffix @@ -691,11 +693,18 @@ compile_offload_image (const char *target, const char *compiler_path, obstack_ptr_grow (&argv_obstack, NULL); argv = XOBFINISH (&argv_obstack, char **); - fork_execute (argv[0], argv, true); + fork_execute (argv[0], argv, true, false); obstack_free (&argv_obstack, NULL); } free_array_of_ptrs ((void **) paths, n_paths); + + if (filename && (stat (filename, &st) != 0 || st.st_size == 0)) + { + XDELETEVEC (filename); + filename = NULL; + } + return filename; } @@ -716,28 +725,27 @@ compile_images_for_offload_targets (unsigned in_argc, char *in_argv[], const char *target_names = getenv (OFFLOAD_TARGET_NAMES_ENV); if (!target_names) return; - unsigned num_targets = parse_env_var (target_names, &names, NULL); + num_offload_targets = parse_env_var (target_names, &names, NULL); const char compiler_path = getenv ("COMPILER_PATH"); if (!compiler_path) goto out; / Prepare an image for each target and save the name of the resultant object - file to the OFFLOAD_NAMES array. It is terminated by a NULL entry. */ - offload_names = XCNEWVEC (char , num_targets + 1); - for (unsigned i = 0; i < num_targets; i++) + file to the OFFLOAD_NAMES array. */ + offload_names = XCNEWVEC (char *, num_offload_targets + 1); + for (unsigned i = 0; i < num_offload_targets; i++) { offload_names[i] = compile_offload_image (names[i], compiler_path, in_argc, in_argv, compiler_opts, compiler_opt_count, linker_opts, linker_opt_count); if (!offload_names[i]) - fatal_error (input_location, - "problem with building target image for %s\n", names[i]); + warning (0, "problem with building target image for %s", names[i]); } out: - free_array_of_ptrs ((void **) names, num_targets); + free_array_of_ptrs ((void **) names, num_offload_targets); } /* Copy a file from SRC to DEST. */ @@ -1063,9 +1071,10 @@ run_gcc (unsigned argc, char *argv[]) if (offload_names) { find_offloadbeginend (); - for (i = 0; offload_names[i]; i++) - printf ("%s\n", offload_names[i]); - free_array_of_ptrs ((void **) offload_names, i); + for (i = 0; i < num_offload_targets; i++) + if (offload_names[i]) + printf ("%s\n", offload_names[i]); + free_array_of_ptrs ((void **) offload_names, num_offload_targets); } } @@ -1154,7 +1163,7 @@ run_gcc (unsigned argc, char *argv[]) new_argv = XOBFINISH (&argv_obstack, const char **); argv_ptr = &new_argv[new_head_argc]; - fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true); + fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true, false); if (lto_mode == LTO_MODE_LTO) { @@ -1263,7 +1272,7 @@ cont: else { fork_execute (new_argv[0], CONST_CAST (char **, new_argv), - true); + true, false); maybe_unlink (input_name); } @@ -1301,7 +1310,7 @@ cont: new_argv[i++] = NULL; pex = collect_execute (new_argv[0], CONST_CAST (char **, new_argv), NULL, NULL, PEX_SEARCH, false); - do_wait (new_argv[0], pex); + do_wait (new_argv[0], pex, false); maybe_unlink (makefile); makefile = NULL; for (i = 0; i < nr; ++i) diff --git a/libgomp/target.c b/libgomp/target.c index 73e757a..4d770c4 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -735,6 +735,24 @@ gomp_fini_device (struct gomp_device_descr *devicep) devicep->is_initialized = false; } +/ Host fallback for GOMP_target routine. */ + +static void +gomp_target_fallback (void (*fn) (void *), void **hostaddrs) +{ + struct gomp_thread old_thr, *thr = gomp_thread (); + old_thr = *thr; + memset (thr, '\0', sizeof (*thr)); + if (gomp_places_list) + { + thr->place = old_thr.place; + thr->ts.place_partition_len = gomp_places_list_len; + } + fn (hostaddrs); + gomp_free_thread (thr); + thr = old_thr; +} + / Called when encountering a target directive. If DEVICE is GOMP_DEVICE_ICV, it means use device-var ICV. If it is GOMP_DEVICE_HOST_FALLBACK (or any value @@ -754,21 +772,7 @@ GOMP_target (int device, void (*fn) (void *), const void unused, if (devicep == NULL || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)) - { - / Host fallback. */ - struct gomp_thread old_thr, *thr = gomp_thread (); - old_thr = *thr; - memset (thr, '\0', sizeof (*thr)); - if (gomp_places_list) - { - thr->place = old_thr.place; - thr->ts.place_partition_len = gomp_places_list_len; - } - fn (hostaddrs); - gomp_free_thread (thr); - *thr = old_thr; - return; - } + return gomp_target_fallback (fn, hostaddrs); gomp_mutex_lock (&devicep->lock); if (!devicep->is_initialized) @@ -792,8 +796,11 @@ GOMP_target (int device, void (*fn) (void *), const void *unused, k.host_end = k.host_start + 1; splay_tree_key tgt_fn = splay_tree_lookup (&mm->splay_tree, &k); if (tgt_fn == NULL) - gomp_fatal ("Target function wasn't mapped");
- {
gomp_target_fallback (fn, hostaddrs);
gomp_mutex_unlock (&mm->lock);
return;
- } gomp_mutex_unlock (&mm->lock); fn_addr = (void *) tgt_fn->tgt->tgt_start;
Thanks, -- Ilya
- References:
- Re: [PATCH][OpenMP] Forbid usage of non-target functions in target regions
* From: Jakub Jelinek
- Re: [PATCH][OpenMP] Forbid usage of non-target functions in target regions
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |