Merge current set of OpenACC changes from gomp-4_0-branch.

contrib/
	* gcc_update (files_and_dependencies): Update rules for new
	libgomp/plugin/Makefrag.am and libgomp/plugin/configfrag.ac files.
	gcc/
	* builtin-types.def (BT_FN_VOID_INT_INT_VAR)
	(BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR_INT_INT_VAR)
	(BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR_INT_INT_INT_INT_INT_VAR):
	New function types.
	* builtins.c: Include "gomp-constants.h".
	(expand_builtin_acc_on_device): New function.
	(expand_builtin, is_inexpensive_builtin): Handle
	BUILT_IN_ACC_ON_DEVICE.
	* builtins.def (DEF_GOACC_BUILTIN, DEF_GOACC_BUILTIN_COMPILER):
	New macros.
	* cgraph.c (cgraph_node::create): Consider flag_openacc next to
	flag_openmp.
	* config.gcc <nvptx-*> (tm_file): Add nvptx/offload.h.
	<*-intelmic-* | *-intelmicemul-*> (tm_file): Add
	i386/intelmic-offload.h.
	* gcc.c (LINK_COMMAND_SPEC, GOMP_SELF_SPECS): For -fopenacc, link
	to libgomp and its dependencies.
	* config/arc/arc.h (LINK_COMMAND_SPEC): Likewise.
	* config/darwin.h (LINK_COMMAND_SPEC_A): Likewise.
	* config/i386/mingw32.h (GOMP_SELF_SPECS): Likewise.
	* config/ia64/hpux.h (LIB_SPEC): Likewise.
	* config/pa/pa-hpux11.h (LIB_SPEC): Likewise.
	* config/pa/pa64-hpux.h (LIB_SPEC): Likewise.
	* doc/generic.texi: Update for OpenACC changes.
	* doc/gimple.texi: Likewise.
	* doc/invoke.texi: Likewise.
	* doc/sourcebuild.texi: Likewise.
	* gimple-pretty-print.c (dump_gimple_omp_for): Handle
	GF_OMP_FOR_KIND_OACC_LOOP.
	(dump_gimple_omp_target): Handle GF_OMP_TARGET_KIND_OACC_KERNELS,
	GF_OMP_TARGET_KIND_OACC_PARALLEL, GF_OMP_TARGET_KIND_OACC_DATA,
	GF_OMP_TARGET_KIND_OACC_UPDATE,
	GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA.
	Dump more data.
	* gimple.c: Update comments for OpenACC changes.
	* gimple.def: Likewise.
	* gimple.h: Likewise.
	(enum gf_mask): Add GF_OMP_FOR_KIND_OACC_LOOP,
	GF_OMP_TARGET_KIND_OACC_PARALLEL, GF_OMP_TARGET_KIND_OACC_KERNELS,
	GF_OMP_TARGET_KIND_OACC_DATA, GF_OMP_TARGET_KIND_OACC_UPDATE,
	GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA.
	(gimple_omp_for_cond, gimple_omp_for_set_cond): Sort in the
	appropriate place.
	(is_gimple_omp_oacc, is_gimple_omp_offloaded): New functions.
	* gimplify.c: Include "gomp-constants.h".
	Update comments for OpenACC changes.
	(is_gimple_stmt): Handle OACC_PARALLEL, OACC_KERNELS, OACC_DATA,
	OACC_HOST_DATA, OACC_DECLARE, OACC_UPDATE, OACC_ENTER_DATA,
	OACC_EXIT_DATA, OACC_CACHE, OACC_LOOP.
	(gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses): Handle
	OMP_CLAUSE__CACHE_, OMP_CLAUSE_ASYNC, OMP_CLAUSE_WAIT,
	OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS,
	OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER,
	OMP_CLAUSE_VECTOR, OMP_CLAUSE_DEVICE_RESIDENT,
	OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE_INDEPENDENT, OMP_CLAUSE_AUTO,
	OMP_CLAUSE_SEQ.
	(gimplify_adjust_omp_clauses_1, gimplify_adjust_omp_clauses): Use
	GOMP_MAP_* instead of OMP_CLAUSE_MAP_*.  Use
	OMP_CLAUSE_SET_MAP_KIND.
	(gimplify_oacc_cache): New function.
	(gimplify_omp_for): Handle OACC_LOOP.
	(gimplify_omp_workshare): Handle OACC_KERNELS, OACC_PARALLEL,
	OACC_DATA.
	(gimplify_omp_target_update): Handle OACC_ENTER_DATA,
	OACC_EXIT_DATA, OACC_UPDATE.
	(gimplify_expr): Handle OACC_LOOP, OACC_CACHE, OACC_HOST_DATA,
	OACC_DECLARE, OACC_KERNELS, OACC_PARALLEL, OACC_DATA,
	OACC_ENTER_DATA, OACC_EXIT_DATA, OACC_UPDATE.
	(gimplify_body): Consider flag_openacc next to flag_openmp.
	* lto-streamer-out.c: Include "gomp-constants.h".
	* omp-builtins.def (BUILT_IN_ACC_GET_DEVICE_TYPE)
	(BUILT_IN_GOACC_DATA_START, BUILT_IN_GOACC_DATA_END)
	(BUILT_IN_GOACC_ENTER_EXIT_DATA, BUILT_IN_GOACC_PARALLEL)
	(BUILT_IN_GOACC_UPDATE, BUILT_IN_GOACC_WAIT)
	(BUILT_IN_GOACC_GET_THREAD_NUM, BUILT_IN_GOACC_GET_NUM_THREADS)
	(BUILT_IN_ACC_ON_DEVICE): New builtins.
	* omp-low.c: Include "gomp-constants.h".
	Update comments for OpenACC changes.
	(struct omp_context): Add reduction_map, gwv_below, gwv_this
	members.
	(extract_omp_for_data, use_pointer_for_field, install_var_field)
	(new_omp_context, delete_omp_context, scan_sharing_clauses)
	(create_omp_child_function, scan_omp_for, scan_omp_target)
	(check_omp_nesting_restrictions, lower_reduction_clauses)
	(build_omp_regions_1, diagnose_sb_0, make_gimple_omp_edges):
	Update for OpenACC changes.
	(scan_sharing_clauses): Handle OMP_CLAUSE_NUM_GANGS:
	OMP_CLAUSE_NUM_WORKERS: OMP_CLAUSE_VECTOR_LENGTH,
	OMP_CLAUSE_ASYNC, OMP_CLAUSE_WAIT, OMP_CLAUSE_GANG,
	OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_DEVICE_RESIDENT,
	OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE__CACHE_, OMP_CLAUSE_INDEPENDENT,
	OMP_CLAUSE_AUTO, OMP_CLAUSE_SEQ.  Use GOMP_MAP_* instead of
	OMP_CLAUSE_MAP_*.
	(expand_omp_for_static_nochunk, expand_omp_for_static_chunk):
	Handle GF_OMP_FOR_KIND_OACC_LOOP.
	(expand_omp_target, lower_omp_target): Handle
	GF_OMP_TARGET_KIND_OACC_PARALLEL, GF_OMP_TARGET_KIND_OACC_KERNELS,
	GF_OMP_TARGET_KIND_OACC_UPDATE,
	GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA,
	GF_OMP_TARGET_KIND_OACC_DATA.
	(pass_expand_omp::execute, execute_lower_omp)
	(pass_diagnose_omp_blocks::gate): Consider flag_openacc next to
	flag_openmp.
	(offload_symbol_decl): New variable.
	(oacc_get_reduction_array_id, oacc_max_threads)
	(get_offload_symbol_decl, get_base_type, lookup_oacc_reduction)
	(maybe_lookup_oacc_reduction, enclosing_target_ctx)
	(oacc_loop_or_target_p, oacc_lower_reduction_var_helper)
	(oacc_gimple_assign, oacc_initialize_reduction_data)
	(oacc_finalize_reduction_data, oacc_process_reduction_data): New
	functions.
	(is_targetreg_ctx): Remove function.
	* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE__CACHE_,
	OMP_CLAUSE_DEVICE_RESIDENT, OMP_CLAUSE_USE_DEVICE,
	OMP_CLAUSE_GANG, OMP_CLAUSE_ASYNC, OMP_CLAUSE_WAIT,
	OMP_CLAUSE_AUTO, OMP_CLAUSE_SEQ, OMP_CLAUSE_INDEPENDENT,
	OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_NUM_GANGS,
	OMP_CLAUSE_NUM_WORKERS, OMP_CLAUSE_VECTOR_LENGTH.
	* tree.c (omp_clause_code_name, walk_tree_1): Update accordingly.
	* tree.h (OMP_CLAUSE_GANG_EXPR, OMP_CLAUSE_GANG_STATIC_EXPR)
	(OMP_CLAUSE_ASYNC_EXPR, OMP_CLAUSE_WAIT_EXPR)
	(OMP_CLAUSE_VECTOR_EXPR, OMP_CLAUSE_WORKER_EXPR)
	(OMP_CLAUSE_NUM_GANGS_EXPR, OMP_CLAUSE_NUM_WORKERS_EXPR)
	(OMP_CLAUSE_VECTOR_LENGTH_EXPR): New macros.
	* tree-core.h: Update comments for OpenACC changes.
	(enum omp_clause_map_kind): Remove.
	(struct tree_omp_clause): Change type of map_kind member from enum
	omp_clause_map_kind to unsigned char.
	* tree-inline.c: Update comments for OpenACC changes.
	* tree-nested.c: Likewise.  Include "gomp-constants.h".
	(convert_nonlocal_reference_stmt, convert_local_reference_stmt)
	(convert_tramp_reference_stmt, convert_gimple_call): Update for
	OpenACC changes.  Use GOMP_MAP_* instead of OMP_CLAUSE_MAP_*.  Use
	OMP_CLAUSE_SET_MAP_KIND.
	* tree-pretty-print.c: Include "gomp-constants.h".
	(dump_omp_clause): Handle OMP_CLAUSE_DEVICE_RESIDENT,
	OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE__CACHE_, OMP_CLAUSE_GANG,
	OMP_CLAUSE_ASYNC, OMP_CLAUSE_AUTO, OMP_CLAUSE_SEQ,
	OMP_CLAUSE_WAIT, OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR,
	OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS,
	OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_INDEPENDENT.  Use GOMP_MAP_*
	instead of OMP_CLAUSE_MAP_*.
	(dump_generic_node): Handle OACC_PARALLEL, OACC_KERNELS,
	OACC_DATA, OACC_HOST_DATA, OACC_DECLARE, OACC_UPDATE,
	OACC_ENTER_DATA, OACC_EXIT_DATA, OACC_CACHE, OACC_LOOP.
	* tree-streamer-in.c: Include "gomp-constants.h".
	(unpack_ts_omp_clause_value_fields) Use GOMP_MAP_* instead of
	OMP_CLAUSE_MAP_*.  Use OMP_CLAUSE_SET_MAP_KIND.
	* tree-streamer-out.c: Include "gomp-constants.h".
	(pack_ts_omp_clause_value_fields): Use GOMP_MAP_* instead of
	OMP_CLAUSE_MAP_*.
	* tree.def (OACC_PARALLEL, OACC_KERNELS, OACC_DATA)
	(OACC_HOST_DATA, OACC_LOOP, OACC_CACHE, OACC_DECLARE)
	(OACC_ENTER_DATA, OACC_EXIT_DATA, OACC_UPDATE): New tree codes.
	* tree.c (omp_clause_num_ops): Update accordingly.
	* tree.h (OMP_BODY, OMP_CLAUSES, OMP_LOOP_CHECK, OMP_CLAUSE_SIZE):
	Likewise.
	(OACC_PARALLEL_BODY, OACC_PARALLEL_CLAUSES, OACC_KERNELS_BODY)
	(OACC_KERNELS_CLAUSES, OACC_DATA_BODY, OACC_DATA_CLAUSES)
	(OACC_HOST_DATA_BODY, OACC_HOST_DATA_CLAUSES, OACC_CACHE_CLAUSES)
	(OACC_DECLARE_CLAUSES, OACC_ENTER_DATA_CLAUSES)
	(OACC_EXIT_DATA_CLAUSES, OACC_UPDATE_CLAUSES)
	(OACC_KERNELS_COMBINED, OACC_PARALLEL_COMBINED): New macros.
	* tree.h (OMP_CLAUSE_MAP_KIND): Cast it to enum gomp_map_kind.
	(OMP_CLAUSE_SET_MAP_KIND): New macro.
	* varpool.c (varpool_node::get_create): Consider flag_openacc next
	to flag_openmp.
	* config/i386/intelmic-offload.h: New file.
	* config/nvptx/offload.h: Likewise.
	gcc/ada/
	* gcc-interface/utils.c (DEF_FUNCTION_TYPE_VAR_8)
	(DEF_FUNCTION_TYPE_VAR_12): New macros.
	gcc/c-family/
	* c.opt (fopenacc): New option.
	* c-cppbuiltin.c (c_cpp_builtins): Conditionally define _OPENACC.
	* c-common.c (DEF_FUNCTION_TYPE_VAR_8, DEF_FUNCTION_TYPE_VAR_12):
	New macros.
	* c-common.h (c_finish_oacc_wait): New prototype.
	* c-omp.c: Include "omp-low.h" and "gomp-constants.h".
	(c_finish_oacc_wait): New function.
	* c-pragma.c (oacc_pragmas): New variable.
	(c_pp_lookup_pragma, init_pragma): Handle it.
	* c-pragma.h (enum pragma_kind): Add PRAGMA_OACC_CACHE,
	PRAGMA_OACC_DATA, PRAGMA_OACC_ENTER_DATA, PRAGMA_OACC_EXIT_DATA,
	PRAGMA_OACC_KERNELS, PRAGMA_OACC_LOOP, PRAGMA_OACC_PARALLEL,
	PRAGMA_OACC_UPDATE, PRAGMA_OACC_WAIT.
	(enum pragma_omp_clause): Add PRAGMA_OACC_CLAUSE_ASYNC,
	PRAGMA_OACC_CLAUSE_AUTO, PRAGMA_OACC_CLAUSE_COLLAPSE,
	PRAGMA_OACC_CLAUSE_COPY, PRAGMA_OACC_CLAUSE_COPYIN,
	PRAGMA_OACC_CLAUSE_COPYOUT, PRAGMA_OACC_CLAUSE_CREATE,
	PRAGMA_OACC_CLAUSE_DELETE, PRAGMA_OACC_CLAUSE_DEVICE,
	PRAGMA_OACC_CLAUSE_DEVICEPTR, PRAGMA_OACC_CLAUSE_FIRSTPRIVATE,
	PRAGMA_OACC_CLAUSE_GANG, PRAGMA_OACC_CLAUSE_HOST,
	PRAGMA_OACC_CLAUSE_IF, PRAGMA_OACC_CLAUSE_NUM_GANGS,
	PRAGMA_OACC_CLAUSE_NUM_WORKERS, PRAGMA_OACC_CLAUSE_PRESENT,
	PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY,
	PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN,
	PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT,
	PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE, PRAGMA_OACC_CLAUSE_PRIVATE,
	PRAGMA_OACC_CLAUSE_REDUCTION, PRAGMA_OACC_CLAUSE_SELF,
	PRAGMA_OACC_CLAUSE_SEQ, PRAGMA_OACC_CLAUSE_VECTOR,
	PRAGMA_OACC_CLAUSE_VECTOR_LENGTH, PRAGMA_OACC_CLAUSE_WAIT,
	PRAGMA_OACC_CLAUSE_WORKER.
	gcc/c/
	* c-parser.c: Include "gomp-constants.h".
	(c_parser_omp_clause_map): Use enum gomp_map_kind instead of enum
	omp_clause_map_kind.  Use GOMP_MAP_* instead of OMP_CLAUSE_MAP_*.
	Use OMP_CLAUSE_SET_MAP_KIND.
	(c_parser_pragma): Handle PRAGMA_OACC_ENTER_DATA,
	PRAGMA_OACC_EXIT_DATA, PRAGMA_OACC_UPDATE.
	(c_parser_omp_construct): Handle PRAGMA_OACC_CACHE,
	PRAGMA_OACC_DATA, PRAGMA_OACC_KERNELS, PRAGMA_OACC_LOOP,
	PRAGMA_OACC_PARALLEL, PRAGMA_OACC_WAIT.
	(c_parser_omp_clause_name): Handle "auto", "async", "copy",
	"copyout", "create", "delete", "deviceptr", "gang", "host",
	"num_gangs", "num_workers", "present", "present_or_copy", "pcopy",
	"present_or_copyin", "pcopyin", "present_or_copyout", "pcopyout",
	"present_or_create", "pcreate", "seq", "self", "vector",
	"vector_length", "wait", "worker".
	(OACC_DATA_CLAUSE_MASK, OACC_KERNELS_CLAUSE_MASK)
	(OACC_ENTER_DATA_CLAUSE_MASK, OACC_EXIT_DATA_CLAUSE_MASK)
	(OACC_LOOP_CLAUSE_MASK, OACC_PARALLEL_CLAUSE_MASK)
	(OACC_UPDATE_CLAUSE_MASK, OACC_WAIT_CLAUSE_MASK): New macros.
	(c_parser_omp_variable_list): Handle OMP_CLAUSE__CACHE_.
	(c_parser_oacc_wait_list, c_parser_oacc_data_clause)
	(c_parser_oacc_data_clause_deviceptr)
	(c_parser_omp_clause_num_gangs, c_parser_omp_clause_num_workers)
	(c_parser_oacc_clause_async, c_parser_oacc_clause_wait)
	(c_parser_omp_clause_vector_length, c_parser_oacc_all_clauses)
	(c_parser_oacc_cache, c_parser_oacc_data, c_parser_oacc_kernels)
	(c_parser_oacc_enter_exit_data, c_parser_oacc_loop)
	(c_parser_oacc_parallel, c_parser_oacc_update)
	(c_parser_oacc_wait): New functions.
	* c-tree.h (c_finish_oacc_parallel, c_finish_oacc_kernels)
	(c_finish_oacc_data): New prototypes.
	* c-typeck.c: Include "gomp-constants.h".
	(handle_omp_array_sections): Handle GOMP_MAP_FORCE_DEVICEPTR.  Use
	GOMP_MAP_* instead of OMP_CLAUSE_MAP_*.  Use
	OMP_CLAUSE_SET_MAP_KIND.
	(c_finish_oacc_parallel, c_finish_oacc_kernels)
	(c_finish_oacc_data): New functions.
	(c_finish_omp_clauses): Handle OMP_CLAUSE__CACHE_,
	OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS,
	OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_ASYNC, OMP_CLAUSE_WAIT,
	OMP_CLAUSE_AUTO, OMP_CLAUSE_SEQ, OMP_CLAUSE_GANG,
	OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, and OMP_CLAUSE_MAP's
	GOMP_MAP_FORCE_DEVICEPTR.
	gcc/cp/
	* parser.c: Include "gomp-constants.h".
	(cp_parser_omp_clause_map): Use enum gomp_map_kind instead of enum
	omp_clause_map_kind.  Use GOMP_MAP_* instead of OMP_CLAUSE_MAP_*.
	Use OMP_CLAUSE_SET_MAP_KIND.
	(cp_parser_omp_construct, cp_parser_pragma): Handle
	PRAGMA_OACC_CACHE, PRAGMA_OACC_DATA, PRAGMA_OACC_ENTER_DATA,
	PRAGMA_OACC_EXIT_DATA, PRAGMA_OACC_KERNELS, PRAGMA_OACC_PARALLEL,
	PRAGMA_OACC_LOOP, PRAGMA_OACC_UPDATE, PRAGMA_OACC_WAIT.
	(cp_parser_omp_clause_name): Handle "async", "copy", "copyout",
	"create", "delete", "deviceptr", "host", "num_gangs",
	"num_workers", "present", "present_or_copy", "pcopy",
	"present_or_copyin", "pcopyin", "present_or_copyout", "pcopyout",
	"present_or_create", "pcreate", "vector_length", "wait".
	(OACC_DATA_CLAUSE_MASK, OACC_ENTER_DATA_CLAUSE_MASK)
	(OACC_EXIT_DATA_CLAUSE_MASK, OACC_KERNELS_CLAUSE_MASK)
	(OACC_LOOP_CLAUSE_MASK, OACC_PARALLEL_CLAUSE_MASK)
	(OACC_UPDATE_CLAUSE_MASK, OACC_WAIT_CLAUSE_MASK): New macros.
	(cp_parser_omp_var_list_no_open): Handle OMP_CLAUSE__CACHE_.
	(cp_parser_oacc_data_clause, cp_parser_oacc_data_clause_deviceptr)
	(cp_parser_oacc_clause_vector_length, cp_parser_oacc_wait_list)
	(cp_parser_oacc_clause_wait, cp_parser_omp_clause_num_gangs)
	(cp_parser_omp_clause_num_workers, cp_parser_oacc_clause_async)
	(cp_parser_oacc_all_clauses, cp_parser_oacc_cache)
	(cp_parser_oacc_data, cp_parser_oacc_enter_exit_data)
	(cp_parser_oacc_kernels, cp_parser_oacc_loop)
	(cp_parser_oacc_parallel, cp_parser_oacc_update)
	(cp_parser_oacc_wait): New functions.
	* cp-tree.h (finish_oacc_data, finish_oacc_kernels)
	(finish_oacc_parallel): New prototypes.
	* semantics.c: Include "gomp-constants.h".
	(handle_omp_array_sections): Handle GOMP_MAP_FORCE_DEVICEPTR.  Use
	GOMP_MAP_* instead of OMP_CLAUSE_MAP_*.  Use
	OMP_CLAUSE_SET_MAP_KIND.
	(finish_omp_clauses): Handle OMP_CLAUSE_ASYNC,
	OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_WAIT, OMP_CLAUSE__CACHE_.
	Use GOMP_MAP_* instead of OMP_CLAUSE_MAP_*.
	(finish_oacc_data, finish_oacc_kernels, finish_oacc_parallel): New
	functions.
	gcc/fortran/
	* lang.opt (fopenacc): New option.
	* cpp.c (cpp_define_builtins): Conditionally define _OPENACC.
	* dump-parse-tree.c (show_omp_node): Split part of it into...
	(show_omp_clauses): ... this new function.
	(show_omp_node, show_code_node): Handle EXEC_OACC_PARALLEL_LOOP,
	EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS_LOOP, EXEC_OACC_KERNELS,
	EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP,
	EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE,
	EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA.
	(show_namespace): Update for OpenACC.
	* f95-lang.c (DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_8)
	(DEF_FUNCTION_TYPE_VAR_12, DEF_GOACC_BUILTIN)
	(DEF_GOACC_BUILTIN_COMPILER): New macros.
	* types.def (BT_FN_VOID_INT_INT_VAR)
	(BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR_INT_INT_VAR)
	(BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR_INT_INT_INT_INT_INT_VAR):
	New function types.
	* gfortran.h (gfc_statement): Add ST_OACC_PARALLEL_LOOP,
	ST_OACC_END_PARALLEL_LOOP, ST_OACC_PARALLEL, ST_OACC_END_PARALLEL,
	ST_OACC_KERNELS, ST_OACC_END_KERNELS, ST_OACC_DATA,
	ST_OACC_END_DATA, ST_OACC_HOST_DATA, ST_OACC_END_HOST_DATA,
	ST_OACC_LOOP, ST_OACC_END_LOOP, ST_OACC_DECLARE, ST_OACC_UPDATE,
	ST_OACC_WAIT, ST_OACC_CACHE, ST_OACC_KERNELS_LOOP,
	ST_OACC_END_KERNELS_LOOP, ST_OACC_ENTER_DATA, ST_OACC_EXIT_DATA,
	ST_OACC_ROUTINE.
	(struct gfc_expr_list): New data type.
	(gfc_get_expr_list): New macro.
	(gfc_omp_map_op): Add OMP_MAP_FORCE_ALLOC, OMP_MAP_FORCE_DEALLOC,
	OMP_MAP_FORCE_TO, OMP_MAP_FORCE_FROM, OMP_MAP_FORCE_TOFROM,
	OMP_MAP_FORCE_PRESENT, OMP_MAP_FORCE_DEVICEPTR.
	(OMP_LIST_FIRST, OMP_LIST_DEVICE_RESIDENT, OMP_LIST_USE_DEVICE)
	(OMP_LIST_CACHE): New enumerators.
	(struct gfc_omp_clauses): Add async_expr, gang_expr, worker_expr,
	vector_expr, num_gangs_expr, num_workers_expr, vector_length_expr,
	wait_list, tile_list, async, gang, worker, vector, seq,
	independent, wait, par_auto, gang_static, and loc members.
	(struct gfc_namespace): Add oacc_declare_clauses member.
	(gfc_exec_op): Add EXEC_OACC_KERNELS_LOOP,
	EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS,
	EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP,
	EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE,
	EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA.
	(gfc_free_expr_list, gfc_resolve_oacc_directive)
	(gfc_resolve_oacc_declare, gfc_resolve_oacc_parallel_loop_blocks)
	(gfc_resolve_oacc_blocks): New prototypes.
	* match.c (match_exit_cycle): Handle EXEC_OACC_LOOP and
	EXEC_OACC_PARALLEL_LOOP.
	* match.h (gfc_match_oacc_cache, gfc_match_oacc_wait)
	(gfc_match_oacc_update, gfc_match_oacc_declare)
	(gfc_match_oacc_loop, gfc_match_oacc_host_data)
	(gfc_match_oacc_data, gfc_match_oacc_kernels)
	(gfc_match_oacc_kernels_loop, gfc_match_oacc_parallel)
	(gfc_match_oacc_parallel_loop, gfc_match_oacc_enter_data)
	(gfc_match_oacc_exit_data, gfc_match_oacc_routine): New
	prototypes.
	* openmp.c: Include "diagnostic.h" and "gomp-constants.h".
	(gfc_free_omp_clauses): Update for members added to struct
	gfc_omp_clauses.
	(gfc_match_omp_clauses): Change mask paramter to uint64_t.  Add
	openacc parameter.
	(resolve_omp_clauses): Add openacc parameter.  Update for OpenACC.
	(struct fortran_omp_context): Add is_openmp member.
	(gfc_resolve_omp_parallel_blocks): Initialize it.
	(gfc_resolve_do_iterator): Update for OpenACC.
	(gfc_resolve_omp_directive): Call
	resolve_omp_directive_inside_oacc_region.
	(OMP_CLAUSE_PRIVATE, OMP_CLAUSE_FIRSTPRIVATE)
	(OMP_CLAUSE_LASTPRIVATE, OMP_CLAUSE_COPYPRIVATE)
	(OMP_CLAUSE_SHARED, OMP_CLAUSE_COPYIN, OMP_CLAUSE_REDUCTION)
	(OMP_CLAUSE_IF, OMP_CLAUSE_NUM_THREADS, OMP_CLAUSE_SCHEDULE)
	(OMP_CLAUSE_DEFAULT, OMP_CLAUSE_ORDERED, OMP_CLAUSE_COLLAPSE)
	(OMP_CLAUSE_UNTIED, OMP_CLAUSE_FINAL, OMP_CLAUSE_MERGEABLE)
	(OMP_CLAUSE_ALIGNED, OMP_CLAUSE_DEPEND, OMP_CLAUSE_INBRANCH)
	(OMP_CLAUSE_LINEAR, OMP_CLAUSE_NOTINBRANCH, OMP_CLAUSE_PROC_BIND)
	(OMP_CLAUSE_SAFELEN, OMP_CLAUSE_SIMDLEN, OMP_CLAUSE_UNIFORM)
	(OMP_CLAUSE_DEVICE, OMP_CLAUSE_MAP, OMP_CLAUSE_TO)
	(OMP_CLAUSE_FROM, OMP_CLAUSE_NUM_TEAMS, OMP_CLAUSE_THREAD_LIMIT)
	(OMP_CLAUSE_DIST_SCHEDULE): Use uint64_t.
	(OMP_CLAUSE_ASYNC, OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS)
	(OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_COPY, OMP_CLAUSE_COPYOUT)
	(OMP_CLAUSE_CREATE, OMP_CLAUSE_PRESENT)
	(OMP_CLAUSE_PRESENT_OR_COPY, OMP_CLAUSE_PRESENT_OR_COPYIN)
	(OMP_CLAUSE_PRESENT_OR_COPYOUT, OMP_CLAUSE_PRESENT_OR_CREATE)
	(OMP_CLAUSE_DEVICEPTR, OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER)
	(OMP_CLAUSE_VECTOR, OMP_CLAUSE_SEQ, OMP_CLAUSE_INDEPENDENT)
	(OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE_DEVICE_RESIDENT)
	(OMP_CLAUSE_HOST_SELF, OMP_CLAUSE_OACC_DEVICE, OMP_CLAUSE_WAIT)
	(OMP_CLAUSE_DELETE, OMP_CLAUSE_AUTO, OMP_CLAUSE_TILE): New macros.
	(gfc_match_omp_clauses): Handle those.
	(OACC_PARALLEL_CLAUSES, OACC_KERNELS_CLAUSES, OACC_DATA_CLAUSES)
	(OACC_LOOP_CLAUSES, OACC_PARALLEL_LOOP_CLAUSES)
	(OACC_KERNELS_LOOP_CLAUSES, OACC_HOST_DATA_CLAUSES)
	(OACC_DECLARE_CLAUSES, OACC_UPDATE_CLAUSES)
	(OACC_ENTER_DATA_CLAUSES, OACC_EXIT_DATA_CLAUSES)
	(OACC_WAIT_CLAUSES): New macros.
	(gfc_free_expr_list, match_oacc_expr_list, match_oacc_clause_gang)
	(gfc_match_omp_map_clause, gfc_match_oacc_parallel_loop)
	(gfc_match_oacc_parallel, gfc_match_oacc_kernels_loop)
	(gfc_match_oacc_kernels, gfc_match_oacc_data)
	(gfc_match_oacc_host_data, gfc_match_oacc_loop)
	(gfc_match_oacc_declare, gfc_match_oacc_update)
	(gfc_match_oacc_enter_data, gfc_match_oacc_exit_data)
	(gfc_match_oacc_wait, gfc_match_oacc_cache)
	(gfc_match_oacc_routine, oacc_is_loop)
	(resolve_oacc_scalar_int_expr, resolve_oacc_positive_int_expr)
	(check_symbol_not_pointer, check_array_not_assumed)
	(resolve_oacc_data_clauses, resolve_oacc_deviceptr_clause)
	(oacc_compatible_clauses, oacc_is_parallel, oacc_is_kernels)
	(omp_code_to_statement, oacc_code_to_statement)
	(resolve_oacc_directive_inside_omp_region)
	(resolve_omp_directive_inside_oacc_region)
	(resolve_oacc_nested_loops, resolve_oacc_params_in_parallel)
	(resolve_oacc_loop_blocks, gfc_resolve_oacc_blocks)
	(resolve_oacc_loop, resolve_oacc_cache, gfc_resolve_oacc_declare)
	(gfc_resolve_oacc_directive): New functions.
	* parse.c (next_free): Update for OpenACC.  Move some code into...
	(verify_token_free): ... this new function.
	(next_fixed): Update for OpenACC.  Move some code into...
	(verify_token_fixed): ... this new function.
	(case_executable): Add ST_OACC_UPDATE, ST_OACC_WAIT,
	ST_OACC_CACHE, ST_OACC_ENTER_DATA, and ST_OACC_EXIT_DATA.
	(case_exec_markers): Add ST_OACC_PARALLEL_LOOP, ST_OACC_PARALLEL,
	ST_OACC_KERNELS, ST_OACC_DATA, ST_OACC_HOST_DATA, ST_OACC_LOOP,
	ST_OACC_KERNELS_LOOP.
	(case_decl): Add ST_OACC_ROUTINE.
	(push_state, parse_critical_block, parse_progunit): Update for
	OpenACC.
	(gfc_ascii_statement): Handle ST_OACC_PARALLEL_LOOP,
	ST_OACC_END_PARALLEL_LOOP, ST_OACC_PARALLEL, ST_OACC_END_PARALLEL,
	ST_OACC_KERNELS, ST_OACC_END_KERNELS, ST_OACC_KERNELS_LOOP,
	ST_OACC_END_KERNELS_LOOP, ST_OACC_DATA, ST_OACC_END_DATA,
	ST_OACC_HOST_DATA, ST_OACC_END_HOST_DATA, ST_OACC_LOOP,
	ST_OACC_END_LOOP, ST_OACC_DECLARE, ST_OACC_UPDATE, ST_OACC_WAIT,
	ST_OACC_CACHE, ST_OACC_ENTER_DATA, ST_OACC_EXIT_DATA,
	ST_OACC_ROUTINE.
	(verify_st_order, parse_spec): Handle ST_OACC_DECLARE.
	(parse_executable): Handle ST_OACC_PARALLEL_LOOP,
	ST_OACC_KERNELS_LOOP, ST_OACC_LOOP, ST_OACC_PARALLEL,
	ST_OACC_KERNELS, ST_OACC_DATA, ST_OACC_HOST_DATA.
	(decode_oacc_directive, parse_oacc_structured_block)
	(parse_oacc_loop, is_oacc): New functions.
	* parse.h (struct gfc_state_data): Add oacc_declare_clauses
	member.
	(is_oacc): New prototype.
	* resolve.c (gfc_resolve_blocks, gfc_resolve_code): Handle
	EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_PARALLEL,
	EXEC_OACC_KERNELS_LOOP, EXEC_OACC_KERNELS, EXEC_OACC_DATA,
	EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP, EXEC_OACC_UPDATE,
	EXEC_OACC_WAIT, EXEC_OACC_CACHE, EXEC_OACC_ENTER_DATA,
	EXEC_OACC_EXIT_DATA.
	(resolve_codes): Call gfc_resolve_oacc_declare.
	* scanner.c (openacc_flag, openacc_locus): New variables.
	(skip_free_comments): Update for OpenACC.  Move some code into...
	(skip_omp_attribute): ... this new function.
	(skip_oacc_attribute): New function.
	(skip_fixed_comments, gfc_next_char_literal): Update for OpenACC.
	* st.c (gfc_free_statement): Handle EXEC_OACC_PARALLEL_LOOP,
	EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS_LOOP, EXEC_OACC_KERNELS,
	EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP,
	EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE,
	EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA.
	* trans-decl.c (gfc_generate_function_code): Update for OpenACC.
	* trans-openmp.c: Include "gomp-constants.h".
	(gfc_omp_finish_clause, gfc_trans_omp_clauses): Use GOMP_MAP_*
	instead of OMP_CLAUSE_MAP_*.  Use OMP_CLAUSE_SET_MAP_KIND.
	(gfc_trans_omp_clauses): Handle OMP_LIST_USE_DEVICE,
	OMP_LIST_DEVICE_RESIDENT, OMP_LIST_CACHE, and OMP_MAP_FORCE_ALLOC,
	OMP_MAP_FORCE_DEALLOC, OMP_MAP_FORCE_TO, OMP_MAP_FORCE_FROM,
	OMP_MAP_FORCE_TOFROM, OMP_MAP_FORCE_PRESENT,
	OMP_MAP_FORCE_DEVICEPTR, and gfc_omp_clauses' async, seq,
	independent, wait_list, num_gangs_expr, num_workers_expr,
	vector_length_expr, vector, vector_expr, worker, worker_expr,
	gang, gang_expr members.
	(gfc_trans_omp_do): Handle EXEC_OACC_LOOP.
	(gfc_convert_expr_to_tree, gfc_trans_oacc_construct)
	(gfc_trans_oacc_executable_directive)
	(gfc_trans_oacc_wait_directive, gfc_trans_oacc_combined_directive)
	(gfc_trans_oacc_declare, gfc_trans_oacc_directive): New functions.
	* trans-stmt.c (gfc_trans_block_construct): Update for OpenACC.
	* trans-stmt.h (gfc_trans_oacc_directive, gfc_trans_oacc_declare):
	New prototypes.
	* trans.c (tranc_code): Handle EXEC_OACC_CACHE, EXEC_OACC_WAIT,
	EXEC_OACC_UPDATE, EXEC_OACC_LOOP, EXEC_OACC_HOST_DATA,
	EXEC_OACC_DATA, EXEC_OACC_KERNELS, EXEC_OACC_KERNELS_LOOP,
	EXEC_OACC_PARALLEL, EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_ENTER_DATA,
	EXEC_OACC_EXIT_DATA.
	* gfortran.texi: Update for OpenACC.
	* intrinsic.texi: Likewise.
	* invoke.texi: Likewise.
	gcc/lto/
	* lto-lang.c (DEF_FUNCTION_TYPE_VAR_8, DEF_FUNCTION_TYPE_VAR_12):
	New macros.
	* lto.c: Include "gomp-constants.h".
	gcc/testsuite/
	* lib/target-supports.exp (check_effective_target_fopenacc): New
	procedure.
	* g++.dg/goacc-gomp/goacc-gomp.exp: New file.
	* g++.dg/goacc/goacc.exp: Likewise.
	* gcc.dg/goacc-gomp/goacc-gomp.exp: Likewise.
	* gcc.dg/goacc/goacc.exp: Likewise.
	* gfortran.dg/goacc/goacc.exp: Likewise.
	* c-c++-common/cpp/openacc-define-1.c: New file.
	* c-c++-common/cpp/openacc-define-2.c: Likewise.
	* c-c++-common/cpp/openacc-define-3.c: Likewise.
	* c-c++-common/goacc-gomp/nesting-1.c: Likewise.
	* c-c++-common/goacc-gomp/nesting-fail-1.c: Likewise.
	* c-c++-common/goacc/acc_on_device-2-off.c: Likewise.
	* c-c++-common/goacc/acc_on_device-2.c: Likewise.
	* c-c++-common/goacc/asyncwait-1.c: Likewise.
	* c-c++-common/goacc/cache-1.c: Likewise.
	* c-c++-common/goacc/clauses-fail.c: Likewise.
	* c-c++-common/goacc/collapse-1.c: Likewise.
	* c-c++-common/goacc/data-1.c: Likewise.
	* c-c++-common/goacc/data-2.c: Likewise.
	* c-c++-common/goacc/data-clause-duplicate-1.c: Likewise.
	* c-c++-common/goacc/deviceptr-1.c: Likewise.
	* c-c++-common/goacc/deviceptr-2.c: Likewise.
	* c-c++-common/goacc/deviceptr-3.c: Likewise.
	* c-c++-common/goacc/if-clause-1.c: Likewise.
	* c-c++-common/goacc/if-clause-2.c: Likewise.
	* c-c++-common/goacc/kernels-1.c: Likewise.
	* c-c++-common/goacc/loop-1.c: Likewise.
	* c-c++-common/goacc/loop-private-1.c: Likewise.
	* c-c++-common/goacc/nesting-1.c: Likewise.
	* c-c++-common/goacc/nesting-data-1.c: Likewise.
	* c-c++-common/goacc/nesting-fail-1.c: Likewise.
	* c-c++-common/goacc/parallel-1.c: Likewise.
	* c-c++-common/goacc/pcopy.c: Likewise.
	* c-c++-common/goacc/pcopyin.c: Likewise.
	* c-c++-common/goacc/pcopyout.c: Likewise.
	* c-c++-common/goacc/pcreate.c: Likewise.
	* c-c++-common/goacc/pragma_context.c: Likewise.
	* c-c++-common/goacc/present-1.c: Likewise.
	* c-c++-common/goacc/reduction-1.c: Likewise.
	* c-c++-common/goacc/reduction-2.c: Likewise.
	* c-c++-common/goacc/reduction-3.c: Likewise.
	* c-c++-common/goacc/reduction-4.c: Likewise.
	* c-c++-common/goacc/sb-1.c: Likewise.
	* c-c++-common/goacc/sb-2.c: Likewise.
	* c-c++-common/goacc/sb-3.c: Likewise.
	* c-c++-common/goacc/update-1.c: Likewise.
	* gcc.dg/goacc/acc_on_device-1.c: Likewise.
	* gfortran.dg/goacc/acc_on_device-1.f95: Likewise.
	* gfortran.dg/goacc/acc_on_device-2-off.f95: Likewise.
	* gfortran.dg/goacc/acc_on_device-2.f95: Likewise.
	* gfortran.dg/goacc/assumed.f95: Likewise.
	* gfortran.dg/goacc/asyncwait-1.f95: Likewise.
	* gfortran.dg/goacc/asyncwait-2.f95: Likewise.
	* gfortran.dg/goacc/asyncwait-3.f95: Likewise.
	* gfortran.dg/goacc/asyncwait-4.f95: Likewise.
	* gfortran.dg/goacc/branch.f95: Likewise.
	* gfortran.dg/goacc/cache-1.f95: Likewise.
	* gfortran.dg/goacc/coarray.f95: Likewise.
	* gfortran.dg/goacc/continuation-free-form.f95: Likewise.
	* gfortran.dg/goacc/cray.f95: Likewise.
	* gfortran.dg/goacc/critical.f95: Likewise.
	* gfortran.dg/goacc/data-clauses.f95: Likewise.
	* gfortran.dg/goacc/data-tree.f95: Likewise.
	* gfortran.dg/goacc/declare-1.f95: Likewise.
	* gfortran.dg/goacc/enter-exit-data.f95: Likewise.
	* gfortran.dg/goacc/fixed-1.f: Likewise.
	* gfortran.dg/goacc/fixed-2.f: Likewise.
	* gfortran.dg/goacc/fixed-3.f: Likewise.
	* gfortran.dg/goacc/fixed-4.f: Likewise.
	* gfortran.dg/goacc/host_data-tree.f95: Likewise.
	* gfortran.dg/goacc/if.f95: Likewise.
	* gfortran.dg/goacc/kernels-tree.f95: Likewise.
	* gfortran.dg/goacc/list.f95: Likewise.
	* gfortran.dg/goacc/literal.f95: Likewise.
	* gfortran.dg/goacc/loop-1.f95: Likewise.
	* gfortran.dg/goacc/loop-2.f95: Likewise.
	* gfortran.dg/goacc/loop-3.f95: Likewise.
	* gfortran.dg/goacc/loop-tree-1.f90: Likewise.
	* gfortran.dg/goacc/omp.f95: Likewise.
	* gfortran.dg/goacc/parallel-kernels-clauses.f95: Likewise.
	* gfortran.dg/goacc/parallel-kernels-regions.f95: Likewise.
	* gfortran.dg/goacc/parallel-tree.f95: Likewise.
	* gfortran.dg/goacc/parameter.f95: Likewise.
	* gfortran.dg/goacc/private-1.f95: Likewise.
	* gfortran.dg/goacc/private-2.f95: Likewise.
	* gfortran.dg/goacc/private-3.f95: Likewise.
	* gfortran.dg/goacc/pure-elemental-procedures.f95: Likewise.
	* gfortran.dg/goacc/reduction-2.f95: Likewise.
	* gfortran.dg/goacc/reduction.f95: Likewise.
	* gfortran.dg/goacc/routine-1.f90: Likewise.
	* gfortran.dg/goacc/routine-2.f90: Likewise.
	* gfortran.dg/goacc/sentinel-free-form.f95: Likewise.
	* gfortran.dg/goacc/several-directives.f95: Likewise.
	* gfortran.dg/goacc/sie.f95: Likewise.
	* gfortran.dg/goacc/subarrays.f95: Likewise.
	* gfortran.dg/gomp/map-1.f90: Likewise.
	* gfortran.dg/openacc-define-1.f90: Likewise.
	* gfortran.dg/openacc-define-2.f90: Likewise.
	* gfortran.dg/openacc-define-3.f90: Likewise.
	* g++.dg/gomp/block-1.C: Update for changed compiler output.
	* g++.dg/gomp/block-2.C: Likewise.
	* g++.dg/gomp/block-3.C: Likewise.
	* g++.dg/gomp/block-5.C: Likewise.
	* g++.dg/gomp/target-1.C: Likewise.
	* g++.dg/gomp/target-2.C: Likewise.
	* g++.dg/gomp/taskgroup-1.C: Likewise.
	* g++.dg/gomp/teams-1.C: Likewise.
	* gcc.dg/cilk-plus/jump-openmp.c: Likewise.
	* gcc.dg/cilk-plus/jump.c: Likewise.
	* gcc.dg/gomp/block-1.c: Likewise.
	* gcc.dg/gomp/block-10.c: Likewise.
	* gcc.dg/gomp/block-2.c: Likewise.
	* gcc.dg/gomp/block-3.c: Likewise.
	* gcc.dg/gomp/block-4.c: Likewise.
	* gcc.dg/gomp/block-5.c: Likewise.
	* gcc.dg/gomp/block-6.c: Likewise.
	* gcc.dg/gomp/block-7.c: Likewise.
	* gcc.dg/gomp/block-8.c: Likewise.
	* gcc.dg/gomp/block-9.c: Likewise.
	* gcc.dg/gomp/target-1.c: Likewise.
	* gcc.dg/gomp/target-2.c: Likewise.
	* gcc.dg/gomp/taskgroup-1.c: Likewise.
	* gcc.dg/gomp/teams-1.c: Likewise.
	include/
	* gomp-constants.h: New file.
	libgomp/
	* Makefile.am (search_path): Add $(top_srcdir)/../include.
	(libgomp_la_SOURCES): Add splay-tree.c, libgomp-plugin.c,
	oacc-parallel.c, oacc-host.c, oacc-init.c, oacc-mem.c,
	oacc-async.c, oacc-plugin.c, oacc-cuda.c.
	[USE_FORTRAN] (libgomp_la_SOURCES): Add openacc.f90.
	Include $(top_srcdir)/plugin/Makefrag.am.
	(nodist_libsubinclude_HEADERS): Add openacc.h.
	[USE_FORTRAN] (nodist_finclude_HEADERS): Add openacc_lib.h,
	openacc.f90, openacc.mod, openacc_kinds.mod.
	(omp_lib.mod): Generalize into...
	(%.mod): ... this new rule.
	(openacc_kinds.mod, openacc.mod): New rules.
	* plugin/configfrag.ac: New file.
	* configure.ac: Move plugin/offloading support into it.  Include
	it.  Instantiate testsuite/libgomp-test-support.pt.exp.
	* plugin/Makefrag.am: New file.
	* testsuite/Makefile.am (OFFLOAD_TARGETS)
	(OFFLOAD_ADDITIONAL_OPTIONS, OFFLOAD_ADDITIONAL_LIB_PATHS): Don't
	export.
	(libgomp-test-support.exp): New rule.
	(all-local): Depend on it.
	* Makefile.in: Regenerate.
	* testsuite/Makefile.in: Regenerate.
	* config.h.in: Likewise.
	* configure: Likewise.
	* configure.tgt: Harden shell syntax.
	* env.c: Include "oacc-int.h".
	(parse_acc_device_type): New function.
	(gomp_debug_var, goacc_device_type, goacc_device_num): New
	variables.
	(initialize_env): Initialize those.  Call
	goacc_runtime_initialize.
	* error.c (gomp_vdebug, gomp_debug, gomp_vfatal): New functions.
	(gomp_fatal): Call gomp_vfatal.
	* libgomp.h: Include "libgomp-plugin.h" and <stdarg.h>.
	(gomp_debug_var, goacc_device_type, goacc_device_num, gomp_vdebug)
	(gomp_debug, gomp_verror, gomp_vfatal, gomp_init_targets_once)
	(splay_tree_node, splay_tree, splay_tree_key)
	(struct target_mem_desc, struct splay_tree_key_s)
	(struct gomp_memory_mapping, struct acc_dispatch_t)
	(struct gomp_device_descr, gomp_acc_insert_pointer)
	(gomp_acc_remove_pointer, target_mem_desc, gomp_copy_from_async)
	(gomp_unmap_vars, gomp_init_device, gomp_init_tables)
	(gomp_free_memmap, gomp_fini_device): New declarations.
	(gomp_vdebug, gomp_debug): New macros.
	Include "splay-tree.h".
	* libgomp.map (OACC_2.0): New symbol version.  Use for
	acc_get_num_devices, acc_get_num_devices_h_, acc_set_device_type,
	acc_set_device_type_h_, acc_get_device_type,
	acc_get_device_type_h_, acc_set_device_num, acc_set_device_num_h_,
	acc_get_device_num, acc_get_device_num_h_, acc_async_test,
	acc_async_test_h_, acc_async_test_all, acc_async_test_all_h_,
	acc_wait, acc_wait_h_, acc_wait_async, acc_wait_async_h_,
	acc_wait_all, acc_wait_all_h_, acc_wait_all_async,
	acc_wait_all_async_h_, acc_init, acc_init_h_, acc_shutdown,
	acc_shutdown_h_, acc_on_device, acc_on_device_h_, acc_malloc,
	acc_free, acc_copyin, acc_copyin_32_h_, acc_copyin_64_h_,
	acc_copyin_array_h_, acc_present_or_copyin,
	acc_present_or_copyin_32_h_, acc_present_or_copyin_64_h_,
	acc_present_or_copyin_array_h_, acc_create, acc_create_32_h_,
	acc_create_64_h_, acc_create_array_h_, acc_present_or_create,
	acc_present_or_create_32_h_, acc_present_or_create_64_h_,
	acc_present_or_create_array_h_, acc_copyout, acc_copyout_32_h_,
	acc_copyout_64_h_, acc_copyout_array_h_, acc_delete,
	acc_delete_32_h_, acc_delete_64_h_, acc_delete_array_h_,
	acc_update_device, acc_update_device_32_h_,
	acc_update_device_64_h_, acc_update_device_array_h_,
	acc_update_self, acc_update_self_32_h_, acc_update_self_64_h_,
	acc_update_self_array_h_, acc_map_data, acc_unmap_data,
	acc_deviceptr, acc_hostptr, acc_is_present, acc_is_present_32_h_,
	acc_is_present_64_h_, acc_is_present_array_h_,
	acc_memcpy_to_device, acc_memcpy_from_device,
	acc_get_current_cuda_device, acc_get_current_cuda_context,
	acc_get_cuda_stream, acc_set_cuda_stream.
	(GOACC_2.0): New symbol version.  Use for GOACC_data_end,
	GOACC_data_start, GOACC_enter_exit_data, GOACC_parallel,
	GOACC_update, GOACC_wait, GOACC_get_thread_num,
	GOACC_get_num_threads.
	(GOMP_PLUGIN_1.0): New symbol version.  Use for
	GOMP_PLUGIN_malloc, GOMP_PLUGIN_malloc_cleared,
	GOMP_PLUGIN_realloc, GOMP_PLUGIN_debug, GOMP_PLUGIN_error,
	GOMP_PLUGIN_fatal, GOMP_PLUGIN_async_unmap_vars,
	GOMP_PLUGIN_acc_thread.
	* libgomp.texi: Update for OpenACC changes, and GOMP_DEBUG
	environment variable.
	* libgomp_g.h (GOACC_data_start, GOACC_data_end)
	(GOACC_enter_exit_data, GOACC_parallel, GOACC_update, GOACC_wait)
	(GOACC_get_num_threads, GOACC_get_thread_num): New declarations.
	* splay-tree.h (splay_tree_lookup, splay_tree_insert)
	(splay_tree_remove): New declarations.
	(rotate_left, rotate_right, splay_tree_splay, splay_tree_insert)
	(splay_tree_remove, splay_tree_lookup): Move into...
	* splay-tree.c: ... this new file.
	* target.c: Include "oacc-plugin.h", "oacc-int.h", <assert.h>.
	(splay_tree_node, splay_tree, splay_tree_key)
	(struct target_mem_desc, struct splay_tree_key_s)
	(struct gomp_device_descr): Don't declare.
	(num_devices_openmp): New variable.
	(gomp_get_num_devices ): Use it.
	(gomp_init_targets_once): New function.
	(gomp_get_num_devices ): Use it.
	(get_kind, gomp_copy_from_async, gomp_free_memmap)
	(gomp_fini_device, gomp_register_image_for_device): New functions.
	(gomp_map_vars): Add devaddrs parameter.
	(gomp_update): Add mm parameter.
	(gomp_init_device): Move most of it into...
	(gomp_init_tables): ... this new function.
	(gomp_register_images_for_device): Remove function.
	(splay_compare, gomp_map_vars, gomp_unmap_vars, gomp_init_device):
	Make them hidden instead of static.
	(gomp_map_vars_existing, gomp_map_vars, gomp_unmap_vars)
	(gomp_update, gomp_init_device, GOMP_target, GOMP_target_data)
	(GOMP_target_end_data, GOMP_target_update)
	(gomp_load_plugin_for_device, gomp_target_init): Update for
	OpenACC changes.
	* oacc-async.c: New file.
	* oacc-cuda.c: Likewise.
	* oacc-host.c: Likewise.
	* oacc-init.c: Likewise.
	* oacc-int.h: Likewise.
	* oacc-mem.c: Likewise.
	* oacc-parallel.c: Likewise.
	* oacc-plugin.c: Likewise.
	* oacc-plugin.h: Likewise.
	* oacc-ptx.h: Likewise.
	* openacc.f90: Likewise.
	* openacc.h: Likewise.
	* openacc_lib.h: Likewise.
	* plugin/plugin-host.c: Likewise.
	* plugin/plugin-nvptx.c: Likewise.
	* libgomp-plugin.c: Likewise.
	* libgomp-plugin.h: Likewise.
	* libgomp_target.h: Remove file after merging content into the
	former file.  Update all users.
	* testsuite/lib/libgomp.exp: Load libgomp-test-support.exp.
	(offload_targets_s, offload_targets_s_openacc): New variables.
	(check_effective_target_openacc_nvidia_accel_present)
	(check_effective_target_openacc_nvidia_accel_selected): New
	procedures.
	(libgomp_init): Update for OpenACC changes.
	* testsuite/libgomp-test-support.exp.in: New file.
	* testsuite/libgomp.oacc-c++/c++.exp: Likewise.
	* testsuite/libgomp.oacc-c/c.exp: Likewise.
	* testsuite/libgomp.oacc-fortran/fortran.exp: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/abort-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/abort-2.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/abort-3.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/abort-4.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/acc_on_device-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/asyncwait-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/cache-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/clauses-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/clauses-2.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/collapse-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/collapse-2.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/collapse-3.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/collapse-4.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/context-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/context-2.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/context-3.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/context-4.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/data-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/data-2.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/data-3.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/data-already-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/data-already-2.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/data-already-3.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/data-already-4.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/data-already-5.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/data-already-6.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/data-already-7.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/data-already-8.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/deviceptr-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/if-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/kernels-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/kernels-empty.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-10.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-11.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-12.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-13.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-14.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-15.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-16.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-17.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-18.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-19.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-2.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-20.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-21.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-22.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-23.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-24.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-25.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-26.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-27.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-28.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-29.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-3.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-30.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-31.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-32.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-33.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-34.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-35.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-36.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-37.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-38.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-39.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-4.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-40.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-41.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-42.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-43.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-44.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-45.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-46.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-47.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-48.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-49.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-5.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-50.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-51.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-52.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-53.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-54.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-55.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-56.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-57.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-58.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-59.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-6.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-60.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-61.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-62.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-63.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-64.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-65.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-66.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-67.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-68.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-69.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-7.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-70.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-71.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-72.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-73.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-74.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-75.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-76.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-77.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-78.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-79.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-80.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-81.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-82.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-83.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-84.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-85.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-86.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-87.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-88.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-89.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-9.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-90.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-91.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/lib-92.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/nested-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/nested-2.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/offset-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/parallel-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/parallel-empty.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/pointer-align-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/present-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/present-2.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/reduction-1.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/reduction-2.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/reduction-3.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/reduction-4.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/reduction-5.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/reduction-initial-1.c:
	Likewise.
	* testsuite/libgomp.oacc-c-c++-common/subr.h: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/subr.ptx: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/timer.h: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/update-1-2.c: Likewise.
	* testsuite/libgomp.oacc-c-c++-common/update-1.c: Likewise.
	* testsuite/libgomp.oacc-fortran/abort-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/abort-2.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f: Likewise.
	* testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f: Likewise.
	* testsuite/libgomp.oacc-fortran/asyncwait-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/asyncwait-2.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/asyncwait-3.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/collapse-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/collapse-2.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/collapse-3.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/collapse-4.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/collapse-5.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/collapse-6.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/collapse-7.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/collapse-8.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/data-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/data-2.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/data-3.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/data-4-2.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/data-4.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/data-already-1.f: Likewise.
	* testsuite/libgomp.oacc-fortran/data-already-2.f: Likewise.
	* testsuite/libgomp.oacc-fortran/data-already-3.f: Likewise.
	* testsuite/libgomp.oacc-fortran/data-already-4.f: Likewise.
	* testsuite/libgomp.oacc-fortran/data-already-5.f: Likewise.
	* testsuite/libgomp.oacc-fortran/data-already-6.f: Likewise.
	* testsuite/libgomp.oacc-fortran/data-already-7.f: Likewise.
	* testsuite/libgomp.oacc-fortran/data-already-8.f: Likewise.
	* testsuite/libgomp.oacc-fortran/lib-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/lib-10.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/lib-2.f: Likewise.
	* testsuite/libgomp.oacc-fortran/lib-3.f: Likewise.
	* testsuite/libgomp.oacc-fortran/lib-4.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/lib-5.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/lib-6.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/lib-7.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/lib-8.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/map-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/openacc_version-1.f: Likewise.
	* testsuite/libgomp.oacc-fortran/openacc_version-2.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/pointer-align-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/pset-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/reduction-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/reduction-2.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/reduction-3.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/reduction-4.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/reduction-5.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/reduction-6.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/routine-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/routine-2.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/routine-3.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/routine-4.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/subarrays-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/subarrays-2.f90: Likewise.
	liboffloadmic/
	* plugin/libgomp-plugin-intelmic.cpp (GOMP_OFFLOAD_get_name)
	(GOMP_OFFLOAD_get_caps, GOMP_OFFLOAD_fini_device): New functions.

Co-Authored-By: Bernd Schmidt <bernds@codesourcery.com>
Co-Authored-By: Cesar Philippidis <cesar@codesourcery.com>
Co-Authored-By: Dmitry Bocharnikov <dmitry.b@samsung.com>
Co-Authored-By: Evgeny Gavrin <e.gavrin@samsung.com>
Co-Authored-By: Ilmir Usmanov <i.usmanov@samsung.com>
Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
Co-Authored-By: James Norris <jnorris@codesourcery.com>
Co-Authored-By: Julian Brown <julian@codesourcery.com>
Co-Authored-By: Nathan Sidwell <nathan@codesourcery.com>
Co-Authored-By: Tobias Burnus <burnus@net-b.de>
Co-Authored-By: Tom de Vries <tom@codesourcery.com>

From-SVN: r219682
This commit is contained in:
Thomas Schwinge 2015-01-15 21:11:12 +01:00 committed by Thomas Schwinge
parent 96a8798199
commit 41dbbb3789
451 changed files with 37642 additions and 1457 deletions

View File

@ -1,3 +1,8 @@
2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
* gcc_update (files_and_dependencies): Update rules for new
libgomp/plugin/Makefrag.am and libgomp/plugin/configfrag.ac files.
2015-01-12 Yury Gribov <y.gribov@samsung.com>
* check_GNU_style.sh: Support patches coming from stdin.

View File

@ -139,8 +139,10 @@ libcpp/aclocal.m4: libcpp/configure.ac
libcpp/Makefile.in: libcpp/configure.ac libcpp/aclocal.m4
libcpp/configure: libcpp/configure.ac libcpp/aclocal.m4
libgomp/aclocal.m4: libgomp/configure.ac libgomp/acinclude.m4
libgomp/Makefile.am: libgomp/plugin/Makefrag.am
libgomp/Makefile.in: libgomp/Makefile.am libgomp/aclocal.m4
libgomp/testsuite/Makefile.in: libgomp/testsuite/Makefile.am libgomp/aclocal.m4
libgomp/configure.ac: libgomp/plugin/configfrag.ac
libgomp/configure: libgomp/configure.ac libgomp/aclocal.m4
libgomp/config.h.in: libgomp/configure.ac libgomp/aclocal.m4
libitm/aclocal.m4: libitm/configure.ac libitm/acinclude.m4

View File

@ -1,3 +1,183 @@
2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
Bernd Schmidt <bernds@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
James Norris <jnorris@codesourcery.com>
Tom de Vries <tom@codesourcery.com>
Ilmir Usmanov <i.usmanov@samsung.com>
Dmitry Bocharnikov <dmitry.b@samsung.com>
Evgeny Gavrin <e.gavrin@samsung.com>
Jakub Jelinek <jakub@redhat.com>
* builtin-types.def (BT_FN_VOID_INT_INT_VAR)
(BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR_INT_INT_VAR)
(BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR_INT_INT_INT_INT_INT_VAR):
New function types.
* builtins.c: Include "gomp-constants.h".
(expand_builtin_acc_on_device): New function.
(expand_builtin, is_inexpensive_builtin): Handle
BUILT_IN_ACC_ON_DEVICE.
* builtins.def (DEF_GOACC_BUILTIN, DEF_GOACC_BUILTIN_COMPILER):
New macros.
* cgraph.c (cgraph_node::create): Consider flag_openacc next to
flag_openmp.
* config.gcc <nvptx-*> (tm_file): Add nvptx/offload.h.
<*-intelmic-* | *-intelmicemul-*> (tm_file): Add
i386/intelmic-offload.h.
* gcc.c (LINK_COMMAND_SPEC, GOMP_SELF_SPECS): For -fopenacc, link
to libgomp and its dependencies.
* config/arc/arc.h (LINK_COMMAND_SPEC): Likewise.
* config/darwin.h (LINK_COMMAND_SPEC_A): Likewise.
* config/i386/mingw32.h (GOMP_SELF_SPECS): Likewise.
* config/ia64/hpux.h (LIB_SPEC): Likewise.
* config/pa/pa-hpux11.h (LIB_SPEC): Likewise.
* config/pa/pa64-hpux.h (LIB_SPEC): Likewise.
* doc/generic.texi: Update for OpenACC changes.
* doc/gimple.texi: Likewise.
* doc/invoke.texi: Likewise.
* doc/sourcebuild.texi: Likewise.
* gimple-pretty-print.c (dump_gimple_omp_for): Handle
GF_OMP_FOR_KIND_OACC_LOOP.
(dump_gimple_omp_target): Handle GF_OMP_TARGET_KIND_OACC_KERNELS,
GF_OMP_TARGET_KIND_OACC_PARALLEL, GF_OMP_TARGET_KIND_OACC_DATA,
GF_OMP_TARGET_KIND_OACC_UPDATE,
GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA.
Dump more data.
* gimple.c: Update comments for OpenACC changes.
* gimple.def: Likewise.
* gimple.h: Likewise.
(enum gf_mask): Add GF_OMP_FOR_KIND_OACC_LOOP,
GF_OMP_TARGET_KIND_OACC_PARALLEL, GF_OMP_TARGET_KIND_OACC_KERNELS,
GF_OMP_TARGET_KIND_OACC_DATA, GF_OMP_TARGET_KIND_OACC_UPDATE,
GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA.
(gimple_omp_for_cond, gimple_omp_for_set_cond): Sort in the
appropriate place.
(is_gimple_omp_oacc, is_gimple_omp_offloaded): New functions.
* gimplify.c: Include "gomp-constants.h".
Update comments for OpenACC changes.
(is_gimple_stmt): Handle OACC_PARALLEL, OACC_KERNELS, OACC_DATA,
OACC_HOST_DATA, OACC_DECLARE, OACC_UPDATE, OACC_ENTER_DATA,
OACC_EXIT_DATA, OACC_CACHE, OACC_LOOP.
(gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses): Handle
OMP_CLAUSE__CACHE_, OMP_CLAUSE_ASYNC, OMP_CLAUSE_WAIT,
OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS,
OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER,
OMP_CLAUSE_VECTOR, OMP_CLAUSE_DEVICE_RESIDENT,
OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE_INDEPENDENT, OMP_CLAUSE_AUTO,
OMP_CLAUSE_SEQ.
(gimplify_adjust_omp_clauses_1, gimplify_adjust_omp_clauses): Use
GOMP_MAP_* instead of OMP_CLAUSE_MAP_*. Use
OMP_CLAUSE_SET_MAP_KIND.
(gimplify_oacc_cache): New function.
(gimplify_omp_for): Handle OACC_LOOP.
(gimplify_omp_workshare): Handle OACC_KERNELS, OACC_PARALLEL,
OACC_DATA.
(gimplify_omp_target_update): Handle OACC_ENTER_DATA,
OACC_EXIT_DATA, OACC_UPDATE.
(gimplify_expr): Handle OACC_LOOP, OACC_CACHE, OACC_HOST_DATA,
OACC_DECLARE, OACC_KERNELS, OACC_PARALLEL, OACC_DATA,
OACC_ENTER_DATA, OACC_EXIT_DATA, OACC_UPDATE.
(gimplify_body): Consider flag_openacc next to flag_openmp.
* lto-streamer-out.c: Include "gomp-constants.h".
* omp-builtins.def (BUILT_IN_ACC_GET_DEVICE_TYPE)
(BUILT_IN_GOACC_DATA_START, BUILT_IN_GOACC_DATA_END)
(BUILT_IN_GOACC_ENTER_EXIT_DATA, BUILT_IN_GOACC_PARALLEL)
(BUILT_IN_GOACC_UPDATE, BUILT_IN_GOACC_WAIT)
(BUILT_IN_GOACC_GET_THREAD_NUM, BUILT_IN_GOACC_GET_NUM_THREADS)
(BUILT_IN_ACC_ON_DEVICE): New builtins.
* omp-low.c: Include "gomp-constants.h".
Update comments for OpenACC changes.
(struct omp_context): Add reduction_map, gwv_below, gwv_this
members.
(extract_omp_for_data, use_pointer_for_field, install_var_field)
(new_omp_context, delete_omp_context, scan_sharing_clauses)
(create_omp_child_function, scan_omp_for, scan_omp_target)
(check_omp_nesting_restrictions, lower_reduction_clauses)
(build_omp_regions_1, diagnose_sb_0, make_gimple_omp_edges):
Update for OpenACC changes.
(scan_sharing_clauses): Handle OMP_CLAUSE_NUM_GANGS:
OMP_CLAUSE_NUM_WORKERS: OMP_CLAUSE_VECTOR_LENGTH,
OMP_CLAUSE_ASYNC, OMP_CLAUSE_WAIT, OMP_CLAUSE_GANG,
OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_DEVICE_RESIDENT,
OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE__CACHE_, OMP_CLAUSE_INDEPENDENT,
OMP_CLAUSE_AUTO, OMP_CLAUSE_SEQ. Use GOMP_MAP_* instead of
OMP_CLAUSE_MAP_*.
(expand_omp_for_static_nochunk, expand_omp_for_static_chunk):
Handle GF_OMP_FOR_KIND_OACC_LOOP.
(expand_omp_target, lower_omp_target): Handle
GF_OMP_TARGET_KIND_OACC_PARALLEL, GF_OMP_TARGET_KIND_OACC_KERNELS,
GF_OMP_TARGET_KIND_OACC_UPDATE,
GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA,
GF_OMP_TARGET_KIND_OACC_DATA.
(pass_expand_omp::execute, execute_lower_omp)
(pass_diagnose_omp_blocks::gate): Consider flag_openacc next to
flag_openmp.
(offload_symbol_decl): New variable.
(oacc_get_reduction_array_id, oacc_max_threads)
(get_offload_symbol_decl, get_base_type, lookup_oacc_reduction)
(maybe_lookup_oacc_reduction, enclosing_target_ctx)
(oacc_loop_or_target_p, oacc_lower_reduction_var_helper)
(oacc_gimple_assign, oacc_initialize_reduction_data)
(oacc_finalize_reduction_data, oacc_process_reduction_data): New
functions.
(is_targetreg_ctx): Remove function.
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE__CACHE_,
OMP_CLAUSE_DEVICE_RESIDENT, OMP_CLAUSE_USE_DEVICE,
OMP_CLAUSE_GANG, OMP_CLAUSE_ASYNC, OMP_CLAUSE_WAIT,
OMP_CLAUSE_AUTO, OMP_CLAUSE_SEQ, OMP_CLAUSE_INDEPENDENT,
OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_NUM_GANGS,
OMP_CLAUSE_NUM_WORKERS, OMP_CLAUSE_VECTOR_LENGTH.
* tree.c (omp_clause_code_name, walk_tree_1): Update accordingly.
* tree.h (OMP_CLAUSE_GANG_EXPR, OMP_CLAUSE_GANG_STATIC_EXPR)
(OMP_CLAUSE_ASYNC_EXPR, OMP_CLAUSE_WAIT_EXPR)
(OMP_CLAUSE_VECTOR_EXPR, OMP_CLAUSE_WORKER_EXPR)
(OMP_CLAUSE_NUM_GANGS_EXPR, OMP_CLAUSE_NUM_WORKERS_EXPR)
(OMP_CLAUSE_VECTOR_LENGTH_EXPR): New macros.
* tree-core.h: Update comments for OpenACC changes.
(enum omp_clause_map_kind): Remove.
(struct tree_omp_clause): Change type of map_kind member from enum
omp_clause_map_kind to unsigned char.
* tree-inline.c: Update comments for OpenACC changes.
* tree-nested.c: Likewise. Include "gomp-constants.h".
(convert_nonlocal_reference_stmt, convert_local_reference_stmt)
(convert_tramp_reference_stmt, convert_gimple_call): Update for
OpenACC changes. Use GOMP_MAP_* instead of OMP_CLAUSE_MAP_*. Use
OMP_CLAUSE_SET_MAP_KIND.
* tree-pretty-print.c: Include "gomp-constants.h".
(dump_omp_clause): Handle OMP_CLAUSE_DEVICE_RESIDENT,
OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE__CACHE_, OMP_CLAUSE_GANG,
OMP_CLAUSE_ASYNC, OMP_CLAUSE_AUTO, OMP_CLAUSE_SEQ,
OMP_CLAUSE_WAIT, OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR,
OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS,
OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_INDEPENDENT. Use GOMP_MAP_*
instead of OMP_CLAUSE_MAP_*.
(dump_generic_node): Handle OACC_PARALLEL, OACC_KERNELS,
OACC_DATA, OACC_HOST_DATA, OACC_DECLARE, OACC_UPDATE,
OACC_ENTER_DATA, OACC_EXIT_DATA, OACC_CACHE, OACC_LOOP.
* tree-streamer-in.c: Include "gomp-constants.h".
(unpack_ts_omp_clause_value_fields) Use GOMP_MAP_* instead of
OMP_CLAUSE_MAP_*. Use OMP_CLAUSE_SET_MAP_KIND.
* tree-streamer-out.c: Include "gomp-constants.h".
(pack_ts_omp_clause_value_fields): Use GOMP_MAP_* instead of
OMP_CLAUSE_MAP_*.
* tree.def (OACC_PARALLEL, OACC_KERNELS, OACC_DATA)
(OACC_HOST_DATA, OACC_LOOP, OACC_CACHE, OACC_DECLARE)
(OACC_ENTER_DATA, OACC_EXIT_DATA, OACC_UPDATE): New tree codes.
* tree.c (omp_clause_num_ops): Update accordingly.
* tree.h (OMP_BODY, OMP_CLAUSES, OMP_LOOP_CHECK, OMP_CLAUSE_SIZE):
Likewise.
(OACC_PARALLEL_BODY, OACC_PARALLEL_CLAUSES, OACC_KERNELS_BODY)
(OACC_KERNELS_CLAUSES, OACC_DATA_BODY, OACC_DATA_CLAUSES)
(OACC_HOST_DATA_BODY, OACC_HOST_DATA_CLAUSES, OACC_CACHE_CLAUSES)
(OACC_DECLARE_CLAUSES, OACC_ENTER_DATA_CLAUSES)
(OACC_EXIT_DATA_CLAUSES, OACC_UPDATE_CLAUSES)
(OACC_KERNELS_COMBINED, OACC_PARALLEL_COMBINED): New macros.
* tree.h (OMP_CLAUSE_MAP_KIND): Cast it to enum gomp_map_kind.
(OMP_CLAUSE_SET_MAP_KIND): New macro.
* varpool.c (varpool_node::get_create): Consider flag_openacc next
to flag_openmp.
* config/i386/intelmic-offload.h: New file.
* config/nvptx/offload.h: Likewise.
2015-01-15 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
* explow.h: Remove duplicate contents.

View File

@ -1,3 +1,8 @@
2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
* gcc-interface/utils.c (DEF_FUNCTION_TYPE_VAR_8)
(DEF_FUNCTION_TYPE_VAR_12): New macros.
2015-01-09 Michael Collison <michael.collison@linaro.org>
* gcc-interface/cuintp.c: Include hash-set.h, machmode.h,

View File

@ -5339,6 +5339,12 @@ enum c_builtin_type
#define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
#define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
NAME,
#define DEF_FUNCTION_TYPE_VAR_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) \
NAME,
#define DEF_FUNCTION_TYPE_VAR_12(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, ARG12) \
NAME,
#define DEF_POINTER_TYPE(NAME, TYPE) NAME,
#include "builtin-types.def"
#undef DEF_PRIMITIVE_TYPE
@ -5357,6 +5363,8 @@ enum c_builtin_type
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_FUNCTION_TYPE_VAR_4
#undef DEF_FUNCTION_TYPE_VAR_5
#undef DEF_FUNCTION_TYPE_VAR_8
#undef DEF_FUNCTION_TYPE_VAR_12
#undef DEF_POINTER_TYPE
BT_LAST
};
@ -5462,6 +5470,14 @@ install_builtin_function_types (void)
def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
#define DEF_FUNCTION_TYPE_VAR_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) \
def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
ARG7, ARG8);
#define DEF_FUNCTION_TYPE_VAR_12(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, ARG12) \
def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
ARG7, ARG8, ARG9, ARG10, ARG11, ARG12);
#define DEF_POINTER_TYPE(ENUM, TYPE) \
builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
@ -5483,6 +5499,8 @@ install_builtin_function_types (void)
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_FUNCTION_TYPE_VAR_4
#undef DEF_FUNCTION_TYPE_VAR_5
#undef DEF_FUNCTION_TYPE_VAR_8
#undef DEF_FUNCTION_TYPE_VAR_12
#undef DEF_POINTER_TYPE
builtin_types[(int) BT_LAST] = NULL_TREE;
}

View File

@ -568,6 +568,8 @@ DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_INT_CONST_STRING_VAR,
BT_INT, BT_INT, BT_CONST_STRING)
DEF_FUNCTION_TYPE_VAR_2 (BT_FN_PTR_CONST_PTR_SIZE_VAR, BT_PTR,
BT_CONST_PTR, BT_SIZE)
DEF_FUNCTION_TYPE_VAR_2 (BT_FN_VOID_INT_INT_VAR, BT_VOID,
BT_INT, BT_INT)
DEF_FUNCTION_TYPE_VAR_3 (BT_FN_INT_STRING_SIZE_CONST_STRING_VAR,
BT_INT, BT_STRING, BT_SIZE, BT_CONST_STRING)
@ -586,6 +588,15 @@ DEF_FUNCTION_TYPE_VAR_5 (BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR,
DEF_FUNCTION_TYPE_VAR_5 (BT_FN_INT_INT_INT_INT_INT_INT_VAR,
BT_INT, BT_INT, BT_INT, BT_INT, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_VAR_8 (BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR_INT_INT_VAR,
BT_VOID, BT_INT, BT_PTR, BT_SIZE, BT_PTR, BT_PTR,
BT_PTR, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_VAR_12 (BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR_INT_INT_INT_INT_INT_VAR,
BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_PTR, BT_SIZE,
BT_PTR, BT_PTR, BT_PTR, BT_INT, BT_INT, BT_INT,
BT_INT, BT_INT)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_VAR, BT_FN_VOID_VAR)
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE,
BT_PTR, BT_PTR_FN_VOID_VAR, BT_PTR, BT_SIZE)

View File

@ -84,6 +84,7 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "tree-chkp.h"
#include "rtl-chkp.h"
#include "gomp-constants.h"
static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
@ -5903,6 +5904,47 @@ expand_stack_save (void)
return ret;
}
/* Expand OpenACC acc_on_device.
This has to happen late (that is, not in early folding; expand_builtin_*,
rather than fold_builtin_*), as we have to act differently for host and
acceleration device (ACCEL_COMPILER conditional). */
static rtx
expand_builtin_acc_on_device (tree exp, rtx target)
{
if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
return NULL_RTX;
tree arg = CALL_EXPR_ARG (exp, 0);
/* Return (arg == v1 || arg == v2) ? 1 : 0. */
machine_mode v_mode = TYPE_MODE (TREE_TYPE (arg));
rtx v = expand_normal (arg), v1, v2;
#ifdef ACCEL_COMPILER
v1 = GEN_INT (GOMP_DEVICE_NOT_HOST);
v2 = GEN_INT (ACCEL_COMPILER_acc_device);
#else
v1 = GEN_INT (GOMP_DEVICE_NONE);
v2 = GEN_INT (GOMP_DEVICE_HOST);
#endif
machine_mode target_mode = TYPE_MODE (integer_type_node);
if (!REG_P (target) || GET_MODE (target) != target_mode)
target = gen_reg_rtx (target_mode);
emit_move_insn (target, const1_rtx);
rtx_code_label *done_label = gen_label_rtx ();
do_compare_rtx_and_jump (v, v1, EQ, false, v_mode, NULL_RTX,
NULL_RTX, done_label, PROB_EVEN);
do_compare_rtx_and_jump (v, v2, EQ, false, v_mode, NULL_RTX,
NULL_RTX, done_label, PROB_EVEN);
emit_move_insn (target, const0_rtx);
emit_label (done_label);
return target;
}
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
(and in mode MODE if that's convenient).
@ -7041,6 +7083,12 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
error ("Your target platform does not support -fcheck-pointer-bounds");
break;
case BUILT_IN_ACC_ON_DEVICE:
target = expand_builtin_acc_on_device (exp, target);
if (target)
return target;
break;
default: /* just do library call, if unknown builtin */
break;
}
@ -12478,6 +12526,7 @@ is_inexpensive_builtin (tree decl)
case BUILT_IN_LABS:
case BUILT_IN_LLABS:
case BUILT_IN_PREFETCH:
case BUILT_IN_ACC_ON_DEVICE:
return true;
default:

View File

@ -146,10 +146,20 @@ along with GCC; see the file COPYING3. If not see
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_LAST, BT_LAST, false, false, \
false, ATTR_LAST, false, false)
/* Builtin used by the implementation of GNU OpenMP. None of these are
actually implemented in the compiler; they're all in libgomp. */
/* Builtin used by the implementation of OpenACC and OpenMP. Few of these are
actually implemented in the compiler; most are in libgomp. */
/* These builtins also need to be enabled in offloading compilers invoked from
mkoffload; for that purpose, we're checking the -foffload-abi flag here. */
#undef DEF_GOACC_BUILTIN
#define DEF_GOACC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
false, true, true, ATTRS, false, \
(flag_openacc \
|| flag_offload_abi != OFFLOAD_ABI_UNSET))
#undef DEF_GOACC_BUILTIN_COMPILER
#define DEF_GOACC_BUILTIN_COMPILER(ENUM, NAME, TYPE, ATTRS) \
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
flag_openacc, true, true, ATTRS, false, true)
#undef DEF_GOMP_BUILTIN
#define DEF_GOMP_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
@ -897,7 +907,7 @@ DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
/* Synchronization Primitives. */
#include "sync-builtins.def"
/* OpenMP builtins. */
/* Offloading and Multi Processing builtins. */
#include "omp-builtins.def"
/* Cilk keywords builtins. */

View File

@ -1,3 +1,41 @@
2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
Bernd Schmidt <bernds@codesourcery.com>
James Norris <jnorris@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
Ilmir Usmanov <i.usmanov@samsung.com>
Jakub Jelinek <jakub@redhat.com>
* c.opt (fopenacc): New option.
* c-cppbuiltin.c (c_cpp_builtins): Conditionally define _OPENACC.
* c-common.c (DEF_FUNCTION_TYPE_VAR_8, DEF_FUNCTION_TYPE_VAR_12):
New macros.
* c-common.h (c_finish_oacc_wait): New prototype.
* c-omp.c: Include "omp-low.h" and "gomp-constants.h".
(c_finish_oacc_wait): New function.
* c-pragma.c (oacc_pragmas): New variable.
(c_pp_lookup_pragma, init_pragma): Handle it.
* c-pragma.h (enum pragma_kind): Add PRAGMA_OACC_CACHE,
PRAGMA_OACC_DATA, PRAGMA_OACC_ENTER_DATA, PRAGMA_OACC_EXIT_DATA,
PRAGMA_OACC_KERNELS, PRAGMA_OACC_LOOP, PRAGMA_OACC_PARALLEL,
PRAGMA_OACC_UPDATE, PRAGMA_OACC_WAIT.
(enum pragma_omp_clause): Add PRAGMA_OACC_CLAUSE_ASYNC,
PRAGMA_OACC_CLAUSE_AUTO, PRAGMA_OACC_CLAUSE_COLLAPSE,
PRAGMA_OACC_CLAUSE_COPY, PRAGMA_OACC_CLAUSE_COPYIN,
PRAGMA_OACC_CLAUSE_COPYOUT, PRAGMA_OACC_CLAUSE_CREATE,
PRAGMA_OACC_CLAUSE_DELETE, PRAGMA_OACC_CLAUSE_DEVICE,
PRAGMA_OACC_CLAUSE_DEVICEPTR, PRAGMA_OACC_CLAUSE_FIRSTPRIVATE,
PRAGMA_OACC_CLAUSE_GANG, PRAGMA_OACC_CLAUSE_HOST,
PRAGMA_OACC_CLAUSE_IF, PRAGMA_OACC_CLAUSE_NUM_GANGS,
PRAGMA_OACC_CLAUSE_NUM_WORKERS, PRAGMA_OACC_CLAUSE_PRESENT,
PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY,
PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN,
PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT,
PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE, PRAGMA_OACC_CLAUSE_PRIVATE,
PRAGMA_OACC_CLAUSE_REDUCTION, PRAGMA_OACC_CLAUSE_SELF,
PRAGMA_OACC_CLAUSE_SEQ, PRAGMA_OACC_CLAUSE_VECTOR,
PRAGMA_OACC_CLAUSE_VECTOR_LENGTH, PRAGMA_OACC_CLAUSE_WAIT,
PRAGMA_OACC_CLAUSE_WORKER.
2015-01-14 Marcos Diaz <marcos.diaz@tallertechnologies.com>
* c-cppbuiltin.c (c_cpp_builtins): New cpp define __SSP_EXPLICIT__

View File

@ -5234,6 +5234,11 @@ enum c_builtin_type
#define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
#define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
NAME,
#define DEF_FUNCTION_TYPE_VAR_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) NAME,
#define DEF_FUNCTION_TYPE_VAR_12(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, \
ARG12) NAME,
#define DEF_POINTER_TYPE(NAME, TYPE) NAME,
#include "builtin-types.def"
#undef DEF_PRIMITIVE_TYPE
@ -5252,6 +5257,8 @@ enum c_builtin_type
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_FUNCTION_TYPE_VAR_4
#undef DEF_FUNCTION_TYPE_VAR_5
#undef DEF_FUNCTION_TYPE_VAR_8
#undef DEF_FUNCTION_TYPE_VAR_12
#undef DEF_POINTER_TYPE
BT_LAST
};
@ -5344,6 +5351,14 @@ c_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node)
def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
#define DEF_FUNCTION_TYPE_VAR_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) \
def_fn_type (ENUM, RETURN, 1, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
ARG7, ARG8);
#define DEF_FUNCTION_TYPE_VAR_12(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, ARG12) \
def_fn_type (ENUM, RETURN, 1, 12, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
ARG7, ARG8, ARG9, ARG10, ARG11, ARG12);
#define DEF_POINTER_TYPE(ENUM, TYPE) \
builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
@ -5365,6 +5380,8 @@ c_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node)
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_FUNCTION_TYPE_VAR_4
#undef DEF_FUNCTION_TYPE_VAR_5
#undef DEF_FUNCTION_TYPE_VAR_8
#undef DEF_FUNCTION_TYPE_VAR_12
#undef DEF_POINTER_TYPE
builtin_types[(int) BT_LAST] = NULL_TREE;

View File

@ -1248,6 +1248,7 @@ extern void c_finish_omp_taskwait (location_t);
extern void c_finish_omp_taskyield (location_t);
extern tree c_finish_omp_for (location_t, enum tree_code, tree, tree, tree,
tree, tree, tree);
extern tree c_finish_oacc_wait (location_t, tree, tree);
extern void c_omp_split_clauses (location_t, enum tree_code, omp_clause_mask,
tree, tree *);
extern tree c_omp_declare_simd_clauses_to_numbers (tree, tree);

View File

@ -1221,6 +1221,9 @@ c_cpp_builtins (cpp_reader *pfile)
else if (flag_stack_protect == 1)
cpp_define (pfile, "__SSP__=1");
if (flag_openacc)
cpp_define (pfile, "_OPENACC=201306");
if (flag_openmp)
cpp_define (pfile, "_OPENMP=201307");

View File

@ -1,4 +1,4 @@
/* This file contains routines to construct GNU OpenMP constructs,
/* This file contains routines to construct OpenACC and OpenMP constructs,
called from parsing in the C and C++ front ends.
Copyright (C) 2005-2015 Free Software Foundation, Inc.
@ -39,8 +39,48 @@ along with GCC; see the file COPYING3. If not see
#include "c-pragma.h"
#include "gimple-expr.h"
#include "langhooks.h"
#include "omp-low.h"
#include "gomp-constants.h"
/* Complete a #pragma oacc wait construct. LOC is the location of
the #pragma. */
tree
c_finish_oacc_wait (location_t loc, tree parms, tree clauses)
{
const int nparms = list_length (parms);
tree stmt, t;
vec<tree, va_gc> *args;
vec_alloc (args, nparms + 2);
stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
if (find_omp_clause (clauses, OMP_CLAUSE_ASYNC))
t = OMP_CLAUSE_ASYNC_EXPR (clauses);
else
t = build_int_cst (integer_type_node, GOMP_ASYNC_SYNC);
args->quick_push (t);
args->quick_push (build_int_cst (integer_type_node, nparms));
for (t = parms; t; t = TREE_CHAIN (t))
{
if (TREE_CODE (OMP_CLAUSE_WAIT_EXPR (t)) == INTEGER_CST)
args->quick_push (build_int_cst (integer_type_node,
TREE_INT_CST_LOW (OMP_CLAUSE_WAIT_EXPR (t))));
else
args->quick_push (OMP_CLAUSE_WAIT_EXPR (t));
}
stmt = build_call_expr_loc_vec (loc, stmt, args);
add_stmt (stmt);
vec_free (args);
return stmt;
}
/* Complete a #pragma omp master construct. STMT is the structured-block
that follows the pragma. LOC is the l*/
@ -303,7 +343,7 @@ c_finish_omp_flush (location_t loc)
}
/* Check and canonicalize #pragma omp for increment expression.
/* Check and canonicalize OMP_FOR increment expression.
Helper function for c_finish_omp_for. */
static tree
@ -391,7 +431,7 @@ c_omp_for_incr_canonicalize_ptr (location_t loc, tree decl, tree incr)
return incr;
}
/* Validate and emit code for the OpenMP directive #pragma omp for.
/* Validate and generate OMP_FOR.
DECLV is a vector of iteration variables, for each collapsed loop.
INITV, CONDV and INCRV are vectors containing initialization
expressions, controlling predicates and increment expressions.

View File

@ -1190,6 +1190,17 @@ typedef struct
static vec<pragma_ns_name> registered_pp_pragmas;
struct omp_pragma_def { const char *name; unsigned int id; };
static const struct omp_pragma_def oacc_pragmas[] = {
{ "cache", PRAGMA_OACC_CACHE },
{ "data", PRAGMA_OACC_DATA },
{ "enter", PRAGMA_OACC_ENTER_DATA },
{ "exit", PRAGMA_OACC_EXIT_DATA },
{ "kernels", PRAGMA_OACC_KERNELS },
{ "loop", PRAGMA_OACC_LOOP },
{ "parallel", PRAGMA_OACC_PARALLEL },
{ "update", PRAGMA_OACC_UPDATE },
{ "wait", PRAGMA_OACC_WAIT }
};
static const struct omp_pragma_def omp_pragmas[] = {
{ "atomic", PRAGMA_OMP_ATOMIC },
{ "barrier", PRAGMA_OMP_BARRIER },
@ -1222,11 +1233,20 @@ static const struct omp_pragma_def omp_pragmas_simd[] = {
void
c_pp_lookup_pragma (unsigned int id, const char **space, const char **name)
{
const int n_oacc_pragmas = sizeof (oacc_pragmas) / sizeof (*oacc_pragmas);
const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);
const int n_omp_pragmas_simd = sizeof (omp_pragmas_simd)
/ sizeof (*omp_pragmas);
int i;
for (i = 0; i < n_oacc_pragmas; ++i)
if (oacc_pragmas[i].id == id)
{
*space = "acc";
*name = oacc_pragmas[i].name;
return;
}
for (i = 0; i < n_omp_pragmas; ++i)
if (omp_pragmas[i].id == id)
{
@ -1393,6 +1413,17 @@ c_invoke_pragma_handler (unsigned int id)
void
init_pragma (void)
{
if (flag_openacc)
{
const int n_oacc_pragmas
= sizeof (oacc_pragmas) / sizeof (*oacc_pragmas);
int i;
for (i = 0; i < n_oacc_pragmas; ++i)
cpp_register_deferred_pragma (parse_in, "acc", oacc_pragmas[i].name,
oacc_pragmas[i].id, true, true);
}
if (flag_openmp)
{
const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);

View File

@ -27,6 +27,15 @@ along with GCC; see the file COPYING3. If not see
typedef enum pragma_kind {
PRAGMA_NONE = 0,
PRAGMA_OACC_CACHE,
PRAGMA_OACC_DATA,
PRAGMA_OACC_ENTER_DATA,
PRAGMA_OACC_EXIT_DATA,
PRAGMA_OACC_KERNELS,
PRAGMA_OACC_LOOP,
PRAGMA_OACC_PARALLEL,
PRAGMA_OACC_UPDATE,
PRAGMA_OACC_WAIT,
PRAGMA_OMP_ATOMIC,
PRAGMA_OMP_BARRIER,
PRAGMA_OMP_CANCEL,
@ -65,7 +74,7 @@ typedef enum pragma_kind {
} pragma_kind;
/* All clauses defined by OpenMP 2.5, 3.0, 3.1 and 4.0.
/* All clauses defined by OpenACC 2.0, and OpenMP 2.5, 3.0, 3.1, and 4.0.
Used internally by both C and C++ parsers. */
typedef enum pragma_omp_clause {
PRAGMA_OMP_CLAUSE_NONE = 0,
@ -118,7 +127,38 @@ typedef enum pragma_omp_clause {
PRAGMA_CILK_CLAUSE_FIRSTPRIVATE = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
PRAGMA_CILK_CLAUSE_LASTPRIVATE = PRAGMA_OMP_CLAUSE_LASTPRIVATE,
PRAGMA_CILK_CLAUSE_REDUCTION = PRAGMA_OMP_CLAUSE_REDUCTION,
PRAGMA_CILK_CLAUSE_UNIFORM = PRAGMA_OMP_CLAUSE_UNIFORM
PRAGMA_CILK_CLAUSE_UNIFORM = PRAGMA_OMP_CLAUSE_UNIFORM,
/* Clauses for OpenACC. */
PRAGMA_OACC_CLAUSE_ASYNC = PRAGMA_CILK_CLAUSE_VECTORLENGTH + 1,
PRAGMA_OACC_CLAUSE_AUTO,
PRAGMA_OACC_CLAUSE_COPY,
PRAGMA_OACC_CLAUSE_COPYOUT,
PRAGMA_OACC_CLAUSE_CREATE,
PRAGMA_OACC_CLAUSE_DELETE,
PRAGMA_OACC_CLAUSE_DEVICEPTR,
PRAGMA_OACC_CLAUSE_GANG,
PRAGMA_OACC_CLAUSE_HOST,
PRAGMA_OACC_CLAUSE_NUM_GANGS,
PRAGMA_OACC_CLAUSE_NUM_WORKERS,
PRAGMA_OACC_CLAUSE_PRESENT,
PRAGMA_OACC_CLAUSE_PRESENT_OR_COPY,
PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYIN,
PRAGMA_OACC_CLAUSE_PRESENT_OR_COPYOUT,
PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE,
PRAGMA_OACC_CLAUSE_SELF,
PRAGMA_OACC_CLAUSE_SEQ,
PRAGMA_OACC_CLAUSE_VECTOR,
PRAGMA_OACC_CLAUSE_VECTOR_LENGTH,
PRAGMA_OACC_CLAUSE_WAIT,
PRAGMA_OACC_CLAUSE_WORKER,
PRAGMA_OACC_CLAUSE_COLLAPSE = PRAGMA_OMP_CLAUSE_COLLAPSE,
PRAGMA_OACC_CLAUSE_COPYIN = PRAGMA_OMP_CLAUSE_COPYIN,
PRAGMA_OACC_CLAUSE_DEVICE = PRAGMA_OMP_CLAUSE_DEVICE,
PRAGMA_OACC_CLAUSE_FIRSTPRIVATE = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
PRAGMA_OACC_CLAUSE_IF = PRAGMA_OMP_CLAUSE_IF,
PRAGMA_OACC_CLAUSE_PRIVATE = PRAGMA_OMP_CLAUSE_PRIVATE,
PRAGMA_OACC_CLAUSE_REDUCTION = PRAGMA_OMP_CLAUSE_REDUCTION
} pragma_omp_clause;
extern struct cpp_reader* parse_in;

View File

@ -1283,6 +1283,10 @@ fobjc-std=objc1
ObjC ObjC++ Var(flag_objc1_only)
Conform to the Objective-C 1.0 language as implemented in GCC 4.0
fopenacc
C ObjC C++ ObjC++ Var(flag_openacc)
Enable OpenACC
fopenmp
C ObjC C++ ObjC++ Var(flag_openmp)
Enable OpenMP (implies -frecursive in Fortran)

View File

@ -1,3 +1,54 @@
2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
Bernd Schmidt <bernds@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
James Norris <jnorris@codesourcery.com>
Jakub Jelinek <jakub@redhat.com>
Ilmir Usmanov <i.usmanov@samsung.com>
* c-parser.c: Include "gomp-constants.h".
(c_parser_omp_clause_map): Use enum gomp_map_kind instead of enum
omp_clause_map_kind. Use GOMP_MAP_* instead of OMP_CLAUSE_MAP_*.
Use OMP_CLAUSE_SET_MAP_KIND.
(c_parser_pragma): Handle PRAGMA_OACC_ENTER_DATA,
PRAGMA_OACC_EXIT_DATA, PRAGMA_OACC_UPDATE.
(c_parser_omp_construct): Handle PRAGMA_OACC_CACHE,
PRAGMA_OACC_DATA, PRAGMA_OACC_KERNELS, PRAGMA_OACC_LOOP,
PRAGMA_OACC_PARALLEL, PRAGMA_OACC_WAIT.
(c_parser_omp_clause_name): Handle "auto", "async", "copy",
"copyout", "create", "delete", "deviceptr", "gang", "host",
"num_gangs", "num_workers", "present", "present_or_copy", "pcopy",
"present_or_copyin", "pcopyin", "present_or_copyout", "pcopyout",
"present_or_create", "pcreate", "seq", "self", "vector",
"vector_length", "wait", "worker".
(OACC_DATA_CLAUSE_MASK, OACC_KERNELS_CLAUSE_MASK)
(OACC_ENTER_DATA_CLAUSE_MASK, OACC_EXIT_DATA_CLAUSE_MASK)
(OACC_LOOP_CLAUSE_MASK, OACC_PARALLEL_CLAUSE_MASK)
(OACC_UPDATE_CLAUSE_MASK, OACC_WAIT_CLAUSE_MASK): New macros.
(c_parser_omp_variable_list): Handle OMP_CLAUSE__CACHE_.
(c_parser_oacc_wait_list, c_parser_oacc_data_clause)
(c_parser_oacc_data_clause_deviceptr)
(c_parser_omp_clause_num_gangs, c_parser_omp_clause_num_workers)
(c_parser_oacc_clause_async, c_parser_oacc_clause_wait)
(c_parser_omp_clause_vector_length, c_parser_oacc_all_clauses)
(c_parser_oacc_cache, c_parser_oacc_data, c_parser_oacc_kernels)
(c_parser_oacc_enter_exit_data, c_parser_oacc_loop)
(c_parser_oacc_parallel, c_parser_oacc_update)
(c_parser_oacc_wait): New functions.
* c-tree.h (c_finish_oacc_parallel, c_finish_oacc_kernels)
(c_finish_oacc_data): New prototypes.
* c-typeck.c: Include "gomp-constants.h".
(handle_omp_array_sections): Handle GOMP_MAP_FORCE_DEVICEPTR. Use
GOMP_MAP_* instead of OMP_CLAUSE_MAP_*. Use
OMP_CLAUSE_SET_MAP_KIND.
(c_finish_oacc_parallel, c_finish_oacc_kernels)
(c_finish_oacc_data): New functions.
(c_finish_omp_clauses): Handle OMP_CLAUSE__CACHE_,
OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS,
OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_ASYNC, OMP_CLAUSE_WAIT,
OMP_CLAUSE_AUTO, OMP_CLAUSE_SEQ, OMP_CLAUSE_GANG,
OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, and OMP_CLAUSE_MAP's
GOMP_MAP_FORCE_DEVICEPTR.
2015-01-09 Michael Collison <michael.collison@linaro.org>
* c-array-notation.c: Include hash-set.h, machmode.h,

File diff suppressed because it is too large Load Diff

View File

@ -640,6 +640,9 @@ extern tree c_finish_bc_stmt (location_t, tree *, bool);
extern tree c_finish_goto_label (location_t, tree);
extern tree c_finish_goto_ptr (location_t, tree);
extern tree c_expr_to_decl (tree, bool *, bool *);
extern tree c_finish_oacc_parallel (location_t, tree, tree);
extern tree c_finish_oacc_kernels (location_t, tree, tree);
extern tree c_finish_oacc_data (location_t, tree, tree);
extern tree c_begin_omp_parallel (void);
extern tree c_finish_omp_parallel (location_t, tree, tree);
extern tree c_begin_omp_task (void);

View File

@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-family/c-ubsan.h"
#include "cilk.h"
#include "wide-int.h"
#include "gomp-constants.h"
/* Possible cases of implicit bad conversions. Used to select
diagnostic messages in convert_for_assignment. */
@ -11352,6 +11353,63 @@ c_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED, bool *se)
return expr;
}
/* Generate OACC_PARALLEL, with CLAUSES and BLOCK as its compound
statement. LOC is the location of the OACC_PARALLEL. */
tree
c_finish_oacc_parallel (location_t loc, tree clauses, tree block)
{
tree stmt;
block = c_end_compound_stmt (loc, block, true);
stmt = make_node (OACC_PARALLEL);
TREE_TYPE (stmt) = void_type_node;
OACC_PARALLEL_CLAUSES (stmt) = clauses;
OACC_PARALLEL_BODY (stmt) = block;
SET_EXPR_LOCATION (stmt, loc);
return add_stmt (stmt);
}
/* Generate OACC_KERNELS, with CLAUSES and BLOCK as its compound
statement. LOC is the location of the OACC_KERNELS. */
tree
c_finish_oacc_kernels (location_t loc, tree clauses, tree block)
{
tree stmt;
block = c_end_compound_stmt (loc, block, true);
stmt = make_node (OACC_KERNELS);
TREE_TYPE (stmt) = void_type_node;
OACC_KERNELS_CLAUSES (stmt) = clauses;
OACC_KERNELS_BODY (stmt) = block;
SET_EXPR_LOCATION (stmt, loc);
return add_stmt (stmt);
}
/* Generate OACC_DATA, with CLAUSES and BLOCK as its compound
statement. LOC is the location of the OACC_DATA. */
tree
c_finish_oacc_data (location_t loc, tree clauses, tree block)
{
tree stmt;
block = c_end_compound_stmt (loc, block, true);
stmt = make_node (OACC_DATA);
TREE_TYPE (stmt) = void_type_node;
OACC_DATA_CLAUSES (stmt) = clauses;
OACC_DATA_BODY (stmt) = block;
SET_EXPR_LOCATION (stmt, loc);
return add_stmt (stmt);
}
/* Like c_begin_compound_stmt, except force the retention of the BLOCK. */
tree
@ -11883,8 +11941,9 @@ handle_omp_array_sections (tree c)
OMP_CLAUSE_SIZE (c) = size;
if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
return false;
gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (c2) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_POINTER);
if (!c_mark_addressable (t))
return false;
OMP_CLAUSE_DECL (c2) = t;
@ -11946,7 +12005,7 @@ c_find_omp_placeholder_r (tree *tp, int *, void *data)
return NULL_TREE;
}
/* For all elements of CLAUSES, validate them vs OpenMP constraints.
/* For all elements of CLAUSES, validate them against their constraints.
Remove any elements from the list that are invalid. */
tree
@ -12268,6 +12327,7 @@ c_finish_omp_clauses (tree clauses)
case OMP_CLAUSE_MAP:
case OMP_CLAUSE_TO:
case OMP_CLAUSE_FROM:
case OMP_CLAUSE__CACHE_:
t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) == TREE_LIST)
{
@ -12306,7 +12366,9 @@ c_finish_omp_clauses (tree clauses)
else if (!c_mark_addressable (t))
remove = true;
else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
&& OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER)
&& (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
|| (OMP_CLAUSE_MAP_KIND (c)
== GOMP_MAP_FORCE_DEVICEPTR)))
&& !lang_hooks.types.omp_mappable_type (TREE_TYPE (t)))
{
error_at (OMP_CLAUSE_LOCATION (c),
@ -12375,6 +12437,16 @@ c_finish_omp_clauses (tree clauses)
case OMP_CLAUSE_TASKGROUP:
case OMP_CLAUSE_PROC_BIND:
case OMP_CLAUSE__CILK_FOR_COUNT_:
case OMP_CLAUSE_NUM_GANGS:
case OMP_CLAUSE_NUM_WORKERS:
case OMP_CLAUSE_VECTOR_LENGTH:
case OMP_CLAUSE_ASYNC:
case OMP_CLAUSE_WAIT:
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_SEQ:
case OMP_CLAUSE_GANG:
case OMP_CLAUSE_WORKER:
case OMP_CLAUSE_VECTOR:
pc = &OMP_CLAUSE_CHAIN (c);
continue;

View File

@ -512,7 +512,7 @@ cgraph_node::create (tree decl)
node->decl = decl;
if (flag_openmp
if ((flag_openacc || flag_openmp)
&& lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
{
node->offloadable = 1;

View File

@ -2233,6 +2233,7 @@ nios2-*-*)
nvptx-*)
tm_file="${tm_file} newlib-stdint.h"
tmake_file="nvptx/t-nvptx"
tm_file="${tm_file} nvptx/offload.h"
;;
pdp11-*-*)
tm_file="${tm_file} newlib-stdint.h"
@ -2965,6 +2966,7 @@ esac
case ${target} in
*-intelmic-* | *-intelmicemul-*)
tmake_file="${tmake_file} i386/t-intelmic"
tm_file="${tm_file} i386/intelmic-offload.h"
;;
esac

View File

@ -173,7 +173,7 @@ along with GCC; see the file COPYING3. If not see
%(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
%{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
%{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
%{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
%{fopenacc|fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
%(mflib)\
%{fprofile-arcs|fprofile-generate|coverage:-lgcov}\
%{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\

View File

@ -177,7 +177,7 @@ extern GTY(()) int darwin_ms_struct;
%{o*}%{!o:-o a.out} \
%{!nostdlib:%{!nostartfiles:%S}} \
%{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} \
%{fopenmp|ftree-parallelize-loops=*: \
%{fopenacc|fopenmp|ftree-parallelize-loops=*: \
%{static|static-libgcc|static-libstdc++|static-libgfortran: libgomp.a%s; : -lgomp } } \
%{fgnu-tm: \
%{static|static-libgcc|static-libstdc++|static-libgfortran: libitm.a%s; : -litm } } \

View File

@ -22,13 +22,13 @@
#include "config.h"
#include <libgen.h>
#include "libgomp-plugin.h"
#include "system.h"
#include "coretypes.h"
#include "obstack.h"
#include "intl.h"
#include "diagnostic.h"
#include "collect-utils.h"
#include <libgomp_target.h>
const char tool_name[] = "intelmic mkoffload";

View File

@ -0,0 +1,35 @@
/* Support for Intel MIC offloading.
Copyright (C) 2014-2015 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef INTELMIC_OFFLOAD_H
#define INTELMIC_OFFLOAD_H
/* Support for OpenACC acc_on_device. */
#include "gomp-constants.h"
#define ACCEL_COMPILER_acc_device GOMP_DEVICE_INTEL_MIC
#endif

View File

@ -199,7 +199,7 @@ do { \
/* mingw32 uses the -mthreads option to enable thread support. */
#undef GOMP_SELF_SPECS
#define GOMP_SELF_SPECS "%{fopenmp|ftree-parallelize-loops=*: " \
#define GOMP_SELF_SPECS "%{fopenacc|fopenmp|ftree-parallelize-loops=*: " \
"-mthreads -pthread}"
#undef GTM_SELF_SPECS
#define GTM_SELF_SPECS "%{fgnu-tm:-mthreads -pthread}"

View File

@ -92,7 +92,7 @@ do { \
#undef LIB_SPEC
#define LIB_SPEC \
"%{!shared: \
%{mt|pthread:%{fopenmp|ftree-parallelize-loops=*:-lrt} -lpthread} \
%{mt|pthread:%{fopenacc|fopenmp|ftree-parallelize-loops=*:-lrt} -lpthread} \
%{p:%{!mlp64:-L/usr/lib/hpux32/libp} \
%{mlp64:-L/usr/lib/hpux64/libp} -lprof} \
%{pg:%{!mlp64:-L/usr/lib/hpux32/libp} \

View File

@ -0,0 +1,35 @@
/* Support for Nvidia PTX offloading.
Copyright (C) 2014-2015 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_NVPTX_OFFLOAD_H
#define GCC_NVPTX_OFFLOAD_H
/* Support for OpenACC acc_on_device. */
#include "gomp-constants.h"
#define ACCEL_COMPILER_acc_device GOMP_TARGET_NVIDIA_PTX
#endif

View File

@ -122,8 +122,8 @@ along with GCC; see the file COPYING3. If not see
#undef LIB_SPEC
#define LIB_SPEC \
"%{!shared:\
%{fopenmp|ftree-parallelize-loops=*:%{static:-a archive_shared} -lrt\
%{static:-a archive}}\
%{fopenacc|fopenmp|ftree-parallelize-loops=*:\
%{static:-a archive_shared} -lrt %{static:-a archive}}\
%{mt|pthread:-lpthread} -lc\
%{static:%{!nolibdld:-a archive_shared -ldld -a archive -lc}\
%{!mt:%{!pthread:-a shared -lc -a archive}}}}\

View File

@ -58,22 +58,22 @@ along with GCC; see the file COPYING3. If not see
#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GNU_LD)
#define LIB_SPEC \
"%{!shared:\
%{!p:%{!pg:%{fopenmp|ftree-parallelize-loops=*:%{static:-a shared} -lrt\
%{static:-a archive}}\
%{!p:%{!pg:%{fopenacc|fopenmp|ftree-parallelize-loops=*:\
%{static:-a shared} -lrt %{static:-a archive}}\
%{mt|pthread:-lpthread} -lc\
%{static:%{!nolibdld:-a shared -ldld -a archive -lc}\
%{!mt:%{!pthread:-a shared -lc -a archive}}}}}\
%{p:%{!pg:%{static:%{!mhp-ld:-a shared}%{mhp-ld:-a archive_shared}}\
-lprof %{static:-a archive}\
%{fopenmp|ftree-parallelize-loops=*:%{static:-a shared} -lrt\
%{static:-a archive}}\
%{fopenacc|fopenmp|ftree-parallelize-loops=*:\
%{static:-a shared} -lrt %{static:-a archive}}\
%{mt|pthread:-lpthread} -lc\
%{static:%{!nolibdld:-a shared -ldld -a archive -lc}\
%{!mt:%{!pthread:-a shared -lc -a archive}}}}}\
%{pg:%{static:%{!mhp-ld:-a shared}%{mhp-ld:-a archive_shared}}\
-lgprof %{static:-a archive}\
%{fopenmp|ftree-parallelize-loops=*:%{static:-a shared} -lrt\
%{static:-a archive}}\
%{fopenacc|fopenmp|ftree-parallelize-loops=*:\
%{static:-a shared} -lrt %{static:-a archive}}\
%{mt|pthread:-lpthread} -lc\
%{static:%{!nolibdld:-a shared -ldld -a archive -lc}\
%{!mt:%{!pthread:-a shared -lc -a archive}}}}}\
@ -81,22 +81,22 @@ along with GCC; see the file COPYING3. If not see
#else
#define LIB_SPEC \
"%{!shared:\
%{!p:%{!pg:%{fopenmp|ftree-parallelize-loops=*:%{static:-a shared} -lrt\
%{static:-a archive}}\
%{!p:%{!pg:%{fopenacc|fopenmp|ftree-parallelize-loops=*:\
%{static:-a shared} -lrt %{static:-a archive}}\
%{mt|pthread:-lpthread} -lc\
%{static:%{!nolibdld:-a shared -ldld -a archive -lc}\
%{!mt:%{!pthread:-a shared -lc -a archive}}}}}\
%{p:%{!pg:%{static:%{mgnu-ld:-a shared}%{!mgnu-ld:-a archive_shared}}\
-lprof %{static:-a archive}\
%{fopenmp|ftree-parallelize-loops=*:%{static:-a shared} -lrt\
%{static:-a archive}}\
%{fopenacc|fopenmp|ftree-parallelize-loops=*:\
%{static:-a shared} -lrt %{static:-a archive}}\
%{mt|pthread:-lpthread} -lc\
%{static:%{!nolibdld:-a shared -ldld -a archive -lc}\
%{!mt:%{!pthread:-a shared -lc -a archive}}}}}\
%{pg:%{static:%{mgnu-ld:-a shared}%{!mgnu-ld:-a archive_shared}}\
-lgprof %{static:-a archive}\
%{fopenmp|ftree-parallelize-loops=*:%{static:-a shared} -lrt\
%{static:-a archive}}\
%{fopenacc|fopenmp|ftree-parallelize-loops=*:\
%{static:-a shared} -lrt %{static:-a archive}}\
%{mt|pthread:-lpthread} -lc\
%{static:%{!nolibdld:-a shared -ldld -a archive -lc}\
%{!mt:%{!pthread:-a shared -lc -a archive}}}}}\

View File

@ -1,3 +1,48 @@
2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
James Norris <jnorris@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
Ilmir Usmanov <i.usmanov@samsung.com>
Jakub Jelinek <jakub@redhat.com>
* parser.c: Include "gomp-constants.h".
(cp_parser_omp_clause_map): Use enum gomp_map_kind instead of enum
omp_clause_map_kind. Use GOMP_MAP_* instead of OMP_CLAUSE_MAP_*.
Use OMP_CLAUSE_SET_MAP_KIND.
(cp_parser_omp_construct, cp_parser_pragma): Handle
PRAGMA_OACC_CACHE, PRAGMA_OACC_DATA, PRAGMA_OACC_ENTER_DATA,
PRAGMA_OACC_EXIT_DATA, PRAGMA_OACC_KERNELS, PRAGMA_OACC_PARALLEL,
PRAGMA_OACC_LOOP, PRAGMA_OACC_UPDATE, PRAGMA_OACC_WAIT.
(cp_parser_omp_clause_name): Handle "async", "copy", "copyout",
"create", "delete", "deviceptr", "host", "num_gangs",
"num_workers", "present", "present_or_copy", "pcopy",
"present_or_copyin", "pcopyin", "present_or_copyout", "pcopyout",
"present_or_create", "pcreate", "vector_length", "wait".
(OACC_DATA_CLAUSE_MASK, OACC_ENTER_DATA_CLAUSE_MASK)
(OACC_EXIT_DATA_CLAUSE_MASK, OACC_KERNELS_CLAUSE_MASK)
(OACC_LOOP_CLAUSE_MASK, OACC_PARALLEL_CLAUSE_MASK)
(OACC_UPDATE_CLAUSE_MASK, OACC_WAIT_CLAUSE_MASK): New macros.
(cp_parser_omp_var_list_no_open): Handle OMP_CLAUSE__CACHE_.
(cp_parser_oacc_data_clause, cp_parser_oacc_data_clause_deviceptr)
(cp_parser_oacc_clause_vector_length, cp_parser_oacc_wait_list)
(cp_parser_oacc_clause_wait, cp_parser_omp_clause_num_gangs)
(cp_parser_omp_clause_num_workers, cp_parser_oacc_clause_async)
(cp_parser_oacc_all_clauses, cp_parser_oacc_cache)
(cp_parser_oacc_data, cp_parser_oacc_enter_exit_data)
(cp_parser_oacc_kernels, cp_parser_oacc_loop)
(cp_parser_oacc_parallel, cp_parser_oacc_update)
(cp_parser_oacc_wait): New functions.
* cp-tree.h (finish_oacc_data, finish_oacc_kernels)
(finish_oacc_parallel): New prototypes.
* semantics.c: Include "gomp-constants.h".
(handle_omp_array_sections): Handle GOMP_MAP_FORCE_DEVICEPTR. Use
GOMP_MAP_* instead of OMP_CLAUSE_MAP_*. Use
OMP_CLAUSE_SET_MAP_KIND.
(finish_omp_clauses): Handle OMP_CLAUSE_ASYNC,
OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_WAIT, OMP_CLAUSE__CACHE_.
Use GOMP_MAP_* instead of OMP_CLAUSE_MAP_*.
(finish_oacc_data, finish_oacc_kernels, finish_oacc_parallel): New
functions.
2015-01-14 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/58671

View File

@ -5990,6 +5990,9 @@ extern tree finish_omp_clauses (tree);
extern void finish_omp_threadprivate (tree);
extern tree begin_omp_structured_block (void);
extern tree finish_omp_structured_block (tree);
extern tree finish_oacc_data (tree, tree);
extern tree finish_oacc_kernels (tree, tree);
extern tree finish_oacc_parallel (tree, tree);
extern tree begin_omp_parallel (void);
extern tree finish_omp_parallel (tree, tree);
extern tree begin_omp_task (void);

File diff suppressed because it is too large Load Diff

View File

@ -66,6 +66,7 @@ along with GCC; see the file COPYING3. If not see
#include "omp-low.h"
#include "builtins.h"
#include "convert.h"
#include "gomp-constants.h"
/* There routines provide a modular interface to perform many parsing
operations. They may therefore be used during actual parsing, or
@ -4670,7 +4671,7 @@ handle_omp_array_sections (tree c)
return false;
tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (c2) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_POINTER);
if (!cxx_mark_addressable (t))
return false;
OMP_CLAUSE_DECL (c2) = t;
@ -4694,7 +4695,7 @@ handle_omp_array_sections (tree c)
{
tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (c3) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_POINTER);
OMP_CLAUSE_DECL (c3) = ptr;
OMP_CLAUSE_DECL (c2) = convert_from_reference (ptr);
OMP_CLAUSE_SIZE (c3) = size_zero_node;
@ -5571,6 +5572,44 @@ finish_omp_clauses (tree clauses)
}
break;
case OMP_CLAUSE_ASYNC:
t = OMP_CLAUSE_ASYNC_EXPR (c);
if (t == error_mark_node)
remove = true;
else if (!type_dependent_expression_p (t)
&& !INTEGRAL_TYPE_P (TREE_TYPE (t)))
{
error ("%<async%> expression must be integral");
remove = true;
}
else
{
t = mark_rvalue_use (t);
if (!processing_template_decl)
t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
OMP_CLAUSE_ASYNC_EXPR (c) = t;
}
break;
case OMP_CLAUSE_VECTOR_LENGTH:
t = OMP_CLAUSE_VECTOR_LENGTH_EXPR (c);
t = maybe_convert_cond (t);
if (t == error_mark_node)
remove = true;
else if (!processing_template_decl)
t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = t;
break;
case OMP_CLAUSE_WAIT:
t = OMP_CLAUSE_WAIT_EXPR (c);
if (t == error_mark_node)
remove = true;
else if (!processing_template_decl)
t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
OMP_CLAUSE_WAIT_EXPR (c) = t;
break;
case OMP_CLAUSE_THREAD_LIMIT:
t = OMP_CLAUSE_THREAD_LIMIT_EXPR (c);
if (t == error_mark_node)
@ -5721,6 +5760,7 @@ finish_omp_clauses (tree clauses)
case OMP_CLAUSE_MAP:
case OMP_CLAUSE_TO:
case OMP_CLAUSE_FROM:
case OMP_CLAUSE__CACHE_:
t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) == TREE_LIST)
{
@ -5749,7 +5789,7 @@ finish_omp_clauses (tree clauses)
if (processing_template_decl)
break;
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
&& OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER)
&& OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
break;
if (DECL_P (t))
error ("%qD is not a variable in %qs clause", t,
@ -5770,7 +5810,7 @@ finish_omp_clauses (tree clauses)
&& !cxx_mark_addressable (t))
remove = true;
else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
&& OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER)
&& OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
&& !type_dependent_expression_p (t)
&& !cp_omp_mappable_type ((TREE_CODE (TREE_TYPE (t))
== REFERENCE_TYPE)
@ -6088,6 +6128,60 @@ finish_omp_structured_block (tree block)
return do_poplevel (block);
}
/* Generate OACC_DATA, with CLAUSES and BLOCK as its compound
statement. LOC is the location of the OACC_DATA. */
tree
finish_oacc_data (tree clauses, tree block)
{
tree stmt;
block = finish_omp_structured_block (block);
stmt = make_node (OACC_DATA);
TREE_TYPE (stmt) = void_type_node;
OACC_DATA_CLAUSES (stmt) = clauses;
OACC_DATA_BODY (stmt) = block;
return add_stmt (stmt);
}
/* Generate OACC_KERNELS, with CLAUSES and BLOCK as its compound
statement. LOC is the location of the OACC_KERNELS. */
tree
finish_oacc_kernels (tree clauses, tree block)
{
tree stmt;
block = finish_omp_structured_block (block);
stmt = make_node (OACC_KERNELS);
TREE_TYPE (stmt) = void_type_node;
OACC_KERNELS_CLAUSES (stmt) = clauses;
OACC_KERNELS_BODY (stmt) = block;
return add_stmt (stmt);
}
/* Generate OACC_PARALLEL, with CLAUSES and BLOCK as its compound
statement. LOC is the location of the OACC_PARALLEL. */
tree
finish_oacc_parallel (tree clauses, tree block)
{
tree stmt;
block = finish_omp_structured_block (block);
stmt = make_node (OACC_PARALLEL);
TREE_TYPE (stmt) = void_type_node;
OACC_PARALLEL_CLAUSES (stmt) = clauses;
OACC_PARALLEL_BODY (stmt) = block;
return add_stmt (stmt);
}
/* Similarly, except force the retention of the BLOCK. */
tree

View File

@ -1819,6 +1819,7 @@ There are also several varieties of complex statements.
* Jumps::
* Cleanups::
* OpenMP::
* OpenACC::
@end menu
@node Basic Statements
@ -2093,8 +2094,8 @@ variables.
@item OMP_FOR
Represents @code{#pragma omp for [clause1 @dots{} clauseN]}. It
has 5 operands:
Represents @code{#pragma omp for [clause1 @dots{} clauseN]}. It has
six operands:
Operand @code{OMP_FOR_BODY} contains the loop body.
@ -2184,10 +2185,9 @@ building code (@code{omp-low.c}).
@item OMP_CONTINUE
Similarly, this instruction does not represent an OpenMP
directive, it is used by @code{OMP_FOR} and
directive, it is used by @code{OMP_FOR} (and similar codes) as well as
@code{OMP_SECTIONS} to mark the place where the code needs to
loop to the next iteration (in the case of @code{OMP_FOR}) or
the next section (in the case of @code{OMP_SECTIONS}).
loop to the next iteration, or the next section, respectively.
In some cases, @code{OMP_CONTINUE} is placed right before
@code{OMP_RETURN}. But if there are cleanups that need to
@ -2233,6 +2233,67 @@ compilation.
@end table
@node OpenACC
@subsection OpenACC
@tindex OACC_CACHE
@tindex OACC_DATA
@tindex OACC_DECLARE
@tindex OACC_ENTER_DATA
@tindex OACC_EXIT_DATA
@tindex OACC_HOST_DATA
@tindex OACC_KERNELS
@tindex OACC_LOOP
@tindex OACC_PARALLEL
@tindex OACC_UPDATE
All the statements starting with @code{OACC_} represent directives and
clauses used by the OpenACC API @w{@uref{http://www.openacc.org/}}.
@table @code
@item OACC_CACHE
Represents @code{#pragma acc cache (var @dots{})}.
@item OACC_DATA
Represents @code{#pragma acc data [clause1 @dots{} clauseN]}.
@item OACC_DECLARE
Represents @code{#pragma acc declare [clause1 @dots{} clauseN]}.
@item OACC_ENTER_DATA
Represents @code{#pragma acc enter data [clause1 @dots{} clauseN]}.
@item OACC_EXIT_DATA
Represents @code{#pragma acc exit data [clause1 @dots{} clauseN]}.
@item OACC_HOST_DATA
Represents @code{#pragma acc host_data [clause1 @dots{} clauseN]}.
@item OACC_KERNELS
Represents @code{#pragma acc kernels [clause1 @dots{} clauseN]}.
@item OACC_LOOP
Represents @code{#pragma acc loop [clause1 @dots{} clauseN]}.
See the description of the @code{OMP_FOR} code.
@item OACC_PARALLEL
Represents @code{#pragma acc parallel [clause1 @dots{} clauseN]}.
@item OACC_UPDATE
Represents @code{#pragma acc update [clause1 @dots{} clauseN]}.
@end table
@c ---------------------------------------------------------------------
@c Functions
@c ---------------------------------------------------------------------

View File

@ -1828,9 +1828,8 @@ Set @code{NAME} to be the name associated with @code{OMP} critical statement @co
tree clauses, tree index, tree initial, tree final, tree incr, @
gimple_seq pre_body, enum tree_code omp_for_cond)
Build a @code{GIMPLE_OMP_FOR} statement. @code{BODY} is sequence of statements
inside the for loop. @code{CLAUSES}, are any of the @code{OMP} loop
construct's clauses: private, firstprivate, lastprivate,
reductions, ordered, schedule, and nowait. @code{PRE_BODY} is the
inside the for loop. @code{CLAUSES}, are any of the loop
construct's clauses. @code{PRE_BODY} is the
sequence of statements that are loop invariant. @code{INDEX} is the
index variable. @code{INITIAL} is the initial value of @code{INDEX}. @code{FINAL} is
final value of @code{INDEX}. OMP_FOR_COND is the predicate used to

View File

@ -168,8 +168,8 @@ in the following sections.
@gccoptlist{-ansi -std=@var{standard} -fgnu89-inline @gol
-aux-info @var{filename} -fallow-parameterless-variadic-functions @gol
-fno-asm -fno-builtin -fno-builtin-@var{function} @gol
-fhosted -ffreestanding -fopenmp -fopenmp-simd -fms-extensions @gol
-fplan9-extensions -trigraphs -traditional -traditional-cpp @gol
-fhosted -ffreestanding -fopenacc -fopenmp -fopenmp-simd @gol
-fms-extensions -fplan9-extensions -trigraphs -traditional -traditional-cpp @gol
-fallow-single-precision -fcond-mismatch -flax-vector-conversions @gol
-fsigned-bitfields -fsigned-char @gol
-funsigned-bitfields -funsigned-char}
@ -1885,6 +1885,20 @@ This is equivalent to @option{-fno-hosted}.
@xref{Standards,,Language Standards Supported by GCC}, for details of
freestanding and hosted environments.
@item -fopenacc
@opindex fopenacc
@cindex OpenACC accelerator programming
Enable handling of OpenACC directives @code{#pragma acc} in C/C++ and
@code{!$acc} in Fortran. When @option{-fopenacc} is specified, the
compiler generates accelerated code according to the OpenACC Application
Programming Interface v2.0 @w{@uref{http://www.openacc.org/}}. This option
implies @option{-pthread}, and thus is only supported on targets that
have support for @option{-pthread}.
Note that this is an experimental feature, incomplete, and subject to
change in future versions of GCC. See
@w{@uref{https://gcc.gnu.org/wiki/OpenACC}} for more information.
@item -fopenmp
@opindex fopenmp
@cindex OpenMP parallel

View File

@ -1836,6 +1836,9 @@ Target supports Graphite optimizations.
@item fixed_point
Target supports fixed-point extension to C.
@item fopenacc
Target supports OpenACC via @option{-fopenacc}.
@item fopenmp
Target supports OpenMP via @option{-fopenmp}.

View File

@ -1,3 +1,199 @@
2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
James Norris <jnorris@codesourcery.com>
Ilmir Usmanov <i.usmanov@samsung.com>
Tobias Burnus <burnus@net-b.de>
* lang.opt (fopenacc): New option.
* cpp.c (cpp_define_builtins): Conditionally define _OPENACC.
* dump-parse-tree.c (show_omp_node): Split part of it into...
(show_omp_clauses): ... this new function.
(show_omp_node, show_code_node): Handle EXEC_OACC_PARALLEL_LOOP,
EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS_LOOP, EXEC_OACC_KERNELS,
EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP,
EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE,
EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA.
(show_namespace): Update for OpenACC.
* f95-lang.c (DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_8)
(DEF_FUNCTION_TYPE_VAR_12, DEF_GOACC_BUILTIN)
(DEF_GOACC_BUILTIN_COMPILER): New macros.
* types.def (BT_FN_VOID_INT_INT_VAR)
(BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR_INT_INT_VAR)
(BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR_INT_INT_INT_INT_INT_VAR):
New function types.
* gfortran.h (gfc_statement): Add ST_OACC_PARALLEL_LOOP,
ST_OACC_END_PARALLEL_LOOP, ST_OACC_PARALLEL, ST_OACC_END_PARALLEL,
ST_OACC_KERNELS, ST_OACC_END_KERNELS, ST_OACC_DATA,
ST_OACC_END_DATA, ST_OACC_HOST_DATA, ST_OACC_END_HOST_DATA,
ST_OACC_LOOP, ST_OACC_END_LOOP, ST_OACC_DECLARE, ST_OACC_UPDATE,
ST_OACC_WAIT, ST_OACC_CACHE, ST_OACC_KERNELS_LOOP,
ST_OACC_END_KERNELS_LOOP, ST_OACC_ENTER_DATA, ST_OACC_EXIT_DATA,
ST_OACC_ROUTINE.
(struct gfc_expr_list): New data type.
(gfc_get_expr_list): New macro.
(gfc_omp_map_op): Add OMP_MAP_FORCE_ALLOC, OMP_MAP_FORCE_DEALLOC,
OMP_MAP_FORCE_TO, OMP_MAP_FORCE_FROM, OMP_MAP_FORCE_TOFROM,
OMP_MAP_FORCE_PRESENT, OMP_MAP_FORCE_DEVICEPTR.
(OMP_LIST_FIRST, OMP_LIST_DEVICE_RESIDENT, OMP_LIST_USE_DEVICE)
(OMP_LIST_CACHE): New enumerators.
(struct gfc_omp_clauses): Add async_expr, gang_expr, worker_expr,
vector_expr, num_gangs_expr, num_workers_expr, vector_length_expr,
wait_list, tile_list, async, gang, worker, vector, seq,
independent, wait, par_auto, gang_static, and loc members.
(struct gfc_namespace): Add oacc_declare_clauses member.
(gfc_exec_op): Add EXEC_OACC_KERNELS_LOOP,
EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS,
EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP,
EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE,
EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA.
(gfc_free_expr_list, gfc_resolve_oacc_directive)
(gfc_resolve_oacc_declare, gfc_resolve_oacc_parallel_loop_blocks)
(gfc_resolve_oacc_blocks): New prototypes.
* match.c (match_exit_cycle): Handle EXEC_OACC_LOOP and
EXEC_OACC_PARALLEL_LOOP.
* match.h (gfc_match_oacc_cache, gfc_match_oacc_wait)
(gfc_match_oacc_update, gfc_match_oacc_declare)
(gfc_match_oacc_loop, gfc_match_oacc_host_data)
(gfc_match_oacc_data, gfc_match_oacc_kernels)
(gfc_match_oacc_kernels_loop, gfc_match_oacc_parallel)
(gfc_match_oacc_parallel_loop, gfc_match_oacc_enter_data)
(gfc_match_oacc_exit_data, gfc_match_oacc_routine): New
prototypes.
* openmp.c: Include "diagnostic.h" and "gomp-constants.h".
(gfc_free_omp_clauses): Update for members added to struct
gfc_omp_clauses.
(gfc_match_omp_clauses): Change mask paramter to uint64_t. Add
openacc parameter.
(resolve_omp_clauses): Add openacc parameter. Update for OpenACC.
(struct fortran_omp_context): Add is_openmp member.
(gfc_resolve_omp_parallel_blocks): Initialize it.
(gfc_resolve_do_iterator): Update for OpenACC.
(gfc_resolve_omp_directive): Call
resolve_omp_directive_inside_oacc_region.
(OMP_CLAUSE_PRIVATE, OMP_CLAUSE_FIRSTPRIVATE)
(OMP_CLAUSE_LASTPRIVATE, OMP_CLAUSE_COPYPRIVATE)
(OMP_CLAUSE_SHARED, OMP_CLAUSE_COPYIN, OMP_CLAUSE_REDUCTION)
(OMP_CLAUSE_IF, OMP_CLAUSE_NUM_THREADS, OMP_CLAUSE_SCHEDULE)
(OMP_CLAUSE_DEFAULT, OMP_CLAUSE_ORDERED, OMP_CLAUSE_COLLAPSE)
(OMP_CLAUSE_UNTIED, OMP_CLAUSE_FINAL, OMP_CLAUSE_MERGEABLE)
(OMP_CLAUSE_ALIGNED, OMP_CLAUSE_DEPEND, OMP_CLAUSE_INBRANCH)
(OMP_CLAUSE_LINEAR, OMP_CLAUSE_NOTINBRANCH, OMP_CLAUSE_PROC_BIND)
(OMP_CLAUSE_SAFELEN, OMP_CLAUSE_SIMDLEN, OMP_CLAUSE_UNIFORM)
(OMP_CLAUSE_DEVICE, OMP_CLAUSE_MAP, OMP_CLAUSE_TO)
(OMP_CLAUSE_FROM, OMP_CLAUSE_NUM_TEAMS, OMP_CLAUSE_THREAD_LIMIT)
(OMP_CLAUSE_DIST_SCHEDULE): Use uint64_t.
(OMP_CLAUSE_ASYNC, OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS)
(OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_COPY, OMP_CLAUSE_COPYOUT)
(OMP_CLAUSE_CREATE, OMP_CLAUSE_PRESENT)
(OMP_CLAUSE_PRESENT_OR_COPY, OMP_CLAUSE_PRESENT_OR_COPYIN)
(OMP_CLAUSE_PRESENT_OR_COPYOUT, OMP_CLAUSE_PRESENT_OR_CREATE)
(OMP_CLAUSE_DEVICEPTR, OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER)
(OMP_CLAUSE_VECTOR, OMP_CLAUSE_SEQ, OMP_CLAUSE_INDEPENDENT)
(OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE_DEVICE_RESIDENT)
(OMP_CLAUSE_HOST_SELF, OMP_CLAUSE_OACC_DEVICE, OMP_CLAUSE_WAIT)
(OMP_CLAUSE_DELETE, OMP_CLAUSE_AUTO, OMP_CLAUSE_TILE): New macros.
(gfc_match_omp_clauses): Handle those.
(OACC_PARALLEL_CLAUSES, OACC_KERNELS_CLAUSES, OACC_DATA_CLAUSES)
(OACC_LOOP_CLAUSES, OACC_PARALLEL_LOOP_CLAUSES)
(OACC_KERNELS_LOOP_CLAUSES, OACC_HOST_DATA_CLAUSES)
(OACC_DECLARE_CLAUSES, OACC_UPDATE_CLAUSES)
(OACC_ENTER_DATA_CLAUSES, OACC_EXIT_DATA_CLAUSES)
(OACC_WAIT_CLAUSES): New macros.
(gfc_free_expr_list, match_oacc_expr_list, match_oacc_clause_gang)
(gfc_match_omp_map_clause, gfc_match_oacc_parallel_loop)
(gfc_match_oacc_parallel, gfc_match_oacc_kernels_loop)
(gfc_match_oacc_kernels, gfc_match_oacc_data)
(gfc_match_oacc_host_data, gfc_match_oacc_loop)
(gfc_match_oacc_declare, gfc_match_oacc_update)
(gfc_match_oacc_enter_data, gfc_match_oacc_exit_data)
(gfc_match_oacc_wait, gfc_match_oacc_cache)
(gfc_match_oacc_routine, oacc_is_loop)
(resolve_oacc_scalar_int_expr, resolve_oacc_positive_int_expr)
(check_symbol_not_pointer, check_array_not_assumed)
(resolve_oacc_data_clauses, resolve_oacc_deviceptr_clause)
(oacc_compatible_clauses, oacc_is_parallel, oacc_is_kernels)
(omp_code_to_statement, oacc_code_to_statement)
(resolve_oacc_directive_inside_omp_region)
(resolve_omp_directive_inside_oacc_region)
(resolve_oacc_nested_loops, resolve_oacc_params_in_parallel)
(resolve_oacc_loop_blocks, gfc_resolve_oacc_blocks)
(resolve_oacc_loop, resolve_oacc_cache, gfc_resolve_oacc_declare)
(gfc_resolve_oacc_directive): New functions.
* parse.c (next_free): Update for OpenACC. Move some code into...
(verify_token_free): ... this new function.
(next_fixed): Update for OpenACC. Move some code into...
(verify_token_fixed): ... this new function.
(case_executable): Add ST_OACC_UPDATE, ST_OACC_WAIT,
ST_OACC_CACHE, ST_OACC_ENTER_DATA, and ST_OACC_EXIT_DATA.
(case_exec_markers): Add ST_OACC_PARALLEL_LOOP, ST_OACC_PARALLEL,
ST_OACC_KERNELS, ST_OACC_DATA, ST_OACC_HOST_DATA, ST_OACC_LOOP,
ST_OACC_KERNELS_LOOP.
(case_decl): Add ST_OACC_ROUTINE.
(push_state, parse_critical_block, parse_progunit): Update for
OpenACC.
(gfc_ascii_statement): Handle ST_OACC_PARALLEL_LOOP,
ST_OACC_END_PARALLEL_LOOP, ST_OACC_PARALLEL, ST_OACC_END_PARALLEL,
ST_OACC_KERNELS, ST_OACC_END_KERNELS, ST_OACC_KERNELS_LOOP,
ST_OACC_END_KERNELS_LOOP, ST_OACC_DATA, ST_OACC_END_DATA,
ST_OACC_HOST_DATA, ST_OACC_END_HOST_DATA, ST_OACC_LOOP,
ST_OACC_END_LOOP, ST_OACC_DECLARE, ST_OACC_UPDATE, ST_OACC_WAIT,
ST_OACC_CACHE, ST_OACC_ENTER_DATA, ST_OACC_EXIT_DATA,
ST_OACC_ROUTINE.
(verify_st_order, parse_spec): Handle ST_OACC_DECLARE.
(parse_executable): Handle ST_OACC_PARALLEL_LOOP,
ST_OACC_KERNELS_LOOP, ST_OACC_LOOP, ST_OACC_PARALLEL,
ST_OACC_KERNELS, ST_OACC_DATA, ST_OACC_HOST_DATA.
(decode_oacc_directive, parse_oacc_structured_block)
(parse_oacc_loop, is_oacc): New functions.
* parse.h (struct gfc_state_data): Add oacc_declare_clauses
member.
(is_oacc): New prototype.
* resolve.c (gfc_resolve_blocks, gfc_resolve_code): Handle
EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_PARALLEL,
EXEC_OACC_KERNELS_LOOP, EXEC_OACC_KERNELS, EXEC_OACC_DATA,
EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP, EXEC_OACC_UPDATE,
EXEC_OACC_WAIT, EXEC_OACC_CACHE, EXEC_OACC_ENTER_DATA,
EXEC_OACC_EXIT_DATA.
(resolve_codes): Call gfc_resolve_oacc_declare.
* scanner.c (openacc_flag, openacc_locus): New variables.
(skip_free_comments): Update for OpenACC. Move some code into...
(skip_omp_attribute): ... this new function.
(skip_oacc_attribute): New function.
(skip_fixed_comments, gfc_next_char_literal): Update for OpenACC.
* st.c (gfc_free_statement): Handle EXEC_OACC_PARALLEL_LOOP,
EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS_LOOP, EXEC_OACC_KERNELS,
EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP,
EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE,
EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA.
* trans-decl.c (gfc_generate_function_code): Update for OpenACC.
* trans-openmp.c: Include "gomp-constants.h".
(gfc_omp_finish_clause, gfc_trans_omp_clauses): Use GOMP_MAP_*
instead of OMP_CLAUSE_MAP_*. Use OMP_CLAUSE_SET_MAP_KIND.
(gfc_trans_omp_clauses): Handle OMP_LIST_USE_DEVICE,
OMP_LIST_DEVICE_RESIDENT, OMP_LIST_CACHE, and OMP_MAP_FORCE_ALLOC,
OMP_MAP_FORCE_DEALLOC, OMP_MAP_FORCE_TO, OMP_MAP_FORCE_FROM,
OMP_MAP_FORCE_TOFROM, OMP_MAP_FORCE_PRESENT,
OMP_MAP_FORCE_DEVICEPTR, and gfc_omp_clauses' async, seq,
independent, wait_list, num_gangs_expr, num_workers_expr,
vector_length_expr, vector, vector_expr, worker, worker_expr,
gang, gang_expr members.
(gfc_trans_omp_do): Handle EXEC_OACC_LOOP.
(gfc_convert_expr_to_tree, gfc_trans_oacc_construct)
(gfc_trans_oacc_executable_directive)
(gfc_trans_oacc_wait_directive, gfc_trans_oacc_combined_directive)
(gfc_trans_oacc_declare, gfc_trans_oacc_directive): New functions.
* trans-stmt.c (gfc_trans_block_construct): Update for OpenACC.
* trans-stmt.h (gfc_trans_oacc_directive, gfc_trans_oacc_declare):
New prototypes.
* trans.c (tranc_code): Handle EXEC_OACC_CACHE, EXEC_OACC_WAIT,
EXEC_OACC_UPDATE, EXEC_OACC_LOOP, EXEC_OACC_HOST_DATA,
EXEC_OACC_DATA, EXEC_OACC_KERNELS, EXEC_OACC_KERNELS_LOOP,
EXEC_OACC_PARALLEL, EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_ENTER_DATA,
EXEC_OACC_EXIT_DATA.
* gfortran.texi: Update for OpenACC.
* intrinsic.texi: Likewise.
* invoke.texi: Likewise.
2015-01-15 Janus Weil <janus@gcc.gnu.org>
PR fortran/58023

View File

@ -179,6 +179,9 @@ cpp_define_builtins (cpp_reader *pfile)
cpp_define (pfile, "__GFORTRAN__=1");
cpp_define (pfile, "_LANGUAGE_FORTRAN=1");
if (flag_openacc)
cpp_define (pfile, "_OPENACC=201306");
if (flag_openmp)
cpp_define (pfile, "_OPENMP=201307");

View File

@ -1072,7 +1072,265 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n)
}
}
/* Show a single OpenMP directive node and everything underneath it
/* Show OpenMP or OpenACC clauses. */
static void
show_omp_clauses (gfc_omp_clauses *omp_clauses)
{
int list_type;
switch (omp_clauses->cancel)
{
case OMP_CANCEL_UNKNOWN:
break;
case OMP_CANCEL_PARALLEL:
fputs (" PARALLEL", dumpfile);
break;
case OMP_CANCEL_SECTIONS:
fputs (" SECTIONS", dumpfile);
break;
case OMP_CANCEL_DO:
fputs (" DO", dumpfile);
break;
case OMP_CANCEL_TASKGROUP:
fputs (" TASKGROUP", dumpfile);
break;
}
if (omp_clauses->if_expr)
{
fputs (" IF(", dumpfile);
show_expr (omp_clauses->if_expr);
fputc (')', dumpfile);
}
if (omp_clauses->final_expr)
{
fputs (" FINAL(", dumpfile);
show_expr (omp_clauses->final_expr);
fputc (')', dumpfile);
}
if (omp_clauses->num_threads)
{
fputs (" NUM_THREADS(", dumpfile);
show_expr (omp_clauses->num_threads);
fputc (')', dumpfile);
}
if (omp_clauses->async)
{
fputs (" ASYNC", dumpfile);
if (omp_clauses->async_expr)
{
fputc ('(', dumpfile);
show_expr (omp_clauses->async_expr);
fputc (')', dumpfile);
}
}
if (omp_clauses->num_gangs_expr)
{
fputs (" NUM_GANGS(", dumpfile);
show_expr (omp_clauses->num_gangs_expr);
fputc (')', dumpfile);
}
if (omp_clauses->num_workers_expr)
{
fputs (" NUM_WORKERS(", dumpfile);
show_expr (omp_clauses->num_workers_expr);
fputc (')', dumpfile);
}
if (omp_clauses->vector_length_expr)
{
fputs (" VECTOR_LENGTH(", dumpfile);
show_expr (omp_clauses->vector_length_expr);
fputc (')', dumpfile);
}
if (omp_clauses->gang)
{
fputs (" GANG", dumpfile);
if (omp_clauses->gang_expr)
{
fputc ('(', dumpfile);
show_expr (omp_clauses->gang_expr);
fputc (')', dumpfile);
}
}
if (omp_clauses->worker)
{
fputs (" WORKER", dumpfile);
if (omp_clauses->worker_expr)
{
fputc ('(', dumpfile);
show_expr (omp_clauses->worker_expr);
fputc (')', dumpfile);
}
}
if (omp_clauses->vector)
{
fputs (" VECTOR", dumpfile);
if (omp_clauses->vector_expr)
{
fputc ('(', dumpfile);
show_expr (omp_clauses->vector_expr);
fputc (')', dumpfile);
}
}
if (omp_clauses->sched_kind != OMP_SCHED_NONE)
{
const char *type;
switch (omp_clauses->sched_kind)
{
case OMP_SCHED_STATIC: type = "STATIC"; break;
case OMP_SCHED_DYNAMIC: type = "DYNAMIC"; break;
case OMP_SCHED_GUIDED: type = "GUIDED"; break;
case OMP_SCHED_RUNTIME: type = "RUNTIME"; break;
case OMP_SCHED_AUTO: type = "AUTO"; break;
default:
gcc_unreachable ();
}
fprintf (dumpfile, " SCHEDULE (%s", type);
if (omp_clauses->chunk_size)
{
fputc (',', dumpfile);
show_expr (omp_clauses->chunk_size);
}
fputc (')', dumpfile);
}
if (omp_clauses->default_sharing != OMP_DEFAULT_UNKNOWN)
{
const char *type;
switch (omp_clauses->default_sharing)
{
case OMP_DEFAULT_NONE: type = "NONE"; break;
case OMP_DEFAULT_PRIVATE: type = "PRIVATE"; break;
case OMP_DEFAULT_SHARED: type = "SHARED"; break;
case OMP_DEFAULT_FIRSTPRIVATE: type = "FIRSTPRIVATE"; break;
default:
gcc_unreachable ();
}
fprintf (dumpfile, " DEFAULT(%s)", type);
}
if (omp_clauses->tile_list)
{
gfc_expr_list *list;
fputs (" TILE(", dumpfile);
for (list = omp_clauses->tile_list; list; list = list->next)
{
show_expr (list->expr);
if (list->next)
fputs (", ", dumpfile);
}
fputc (')', dumpfile);
}
if (omp_clauses->wait_list)
{
gfc_expr_list *list;
fputs (" WAIT(", dumpfile);
for (list = omp_clauses->wait_list; list; list = list->next)
{
show_expr (list->expr);
if (list->next)
fputs (", ", dumpfile);
}
fputc (')', dumpfile);
}
if (omp_clauses->seq)
fputs (" SEQ", dumpfile);
if (omp_clauses->independent)
fputs (" INDEPENDENT", dumpfile);
if (omp_clauses->ordered)
fputs (" ORDERED", dumpfile);
if (omp_clauses->untied)
fputs (" UNTIED", dumpfile);
if (omp_clauses->mergeable)
fputs (" MERGEABLE", dumpfile);
if (omp_clauses->collapse)
fprintf (dumpfile, " COLLAPSE(%d)", omp_clauses->collapse);
for (list_type = 0; list_type < OMP_LIST_NUM; list_type++)
if (omp_clauses->lists[list_type] != NULL
&& list_type != OMP_LIST_COPYPRIVATE)
{
const char *type = NULL;
switch (list_type)
{
case OMP_LIST_USE_DEVICE: type = "USE_DEVICE"; break;
case OMP_LIST_DEVICE_RESIDENT: type = "USE_DEVICE"; break;
case OMP_LIST_CACHE: type = ""; break;
case OMP_LIST_PRIVATE: type = "PRIVATE"; break;
case OMP_LIST_FIRSTPRIVATE: type = "FIRSTPRIVATE"; break;
case OMP_LIST_LASTPRIVATE: type = "LASTPRIVATE"; break;
case OMP_LIST_SHARED: type = "SHARED"; break;
case OMP_LIST_COPYIN: type = "COPYIN"; break;
case OMP_LIST_UNIFORM: type = "UNIFORM"; break;
case OMP_LIST_ALIGNED: type = "ALIGNED"; break;
case OMP_LIST_LINEAR: type = "LINEAR"; break;
case OMP_LIST_REDUCTION: type = "REDUCTION"; break;
case OMP_LIST_DEPEND: type = "DEPEND"; break;
default:
gcc_unreachable ();
}
fprintf (dumpfile, " %s(", type);
show_omp_namelist (list_type, omp_clauses->lists[list_type]);
fputc (')', dumpfile);
}
if (omp_clauses->safelen_expr)
{
fputs (" SAFELEN(", dumpfile);
show_expr (omp_clauses->safelen_expr);
fputc (')', dumpfile);
}
if (omp_clauses->simdlen_expr)
{
fputs (" SIMDLEN(", dumpfile);
show_expr (omp_clauses->simdlen_expr);
fputc (')', dumpfile);
}
if (omp_clauses->inbranch)
fputs (" INBRANCH", dumpfile);
if (omp_clauses->notinbranch)
fputs (" NOTINBRANCH", dumpfile);
if (omp_clauses->proc_bind != OMP_PROC_BIND_UNKNOWN)
{
const char *type;
switch (omp_clauses->proc_bind)
{
case OMP_PROC_BIND_MASTER: type = "MASTER"; break;
case OMP_PROC_BIND_SPREAD: type = "SPREAD"; break;
case OMP_PROC_BIND_CLOSE: type = "CLOSE"; break;
default:
gcc_unreachable ();
}
fprintf (dumpfile, " PROC_BIND(%s)", type);
}
if (omp_clauses->num_teams)
{
fputs (" NUM_TEAMS(", dumpfile);
show_expr (omp_clauses->num_teams);
fputc (')', dumpfile);
}
if (omp_clauses->device)
{
fputs (" DEVICE(", dumpfile);
show_expr (omp_clauses->device);
fputc (')', dumpfile);
}
if (omp_clauses->thread_limit)
{
fputs (" THREAD_LIMIT(", dumpfile);
show_expr (omp_clauses->thread_limit);
fputc (')', dumpfile);
}
if (omp_clauses->dist_sched_kind != OMP_SCHED_NONE)
{
fprintf (dumpfile, " DIST_SCHEDULE (static");
if (omp_clauses->dist_chunk_size)
{
fputc (',', dumpfile);
show_expr (omp_clauses->dist_chunk_size);
}
fputc (')', dumpfile);
}
}
/* Show a single OpenMP or OpenACC directive node and everything underneath it
if necessary. */
static void
@ -1080,9 +1338,22 @@ show_omp_node (int level, gfc_code *c)
{
gfc_omp_clauses *omp_clauses = NULL;
const char *name = NULL;
bool is_oacc = false;
switch (c->op)
{
case EXEC_OACC_PARALLEL_LOOP: name = "PARALLEL LOOP"; is_oacc = true; break;
case EXEC_OACC_PARALLEL: name = "PARALLEL"; is_oacc = true; break;
case EXEC_OACC_KERNELS_LOOP: name = "KERNELS LOOP"; is_oacc = true; break;
case EXEC_OACC_KERNELS: name = "KERNELS"; is_oacc = true; break;
case EXEC_OACC_DATA: name = "DATA"; is_oacc = true; break;
case EXEC_OACC_HOST_DATA: name = "HOST_DATA"; is_oacc = true; break;
case EXEC_OACC_LOOP: name = "LOOP"; is_oacc = true; break;
case EXEC_OACC_UPDATE: name = "UPDATE"; is_oacc = true; break;
case EXEC_OACC_WAIT: name = "WAIT"; is_oacc = true; break;
case EXEC_OACC_CACHE: name = "CACHE"; is_oacc = true; break;
case EXEC_OACC_ENTER_DATA: name = "ENTER DATA"; is_oacc = true; break;
case EXEC_OACC_EXIT_DATA: name = "EXIT DATA"; is_oacc = true; break;
case EXEC_OMP_ATOMIC: name = "ATOMIC"; break;
case EXEC_OMP_BARRIER: name = "BARRIER"; break;
case EXEC_OMP_CANCEL: name = "CANCEL"; break;
@ -1109,9 +1380,21 @@ show_omp_node (int level, gfc_code *c)
default:
gcc_unreachable ();
}
fprintf (dumpfile, "!$OMP %s", name);
fprintf (dumpfile, "!$%s %s", is_oacc ? "ACC" : "OMP", name);
switch (c->op)
{
case EXEC_OACC_PARALLEL_LOOP:
case EXEC_OACC_PARALLEL:
case EXEC_OACC_KERNELS_LOOP:
case EXEC_OACC_KERNELS:
case EXEC_OACC_DATA:
case EXEC_OACC_HOST_DATA:
case EXEC_OACC_LOOP:
case EXEC_OACC_UPDATE:
case EXEC_OACC_WAIT:
case EXEC_OACC_CACHE:
case EXEC_OACC_ENTER_DATA:
case EXEC_OACC_EXIT_DATA:
case EXEC_OMP_CANCEL:
case EXEC_OMP_CANCELLATION_POINT:
case EXEC_OMP_DO:
@ -1148,170 +1431,13 @@ show_omp_node (int level, gfc_code *c)
break;
}
if (omp_clauses)
{
int list_type;
switch (omp_clauses->cancel)
{
case OMP_CANCEL_UNKNOWN:
break;
case OMP_CANCEL_PARALLEL:
fputs (" PARALLEL", dumpfile);
break;
case OMP_CANCEL_SECTIONS:
fputs (" SECTIONS", dumpfile);
break;
case OMP_CANCEL_DO:
fputs (" DO", dumpfile);
break;
case OMP_CANCEL_TASKGROUP:
fputs (" TASKGROUP", dumpfile);
break;
}
if (omp_clauses->if_expr)
{
fputs (" IF(", dumpfile);
show_expr (omp_clauses->if_expr);
fputc (')', dumpfile);
}
if (omp_clauses->final_expr)
{
fputs (" FINAL(", dumpfile);
show_expr (omp_clauses->final_expr);
fputc (')', dumpfile);
}
if (omp_clauses->num_threads)
{
fputs (" NUM_THREADS(", dumpfile);
show_expr (omp_clauses->num_threads);
fputc (')', dumpfile);
}
if (omp_clauses->sched_kind != OMP_SCHED_NONE)
{
const char *type;
switch (omp_clauses->sched_kind)
{
case OMP_SCHED_STATIC: type = "STATIC"; break;
case OMP_SCHED_DYNAMIC: type = "DYNAMIC"; break;
case OMP_SCHED_GUIDED: type = "GUIDED"; break;
case OMP_SCHED_RUNTIME: type = "RUNTIME"; break;
case OMP_SCHED_AUTO: type = "AUTO"; break;
default:
gcc_unreachable ();
}
fprintf (dumpfile, " SCHEDULE (%s", type);
if (omp_clauses->chunk_size)
{
fputc (',', dumpfile);
show_expr (omp_clauses->chunk_size);
}
fputc (')', dumpfile);
}
if (omp_clauses->default_sharing != OMP_DEFAULT_UNKNOWN)
{
const char *type;
switch (omp_clauses->default_sharing)
{
case OMP_DEFAULT_NONE: type = "NONE"; break;
case OMP_DEFAULT_PRIVATE: type = "PRIVATE"; break;
case OMP_DEFAULT_SHARED: type = "SHARED"; break;
case OMP_DEFAULT_FIRSTPRIVATE: type = "FIRSTPRIVATE"; break;
default:
gcc_unreachable ();
}
fprintf (dumpfile, " DEFAULT(%s)", type);
}
if (omp_clauses->ordered)
fputs (" ORDERED", dumpfile);
if (omp_clauses->untied)
fputs (" UNTIED", dumpfile);
if (omp_clauses->mergeable)
fputs (" MERGEABLE", dumpfile);
if (omp_clauses->collapse)
fprintf (dumpfile, " COLLAPSE(%d)", omp_clauses->collapse);
for (list_type = 0; list_type < OMP_LIST_NUM; list_type++)
if (omp_clauses->lists[list_type] != NULL
&& list_type != OMP_LIST_COPYPRIVATE)
{
const char *type = NULL;
switch (list_type)
{
case OMP_LIST_PRIVATE: type = "PRIVATE"; break;
case OMP_LIST_FIRSTPRIVATE: type = "FIRSTPRIVATE"; break;
case OMP_LIST_LASTPRIVATE: type = "LASTPRIVATE"; break;
case OMP_LIST_SHARED: type = "SHARED"; break;
case OMP_LIST_COPYIN: type = "COPYIN"; break;
case OMP_LIST_UNIFORM: type = "UNIFORM"; break;
case OMP_LIST_ALIGNED: type = "ALIGNED"; break;
case OMP_LIST_LINEAR: type = "LINEAR"; break;
case OMP_LIST_REDUCTION: type = "REDUCTION"; break;
case OMP_LIST_DEPEND: type = "DEPEND"; break;
default:
gcc_unreachable ();
}
fprintf (dumpfile, " %s(", type);
show_omp_namelist (list_type, omp_clauses->lists[list_type]);
fputc (')', dumpfile);
}
if (omp_clauses->safelen_expr)
{
fputs (" SAFELEN(", dumpfile);
show_expr (omp_clauses->safelen_expr);
fputc (')', dumpfile);
}
if (omp_clauses->simdlen_expr)
{
fputs (" SIMDLEN(", dumpfile);
show_expr (omp_clauses->simdlen_expr);
fputc (')', dumpfile);
}
if (omp_clauses->inbranch)
fputs (" INBRANCH", dumpfile);
if (omp_clauses->notinbranch)
fputs (" NOTINBRANCH", dumpfile);
if (omp_clauses->proc_bind != OMP_PROC_BIND_UNKNOWN)
{
const char *type;
switch (omp_clauses->proc_bind)
{
case OMP_PROC_BIND_MASTER: type = "MASTER"; break;
case OMP_PROC_BIND_SPREAD: type = "SPREAD"; break;
case OMP_PROC_BIND_CLOSE: type = "CLOSE"; break;
default:
gcc_unreachable ();
}
fprintf (dumpfile, " PROC_BIND(%s)", type);
}
if (omp_clauses->num_teams)
{
fputs (" NUM_TEAMS(", dumpfile);
show_expr (omp_clauses->num_teams);
fputc (')', dumpfile);
}
if (omp_clauses->device)
{
fputs (" DEVICE(", dumpfile);
show_expr (omp_clauses->device);
fputc (')', dumpfile);
}
if (omp_clauses->thread_limit)
{
fputs (" THREAD_LIMIT(", dumpfile);
show_expr (omp_clauses->thread_limit);
fputc (')', dumpfile);
}
if (omp_clauses->dist_sched_kind != OMP_SCHED_NONE)
{
fprintf (dumpfile, " DIST_SCHEDULE (static");
if (omp_clauses->dist_chunk_size)
{
fputc (',', dumpfile);
show_expr (omp_clauses->dist_chunk_size);
}
fputc (')', dumpfile);
}
}
show_omp_clauses (omp_clauses);
fputc ('\n', dumpfile);
/* OpenACC executable directives don't have associated blocks. */
if (c->op == EXEC_OACC_CACHE || c->op == EXEC_OACC_UPDATE
|| c->op == EXEC_OACC_ENTER_DATA || c->op == EXEC_OACC_EXIT_DATA)
return;
if (c->op == EXEC_OMP_SECTIONS || c->op == EXEC_OMP_PARALLEL_SECTIONS)
{
gfc_code *d = c->block;
@ -1331,7 +1457,7 @@ show_omp_node (int level, gfc_code *c)
return;
fputc ('\n', dumpfile);
code_indent (level, 0);
fprintf (dumpfile, "!$OMP END %s", name);
fprintf (dumpfile, "!$%s END %s", is_oacc ? "ACC" : "OMP", name);
if (omp_clauses != NULL)
{
if (omp_clauses->lists[OMP_LIST_COPYPRIVATE])
@ -2311,6 +2437,18 @@ show_code_node (int level, gfc_code *c)
fprintf (dumpfile, " EOR=%d", dt->eor->value);
break;
case EXEC_OACC_PARALLEL_LOOP:
case EXEC_OACC_PARALLEL:
case EXEC_OACC_KERNELS_LOOP:
case EXEC_OACC_KERNELS:
case EXEC_OACC_DATA:
case EXEC_OACC_HOST_DATA:
case EXEC_OACC_LOOP:
case EXEC_OACC_UPDATE:
case EXEC_OACC_WAIT:
case EXEC_OACC_CACHE:
case EXEC_OACC_ENTER_DATA:
case EXEC_OACC_EXIT_DATA:
case EXEC_OMP_ATOMIC:
case EXEC_OMP_CANCEL:
case EXEC_OMP_CANCELLATION_POINT:
@ -2432,6 +2570,14 @@ show_namespace (gfc_namespace *ns)
for (eq = ns->equiv; eq; eq = eq->next)
show_equiv (eq);
if (ns->oacc_declare_clauses)
{
/* Dump !$ACC DECLARE clauses. */
show_indent ();
fprintf (dumpfile, "!$ACC DECLARE");
show_omp_clauses (ns->oacc_declare_clauses);
}
fputc ('\n', dumpfile);
show_indent ();
fputs ("code:", dumpfile);

View File

@ -672,6 +672,11 @@ gfc_init_builtin_functions (void)
#define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) NAME,
#define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
#define DEF_FUNCTION_TYPE_VAR_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) NAME,
#define DEF_FUNCTION_TYPE_VAR_12(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, ARG12) NAME,
#define DEF_POINTER_TYPE(NAME, TYPE) NAME,
#include "types.def"
#undef DEF_PRIMITIVE_TYPE
@ -685,6 +690,9 @@ gfc_init_builtin_functions (void)
#undef DEF_FUNCTION_TYPE_7
#undef DEF_FUNCTION_TYPE_8
#undef DEF_FUNCTION_TYPE_VAR_0
#undef DEF_FUNCTION_TYPE_VAR_2
#undef DEF_FUNCTION_TYPE_VAR_8
#undef DEF_FUNCTION_TYPE_VAR_12
#undef DEF_POINTER_TYPE
BT_LAST
};
@ -1119,6 +1127,42 @@ gfc_init_builtin_functions (void)
builtin_types[(int) ENUM] \
= build_varargs_function_type_list (builtin_types[(int) RETURN], \
NULL_TREE);
#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
builtin_types[(int) ENUM] \
= build_varargs_function_type_list (builtin_types[(int) RETURN], \
builtin_types[(int) ARG1], \
builtin_types[(int) ARG2], \
NULL_TREE);
#define DEF_FUNCTION_TYPE_VAR_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) \
builtin_types[(int) ENUM] \
= build_varargs_function_type_list (builtin_types[(int) RETURN], \
builtin_types[(int) ARG1], \
builtin_types[(int) ARG2], \
builtin_types[(int) ARG3], \
builtin_types[(int) ARG4], \
builtin_types[(int) ARG5], \
builtin_types[(int) ARG6], \
builtin_types[(int) ARG7], \
builtin_types[(int) ARG8], \
NULL_TREE);
#define DEF_FUNCTION_TYPE_VAR_12(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, ARG12) \
builtin_types[(int) ENUM] \
= build_varargs_function_type_list (builtin_types[(int) RETURN], \
builtin_types[(int) ARG1], \
builtin_types[(int) ARG2], \
builtin_types[(int) ARG3], \
builtin_types[(int) ARG4], \
builtin_types[(int) ARG5], \
builtin_types[(int) ARG6], \
builtin_types[(int) ARG7], \
builtin_types[(int) ARG8], \
builtin_types[(int) ARG9], \
builtin_types[(int) ARG10], \
builtin_types[(int) ARG11], \
builtin_types[(int) ARG12], \
NULL_TREE);
#define DEF_POINTER_TYPE(ENUM, TYPE) \
builtin_types[(int) ENUM] \
= build_pointer_type (builtin_types[(int) TYPE]);
@ -1134,6 +1178,9 @@ gfc_init_builtin_functions (void)
#undef DEF_FUNCTION_TYPE_7
#undef DEF_FUNCTION_TYPE_8
#undef DEF_FUNCTION_TYPE_VAR_0
#undef DEF_FUNCTION_TYPE_VAR_2
#undef DEF_FUNCTION_TYPE_VAR_8
#undef DEF_FUNCTION_TYPE_VAR_12
#undef DEF_POINTER_TYPE
builtin_types[(int) BT_LAST] = NULL_TREE;
@ -1145,13 +1192,36 @@ gfc_init_builtin_functions (void)
#include "../sync-builtins.def"
#undef DEF_SYNC_BUILTIN
if (flag_openacc)
{
#undef DEF_GOACC_BUILTIN
#define DEF_GOACC_BUILTIN(code, name, type, attr) \
gfc_define_builtin ("__builtin_" name, builtin_types[type], \
code, name, attr);
#undef DEF_GOACC_BUILTIN_COMPILER
#define DEF_GOACC_BUILTIN_COMPILER(code, name, type, attr) \
gfc_define_builtin (name, builtin_types[type], code, name, attr);
#undef DEF_GOMP_BUILTIN
#define DEF_GOMP_BUILTIN(code, name, type, attr) /* ignore */
#include "../omp-builtins.def"
#undef DEF_GOACC_BUILTIN
#undef DEF_GOACC_BUILTIN_COMPILER
#undef DEF_GOMP_BUILTIN
}
if (flag_openmp || flag_openmp_simd || flag_tree_parallelize_loops)
{
#undef DEF_GOACC_BUILTIN
#define DEF_GOACC_BUILTIN(code, name, type, attr) /* ignore */
#undef DEF_GOACC_BUILTIN_COMPILER
#define DEF_GOACC_BUILTIN_COMPILER(code, name, type, attr) /* ignore */
#undef DEF_GOMP_BUILTIN
#define DEF_GOMP_BUILTIN(code, name, type, attr) \
gfc_define_builtin ("__builtin_" name, builtin_types[type], \
code, name, attr);
#include "../omp-builtins.def"
#undef DEF_GOACC_BUILTIN
#undef DEF_GOACC_BUILTIN_COMPILER
#undef DEF_GOMP_BUILTIN
}

View File

@ -216,6 +216,12 @@ typedef enum
ST_WRITE, ST_ASSIGNMENT, ST_POINTER_ASSIGNMENT, ST_SELECT_CASE, ST_SEQUENCE,
ST_SIMPLE_IF, ST_STATEMENT_FUNCTION, ST_DERIVED_DECL, ST_LABEL_ASSIGNMENT,
ST_ENUM, ST_ENUMERATOR, ST_END_ENUM, ST_SELECT_TYPE, ST_TYPE_IS, ST_CLASS_IS,
ST_OACC_PARALLEL_LOOP, ST_OACC_END_PARALLEL_LOOP, ST_OACC_PARALLEL,
ST_OACC_END_PARALLEL, ST_OACC_KERNELS, ST_OACC_END_KERNELS, ST_OACC_DATA,
ST_OACC_END_DATA, ST_OACC_HOST_DATA, ST_OACC_END_HOST_DATA, ST_OACC_LOOP,
ST_OACC_END_LOOP, ST_OACC_DECLARE, ST_OACC_UPDATE, ST_OACC_WAIT,
ST_OACC_CACHE, ST_OACC_KERNELS_LOOP, ST_OACC_END_KERNELS_LOOP,
ST_OACC_ENTER_DATA, ST_OACC_EXIT_DATA, ST_OACC_ROUTINE,
ST_OMP_ATOMIC, ST_OMP_BARRIER, ST_OMP_CRITICAL, ST_OMP_END_ATOMIC,
ST_OMP_END_CRITICAL, ST_OMP_END_DO, ST_OMP_END_MASTER, ST_OMP_END_ORDERED,
ST_OMP_END_PARALLEL, ST_OMP_END_PARALLEL_DO, ST_OMP_END_PARALLEL_SECTIONS,
@ -1067,6 +1073,16 @@ gfc_namelist;
#define gfc_get_namelist() XCNEW (gfc_namelist)
/* Likewise to gfc_namelist, but contains expressions. */
typedef struct gfc_expr_list
{
struct gfc_expr *expr;
struct gfc_expr_list *next;
}
gfc_expr_list;
#define gfc_get_expr_list() XCNEW (gfc_expr_list)
typedef enum
{
OMP_REDUCTION_NONE = -1,
@ -1099,7 +1115,14 @@ typedef enum
OMP_MAP_ALLOC,
OMP_MAP_TO,
OMP_MAP_FROM,
OMP_MAP_TOFROM
OMP_MAP_TOFROM,
OMP_MAP_FORCE_ALLOC,
OMP_MAP_FORCE_DEALLOC,
OMP_MAP_FORCE_TO,
OMP_MAP_FORCE_FROM,
OMP_MAP_FORCE_TOFROM,
OMP_MAP_FORCE_PRESENT,
OMP_MAP_FORCE_DEVICEPTR
}
gfc_omp_map_op;
@ -1125,7 +1148,8 @@ gfc_omp_namelist;
enum
{
OMP_LIST_PRIVATE,
OMP_LIST_FIRST,
OMP_LIST_PRIVATE = OMP_LIST_FIRST,
OMP_LIST_FIRSTPRIVATE,
OMP_LIST_LASTPRIVATE,
OMP_LIST_COPYPRIVATE,
@ -1139,6 +1163,9 @@ enum
OMP_LIST_TO,
OMP_LIST_FROM,
OMP_LIST_REDUCTION,
OMP_LIST_DEVICE_RESIDENT,
OMP_LIST_USE_DEVICE,
OMP_LIST_CACHE,
OMP_LIST_NUM
};
@ -1202,6 +1229,21 @@ typedef struct gfc_omp_clauses
struct gfc_expr *thread_limit;
enum gfc_omp_sched_kind dist_sched_kind;
struct gfc_expr *dist_chunk_size;
/* OpenACC. */
struct gfc_expr *async_expr;
struct gfc_expr *gang_expr;
struct gfc_expr *worker_expr;
struct gfc_expr *vector_expr;
struct gfc_expr *num_gangs_expr;
struct gfc_expr *num_workers_expr;
struct gfc_expr *vector_length_expr;
gfc_expr_list *wait_list;
gfc_expr_list *tile_list;
unsigned async:1, gang:1, worker:1, vector:1, seq:1, independent:1;
unsigned wait:1, par_auto:1, gang_static:1;
locus loc;
}
gfc_omp_clauses;
@ -1609,6 +1651,9 @@ typedef struct gfc_namespace
this namespace. */
struct gfc_data *data, *old_data;
/* !$ACC DECLARE clauses. */
gfc_omp_clauses *oacc_declare_clauses;
gfc_charlen *cl_list, *old_cl_list;
gfc_dt_list *derived_types;
@ -2276,6 +2321,10 @@ typedef enum
EXEC_READ, EXEC_WRITE, EXEC_IOLENGTH, EXEC_TRANSFER, EXEC_DT_END,
EXEC_BACKSPACE, EXEC_ENDFILE, EXEC_INQUIRE, EXEC_REWIND, EXEC_FLUSH,
EXEC_LOCK, EXEC_UNLOCK,
EXEC_OACC_KERNELS_LOOP, EXEC_OACC_PARALLEL_LOOP,
EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS, EXEC_OACC_DATA, EXEC_OACC_HOST_DATA,
EXEC_OACC_LOOP, EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE,
EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA,
EXEC_OMP_CRITICAL, EXEC_OMP_DO, EXEC_OMP_FLUSH, EXEC_OMP_MASTER,
EXEC_OMP_ORDERED, EXEC_OMP_PARALLEL, EXEC_OMP_PARALLEL_DO,
EXEC_OMP_PARALLEL_SECTIONS, EXEC_OMP_PARALLEL_WORKSHARE,
@ -2877,6 +2926,11 @@ void gfc_resolve_omp_declare_simd (gfc_namespace *);
void gfc_resolve_omp_udrs (gfc_symtree *);
void gfc_omp_save_and_clear_state (struct gfc_omp_saved_state *);
void gfc_omp_restore_state (struct gfc_omp_saved_state *);
void gfc_free_expr_list (gfc_expr_list *);
void gfc_resolve_oacc_directive (gfc_code *, gfc_namespace *);
void gfc_resolve_oacc_declare (gfc_namespace *);
void gfc_resolve_oacc_parallel_loop_blocks (gfc_code *, gfc_namespace *);
void gfc_resolve_oacc_blocks (gfc_code *, gfc_namespace *);
/* expr.c */
void gfc_free_actual_arglist (gfc_actual_arglist *);

View File

@ -477,6 +477,10 @@ used on real-world programs. In particular, the supported extensions
include OpenMP, Cray-style pointers, and several Fortran 2003 and Fortran
2008 features, including TR 15581. However, it is still under
development and has a few remaining rough edges.
There also is initial support for OpenACC.
Note that this is an experimental feature, incomplete, and subject to
change in future versions of GCC. See
@uref{https://gcc.gnu.org/wiki/OpenACC} for more information.
At present, the GNU Fortran compiler passes the
@uref{http://www.fortran-2000.com/ArnaudRecipes/fcvs21_f95.html,
@ -533,6 +537,11 @@ The current status of the support is can be found in the
Additionally, the GNU Fortran compilers supports the OpenMP specification
(version 4.0, @url{http://openmp.org/@/wp/@/openmp-specifications/}).
There also is initial support for the OpenACC specification (targeting
version 2.0, @uref{http://www.openacc.org/}).
Note that this is an experimental feature, incomplete, and subject to
change in future versions of GCC. See
@uref{https://gcc.gnu.org/wiki/OpenACC} for more information.
@node Varying Length Character Strings
@subsection Varying Length Character Strings
@ -963,7 +972,8 @@ module.
@cindex statement, @code{ISO_FORTRAN_ENV}
@code{USE} statement with @code{INTRINSIC} and @code{NON_INTRINSIC}
attribute; supported intrinsic modules: @code{ISO_FORTRAN_ENV},
@code{ISO_C_BINDING}, @code{OMP_LIB} and @code{OMP_LIB_KINDS}.
@code{ISO_C_BINDING}, @code{OMP_LIB} and @code{OMP_LIB_KINDS},
and @code{OPENACC}.
@item
Renaming of operators in the @code{USE} statement.
@ -1375,6 +1385,7 @@ without warning.
* Cray pointers::
* CONVERT specifier::
* OpenMP::
* OpenACC::
* Argument list functions::
@end menu
@ -1949,6 +1960,37 @@ to the command line. However, this is not supported by @command{gcc} and
thus not recommended.
@end itemize
@node OpenACC
@subsection OpenACC
@cindex OpenACC
OpenACC is an application programming interface (API) that supports
offloading of code to accelerator devices. It consists of a set of
compiler directives, library routines, and environment variables that
influence run-time behavior.
GNU Fortran strives to be compatible to the
@uref{http://www.openacc.org/, OpenACC Application Programming
Interface v2.0}.
To enable the processing of the OpenACC directive @code{!$acc} in
free-form source code; the @code{c$acc}, @code{*$acc} and @code{!$acc}
directives in fixed form; the @code{!$} conditional compilation
sentinels in free form; and the @code{c$}, @code{*$} and @code{!$}
sentinels in fixed form, @command{gfortran} needs to be invoked with
the @option{-fopenacc}. This also arranges for automatic linking of
the GNU Offloading and Multi Processing Runtime Library
@ref{Top,,libgomp,libgomp,GNU Offloading and Multi Processing Runtime
Library}.
The OpenACC Fortran runtime library routines are provided both in a
form of a Fortran 90 module named @code{openacc} and in a form of a
Fortran @code{include} file named @file{openacc_lib.h}.
Note that this is an experimental feature, incomplete, and subject to
change in future versions of GCC. See
@uref{https://gcc.gnu.org/wiki/OpenACC} for more information.
@node Argument list functions
@subsection Argument list functions @code{%VAL}, @code{%REF} and @code{%LOC}
@cindex argument list functions

View File

@ -13774,6 +13774,7 @@ Fortran 95 elemental function: @ref{IEOR}
* ISO_C_BINDING::
* IEEE modules::
* OpenMP Modules OMP_LIB and OMP_LIB_KINDS::
* OpenACC Module OPENACC::
@end menu
@node ISO_FORTRAN_ENV
@ -14018,6 +14019,7 @@ with the following options: @code{-fno-unsafe-math-optimizations
-frounding-math -fsignaling-nans}.
@node OpenMP Modules OMP_LIB and OMP_LIB_KINDS
@section OpenMP Modules @code{OMP_LIB} and @code{OMP_LIB_KINDS}
@table @asis
@ -14074,3 +14076,30 @@ kind @code{omp_proc_bind_kind}:
@item @code{omp_proc_bind_close}
@item @code{omp_proc_bind_spread}
@end table
@node OpenACC Module OPENACC
@section OpenACC Module @code{OPENACC}
@table @asis
@item @emph{Standard}:
OpenACC Application Programming Interface v2.0
@end table
The OpenACC Fortran runtime library routines are provided both in a
form of a Fortran 90 module, named @code{OPENACC}, and in form of a
Fortran @code{include} file named @file{openacc_lib.h}. The
procedures provided by @code{OPENACC} can be found in the
@ref{Top,,Introduction,libgomp,GNU Offloading and Multi Processing
Runtime Library} manual, the named constants defined in the modules
are listed below.
For details refer to the actual
@uref{http://www.openacc.org/,
OpenACC Application Programming Interface v2.0}.
@code{OPENACC} provides the scalar default-integer
named constant @code{openacc_version} with a value of the form
@var{yyyymm}, where @code{yyyy} is the year and @var{mm} the month
of the OpenACC version; for OpenACC v2.0 the value is @code{201306}.

View File

@ -120,7 +120,7 @@ by type. Explanations are in the following sections.
-ffixed-line-length-none -ffree-form -ffree-line-length-@var{n} @gol
-ffree-line-length-none -fimplicit-none -finteger-4-integer-8 @gol
-fmax-identifier-length -fmodule-private -fno-fixed-form -fno-range-check @gol
-fopenmp -freal-4-real-10 -freal-4-real-16 -freal-4-real-8 @gol
-fopenacc -fopenmp -freal-4-real-10 -freal-4-real-16 -freal-4-real-8 @gol
-freal-8-real-10 -freal-8-real-16 -freal-8-real-4 -std=@var{std}
}
@ -302,6 +302,20 @@ Specify that no implicit typing is allowed, unless overridden by explicit
Enable the Cray pointer extension, which provides C-like pointer
functionality.
@item -fopenacc
@opindex @code{fopenacc}
@cindex OpenACC
Enable the OpenACC extensions. This includes OpenACC @code{!$acc}
directives in free form and @code{c$acc}, @code{*$acc} and
@code{!$acc} directives in fixed form, @code{!$} conditional
compilation sentinels in free form and @code{c$}, @code{*$} and
@code{!$} sentinels in fixed form, and when linking arranges for the
OpenACC runtime library to be linked in.
Note that this is an experimental feature, incomplete, and subject to
change in future versions of GCC. See
@w{@uref{https://gcc.gnu.org/wiki/OpenACC}} for more information.
@item -fopenmp
@opindex @code{fopenmp}
@cindex OpenMP

View File

@ -566,6 +566,10 @@ fmodule-private
Fortran Var(flag_module_private)
Set default accessibility of module entities to PRIVATE.
fopenacc
Fortran
; Documented in C
fopenmp
Fortran
; Documented in C

View File

@ -2501,7 +2501,9 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op)
if (o != NULL)
{
gfc_error ("%s statement at %C leaving OpenMP structured block",
gfc_error (is_oacc (p)
? "%s statement at %C leaving OpenACC structured block"
: "%s statement at %C leaving OpenMP structured block",
gfc_ascii_statement (st));
return MATCH_ERROR;
}
@ -2511,6 +2513,33 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op)
if (cnt > 0
&& o != NULL
&& o->state == COMP_OMP_STRUCTURED_BLOCK
&& (o->head->op == EXEC_OACC_LOOP
|| o->head->op == EXEC_OACC_PARALLEL_LOOP))
{
int collapse = 1;
gcc_assert (o->head->next != NULL
&& (o->head->next->op == EXEC_DO
|| o->head->next->op == EXEC_DO_WHILE)
&& o->previous != NULL
&& o->previous->tail->op == o->head->op);
if (o->previous->tail->ext.omp_clauses != NULL
&& o->previous->tail->ext.omp_clauses->collapse > 1)
collapse = o->previous->tail->ext.omp_clauses->collapse;
if (st == ST_EXIT && cnt <= collapse)
{
gfc_error ("EXIT statement at %C terminating !$ACC LOOP loop");
return MATCH_ERROR;
}
if (st == ST_CYCLE && cnt < collapse)
{
gfc_error ("CYCLE statement at %C to non-innermost collapsed"
" !$ACC LOOP loop");
return MATCH_ERROR;
}
}
if (cnt > 0
&& o != NULL
&& (o->state == COMP_OMP_STRUCTURED_BLOCK)
&& (o->head->op == EXEC_OMP_DO
|| o->head->op == EXEC_OMP_PARALLEL_DO
|| o->head->op == EXEC_OMP_SIMD

View File

@ -122,6 +122,22 @@ gfc_common_head *gfc_get_common (const char *, int);
/* openmp.c. */
/* OpenACC directive matchers. */
match gfc_match_oacc_cache (void);
match gfc_match_oacc_wait (void);
match gfc_match_oacc_update (void);
match gfc_match_oacc_declare (void);
match gfc_match_oacc_loop (void);
match gfc_match_oacc_host_data (void);
match gfc_match_oacc_data (void);
match gfc_match_oacc_kernels (void);
match gfc_match_oacc_kernels_loop (void);
match gfc_match_oacc_parallel (void);
match gfc_match_oacc_parallel_loop (void);
match gfc_match_oacc_enter_data (void);
match gfc_match_oacc_exit_data (void);
match gfc_match_oacc_routine (void);
/* OpenMP directive matchers. */
match gfc_match_omp_eos (void);
match gfc_match_omp_atomic (void);

File diff suppressed because it is too large Load Diff

View File

@ -584,6 +584,93 @@ decode_statement (void)
undo_new_statement (); \
} while (0);
static gfc_statement
decode_oacc_directive (void)
{
locus old_locus;
char c;
gfc_enforce_clean_symbol_state ();
gfc_clear_error (); /* Clear any pending errors. */
gfc_clear_warning (); /* Clear any pending warnings. */
if (gfc_pure (NULL))
{
gfc_error_now ("OpenACC directives at %C may not appear in PURE "
"procedures");
gfc_error_recovery ();
return ST_NONE;
}
gfc_unset_implicit_pure (NULL);
old_locus = gfc_current_locus;
/* General OpenACC directive matching: Instead of testing every possible
statement, we eliminate most possibilities by peeking at the
first character. */
c = gfc_peek_ascii_char ();
switch (c)
{
case 'c':
match ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
break;
case 'd':
match ("data", gfc_match_oacc_data, ST_OACC_DATA);
match ("declare", gfc_match_oacc_declare, ST_OACC_DECLARE);
break;
case 'e':
match ("end data", gfc_match_omp_eos, ST_OACC_END_DATA);
match ("end host_data", gfc_match_omp_eos, ST_OACC_END_HOST_DATA);
match ("end kernels loop", gfc_match_omp_eos, ST_OACC_END_KERNELS_LOOP);
match ("end kernels", gfc_match_omp_eos, ST_OACC_END_KERNELS);
match ("end loop", gfc_match_omp_eos, ST_OACC_END_LOOP);
match ("end parallel loop", gfc_match_omp_eos, ST_OACC_END_PARALLEL_LOOP);
match ("end parallel", gfc_match_omp_eos, ST_OACC_END_PARALLEL);
match ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
match ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
break;
case 'h':
match ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
break;
case 'p':
match ("parallel loop", gfc_match_oacc_parallel_loop, ST_OACC_PARALLEL_LOOP);
match ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
break;
case 'k':
match ("kernels loop", gfc_match_oacc_kernels_loop, ST_OACC_KERNELS_LOOP);
match ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
break;
case 'l':
match ("loop", gfc_match_oacc_loop, ST_OACC_LOOP);
break;
case 'r':
match ("routine", gfc_match_oacc_routine, ST_OACC_ROUTINE);
break;
case 'u':
match ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
break;
case 'w':
match ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
break;
}
/* Directive not found or stored an error message.
Check and give up. */
if (gfc_error_check () == 0)
gfc_error_now ("Unclassifiable OpenACC directive at %C");
reject_statement ();
gfc_error_recovery ();
return ST_NONE;
}
static gfc_statement
decode_omp_directive (void)
{
@ -811,6 +898,23 @@ decode_gcc_attribute (void)
#undef match
/* Assert next length characters to be equal to token in free form. */
static void
verify_token_free (const char* token, int length, bool last_was_use_stmt)
{
int i;
char c;
c = gfc_next_ascii_char ();
for (i = 0; i < length; i++, c = gfc_next_ascii_char ())
gcc_assert (c == token[i]);
gcc_assert (gfc_is_whitespace(c));
gfc_gobble_whitespace ();
if (last_was_use_stmt)
use_modules ();
}
/* Get the next statement in free form source. */
@ -880,7 +984,7 @@ next_free (void)
else if (c == '!')
{
/* Comments have already been skipped by the time we get here,
except for GCC attributes and OpenMP directives. */
except for GCC attributes and OpenMP/OpenACC directives. */
gfc_next_ascii_char (); /* Eat up the exclamation sign. */
c = gfc_peek_ascii_char ();
@ -897,21 +1001,39 @@ next_free (void)
return decode_gcc_attribute ();
}
else if (c == '$' && (flag_openmp || flag_openmp_simd))
else if (c == '$')
{
int i;
/* Since both OpenMP and OpenACC directives starts with
!$ character sequence, we must check all flags combinations */
if ((flag_openmp || flag_openmp_simd)
&& !flag_openacc)
{
verify_token_free ("$omp", 4, last_was_use_stmt);
return decode_omp_directive ();
}
else if ((flag_openmp || flag_openmp_simd)
&& flag_openacc)
{
gfc_next_ascii_char (); /* Eat up dollar character */
c = gfc_peek_ascii_char ();
c = gfc_next_ascii_char ();
for (i = 0; i < 4; i++, c = gfc_next_ascii_char ())
gcc_assert (c == "$omp"[i]);
gcc_assert (c == ' ' || c == '\t');
gfc_gobble_whitespace ();
if (last_was_use_stmt)
use_modules ();
return decode_omp_directive ();
if (c == 'o')
{
verify_token_free ("omp", 3, last_was_use_stmt);
return decode_omp_directive ();
}
else if (c == 'a')
{
verify_token_free ("acc", 3, last_was_use_stmt);
return decode_oacc_directive ();
}
}
else if (flag_openacc)
{
verify_token_free ("$acc", 4, last_was_use_stmt);
return decode_oacc_directive ();
}
}
gcc_unreachable ();
}
@ -927,6 +1049,28 @@ next_free (void)
return decode_statement ();
}
/* Assert next length characters to be equal to token in fixed form. */
static bool
verify_token_fixed (const char *token, int length, bool last_was_use_stmt)
{
int i;
char c = gfc_next_char_literal (NONSTRING);
for (i = 0; i < length; i++, c = gfc_next_char_literal (NONSTRING))
gcc_assert ((char) gfc_wide_tolower (c) == token[i]);
if (c != ' ' && c != '0')
{
gfc_buffer_error (false);
gfc_error ("Bad continuation line at %C");
return false;
}
if (last_was_use_stmt)
use_modules ();
return true;
}
/* Get the next statement in fixed-form source. */
@ -986,21 +1130,38 @@ next_fixed (void)
return decode_gcc_attribute ();
}
else if (c == '$'
&& (flag_openmp || flag_openmp_simd))
else if (c == '$')
{
for (i = 0; i < 4; i++, c = gfc_next_char_literal (NONSTRING))
gcc_assert ((char) gfc_wide_tolower (c) == "$omp"[i]);
if (c != ' ' && c != '0')
if ((flag_openmp || flag_openmp_simd)
&& !flag_openacc)
{
gfc_buffer_error (false);
gfc_error ("Bad continuation line at %C");
return ST_NONE;
if (!verify_token_fixed ("omp", 3, last_was_use_stmt))
return ST_NONE;
return decode_omp_directive ();
}
else if ((flag_openmp || flag_openmp_simd)
&& flag_openacc)
{
c = gfc_next_char_literal(NONSTRING);
if (c == 'o' || c == 'O')
{
if (!verify_token_fixed ("mp", 2, last_was_use_stmt))
return ST_NONE;
return decode_omp_directive ();
}
else if (c == 'a' || c == 'A')
{
if (!verify_token_fixed ("cc", 2, last_was_use_stmt))
return ST_NONE;
return decode_oacc_directive ();
}
}
else if (flag_openacc)
{
if (!verify_token_fixed ("acc", 3, last_was_use_stmt))
return ST_NONE;
return decode_oacc_directive ();
}
if (last_was_use_stmt)
use_modules ();
return decode_omp_directive ();
}
/* FALLTHROUGH */
@ -1161,7 +1322,9 @@ next_statement (void)
case ST_OMP_BARRIER: case ST_OMP_TASKWAIT: case ST_OMP_TASKYIELD: \
case ST_OMP_CANCEL: case ST_OMP_CANCELLATION_POINT: \
case ST_OMP_TARGET_UPDATE: case ST_ERROR_STOP: case ST_SYNC_ALL: \
case ST_SYNC_IMAGES: case ST_SYNC_MEMORY: case ST_LOCK: case ST_UNLOCK
case ST_SYNC_IMAGES: case ST_SYNC_MEMORY: case ST_LOCK: case ST_UNLOCK: \
case ST_OACC_UPDATE: case ST_OACC_WAIT: case ST_OACC_CACHE: \
case ST_OACC_ENTER_DATA: case ST_OACC_EXIT_DATA
/* Statements that mark other executable statements. */
@ -1186,7 +1349,9 @@ next_statement (void)
case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: case ST_OMP_DISTRIBUTE: \
case ST_OMP_DISTRIBUTE_SIMD: case ST_OMP_DISTRIBUTE_PARALLEL_DO: \
case ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD: \
case ST_CRITICAL
case ST_CRITICAL: \
case ST_OACC_PARALLEL_LOOP: case ST_OACC_PARALLEL: case ST_OACC_KERNELS: \
case ST_OACC_DATA: case ST_OACC_HOST_DATA: case ST_OACC_LOOP: case ST_OACC_KERNELS_LOOP
/* Declaration statements */
@ -1194,7 +1359,7 @@ next_statement (void)
case ST_EQUIVALENCE: case ST_NAMELIST: case ST_STATEMENT_FUNCTION: \
case ST_TYPE: case ST_INTERFACE: case ST_OMP_THREADPRIVATE: \
case ST_PROCEDURE: case ST_OMP_DECLARE_SIMD: case ST_OMP_DECLARE_REDUCTION: \
case ST_OMP_DECLARE_TARGET
case ST_OMP_DECLARE_TARGET: case ST_OACC_ROUTINE
/* Block end statements. Errors associated with interchanging these
are detected in gfc_match_end(). */
@ -1214,6 +1379,8 @@ push_state (gfc_state_data *p, gfc_compile_state new_state, gfc_symbol *sym)
p->sym = sym;
p->head = p->tail = NULL;
p->do_variable = NULL;
if (p->state != COMP_DO && p->state != COMP_DO_CONCURRENT)
p->ext.oacc_declare_clauses = NULL;
/* If this the state of a construct like BLOCK, DO or IF, the corresponding
construct statement was accepted right before pushing the state. Thus,
@ -1679,6 +1846,69 @@ gfc_ascii_statement (gfc_statement st)
case ST_END_ENUM:
p = "END ENUM";
break;
case ST_OACC_PARALLEL_LOOP:
p = "!$ACC PARALLEL LOOP";
break;
case ST_OACC_END_PARALLEL_LOOP:
p = "!$ACC END PARALLEL LOOP";
break;
case ST_OACC_PARALLEL:
p = "!$ACC PARALLEL";
break;
case ST_OACC_END_PARALLEL:
p = "!$ACC END PARALLEL";
break;
case ST_OACC_KERNELS:
p = "!$ACC KERNELS";
break;
case ST_OACC_END_KERNELS:
p = "!$ACC END KERNELS";
break;
case ST_OACC_KERNELS_LOOP:
p = "!$ACC KERNELS LOOP";
break;
case ST_OACC_END_KERNELS_LOOP:
p = "!$ACC END KERNELS LOOP";
break;
case ST_OACC_DATA:
p = "!$ACC DATA";
break;
case ST_OACC_END_DATA:
p = "!$ACC END DATA";
break;
case ST_OACC_HOST_DATA:
p = "!$ACC HOST_DATA";
break;
case ST_OACC_END_HOST_DATA:
p = "!$ACC END HOST_DATA";
break;
case ST_OACC_LOOP:
p = "!$ACC LOOP";
break;
case ST_OACC_END_LOOP:
p = "!$ACC END LOOP";
break;
case ST_OACC_DECLARE:
p = "!$ACC DECLARE";
break;
case ST_OACC_UPDATE:
p = "!$ACC UPDATE";
break;
case ST_OACC_WAIT:
p = "!$ACC WAIT";
break;
case ST_OACC_CACHE:
p = "!$ACC CACHE";
break;
case ST_OACC_ENTER_DATA:
p = "!$ACC ENTER DATA";
break;
case ST_OACC_EXIT_DATA:
p = "!$ACC EXIT DATA";
break;
case ST_OACC_ROUTINE:
p = "!$ACC ROUTINE";
break;
case ST_OMP_ATOMIC:
p = "!$OMP ATOMIC";
break;
@ -2180,6 +2410,7 @@ verify_st_order (st_state *p, gfc_statement st, bool silent)
case ST_PUBLIC:
case ST_PRIVATE:
case ST_DERIVED_DECL:
case ST_OACC_DECLARE:
case_decl:
if (p->state >= ORDER_EXEC)
goto order;
@ -3081,6 +3312,19 @@ declSt:
st = next_statement ();
goto loop;
case ST_OACC_DECLARE:
if (!verify_st_order(&ss, st, false))
{
reject_statement ();
st = next_statement ();
goto loop;
}
if (gfc_state_stack->ext.oacc_declare_clauses == NULL)
gfc_state_stack->ext.oacc_declare_clauses = new_st.ext.omp_clauses;
accept_statement (st);
st = next_statement ();
goto loop;
default:
break;
}
@ -3571,9 +3815,15 @@ static void
parse_critical_block (void)
{
gfc_code *top, *d;
gfc_state_data s;
gfc_state_data s, *sd;
gfc_statement st;
for (sd = gfc_state_stack; sd; sd = sd->previous)
if (sd->state == COMP_OMP_STRUCTURED_BLOCK)
gfc_error_now (is_oacc (sd)
? "CRITICAL block inside of OpenACC region at %C"
: "CRITICAL block inside of OpenMP region at %C");
s.ext.end_do_label = new_st.label1;
accept_statement (ST_CRITICAL);
@ -3988,6 +4238,128 @@ parse_omp_atomic (void)
}
/* Parse the statements of an OpenACC structured block. */
static void
parse_oacc_structured_block (gfc_statement acc_st)
{
gfc_statement st, acc_end_st;
gfc_code *cp, *np;
gfc_state_data s, *sd;
for (sd = gfc_state_stack; sd; sd = sd->previous)
if (sd->state == COMP_CRITICAL)
gfc_error_now ("OpenACC directive inside of CRITICAL block at %C");
accept_statement (acc_st);
cp = gfc_state_stack->tail;
push_state (&s, COMP_OMP_STRUCTURED_BLOCK, NULL);
np = new_level (cp);
np->op = cp->op;
np->block = NULL;
switch (acc_st)
{
case ST_OACC_PARALLEL:
acc_end_st = ST_OACC_END_PARALLEL;
break;
case ST_OACC_KERNELS:
acc_end_st = ST_OACC_END_KERNELS;
break;
case ST_OACC_DATA:
acc_end_st = ST_OACC_END_DATA;
break;
case ST_OACC_HOST_DATA:
acc_end_st = ST_OACC_END_HOST_DATA;
break;
default:
gcc_unreachable ();
}
do
{
st = parse_executable (ST_NONE);
if (st == ST_NONE)
unexpected_eof ();
else if (st != acc_end_st)
gfc_error ("Expecting %s at %C", gfc_ascii_statement (acc_end_st));
reject_statement ();
}
while (st != acc_end_st);
gcc_assert (new_st.op == EXEC_NOP);
gfc_clear_new_st ();
gfc_commit_symbols ();
gfc_warning_check ();
pop_state ();
}
/* Parse the statements of OpenACC loop/parallel loop/kernels loop. */
static gfc_statement
parse_oacc_loop (gfc_statement acc_st)
{
gfc_statement st;
gfc_code *cp, *np;
gfc_state_data s, *sd;
for (sd = gfc_state_stack; sd; sd = sd->previous)
if (sd->state == COMP_CRITICAL)
gfc_error_now ("OpenACC directive inside of CRITICAL block at %C");
accept_statement (acc_st);
cp = gfc_state_stack->tail;
push_state (&s, COMP_OMP_STRUCTURED_BLOCK, NULL);
np = new_level (cp);
np->op = cp->op;
np->block = NULL;
for (;;)
{
st = next_statement ();
if (st == ST_NONE)
unexpected_eof ();
else if (st == ST_DO)
break;
else
{
gfc_error ("Expected DO loop at %C");
reject_statement ();
}
}
parse_do_block ();
if (gfc_statement_label != NULL
&& gfc_state_stack->previous != NULL
&& gfc_state_stack->previous->state == COMP_DO
&& gfc_state_stack->previous->ext.end_do_label == gfc_statement_label)
{
pop_state ();
return ST_IMPLIED_ENDDO;
}
check_do_closure ();
pop_state ();
st = next_statement ();
if (st == ST_OACC_END_LOOP)
gfc_warning ("Redundant !$ACC END LOOP at %C");
if ((acc_st == ST_OACC_PARALLEL_LOOP && st == ST_OACC_END_PARALLEL_LOOP) ||
(acc_st == ST_OACC_KERNELS_LOOP && st == ST_OACC_END_KERNELS_LOOP) ||
(acc_st == ST_OACC_LOOP && st == ST_OACC_END_LOOP))
{
gcc_assert (new_st.op == EXEC_NOP);
gfc_clear_new_st ();
gfc_commit_symbols ();
gfc_warning_check ();
st = next_statement ();
}
return st;
}
/* Parse the statements of an OpenMP structured block. */
static void
@ -4307,6 +4679,21 @@ parse_executable (gfc_statement st)
parse_forall_block ();
break;
case ST_OACC_PARALLEL_LOOP:
case ST_OACC_KERNELS_LOOP:
case ST_OACC_LOOP:
st = parse_oacc_loop (st);
if (st == ST_IMPLIED_ENDDO)
return st;
continue;
case ST_OACC_PARALLEL:
case ST_OACC_KERNELS:
case ST_OACC_DATA:
case ST_OACC_HOST_DATA:
parse_oacc_structured_block (st);
break;
case ST_OMP_PARALLEL:
case ST_OMP_PARALLEL_SECTIONS:
case ST_OMP_SECTIONS:
@ -4637,6 +5024,13 @@ contains:
done:
gfc_current_ns->code = gfc_state_stack->head;
if (gfc_state_stack->state == COMP_PROGRAM
|| gfc_state_stack->state == COMP_MODULE
|| gfc_state_stack->state == COMP_SUBROUTINE
|| gfc_state_stack->state == COMP_FUNCTION
|| gfc_state_stack->state == COMP_BLOCK)
gfc_current_ns->oacc_declare_clauses
= gfc_state_stack->ext.oacc_declare_clauses;
}
@ -5155,3 +5549,28 @@ duplicate_main:
gfc_done_2 ();
return true;
}
/* Return true if this state data represents an OpenACC region. */
bool
is_oacc (gfc_state_data *sd)
{
switch (sd->construct->op)
{
case EXEC_OACC_PARALLEL_LOOP:
case EXEC_OACC_PARALLEL:
case EXEC_OACC_KERNELS_LOOP:
case EXEC_OACC_KERNELS:
case EXEC_OACC_DATA:
case EXEC_OACC_HOST_DATA:
case EXEC_OACC_LOOP:
case EXEC_OACC_UPDATE:
case EXEC_OACC_WAIT:
case EXEC_OACC_CACHE:
case EXEC_OACC_ENTER_DATA:
case EXEC_OACC_EXIT_DATA:
return true;
default:
return false;
}
}

View File

@ -49,6 +49,7 @@ typedef struct gfc_state_data
union
{
gfc_st_label *end_do_label;
gfc_omp_clauses *oacc_declare_clauses;
}
ext;
}
@ -68,4 +69,5 @@ match gfc_match_enumerator_def (void);
void gfc_free_enum_history (void);
extern bool gfc_matching_function;
match gfc_match_prefix (gfc_typespec *);
bool is_oacc (gfc_state_data *);
#endif /* GFC_PARSE_H */

View File

@ -9126,6 +9126,18 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
case EXEC_WAIT:
break;
case EXEC_OACC_PARALLEL_LOOP:
case EXEC_OACC_PARALLEL:
case EXEC_OACC_KERNELS_LOOP:
case EXEC_OACC_KERNELS:
case EXEC_OACC_DATA:
case EXEC_OACC_HOST_DATA:
case EXEC_OACC_LOOP:
case EXEC_OACC_UPDATE:
case EXEC_OACC_WAIT:
case EXEC_OACC_CACHE:
case EXEC_OACC_ENTER_DATA:
case EXEC_OACC_EXIT_DATA:
case EXEC_OMP_ATOMIC:
case EXEC_OMP_CRITICAL:
case EXEC_OMP_DISTRIBUTE:
@ -9941,6 +9953,15 @@ gfc_resolve_code (gfc_code *code, gfc_namespace *ns)
omp_workshare_save = -1;
switch (code->op)
{
case EXEC_OACC_PARALLEL_LOOP:
case EXEC_OACC_PARALLEL:
case EXEC_OACC_KERNELS_LOOP:
case EXEC_OACC_KERNELS:
case EXEC_OACC_DATA:
case EXEC_OACC_HOST_DATA:
case EXEC_OACC_LOOP:
gfc_resolve_oacc_blocks (code, ns);
break;
case EXEC_OMP_PARALLEL_WORKSHARE:
omp_workshare_save = omp_workshare_flag;
omp_workshare_flag = 1;
@ -10293,6 +10314,21 @@ gfc_resolve_code (gfc_code *code, gfc_namespace *ns)
"expression", &code->expr1->where);
break;
case EXEC_OACC_PARALLEL_LOOP:
case EXEC_OACC_PARALLEL:
case EXEC_OACC_KERNELS_LOOP:
case EXEC_OACC_KERNELS:
case EXEC_OACC_DATA:
case EXEC_OACC_HOST_DATA:
case EXEC_OACC_LOOP:
case EXEC_OACC_UPDATE:
case EXEC_OACC_WAIT:
case EXEC_OACC_CACHE:
case EXEC_OACC_ENTER_DATA:
case EXEC_OACC_EXIT_DATA:
gfc_resolve_oacc_directive (code, ns);
break;
case EXEC_OMP_ATOMIC:
case EXEC_OMP_BARRIER:
case EXEC_OMP_CANCEL:
@ -14931,6 +14967,7 @@ resolve_codes (gfc_namespace *ns)
old_obstack = labels_obstack;
bitmap_obstack_initialize (&labels_obstack);
gfc_resolve_oacc_declare (ns);
gfc_resolve_code (ns->code, ns);
bitmap_obstack_release (&labels_obstack);

View File

@ -55,9 +55,12 @@ gfc_directorylist *include_dirs, *intrinsic_modules_dirs;
static gfc_file *file_head, *current_file;
static int continue_flag, end_flag, openmp_flag, gcc_attribute_flag;
static int continue_flag, end_flag, gcc_attribute_flag;
/* If !$omp/!$acc occurred in current comment line. */
static int openmp_flag, openacc_flag;
static int continue_count, continue_line;
static locus openmp_locus;
static locus openacc_locus;
static locus gcc_attribute_locus;
gfc_source_form gfc_current_form;
@ -707,11 +710,89 @@ skip_gcc_attribute (locus start)
return r;
}
/* Return true if CC was matched. */
static bool
skip_oacc_attribute (locus start, locus old_loc, bool continue_flag)
{
bool r = false;
char c;
if ((c = next_char ()) == 'c' || c == 'C')
if ((c = next_char ()) == 'c' || c == 'C')
r = true;
if (r)
{
if ((c = next_char ()) == ' ' || c == '\t'
|| continue_flag)
{
while (gfc_is_whitespace (c))
c = next_char ();
if (c != '\n' && c != '!')
{
openacc_flag = 1;
openacc_locus = old_loc;
gfc_current_locus = start;
}
else
r = false;
}
else
{
gfc_warning_now ("!$ACC at %C starts a commented "
"line as it neither is followed "
"by a space nor is a "
"continuation line");
r = false;
}
}
return r;
}
/* Return true if MP was matched. */
static bool
skip_omp_attribute (locus start, locus old_loc, bool continue_flag)
{
bool r = false;
char c;
if ((c = next_char ()) == 'm' || c == 'M')
if ((c = next_char ()) == 'p' || c == 'P')
r = true;
if (r)
{
if ((c = next_char ()) == ' ' || c == '\t'
|| continue_flag)
{
while (gfc_is_whitespace (c))
c = next_char ();
if (c != '\n' && c != '!')
{
openmp_flag = 1;
openmp_locus = old_loc;
gfc_current_locus = start;
}
else
r = false;
}
else
{
gfc_warning_now ("!$OMP at %C starts a commented "
"line as it neither is followed "
"by a space nor is a "
"continuation line");
r = false;
}
}
return r;
}
/* Comment lines are null lines, lines containing only blanks or lines
on which the first nonblank line is a '!'.
Return true if !$ openmp conditional compilation sentinel was
Return true if !$ openmp or openacc conditional compilation sentinel was
seen. */
static bool
@ -744,55 +825,98 @@ skip_free_comments (void)
if (at_bol && skip_gcc_attribute (start))
return false;
/* If -fopenmp, we need to handle here 2 things:
1) don't treat !$omp as comments, but directives
2) handle OpenMP conditional compilation, where
/* If -fopenmp/-fopenacc, we need to handle here 2 things:
1) don't treat !$omp/!$acc as comments, but directives
2) handle OpenMP/OpenACC conditional compilation, where
!$ should be treated as 2 spaces (for initial lines
only if followed by space). */
if ((flag_openmp || flag_openmp_simd) && at_bol)
{
locus old_loc = gfc_current_locus;
if (next_char () == '$')
{
c = next_char ();
if (c == 'o' || c == 'O')
{
if (((c = next_char ()) == 'm' || c == 'M')
&& ((c = next_char ()) == 'p' || c == 'P'))
if (at_bol)
{
if ((flag_openmp || flag_openmp_simd)
&& flag_openacc)
{
locus old_loc = gfc_current_locus;
if (next_char () == '$')
{
c = next_char ();
if (c == 'o' || c == 'O')
{
if (skip_omp_attribute (start, old_loc, continue_flag))
return false;
gfc_current_locus = old_loc;
next_char ();
c = next_char ();
}
else if (c == 'a' || c == 'A')
{
if (skip_oacc_attribute (start, old_loc, continue_flag))
return false;
gfc_current_locus = old_loc;
next_char ();
c = next_char ();
}
if (continue_flag || c == ' ' || c == '\t')
{
gfc_current_locus = old_loc;
next_char ();
openmp_flag = openacc_flag = 0;
return true;
}
}
gfc_current_locus = old_loc;
}
else if ((flag_openmp || flag_openmp_simd)
&& !flag_openacc)
{
locus old_loc = gfc_current_locus;
if (next_char () == '$')
{
c = next_char ();
if (c == 'o' || c == 'O')
{
if (skip_omp_attribute (start, old_loc, continue_flag))
return false;
gfc_current_locus = old_loc;
next_char ();
c = next_char ();
}
if (continue_flag || c == ' ' || c == '\t')
{
gfc_current_locus = old_loc;
next_char ();
openmp_flag = 0;
return true;
}
}
gfc_current_locus = old_loc;
}
else if (flag_openacc
&& !(flag_openmp || flag_openmp_simd))
{
locus old_loc = gfc_current_locus;
if (next_char () == '$')
{
c = next_char ();
if (c == 'a' || c == 'A')
{
if ((c = next_char ()) == ' ' || c == '\t'
|| continue_flag)
{
while (gfc_is_whitespace (c))
c = next_char ();
if (c != '\n' && c != '!')
{
openmp_flag = 1;
openmp_locus = old_loc;
gfc_current_locus = start;
return false;
}
}
else
gfc_warning_now ("!$OMP at %C starts a commented "
"line as it neither is followed "
"by a space nor is a "
"continuation line");
if (skip_oacc_attribute (start, old_loc,
continue_flag))
return false;
gfc_current_locus = old_loc;
next_char();
c = next_char();
}
gfc_current_locus = old_loc;
next_char ();
c = next_char ();
}
if (continue_flag || c == ' ' || c == '\t')
{
gfc_current_locus = old_loc;
next_char ();
openmp_flag = 0;
return true;
}
}
gfc_current_locus = old_loc;
}
if (continue_flag || c == ' ' || c == '\t')
{
gfc_current_locus = old_loc;
next_char();
openacc_flag = 0;
return true;
}
}
gfc_current_locus = old_loc;
}
}
skip_comment_line ();
continue;
}
@ -803,6 +927,9 @@ skip_free_comments (void)
if (openmp_flag && at_bol)
openmp_flag = 0;
if (openacc_flag && at_bol)
openacc_flag = 0;
gcc_attribute_flag = 0;
gfc_current_locus = start;
return false;
@ -865,9 +992,10 @@ skip_fixed_comments (void)
return;
}
/* If -fopenmp, we need to handle here 2 things:
1) don't treat !$omp|c$omp|*$omp as comments, but directives
2) handle OpenMP conditional compilation, where
/* If -fopenmp/-fopenacc, we need to handle here 2 things:
1) don't treat !$omp/!$acc|c$omp/c$acc|*$omp / *$acc as comments,
but directives
2) handle OpenMP/OpenACC conditional compilation, where
!$|c$|*$ should be treated as 2 spaces if the characters
in columns 3 to 6 are valid fixed form label columns
characters. */
@ -934,6 +1062,67 @@ skip_fixed_comments (void)
}
gfc_current_locus = start;
}
if (flag_openacc)
{
if (next_char () == '$')
{
c = next_char ();
if (c == 'a' || c == 'A')
{
if (((c = next_char ()) == 'c' || c == 'C')
&& ((c = next_char ()) == 'c' || c == 'C'))
{
c = next_char ();
if (c != '\n'
&& ((openacc_flag && continue_flag)
|| c == ' ' || c == '\t' || c == '0'))
{
do
c = next_char ();
while (gfc_is_whitespace (c));
if (c != '\n' && c != '!')
{
/* Canonicalize to *$acc. */
*start.nextc = '*';
openacc_flag = 1;
gfc_current_locus = start;
return;
}
}
}
}
else
{
int digit_seen = 0;
for (col = 3; col < 6; col++, c = next_char ())
if (c == ' ')
continue;
else if (c == '\t')
{
col = 6;
break;
}
else if (c < '0' || c > '9')
break;
else
digit_seen = 1;
if (col == 6 && c != '\n'
&& ((continue_flag && !digit_seen)
|| c == ' ' || c == '\t' || c == '0'))
{
gfc_current_locus = start;
start.nextc[0] = ' ';
start.nextc[1] = ' ';
continue;
}
}
}
gfc_current_locus = start;
}
skip_comment_line ();
continue;
}
@ -976,6 +1165,7 @@ skip_fixed_comments (void)
}
openmp_flag = 0;
openacc_flag = 0;
gcc_attribute_flag = 0;
gfc_current_locus = start;
}
@ -1004,10 +1194,11 @@ gfc_char_t
gfc_next_char_literal (gfc_instring in_string)
{
locus old_loc;
int i, prev_openmp_flag;
int i, prev_openmp_flag, prev_openacc_flag;
gfc_char_t c;
continue_flag = 0;
prev_openacc_flag = prev_openmp_flag = 0;
restart:
c = next_char ();
@ -1033,6 +1224,11 @@ restart:
sizeof (gfc_current_locus)) == 0)
goto done;
if (openacc_flag
&& memcmp (&gfc_current_locus, &openacc_locus,
sizeof (gfc_current_locus)) == 0)
goto done;
/* This line can't be continued */
do
{
@ -1088,7 +1284,11 @@ restart:
goto done;
}
prev_openmp_flag = openmp_flag;
if (flag_openmp)
prev_openmp_flag = openmp_flag;
if (flag_openacc)
prev_openacc_flag = openacc_flag;
continue_flag = 1;
if (c == '!')
skip_comment_line ();
@ -1118,13 +1318,23 @@ restart:
&& continue_line < gfc_linebuf_linenum (gfc_current_locus.lb))
continue_line = gfc_linebuf_linenum (gfc_current_locus.lb);
if (prev_openmp_flag != openmp_flag)
{
gfc_current_locus = old_loc;
openmp_flag = prev_openmp_flag;
c = '&';
goto done;
}
if (flag_openmp)
if (prev_openmp_flag != openmp_flag)
{
gfc_current_locus = old_loc;
openmp_flag = prev_openmp_flag;
c = '&';
goto done;
}
if (flag_openacc)
if (prev_openacc_flag != openacc_flag)
{
gfc_current_locus = old_loc;
openacc_flag = prev_openacc_flag;
c = '&';
goto done;
}
/* Now that we have a non-comment line, probe ahead for the
first non-whitespace character. If it is another '&', then
@ -1148,6 +1358,17 @@ restart:
while (gfc_is_whitespace (c))
c = next_char ();
}
if (openacc_flag)
{
for (i = 0; i < 5; i++, c = next_char ())
{
gcc_assert (gfc_wide_tolower (c) == (unsigned char) "!$acc"[i]);
if (i == 4)
old_loc = gfc_current_locus;
}
while (gfc_is_whitespace (c))
c = next_char ();
}
if (c != '&')
{
@ -1161,7 +1382,7 @@ restart:
}
/* Both !$omp and !$ -fopenmp continuation lines have & on the
continuation line only optionally. */
else if (openmp_flag || openmp_cond_flag)
else if (openmp_flag || openacc_flag || openmp_cond_flag)
gfc_current_locus.nextc--;
else
{
@ -1199,7 +1420,11 @@ restart:
"Line truncated at %L", &gfc_current_locus);
}
prev_openmp_flag = openmp_flag;
if (flag_openmp)
prev_openmp_flag = openmp_flag;
if (flag_openacc)
prev_openacc_flag = openacc_flag;
continue_flag = 1;
old_loc = gfc_current_locus;
@ -1207,26 +1432,38 @@ restart:
skip_fixed_comments ();
/* See if this line is a continuation line. */
if (openmp_flag != prev_openmp_flag)
if (flag_openmp && openmp_flag != prev_openmp_flag)
{
openmp_flag = prev_openmp_flag;
goto not_continuation;
}
if (flag_openacc && openacc_flag != prev_openacc_flag)
{
openacc_flag = prev_openacc_flag;
goto not_continuation;
}
if (!openmp_flag)
if (!openmp_flag && !openacc_flag)
for (i = 0; i < 5; i++)
{
c = next_char ();
if (c != ' ')
goto not_continuation;
}
else
else if (openmp_flag)
for (i = 0; i < 5; i++)
{
c = next_char ();
if (gfc_wide_tolower (c) != (unsigned char) "*$omp"[i])
goto not_continuation;
}
else if (openacc_flag)
for (i = 0; i < 5; i++)
{
c = next_char ();
if (gfc_wide_tolower (c) != (unsigned char) "*$acc"[i])
goto not_continuation;
}
c = next_char ();
if (c == '0' || c == ' ' || c == '\n')

View File

@ -185,6 +185,18 @@ gfc_free_statement (gfc_code *p)
gfc_free_forall_iterator (p->ext.forall_iterator);
break;
case EXEC_OACC_PARALLEL_LOOP:
case EXEC_OACC_PARALLEL:
case EXEC_OACC_KERNELS_LOOP:
case EXEC_OACC_KERNELS:
case EXEC_OACC_DATA:
case EXEC_OACC_HOST_DATA:
case EXEC_OACC_LOOP:
case EXEC_OACC_UPDATE:
case EXEC_OACC_WAIT:
case EXEC_OACC_CACHE:
case EXEC_OACC_ENTER_DATA:
case EXEC_OACC_EXIT_DATA:
case EXEC_OMP_CANCEL:
case EXEC_OMP_CANCELLATION_POINT:
case EXEC_OMP_DISTRIBUTE:

View File

@ -5804,6 +5804,13 @@ gfc_generate_function_code (gfc_namespace * ns)
if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !sym->attr.is_bind_c)
add_argument_checking (&body, sym);
/* Generate !$ACC DECLARE directive. */
if (ns->oacc_declare_clauses)
{
tree tmp = gfc_trans_oacc_declare (&body, ns);
gfc_add_expr_to_block (&body, tmp);
}
tmp = gfc_trans_code (ns->code);
gfc_add_expr_to_block (&body, tmp);

View File

@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "trans-const.h"
#include "arith.h"
#include "omp-low.h"
#include "gomp-constants.h"
int ompws_flags;
@ -1045,7 +1046,7 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p)
return;
tree orig_decl = decl;
c4 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (c4) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_POINTER);
OMP_CLAUSE_DECL (c4) = decl;
OMP_CLAUSE_SIZE (c4) = size_int (0);
decl = build_fold_indirect_ref (decl);
@ -1056,7 +1057,7 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p)
|| GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl)))
{
c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (c3) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_POINTER);
OMP_CLAUSE_DECL (c3) = unshare_expr (decl);
OMP_CLAUSE_SIZE (c3) = size_int (0);
decl = build_fold_indirect_ref (decl);
@ -1073,11 +1074,11 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p)
ptr = build_fold_indirect_ref (ptr);
OMP_CLAUSE_DECL (c) = ptr;
c2 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (c2) = OMP_CLAUSE_MAP_TO_PSET;
OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_TO_PSET);
OMP_CLAUSE_DECL (c2) = decl;
OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (type);
c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (c3) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_POINTER);
OMP_CLAUSE_DECL (c3) = gfc_conv_descriptor_data_get (decl);
OMP_CLAUSE_SIZE (c3) = size_int (0);
tree size = create_tmp_var (gfc_array_index_type);
@ -1718,6 +1719,21 @@ gfc_trans_omp_reduction_list (gfc_omp_namelist *namelist, tree list,
return list;
}
static inline tree
gfc_convert_expr_to_tree (stmtblock_t *block, gfc_expr *expr)
{
gfc_se se;
tree result;
gfc_init_se (&se, NULL );
gfc_conv_expr (&se, expr);
gfc_add_block_to_block (block, &se.pre);
result = gfc_evaluate_now (se.expr, block);
gfc_add_block_to_block (block, &se.post);
return result;
}
static tree
gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
locus where, bool declare_simd = false)
@ -1761,7 +1777,17 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
goto add_clause;
case OMP_LIST_UNIFORM:
clause_code = OMP_CLAUSE_UNIFORM;
/* FALLTHROUGH */
goto add_clause;
case OMP_LIST_USE_DEVICE:
clause_code = OMP_CLAUSE_USE_DEVICE;
goto add_clause;
case OMP_LIST_DEVICE_RESIDENT:
clause_code = OMP_CLAUSE_DEVICE_RESIDENT;
goto add_clause;
case OMP_LIST_CACHE:
clause_code = OMP_CLAUSE__CACHE_;
goto add_clause;
add_clause:
omp_clauses
= gfc_trans_omp_variable_list (clause_code, n, omp_clauses,
@ -1928,7 +1954,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
tree orig_decl = decl;
node4 = build_omp_clause (input_location,
OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (node4) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
OMP_CLAUSE_DECL (node4) = decl;
OMP_CLAUSE_SIZE (node4) = size_int (0);
decl = build_fold_indirect_ref (decl);
@ -1938,7 +1964,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
{
node3 = build_omp_clause (input_location,
OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (node3) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
OMP_CLAUSE_DECL (node3) = decl;
OMP_CLAUSE_SIZE (node3) = size_int (0);
decl = build_fold_indirect_ref (decl);
@ -1954,12 +1980,12 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
OMP_CLAUSE_DECL (node) = ptr;
node2 = build_omp_clause (input_location,
OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (node2) = OMP_CLAUSE_MAP_TO_PSET;
OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET);
OMP_CLAUSE_DECL (node2) = decl;
OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
node3 = build_omp_clause (input_location,
OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (node3) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
OMP_CLAUSE_DECL (node3)
= gfc_conv_descriptor_data_get (decl);
OMP_CLAUSE_SIZE (node3) = size_int (0);
@ -2045,7 +2071,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
{
node4 = build_omp_clause (input_location,
OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (node4) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
OMP_CLAUSE_DECL (node4) = decl;
OMP_CLAUSE_SIZE (node4) = size_int (0);
decl = build_fold_indirect_ref (decl);
@ -2057,12 +2083,12 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
ptr2 = gfc_conv_descriptor_data_get (decl);
node2 = build_omp_clause (input_location,
OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (node2) = OMP_CLAUSE_MAP_TO_PSET;
OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET);
OMP_CLAUSE_DECL (node2) = decl;
OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
node3 = build_omp_clause (input_location,
OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (node3) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
OMP_CLAUSE_DECL (node3)
= gfc_conv_descriptor_data_get (decl);
}
@ -2077,7 +2103,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
}
node3 = build_omp_clause (input_location,
OMP_CLAUSE_MAP);
OMP_CLAUSE_MAP_KIND (node3) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
OMP_CLAUSE_DECL (node3) = decl;
}
ptr2 = fold_convert (sizetype, ptr2);
@ -2087,16 +2113,37 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
switch (n->u.map_op)
{
case OMP_MAP_ALLOC:
OMP_CLAUSE_MAP_KIND (node) = OMP_CLAUSE_MAP_ALLOC;
OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALLOC);
break;
case OMP_MAP_TO:
OMP_CLAUSE_MAP_KIND (node) = OMP_CLAUSE_MAP_TO;
OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_TO);
break;
case OMP_MAP_FROM:
OMP_CLAUSE_MAP_KIND (node) = OMP_CLAUSE_MAP_FROM;
OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FROM);
break;
case OMP_MAP_TOFROM:
OMP_CLAUSE_MAP_KIND (node) = OMP_CLAUSE_MAP_TOFROM;
OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_TOFROM);
break;
case OMP_MAP_FORCE_ALLOC:
OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_ALLOC);
break;
case OMP_MAP_FORCE_DEALLOC:
OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_DEALLOC);
break;
case OMP_MAP_FORCE_TO:
OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_TO);
break;
case OMP_MAP_FORCE_FROM:
OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_FROM);
break;
case OMP_MAP_FORCE_TOFROM:
OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_TOFROM);
break;
case OMP_MAP_FORCE_PRESENT:
OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_PRESENT);
break;
case OMP_MAP_FORCE_DEVICEPTR:
OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_DEVICEPTR);
break;
default:
gcc_unreachable ();
@ -2463,6 +2510,111 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
if (clauses->async)
{
c = build_omp_clause (where.lb->location, OMP_CLAUSE_ASYNC);
if (clauses->async_expr)
OMP_CLAUSE_ASYNC_EXPR (c)
= gfc_convert_expr_to_tree (block, clauses->async_expr);
else
OMP_CLAUSE_ASYNC_EXPR (c) = NULL;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
if (clauses->seq)
{
c = build_omp_clause (where.lb->location, OMP_CLAUSE_ORDERED);
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
if (clauses->independent)
{
c = build_omp_clause (where.lb->location, OMP_CLAUSE_INDEPENDENT);
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
if (clauses->wait_list)
{
gfc_expr_list *el;
for (el = clauses->wait_list; el; el = el->next)
{
c = build_omp_clause (where.lb->location, OMP_CLAUSE_WAIT);
OMP_CLAUSE_DECL (c) = gfc_convert_expr_to_tree (block, el->expr);
OMP_CLAUSE_CHAIN (c) = omp_clauses;
omp_clauses = c;
}
}
if (clauses->num_gangs_expr)
{
tree num_gangs_var
= gfc_convert_expr_to_tree (block, clauses->num_gangs_expr);
c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_GANGS);
OMP_CLAUSE_NUM_GANGS_EXPR (c) = num_gangs_var;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
if (clauses->num_workers_expr)
{
tree num_workers_var
= gfc_convert_expr_to_tree (block, clauses->num_workers_expr);
c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_WORKERS);
OMP_CLAUSE_NUM_WORKERS_EXPR (c) = num_workers_var;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
if (clauses->vector_length_expr)
{
tree vector_length_var
= gfc_convert_expr_to_tree (block, clauses->vector_length_expr);
c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR_LENGTH);
OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = vector_length_var;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
if (clauses->vector)
{
if (clauses->vector_expr)
{
tree vector_var
= gfc_convert_expr_to_tree (block, clauses->vector_expr);
c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR);
OMP_CLAUSE_VECTOR_EXPR (c) = vector_var;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
else
{
c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR);
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
}
if (clauses->worker)
{
if (clauses->worker_expr)
{
tree worker_var
= gfc_convert_expr_to_tree (block, clauses->worker_expr);
c = build_omp_clause (where.lb->location, OMP_CLAUSE_WORKER);
OMP_CLAUSE_WORKER_EXPR (c) = worker_var;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
else
{
c = build_omp_clause (where.lb->location, OMP_CLAUSE_WORKER);
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
}
if (clauses->gang)
{
if (clauses->gang_expr)
{
tree gang_var
= gfc_convert_expr_to_tree (block, clauses->gang_expr);
c = build_omp_clause (where.lb->location, OMP_CLAUSE_GANG);
OMP_CLAUSE_GANG_EXPR (c) = gang_var;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
else
{
c = build_omp_clause (where.lb->location, OMP_CLAUSE_GANG);
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
}
return nreverse (omp_clauses);
}
@ -2490,6 +2642,115 @@ gfc_trans_omp_code (gfc_code *code, bool force_empty)
return stmt;
}
/* Trans OpenACC directives. */
/* parallel, kernels, data and host_data. */
static tree
gfc_trans_oacc_construct (gfc_code *code)
{
stmtblock_t block;
tree stmt, oacc_clauses;
enum tree_code construct_code;
switch (code->op)
{
case EXEC_OACC_PARALLEL:
construct_code = OACC_PARALLEL;
break;
case EXEC_OACC_KERNELS:
construct_code = OACC_KERNELS;
break;
case EXEC_OACC_DATA:
construct_code = OACC_DATA;
break;
case EXEC_OACC_HOST_DATA:
construct_code = OACC_HOST_DATA;
break;
default:
gcc_unreachable ();
}
gfc_start_block (&block);
oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
code->loc);
stmt = gfc_trans_omp_code (code->block->next, true);
stmt = build2_loc (input_location, construct_code, void_type_node, stmt,
oacc_clauses);
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
}
/* update, enter_data, exit_data, cache. */
static tree
gfc_trans_oacc_executable_directive (gfc_code *code)
{
stmtblock_t block;
tree stmt, oacc_clauses;
enum tree_code construct_code;
switch (code->op)
{
case EXEC_OACC_UPDATE:
construct_code = OACC_UPDATE;
break;
case EXEC_OACC_ENTER_DATA:
construct_code = OACC_ENTER_DATA;
break;
case EXEC_OACC_EXIT_DATA:
construct_code = OACC_EXIT_DATA;
break;
case EXEC_OACC_CACHE:
construct_code = OACC_CACHE;
break;
default:
gcc_unreachable ();
}
gfc_start_block (&block);
oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
code->loc);
stmt = build1_loc (input_location, construct_code, void_type_node,
oacc_clauses);
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
}
static tree
gfc_trans_oacc_wait_directive (gfc_code *code)
{
stmtblock_t block;
tree stmt, t;
vec<tree, va_gc> *args;
int nparms = 0;
gfc_expr_list *el;
gfc_omp_clauses *clauses = code->ext.omp_clauses;
location_t loc = input_location;
for (el = clauses->wait_list; el; el = el->next)
nparms++;
vec_alloc (args, nparms + 2);
stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
gfc_start_block (&block);
if (clauses->async_expr)
t = gfc_convert_expr_to_tree (&block, clauses->async_expr);
else
t = build_int_cst (integer_type_node, -2);
args->quick_push (t);
args->quick_push (build_int_cst (integer_type_node, nparms));
for (el = clauses->wait_list; el; el = el->next)
args->quick_push (gfc_convert_expr_to_tree (&block, el->expr));
stmt = build_call_expr_loc_vec (loc, stmt, args);
gfc_add_expr_to_block (&block, stmt);
vec_free (args);
return gfc_finish_block (&block);
}
static tree gfc_trans_omp_sections (gfc_code *, gfc_omp_clauses *);
static tree gfc_trans_omp_workshare (gfc_code *, gfc_omp_clauses *);
@ -3115,6 +3376,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
case EXEC_OMP_SIMD: stmt = make_node (OMP_SIMD); break;
case EXEC_OMP_DO: stmt = make_node (OMP_FOR); break;
case EXEC_OMP_DISTRIBUTE: stmt = make_node (OMP_DISTRIBUTE); break;
case EXEC_OACC_LOOP: stmt = make_node (OACC_LOOP); break;
default: gcc_unreachable ();
}
@ -3129,6 +3391,68 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
return gfc_finish_block (&block);
}
/* parallel loop and kernels loop. */
static tree
gfc_trans_oacc_combined_directive (gfc_code *code)
{
stmtblock_t block, *pblock = NULL;
gfc_omp_clauses construct_clauses, loop_clauses;
tree stmt, oacc_clauses = NULL_TREE;
enum tree_code construct_code;
switch (code->op)
{
case EXEC_OACC_PARALLEL_LOOP:
construct_code = OACC_PARALLEL;
break;
case EXEC_OACC_KERNELS_LOOP:
construct_code = OACC_KERNELS;
break;
default:
gcc_unreachable ();
}
gfc_start_block (&block);
memset (&loop_clauses, 0, sizeof (loop_clauses));
if (code->ext.omp_clauses != NULL)
{
memcpy (&construct_clauses, code->ext.omp_clauses,
sizeof (construct_clauses));
loop_clauses.collapse = construct_clauses.collapse;
loop_clauses.gang = construct_clauses.gang;
loop_clauses.vector = construct_clauses.vector;
loop_clauses.worker = construct_clauses.worker;
loop_clauses.seq = construct_clauses.seq;
loop_clauses.independent = construct_clauses.independent;
construct_clauses.collapse = 0;
construct_clauses.gang = false;
construct_clauses.vector = false;
construct_clauses.worker = false;
construct_clauses.seq = false;
construct_clauses.independent = false;
oacc_clauses = gfc_trans_omp_clauses (&block, &construct_clauses,
code->loc);
}
if (!loop_clauses.seq)
pblock = &block;
else
pushlevel ();
stmt = gfc_trans_omp_do (code, code->op, pblock, &loop_clauses, NULL);
if (TREE_CODE (stmt) != BIND_EXPR)
stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
else
poplevel (0, 0);
stmt = build2_loc (input_location, construct_code, void_type_node, stmt,
oacc_clauses);
if (code->op == EXEC_OACC_KERNELS_LOOP)
OACC_KERNELS_COMBINED (stmt) = 1;
else
OACC_PARALLEL_COMBINED (stmt) = 1;
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
}
static tree
gfc_trans_omp_flush (void)
{
@ -4018,6 +4342,44 @@ gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
return stmt;
}
tree
gfc_trans_oacc_declare (stmtblock_t *block, gfc_namespace *ns)
{
tree oacc_clauses;
oacc_clauses = gfc_trans_omp_clauses (block, ns->oacc_declare_clauses,
ns->oacc_declare_clauses->loc);
return build1_loc (ns->oacc_declare_clauses->loc.lb->location,
OACC_DECLARE, void_type_node, oacc_clauses);
}
tree
gfc_trans_oacc_directive (gfc_code *code)
{
switch (code->op)
{
case EXEC_OACC_PARALLEL_LOOP:
case EXEC_OACC_KERNELS_LOOP:
return gfc_trans_oacc_combined_directive (code);
case EXEC_OACC_PARALLEL:
case EXEC_OACC_KERNELS:
case EXEC_OACC_DATA:
case EXEC_OACC_HOST_DATA:
return gfc_trans_oacc_construct (code);
case EXEC_OACC_LOOP:
return gfc_trans_omp_do (code, code->op, NULL, code->ext.omp_clauses,
NULL);
case EXEC_OACC_UPDATE:
case EXEC_OACC_CACHE:
case EXEC_OACC_ENTER_DATA:
case EXEC_OACC_EXIT_DATA:
return gfc_trans_oacc_executable_directive (code);
case EXEC_OACC_WAIT:
return gfc_trans_oacc_wait_directive (code);
default:
gcc_unreachable ();
}
}
tree
gfc_trans_omp_directive (gfc_code *code)
{

View File

@ -1378,6 +1378,14 @@ gfc_trans_block_construct (gfc_code* code)
gfc_init_block (&body);
exit_label = gfc_build_label_decl (NULL_TREE);
code->exit_label = exit_label;
/* Generate !$ACC DECLARE directive. */
if (ns->oacc_declare_clauses)
{
tree tmp = gfc_trans_oacc_declare (&body, ns);
gfc_add_expr_to_block (&body, tmp);
}
gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));

View File

@ -65,6 +65,10 @@ tree gfc_trans_deallocate_array (tree);
tree gfc_trans_omp_directive (gfc_code *);
void gfc_trans_omp_declare_simd (gfc_namespace *);
/* trans-openacc.c */
tree gfc_trans_oacc_directive (gfc_code *);
tree gfc_trans_oacc_declare (stmtblock_t *block, gfc_namespace *);
/* trans-io.c */
tree gfc_trans_open (gfc_code *);
tree gfc_trans_close (gfc_code *);

View File

@ -1900,6 +1900,21 @@ trans_code (gfc_code * code, tree cond)
res = gfc_trans_omp_directive (code);
break;
case EXEC_OACC_CACHE:
case EXEC_OACC_WAIT:
case EXEC_OACC_UPDATE:
case EXEC_OACC_LOOP:
case EXEC_OACC_HOST_DATA:
case EXEC_OACC_DATA:
case EXEC_OACC_KERNELS:
case EXEC_OACC_KERNELS_LOOP:
case EXEC_OACC_PARALLEL:
case EXEC_OACC_PARALLEL_LOOP:
case EXEC_OACC_ENTER_DATA:
case EXEC_OACC_EXIT_DATA:
res = gfc_trans_oacc_directive (code);
break;
default:
gfc_internal_error ("gfc_trans_code(): Bad statement code");
}

View File

@ -82,6 +82,7 @@ DEF_FUNCTION_TYPE_0 (BT_FN_VOID, BT_VOID)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_PTR, BT_VOID, BT_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_PTRPTR, BT_VOID, BT_PTR_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_VPTR, BT_VOID, BT_VOLATILE_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_INT, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_1 (BT_FN_UINT_UINT, BT_UINT, BT_UINT)
DEF_FUNCTION_TYPE_1 (BT_FN_PTR_PTR, BT_PTR, BT_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_INT, BT_VOID, BT_INT)
@ -209,3 +210,14 @@ DEF_FUNCTION_TYPE_8 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR,
BT_BOOL, BT_UINT, BT_PTR)
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
DEF_FUNCTION_TYPE_VAR_2 (BT_FN_VOID_INT_INT_VAR, BT_VOID, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_VAR_8 (BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR_INT_INT_VAR,
BT_VOID, BT_INT, BT_PTR, BT_SIZE, BT_PTR, BT_PTR,
BT_PTR, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_VAR_12 (BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR_INT_INT_INT_INT_INT_VAR,
BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_PTR, BT_SIZE,
BT_PTR, BT_PTR, BT_PTR, BT_INT, BT_INT, BT_INT,
BT_INT, BT_INT)

View File

@ -829,7 +829,7 @@ proper position among the other output files. */
"%X %{o*} %{e*} %{N} %{n} %{r}\
%{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} " VTABLE_VERIFICATION_SPEC " \
%{static:} %{L*} %(mfwrap) %(link_libgcc) " SANITIZER_EARLY_SPEC " %o\
%{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
%{fopenacc|fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
%{fcilkplus:%:include(libcilkrts.spec)%(link_cilkrts)}\
%{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
%(mflib) " STACK_SPLIT_SPEC "\
@ -990,7 +990,8 @@ static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
/* Linking to libgomp implies pthreads. This is particularly important
for targets that use different start files and suchlike. */
#ifndef GOMP_SELF_SPECS
#define GOMP_SELF_SPECS "%{fopenmp|ftree-parallelize-loops=*: -pthread}"
#define GOMP_SELF_SPECS "%{fopenacc|fopenmp|ftree-parallelize-loops=*: " \
"-pthread}"
#endif
/* Likewise for -fgnu-tm. */

View File

@ -1151,18 +1151,21 @@ dump_gimple_omp_for (pretty_printer *buffer, gomp_for *gs, int spc, int flags)
case GF_OMP_FOR_KIND_FOR:
kind = "";
break;
case GF_OMP_FOR_KIND_SIMD:
kind = " simd";
break;
case GF_OMP_FOR_KIND_CILKSIMD:
kind = " cilksimd";
break;
case GF_OMP_FOR_KIND_DISTRIBUTE:
kind = " distribute";
break;
case GF_OMP_FOR_KIND_CILKFOR:
kind = " _Cilk_for";
break;
case GF_OMP_FOR_KIND_OACC_LOOP:
kind = " oacc_loop";
break;
case GF_OMP_FOR_KIND_SIMD:
kind = " simd";
break;
case GF_OMP_FOR_KIND_CILKSIMD:
kind = " cilksimd";
break;
default:
gcc_unreachable ();
}
@ -1188,17 +1191,20 @@ dump_gimple_omp_for (pretty_printer *buffer, gomp_for *gs, int spc, int flags)
case GF_OMP_FOR_KIND_FOR:
pp_string (buffer, "#pragma omp for");
break;
case GF_OMP_FOR_KIND_DISTRIBUTE:
pp_string (buffer, "#pragma omp distribute");
break;
case GF_OMP_FOR_KIND_CILKFOR:
break;
case GF_OMP_FOR_KIND_OACC_LOOP:
pp_string (buffer, "#pragma acc loop");
break;
case GF_OMP_FOR_KIND_SIMD:
pp_string (buffer, "#pragma omp simd");
break;
case GF_OMP_FOR_KIND_CILKSIMD:
pp_string (buffer, "#pragma simd");
break;
case GF_OMP_FOR_KIND_DISTRIBUTE:
pp_string (buffer, "#pragma omp distribute");
break;
case GF_OMP_FOR_KIND_CILKFOR:
break;
default:
gcc_unreachable ();
}
@ -1344,6 +1350,21 @@ dump_gimple_omp_target (pretty_printer *buffer, gomp_target *gs,
case GF_OMP_TARGET_KIND_UPDATE:
kind = " update";
break;
case GF_OMP_TARGET_KIND_OACC_KERNELS:
kind = " oacc_kernels";
break;
case GF_OMP_TARGET_KIND_OACC_PARALLEL:
kind = " oacc_parallel";
break;
case GF_OMP_TARGET_KIND_OACC_DATA:
kind = " oacc_data";
break;
case GF_OMP_TARGET_KIND_OACC_UPDATE:
kind = " oacc_update";
break;
case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
kind = " oacc_enter_exit_data";
break;
default:
gcc_unreachable ();
}
@ -1352,7 +1373,9 @@ dump_gimple_omp_target (pretty_printer *buffer, gomp_target *gs,
dump_gimple_fmt (buffer, spc, flags, "%G%s <%+BODY <%S>%nCLAUSES <", gs,
kind, gimple_omp_body (gs));
dump_omp_clauses (buffer, gimple_omp_target_clauses (gs), spc, flags);
dump_gimple_fmt (buffer, spc, flags, " >");
dump_gimple_fmt (buffer, spc, flags, " >, %T, %T%n>",
gimple_omp_target_child_fn (gs),
gimple_omp_target_data_arg (gs));
}
else
{
@ -1364,16 +1387,28 @@ dump_gimple_omp_target (pretty_printer *buffer, gomp_target *gs,
pp_string (buffer, " [child fn: ");
dump_generic_node (buffer, gimple_omp_target_child_fn (gs),
spc, flags, false);
pp_right_bracket (buffer);
pp_string (buffer, " (");
if (gimple_omp_target_data_arg (gs))
dump_generic_node (buffer, gimple_omp_target_data_arg (gs),
spc, flags, false);
else
pp_string (buffer, "???");
pp_string (buffer, ")]");
}
if (!gimple_seq_empty_p (gimple_omp_body (gs)))
gimple_seq body = gimple_omp_body (gs);
if (body && gimple_code (gimple_seq_first_stmt (body)) != GIMPLE_BIND)
{
newline_and_indent (buffer, spc + 2);
pp_character (buffer, '{');
pp_left_brace (buffer);
pp_newline (buffer);
dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
dump_gimple_seq (buffer, body, spc + 4, flags);
newline_and_indent (buffer, spc + 2);
pp_character (buffer, '}');
pp_right_brace (buffer);
}
else if (body)
{
pp_newline (buffer);
dump_gimple_seq (buffer, body, spc + 2, flags);
}
}
}

View File

@ -872,8 +872,7 @@ gimple_build_omp_critical (gimple_seq body, tree name)
BODY is sequence of statements inside the for loop.
KIND is the `for' variant.
CLAUSES, are any of the OMP loop construct's clauses: private, firstprivate,
lastprivate, reductions, ordered, schedule, and nowait.
CLAUSES, are any of the construct's clauses.
COLLAPSE is the collapse count.
PRE_BODY is the sequence of statements that are loop invariant. */
@ -1088,7 +1087,8 @@ gimple_build_omp_single (gimple_seq body, tree clauses)
/* Build a GIMPLE_OMP_TARGET statement.
BODY is the sequence of statements that will be executed.
CLAUSES are any of the OMP target construct's clauses. */
KIND is the kind of the region.
CLAUSES are any of the construct's clauses. */
gomp_target *
gimple_build_omp_target (gimple_seq body, int kind, tree clauses)

View File

@ -243,6 +243,9 @@ DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", GSS_OMP_CRITICAL)
for (INDEX = INITIAL; INDEX COND FINAL; INDEX {+=,-=} INCR)
BODY
Likewise for:
#pragma acc loop [clause1 ... clauseN]
BODY is the loop body.
CLAUSES is the list of clauses.
@ -269,7 +272,7 @@ DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", GSS_OMP_CRITICAL)
INITIAL, FINAL and INCR are required to be loop invariant integer
expressions that are evaluated without any synchronization.
The evaluation order, frequency of evaluation and side-effects are
unspecified by the standard. */
unspecified by the standards. */
DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", GSS_OMP_FOR)
/* GIMPLE_OMP_MASTER <BODY> represents #pragma omp master.
@ -354,11 +357,12 @@ DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE)
DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE_LAYOUT)
/* GIMPLE_OMP_TARGET <BODY, CLAUSES, CHILD_FN> represents
#pragma acc {kernels,parallel,data,enter data,exit data,update}
#pragma omp target {,data,update}
BODY is the sequence of statements inside the target construct
(NULL for target update).
BODY is the sequence of statements inside the construct
(NULL for some variants).
CLAUSES is an OMP_CLAUSE chain holding the associated clauses.
CHILD_FN is set when outlining the body of the target region.
CHILD_FN is set when outlining the body of the offloaded region.
All the statements in BODY are moved into this newly created
function when converting OMP constructs into low-GIMPLE.
DATA_ARG is a vec of 3 local variables in the parent function

View File

@ -89,20 +89,26 @@ enum gf_mask {
GF_CALL_CTRL_ALTERING = 1 << 7,
GF_CALL_WITH_BOUNDS = 1 << 8,
GF_OMP_PARALLEL_COMBINED = 1 << 0,
GF_OMP_FOR_KIND_MASK = 7 << 0,
GF_OMP_FOR_KIND_MASK = (1 << 3) - 1,
GF_OMP_FOR_KIND_FOR = 0,
GF_OMP_FOR_KIND_DISTRIBUTE = 1,
GF_OMP_FOR_KIND_CILKFOR = 2,
GF_OMP_FOR_KIND_OACC_LOOP = 3,
/* Flag for SIMD variants of OMP_FOR kinds. */
GF_OMP_FOR_SIMD = 1 << 2,
GF_OMP_FOR_KIND_SIMD = GF_OMP_FOR_SIMD | 0,
GF_OMP_FOR_KIND_CILKSIMD = GF_OMP_FOR_SIMD | 1,
GF_OMP_FOR_COMBINED = 1 << 3,
GF_OMP_FOR_COMBINED_INTO = 1 << 4,
GF_OMP_TARGET_KIND_MASK = (1 << 2) - 1,
GF_OMP_TARGET_KIND_MASK = (1 << 3) - 1,
GF_OMP_TARGET_KIND_REGION = 0,
GF_OMP_TARGET_KIND_DATA = 1,
GF_OMP_TARGET_KIND_UPDATE = 2,
GF_OMP_TARGET_KIND_OACC_PARALLEL = 3,
GF_OMP_TARGET_KIND_OACC_KERNELS = 4,
GF_OMP_TARGET_KIND_OACC_DATA = 5,
GF_OMP_TARGET_KIND_OACC_UPDATE = 6,
GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA = 7,
/* True on an GIMPLE_OMP_RETURN statement if the return does not require
a thread synchronization via some sort of barrier. The exact barrier
@ -291,7 +297,7 @@ struct GTY((tag("GSS_CALL")))
};
/* OpenMP statements (#pragma omp). */
/* OMP statements. */
struct GTY((tag("GSS_OMP")))
gimple_statement_omp : public gimple_statement_base
@ -552,7 +558,8 @@ struct GTY((tag("GSS_OMP_FOR")))
};
/* GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET */
/* GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET, GIMPLE_OMP_TASK */
struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT")))
gimple_statement_omp_parallel_layout : public gimple_statement_omp
{
@ -580,7 +587,6 @@ struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT")))
|| stmt->code == GIMPLE_OMP_TASK. */
};
/* GIMPLE_OMP_PARALLEL */
struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT")))
gomp_parallel : public gimple_statement_omp_taskreg
@ -589,6 +595,7 @@ struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT")))
stmt->code == GIMPLE_OMP_PARALLEL. */
};
/* GIMPLE_OMP_TARGET */
struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT")))
gomp_target : public gimple_statement_omp_parallel_layout
{
@ -4409,7 +4416,7 @@ gimple_omp_critical_set_name (gomp_critical *crit_stmt, tree name)
}
/* Return the kind of OMP for statemement. */
/* Return the kind of the OMP_FOR statemement G. */
static inline int
gimple_omp_for_kind (const_gimple g)
@ -4419,7 +4426,7 @@ gimple_omp_for_kind (const_gimple g)
}
/* Set the OMP for kind. */
/* Set the kind of the OMP_FOR statement G. */
static inline void
gimple_omp_for_set_kind (gomp_for *g, int kind)
@ -4429,7 +4436,7 @@ gimple_omp_for_set_kind (gomp_for *g, int kind)
}
/* Return true if OMP for statement G has the
/* Return true if OMP_FOR statement G has the
GF_OMP_FOR_COMBINED flag set. */
static inline bool
@ -4440,8 +4447,8 @@ gimple_omp_for_combined_p (const_gimple g)
}
/* Set the GF_OMP_FOR_COMBINED field in G depending on the boolean
value of COMBINED_P. */
/* Set the GF_OMP_FOR_COMBINED field in the OMP_FOR statement G depending on
the boolean value of COMBINED_P. */
static inline void
gimple_omp_for_set_combined_p (gomp_for *g, bool combined_p)
@ -4453,7 +4460,7 @@ gimple_omp_for_set_combined_p (gomp_for *g, bool combined_p)
}
/* Return true if OMP for statement G has the
/* Return true if the OMP_FOR statement G has the
GF_OMP_FOR_COMBINED_INTO flag set. */
static inline bool
@ -4464,8 +4471,8 @@ gimple_omp_for_combined_into_p (const_gimple g)
}
/* Set the GF_OMP_FOR_COMBINED_INTO field in G depending on the boolean
value of COMBINED_P. */
/* Set the GF_OMP_FOR_COMBINED_INTO field in the OMP_FOR statement G depending
on the boolean value of COMBINED_P. */
static inline void
gimple_omp_for_set_combined_into_p (gomp_for *g, bool combined_p)
@ -4477,7 +4484,7 @@ gimple_omp_for_set_combined_into_p (gomp_for *g, bool combined_p)
}
/* Return the clauses associated with OMP_FOR GS. */
/* Return the clauses associated with the OMP_FOR statement GS. */
static inline tree
gimple_omp_for_clauses (const_gimple gs)
@ -4487,7 +4494,8 @@ gimple_omp_for_clauses (const_gimple gs)
}
/* Return a pointer to the OMP_FOR GS. */
/* Return a pointer to the clauses associated with the OMP_FOR statement
GS. */
static inline tree *
gimple_omp_for_clauses_ptr (gimple gs)
@ -4497,7 +4505,8 @@ gimple_omp_for_clauses_ptr (gimple gs)
}
/* Set CLAUSES to be the list of clauses associated with OMP_FOR GS. */
/* Set CLAUSES to be the list of clauses associated with the OMP_FOR statement
GS. */
static inline void
gimple_omp_for_set_clauses (gimple gs, tree clauses)
@ -4507,7 +4516,7 @@ gimple_omp_for_set_clauses (gimple gs, tree clauses)
}
/* Get the collapse count of OMP_FOR GS. */
/* Get the collapse count of the OMP_FOR statement GS. */
static inline size_t
gimple_omp_for_collapse (gimple gs)
@ -4517,7 +4526,30 @@ gimple_omp_for_collapse (gimple gs)
}
/* Return the index variable for OMP_FOR GS. */
/* Return the condition code associated with the OMP_FOR statement GS. */
static inline enum tree_code
gimple_omp_for_cond (const_gimple gs, size_t i)
{
const gomp_for *omp_for_stmt = as_a <const gomp_for *> (gs);
gcc_gimple_checking_assert (i < omp_for_stmt->collapse);
return omp_for_stmt->iter[i].cond;
}
/* Set COND to be the condition code for the OMP_FOR statement GS. */
static inline void
gimple_omp_for_set_cond (gimple gs, size_t i, enum tree_code cond)
{
gomp_for *omp_for_stmt = as_a <gomp_for *> (gs);
gcc_gimple_checking_assert (TREE_CODE_CLASS (cond) == tcc_comparison
&& i < omp_for_stmt->collapse);
omp_for_stmt->iter[i].cond = cond;
}
/* Return the index variable for the OMP_FOR statement GS. */
static inline tree
gimple_omp_for_index (const_gimple gs, size_t i)
@ -4528,7 +4560,7 @@ gimple_omp_for_index (const_gimple gs, size_t i)
}
/* Return a pointer to the index variable for OMP_FOR GS. */
/* Return a pointer to the index variable for the OMP_FOR statement GS. */
static inline tree *
gimple_omp_for_index_ptr (gimple gs, size_t i)
@ -4539,7 +4571,7 @@ gimple_omp_for_index_ptr (gimple gs, size_t i)
}
/* Set INDEX to be the index variable for OMP_FOR GS. */
/* Set INDEX to be the index variable for the OMP_FOR statement GS. */
static inline void
gimple_omp_for_set_index (gimple gs, size_t i, tree index)
@ -4550,7 +4582,7 @@ gimple_omp_for_set_index (gimple gs, size_t i, tree index)
}
/* Return the initial value for OMP_FOR GS. */
/* Return the initial value for the OMP_FOR statement GS. */
static inline tree
gimple_omp_for_initial (const_gimple gs, size_t i)
@ -4561,7 +4593,7 @@ gimple_omp_for_initial (const_gimple gs, size_t i)
}
/* Return a pointer to the initial value for OMP_FOR GS. */
/* Return a pointer to the initial value for the OMP_FOR statement GS. */
static inline tree *
gimple_omp_for_initial_ptr (gimple gs, size_t i)
@ -4572,7 +4604,7 @@ gimple_omp_for_initial_ptr (gimple gs, size_t i)
}
/* Set INITIAL to be the initial value for OMP_FOR GS. */
/* Set INITIAL to be the initial value for the OMP_FOR statement GS. */
static inline void
gimple_omp_for_set_initial (gimple gs, size_t i, tree initial)
@ -4583,7 +4615,7 @@ gimple_omp_for_set_initial (gimple gs, size_t i, tree initial)
}
/* Return the final value for OMP_FOR GS. */
/* Return the final value for the OMP_FOR statement GS. */
static inline tree
gimple_omp_for_final (const_gimple gs, size_t i)
@ -4594,7 +4626,7 @@ gimple_omp_for_final (const_gimple gs, size_t i)
}
/* Return a pointer to the final value for OMP_FOR GS. */
/* Return a pointer to the final value for the OMP_FOR statement GS. */
static inline tree *
gimple_omp_for_final_ptr (gimple gs, size_t i)
@ -4605,7 +4637,7 @@ gimple_omp_for_final_ptr (gimple gs, size_t i)
}
/* Set FINAL to be the final value for OMP_FOR GS. */
/* Set FINAL to be the final value for the OMP_FOR statement GS. */
static inline void
gimple_omp_for_set_final (gimple gs, size_t i, tree final)
@ -4616,7 +4648,7 @@ gimple_omp_for_set_final (gimple gs, size_t i, tree final)
}
/* Return the increment value for OMP_FOR GS. */
/* Return the increment value for the OMP_FOR statement GS. */
static inline tree
gimple_omp_for_incr (const_gimple gs, size_t i)
@ -4627,7 +4659,7 @@ gimple_omp_for_incr (const_gimple gs, size_t i)
}
/* Return a pointer to the increment value for OMP_FOR GS. */
/* Return a pointer to the increment value for the OMP_FOR statement GS. */
static inline tree *
gimple_omp_for_incr_ptr (gimple gs, size_t i)
@ -4638,7 +4670,7 @@ gimple_omp_for_incr_ptr (gimple gs, size_t i)
}
/* Set INCR to be the increment value for OMP_FOR GS. */
/* Set INCR to be the increment value for the OMP_FOR statement GS. */
static inline void
gimple_omp_for_set_incr (gimple gs, size_t i, tree incr)
@ -5109,7 +5141,7 @@ gimple_omp_target_set_clauses (gomp_target *omp_target_stmt,
}
/* Return the kind of OMP target statemement. */
/* Return the kind of the OMP_TARGET G. */
static inline int
gimple_omp_target_kind (const_gimple g)
@ -5119,7 +5151,7 @@ gimple_omp_target_kind (const_gimple g)
}
/* Set the OMP target kind. */
/* Set the kind of the OMP_TARGET G. */
static inline void
gimple_omp_target_set_kind (gomp_target *g, int kind)
@ -5279,29 +5311,6 @@ gimple_omp_sections_set_control (gimple gs, tree control)
}
/* Set COND to be the condition code for OMP_FOR GS. */
static inline void
gimple_omp_for_set_cond (gimple gs, size_t i, enum tree_code cond)
{
gomp_for *omp_for_stmt = as_a <gomp_for *> (gs);
gcc_gimple_checking_assert (TREE_CODE_CLASS (cond) == tcc_comparison
&& i < omp_for_stmt->collapse);
omp_for_stmt->iter[i].cond = cond;
}
/* Return the condition code associated with OMP_FOR GS. */
static inline enum tree_code
gimple_omp_for_cond (const_gimple gs, size_t i)
{
const gomp_for *omp_for_stmt = as_a <const gomp_for *> (gs);
gcc_gimple_checking_assert (i < omp_for_stmt->collapse);
return omp_for_stmt->iter[i].cond;
}
/* Set the value being stored in an atomic store. */
static inline void
@ -5547,7 +5556,7 @@ gimple_return_set_retbnd (gimple gs, tree retval)
}
/* Returns true when the gimple statement STMT is any of the OpenMP types. */
/* Returns true when the gimple statement STMT is any of the OMP types. */
#define CASE_GIMPLE_OMP \
case GIMPLE_OMP_PARALLEL: \
@ -5580,6 +5589,64 @@ is_gimple_omp (const_gimple stmt)
}
}
/* Return true if the OMP gimple statement STMT is any of the OpenACC types
specifically. */
static inline bool
is_gimple_omp_oacc (const_gimple stmt)
{
gcc_assert (is_gimple_omp (stmt));
switch (gimple_code (stmt))
{
case GIMPLE_OMP_FOR:
switch (gimple_omp_for_kind (stmt))
{
case GF_OMP_FOR_KIND_OACC_LOOP:
return true;
default:
return false;
}
case GIMPLE_OMP_TARGET:
switch (gimple_omp_target_kind (stmt))
{
case GF_OMP_TARGET_KIND_OACC_PARALLEL:
case GF_OMP_TARGET_KIND_OACC_KERNELS:
case GF_OMP_TARGET_KIND_OACC_DATA:
case GF_OMP_TARGET_KIND_OACC_UPDATE:
case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
return true;
default:
return false;
}
default:
return false;
}
}
/* Return true if the OMP gimple statement STMT is offloaded. */
static inline bool
is_gimple_omp_offloaded (const_gimple stmt)
{
gcc_assert (is_gimple_omp (stmt));
switch (gimple_code (stmt))
{
case GIMPLE_OMP_TARGET:
switch (gimple_omp_target_kind (stmt))
{
case GF_OMP_TARGET_KIND_REGION:
case GF_OMP_TARGET_KIND_OACC_PARALLEL:
case GF_OMP_TARGET_KIND_OACC_KERNELS:
return true;
default:
return false;
}
default:
return false;
}
}
/* Returns TRUE if statement G is a GIMPLE_NOP. */

View File

@ -86,6 +86,7 @@ along with GCC; see the file COPYING3. If not see
#include "omp-low.h"
#include "gimple-low.h"
#include "cilk.h"
#include "gomp-constants.h"
#include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
#include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
@ -106,7 +107,10 @@ enum gimplify_omp_var_data
GOVD_PRIVATE_OUTER_REF = 1024,
GOVD_LINEAR = 2048,
GOVD_ALIGNED = 4096,
/* Flag for GOVD_MAP: don't copy back. */
GOVD_MAP_TO_ONLY = 8192,
GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
| GOVD_LOCAL)
@ -122,7 +126,9 @@ enum omp_region_type
ORT_TASK = 4,
ORT_UNTIED_TASK = 5,
ORT_TEAMS = 8,
/* Data region. */
ORT_TARGET_DATA = 16,
/* Data region with offloading. */
ORT_TARGET = 32
};
@ -1560,9 +1566,10 @@ gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
struct gimplify_ctx *ctxp;
glabel *label_stmt;
/* Invalid OpenMP programs can play Duff's Device type games with
/* Invalid programs can play Duff's Device type games with, for example,
#pragma omp parallel. At least in the C front end, we don't
detect such invalid branches until after gimplification. */
detect such invalid branches until after gimplification, in the
diagnose_omp_blocks pass. */
for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
if (ctxp->case_labels.exists ())
break;
@ -1791,7 +1798,7 @@ gimplify_var_or_parm_decl (tree *expr_p)
return GS_ERROR;
}
/* When within an OpenMP context, notice uses of variables. */
/* When within an OMP context, notice uses of variables. */
if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
return GS_ALL_DONE;
@ -2260,7 +2267,7 @@ gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location)
return gimplify_expr (arg_p, pre_p, NULL, test, fb);
}
/* Don't fold STMT inside ORT_TARGET, because it can break code by adding decl
/* Don't fold inside offloading regions: it can break code by adding decl
references that weren't in the source. We'll do it during omplower pass
instead. */
@ -4451,11 +4458,21 @@ is_gimple_stmt (tree t)
case CATCH_EXPR:
case ASM_EXPR:
case STATEMENT_LIST:
case OACC_PARALLEL:
case OACC_KERNELS:
case OACC_DATA:
case OACC_HOST_DATA:
case OACC_DECLARE:
case OACC_UPDATE:
case OACC_ENTER_DATA:
case OACC_EXIT_DATA:
case OACC_CACHE:
case OMP_PARALLEL:
case OMP_FOR:
case OMP_SIMD:
case CILK_SIMD:
case OMP_DISTRIBUTE:
case OACC_LOOP:
case OMP_SECTIONS:
case OMP_SECTION:
case OMP_SINGLE:
@ -5582,7 +5599,7 @@ omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
}
/* Add an entry for DECL in the OpenMP context CTX with FLAGS. */
/* Add an entry for DECL in the OMP context CTX with FLAGS. */
static void
omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
@ -5627,9 +5644,12 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
copy into or out of the context. */
if (!(flags & GOVD_LOCAL))
{
nflags = flags & GOVD_MAP
? GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT
: flags & GOVD_PRIVATE ? GOVD_PRIVATE : GOVD_FIRSTPRIVATE;
if (flags & GOVD_MAP)
nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
else if (flags & GOVD_PRIVATE)
nflags = GOVD_PRIVATE;
else
nflags = GOVD_FIRSTPRIVATE;
nflags |= flags & GOVD_SEEN;
t = DECL_VALUE_EXPR (decl);
gcc_assert (TREE_CODE (t) == INDIRECT_REF);
@ -5683,7 +5703,7 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
}
/* Notice a threadprivate variable DECL used in OpenMP context CTX.
/* Notice a threadprivate variable DECL used in OMP context CTX.
This just prints out diagnostics about threadprivate variable uses
in untied tasks. If DECL2 is non-NULL, prevent this warning
on that variable. */
@ -5725,7 +5745,7 @@ omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
return false;
}
/* Record the fact that DECL was used within the OpenMP context CTX.
/* Record the fact that DECL was used within the OMP context CTX.
IN_CODE is true when real code uses DECL, and false when we should
merely emit default(none) errors. Return true if DECL is going to
be remapped and thus DECL shouldn't be gimplified into its
@ -6006,7 +6026,7 @@ omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
return false;
}
/* Scan the OpenMP clauses in *LIST_P, installing mappings into a new
/* Scan the OMP clauses in *LIST_P, installing mappings into a new
and previous omp contexts. */
static void
@ -6117,6 +6137,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
case OMP_CLAUSE_TO:
case OMP_CLAUSE_FROM:
case OMP_CLAUSE__CACHE_:
decl = OMP_CLAUSE_DECL (c);
if (error_operand_p (decl))
{
@ -6282,15 +6303,35 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
case OMP_CLAUSE_DIST_SCHEDULE:
case OMP_CLAUSE_DEVICE:
case OMP_CLAUSE__CILK_FOR_COUNT_:
case OMP_CLAUSE_ASYNC:
case OMP_CLAUSE_WAIT:
case OMP_CLAUSE_NUM_GANGS:
case OMP_CLAUSE_NUM_WORKERS:
case OMP_CLAUSE_VECTOR_LENGTH:
case OMP_CLAUSE_GANG:
case OMP_CLAUSE_WORKER:
case OMP_CLAUSE_VECTOR:
if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
is_gimple_val, fb_rvalue) == GS_ERROR)
remove = true;
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_GANG
&& gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
is_gimple_val, fb_rvalue) == GS_ERROR)
remove = true;
break;
case OMP_CLAUSE_DEVICE_RESIDENT:
case OMP_CLAUSE_USE_DEVICE:
case OMP_CLAUSE_INDEPENDENT:
remove = true;
break;
case OMP_CLAUSE_NOWAIT:
case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_COLLAPSE:
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_SEQ:
case OMP_CLAUSE_MERGEABLE:
case OMP_CLAUSE_PROC_BIND:
case OMP_CLAUSE_SAFELEN:
@ -6411,9 +6452,10 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
else if (code == OMP_CLAUSE_MAP)
{
OMP_CLAUSE_MAP_KIND (clause) = flags & GOVD_MAP_TO_ONLY
? OMP_CLAUSE_MAP_TO
: OMP_CLAUSE_MAP_TOFROM;
OMP_CLAUSE_SET_MAP_KIND (clause,
flags & GOVD_MAP_TO_ONLY
? GOMP_MAP_TO
: GOMP_MAP_TOFROM);
if (DECL_SIZE (decl)
&& TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
{
@ -6434,7 +6476,7 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
OMP_CLAUSE_MAP);
OMP_CLAUSE_DECL (nc) = decl;
OMP_CLAUSE_SIZE (nc) = size_zero_node;
OMP_CLAUSE_MAP_KIND (nc) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
OMP_CLAUSE_CHAIN (clause) = nc;
}
@ -6584,8 +6626,13 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, tree *list_p)
remove = true;
else if (DECL_SIZE (decl)
&& TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
&& OMP_CLAUSE_MAP_KIND (c) != OMP_CLAUSE_MAP_POINTER)
&& OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER)
{
/* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
for these, TREE_CODE (DECL_SIZE (decl)) will always be
INTEGER_CST. */
gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
tree decl2 = DECL_VALUE_EXPR (decl);
gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
decl2 = TREE_OPERAND (decl2, 0);
@ -6603,7 +6650,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, tree *list_p)
OMP_CLAUSE_MAP);
OMP_CLAUSE_DECL (nc) = decl;
OMP_CLAUSE_SIZE (nc) = size_zero_node;
OMP_CLAUSE_MAP_KIND (nc) = OMP_CLAUSE_MAP_POINTER;
OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
OMP_CLAUSE_CHAIN (c) = nc;
c = nc;
@ -6614,6 +6661,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, tree *list_p)
case OMP_CLAUSE_TO:
case OMP_CLAUSE_FROM:
case OMP_CLAUSE__CACHE_:
decl = OMP_CLAUSE_DECL (c);
if (!DECL_P (decl))
break;
@ -6659,6 +6707,19 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, tree *list_p)
case OMP_CLAUSE_SAFELEN:
case OMP_CLAUSE_DEPEND:
case OMP_CLAUSE__CILK_FOR_COUNT_:
case OMP_CLAUSE_ASYNC:
case OMP_CLAUSE_WAIT:
case OMP_CLAUSE_DEVICE_RESIDENT:
case OMP_CLAUSE_USE_DEVICE:
case OMP_CLAUSE_INDEPENDENT:
case OMP_CLAUSE_NUM_GANGS:
case OMP_CLAUSE_NUM_WORKERS:
case OMP_CLAUSE_VECTOR_LENGTH:
case OMP_CLAUSE_GANG:
case OMP_CLAUSE_WORKER:
case OMP_CLAUSE_VECTOR:
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_SEQ:
break;
default:
@ -6681,6 +6742,21 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, tree *list_p)
delete_omp_context (ctx);
}
/* Gimplify OACC_CACHE. */
static void
gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
{
tree expr = *expr_p;
gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_WORKSHARE);
gimplify_adjust_omp_clauses (pre_p, &OACC_CACHE_CLAUSES (expr));
/* TODO: Do something sensible with this information. */
*expr_p = NULL_TREE;
}
/* Gimplify the contents of an OMP_PARALLEL statement. This involves
gimplification of the body, as well as scanning the body for used
variables. We need to do this scan now, because variable-sized
@ -6795,8 +6871,22 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
orig_for_stmt = for_stmt = *expr_p;
simd = (TREE_CODE (for_stmt) == OMP_SIMD
|| TREE_CODE (for_stmt) == CILK_SIMD);
switch (TREE_CODE (for_stmt))
{
case OMP_FOR:
case CILK_FOR:
case OMP_DISTRIBUTE:
case OACC_LOOP:
simd = false;
break;
case OMP_SIMD:
case CILK_SIMD:
simd = true;
break;
default:
gcc_unreachable ();
}
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p,
simd ? ORT_SIMD : ORT_WORKSHARE);
if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
@ -6832,6 +6922,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
{
gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt), find_combined_omp_for,
NULL, NULL);
gcc_assert (for_stmt != NULL_TREE);
@ -7133,6 +7224,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
case CILK_SIMD: kind = GF_OMP_FOR_KIND_CILKSIMD; break;
case CILK_FOR: kind = GF_OMP_FOR_KIND_CILKFOR; break;
case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
default:
gcc_unreachable ();
}
@ -7173,9 +7265,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
return GS_ALL_DONE;
}
/* Gimplify the gross structure of other OpenMP constructs.
In particular, OMP_SECTIONS, OMP_SINGLE, OMP_TARGET, OMP_TARGET_DATA
and OMP_TEAMS. */
/* Gimplify the gross structure of several OMP constructs. */
static void
gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
@ -7183,16 +7273,20 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
tree expr = *expr_p;
gimple stmt;
gimple_seq body = NULL;
enum omp_region_type ort = ORT_WORKSHARE;
enum omp_region_type ort;
switch (TREE_CODE (expr))
{
case OMP_SECTIONS:
case OMP_SINGLE:
ort = ORT_WORKSHARE;
break;
case OACC_KERNELS:
case OACC_PARALLEL:
case OMP_TARGET:
ort = ORT_TARGET;
break;
case OACC_DATA:
case OMP_TARGET_DATA:
ort = ORT_TARGET_DATA;
break;
@ -7213,9 +7307,21 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
pop_gimplify_context (NULL);
if (ort == ORT_TARGET_DATA)
{
gimple_seq cleanup = NULL;
tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TARGET_END_DATA);
enum built_in_function end_ix;
switch (TREE_CODE (expr))
{
case OACC_DATA:
end_ix = BUILT_IN_GOACC_DATA_END;
break;
case OMP_TARGET_DATA:
end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
break;
default:
gcc_unreachable ();
}
tree fn = builtin_decl_explicit (end_ix);
g = gimple_build_call (fn, 0);
gimple_seq cleanup = NULL;
gimple_seq_add_stmt (&cleanup, g);
g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
body = NULL;
@ -7228,6 +7334,18 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
switch (TREE_CODE (expr))
{
case OACC_DATA:
stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
OMP_CLAUSES (expr));
break;
case OACC_KERNELS:
stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
OMP_CLAUSES (expr));
break;
case OACC_PARALLEL:
stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
OMP_CLAUSES (expr));
break;
case OMP_SECTIONS:
stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
break;
@ -7253,19 +7371,40 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
*expr_p = NULL_TREE;
}
/* Gimplify the gross structure of OpenMP target update construct. */
/* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
target update constructs. */
static void
gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
{
tree expr = *expr_p;
tree expr = *expr_p, clauses;
int kind;
gomp_target *stmt;
gimplify_scan_omp_clauses (&OMP_TARGET_UPDATE_CLAUSES (expr), pre_p,
ORT_WORKSHARE);
gimplify_adjust_omp_clauses (pre_p, &OMP_TARGET_UPDATE_CLAUSES (expr));
stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_UPDATE,
OMP_TARGET_UPDATE_CLAUSES (expr));
switch (TREE_CODE (expr))
{
case OACC_ENTER_DATA:
clauses = OACC_ENTER_DATA_CLAUSES (expr);
kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
break;
case OACC_EXIT_DATA:
clauses = OACC_EXIT_DATA_CLAUSES (expr);
kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
break;
case OACC_UPDATE:
clauses = OACC_UPDATE_CLAUSES (expr);
kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
break;
case OMP_TARGET_UPDATE:
clauses = OMP_TARGET_UPDATE_CLAUSES (expr);
kind = GF_OMP_TARGET_KIND_UPDATE;
break;
default:
gcc_unreachable ();
}
gimplify_scan_omp_clauses (&clauses, pre_p, ORT_WORKSHARE);
gimplify_adjust_omp_clauses (pre_p, &clauses);
stmt = gimple_build_omp_target (NULL, kind, clauses);
gimplify_seq_add_stmt (pre_p, stmt);
*expr_p = NULL_TREE;
@ -7445,7 +7584,7 @@ gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
int subcode = 0;
/* Wrap the transaction body in a BIND_EXPR so we have a context
where to put decls for OpenMP. */
where to put decls for OMP. */
if (TREE_CODE (tbody) != BIND_EXPR)
{
tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
@ -8182,7 +8321,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
break;
case RESULT_DECL:
/* When within an OpenMP context, notice uses of variables. */
/* When within an OMP context, notice uses of variables. */
if (gimplify_omp_ctxp)
omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
ret = GS_ALL_DONE;
@ -8208,9 +8347,38 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
case CILK_SIMD:
case CILK_FOR:
case OMP_DISTRIBUTE:
case OACC_LOOP:
ret = gimplify_omp_for (expr_p, pre_p);
break;
case OACC_CACHE:
gimplify_oacc_cache (expr_p, pre_p);
ret = GS_ALL_DONE;
break;
case OACC_HOST_DATA:
case OACC_DECLARE:
sorry ("directive not yet implemented");
ret = GS_ALL_DONE;
break;
case OACC_KERNELS:
if (OACC_KERNELS_COMBINED (*expr_p))
sorry ("directive not yet implemented");
else
gimplify_omp_workshare (expr_p, pre_p);
ret = GS_ALL_DONE;
break;
case OACC_PARALLEL:
if (OACC_PARALLEL_COMBINED (*expr_p))
sorry ("directive not yet implemented");
else
gimplify_omp_workshare (expr_p, pre_p);
ret = GS_ALL_DONE;
break;
case OACC_DATA:
case OMP_SECTIONS:
case OMP_SINGLE:
case OMP_TARGET:
@ -8220,6 +8388,9 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
ret = GS_ALL_DONE;
break;
case OACC_ENTER_DATA:
case OACC_EXIT_DATA:
case OACC_UPDATE:
case OMP_TARGET_UPDATE:
gimplify_omp_target_update (expr_p, pre_p);
ret = GS_ALL_DONE;
@ -8601,8 +8772,18 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
&& code != LOOP_EXPR
&& code != SWITCH_EXPR
&& code != TRY_FINALLY_EXPR
&& code != OACC_PARALLEL
&& code != OACC_KERNELS
&& code != OACC_DATA
&& code != OACC_HOST_DATA
&& code != OACC_DECLARE
&& code != OACC_UPDATE
&& code != OACC_ENTER_DATA
&& code != OACC_EXIT_DATA
&& code != OACC_CACHE
&& code != OMP_CRITICAL
&& code != OMP_FOR
&& code != OACC_LOOP
&& code != OMP_MASTER
&& code != OMP_TASKGROUP
&& code != OMP_ORDERED
@ -8829,7 +9010,7 @@ gimplify_body (tree fndecl, bool do_parms)
gcc_assert (gimplify_ctxp == NULL);
push_gimplify_context ();
if (flag_openmp)
if (flag_openacc || flag_openmp)
{
gcc_assert (gimplify_omp_ctxp == NULL);
if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
@ -8913,7 +9094,8 @@ gimplify_body (tree fndecl, bool do_parms)
nonlocal_vlas = NULL;
}
if ((flag_openmp || flag_openmp_simd) && gimplify_omp_ctxp)
if ((flag_openacc || flag_openmp || flag_openmp_simd)
&& gimplify_omp_ctxp)
{
delete_omp_context (gimplify_omp_ctxp);
gimplify_omp_ctxp = NULL;

View File

@ -82,6 +82,7 @@ along with GCC; see the file COPYING3. If not see
#include "streamer-hooks.h"
#include "cfgloop.h"
#include "builtins.h"
#include "gomp-constants.h"
static void lto_write_tree (struct output_block*, tree, bool);

View File

@ -1,3 +1,10 @@
2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
James Norris <jnorris@codesourcery.com>
* lto-lang.c (DEF_FUNCTION_TYPE_VAR_8, DEF_FUNCTION_TYPE_VAR_12):
New macros.
* lto.c: Include "gomp-constants.h".
2015-01-14 Ilya Verbin <ilya.verbin@intel.com>
* lto-partition.c (lto_promote_cross_file_statics): Remove argument

View File

@ -177,6 +177,11 @@ enum lto_builtin_type
#define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
#define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) \
NAME,
#define DEF_FUNCTION_TYPE_VAR_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) NAME,
#define DEF_FUNCTION_TYPE_VAR_12(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, \
ARG12) NAME,
#define DEF_POINTER_TYPE(NAME, TYPE) NAME,
#include "builtin-types.def"
#undef DEF_PRIMITIVE_TYPE
@ -195,6 +200,8 @@ enum lto_builtin_type
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_FUNCTION_TYPE_VAR_4
#undef DEF_FUNCTION_TYPE_VAR_5
#undef DEF_FUNCTION_TYPE_VAR_8
#undef DEF_FUNCTION_TYPE_VAR_12
#undef DEF_POINTER_TYPE
BT_LAST
};
@ -679,6 +686,14 @@ lto_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
#define DEF_FUNCTION_TYPE_VAR_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) \
def_fn_type (ENUM, RETURN, 1, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
ARG7, ARG8);
#define DEF_FUNCTION_TYPE_VAR_12(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, ARG12) \
def_fn_type (ENUM, RETURN, 1, 12, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
ARG7, ARG8, ARG9, ARG10, ARG11, ARG12);
#define DEF_POINTER_TYPE(ENUM, TYPE) \
builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
@ -700,6 +715,8 @@ lto_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_FUNCTION_TYPE_VAR_4
#undef DEF_FUNCTION_TYPE_VAR_5
#undef DEF_FUNCTION_TYPE_VAR_8
#undef DEF_FUNCTION_TYPE_VAR_12
#undef DEF_POINTER_TYPE
builtin_types[(int) BT_LAST] = NULL_TREE;

View File

@ -77,6 +77,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-inline.h"
#include "params.h"
#include "ipa-utils.h"
#include "gomp-constants.h"
/* Number of parallel tasks to run, -1 if we want to use GNU Make jobserver. */

View File

@ -1,5 +1,5 @@
/* This file contains the definitions and documentation for the
OpenMP builtins used in the GNU compiler.
Offloading and Multi Processing builtins used in the GNU compiler.
Copyright (C) 2005-2015 Free Software Foundation, Inc.
This file is part of GCC.
@ -20,10 +20,41 @@ along with GCC; see the file COPYING3. If not see
/* Before including this file, you should define a macro:
DEF_GOACC_BUILTIN (ENUM, NAME, TYPE, ATTRS)
DEF_GOACC_BUILTIN_COMPILER (ENUM, NAME, TYPE, ATTRS)
DEF_GOMP_BUILTIN (ENUM, NAME, TYPE, ATTRS)
See builtins.def for details. */
/* The reason why they aren't in gcc/builtins.def is that the Fortran front end
doesn't source those. */
DEF_GOACC_BUILTIN (BUILT_IN_ACC_GET_DEVICE_TYPE, "acc_get_device_type",
BT_FN_INT, ATTR_NOTHROW_LIST)
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_DATA_START, "GOACC_data_start",
BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR, ATTR_NOTHROW_LIST)
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_DATA_END, "GOACC_data_end",
BT_FN_VOID, ATTR_NOTHROW_LIST)
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_ENTER_EXIT_DATA, "GOACC_enter_exit_data",
BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR_INT_INT_VAR,
ATTR_NOTHROW_LIST)
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_PARALLEL, "GOACC_parallel",
BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR_INT_INT_INT_INT_INT_VAR,
ATTR_NOTHROW_LIST)
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_UPDATE, "GOACC_update",
BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR_INT_INT_VAR,
ATTR_NOTHROW_LIST)
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_WAIT, "GOACC_wait",
BT_FN_VOID_INT_INT_VAR,
ATTR_NOTHROW_LIST)
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_GET_THREAD_NUM, "GOACC_get_thread_num",
BT_FN_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_GET_NUM_THREADS, "GOACC_get_num_threads",
BT_FN_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GOACC_BUILTIN_COMPILER (BUILT_IN_ACC_ON_DEVICE, "acc_on_device",
BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_OMP_GET_THREAD_NUM, "omp_get_thread_num",
BT_FN_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_OMP_GET_NUM_THREADS, "omp_get_num_threads",

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,133 @@
2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
James Norris <jnorris@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
Ilmir Usmanov <i.usmanov@samsung.com>
* lib/target-supports.exp (check_effective_target_fopenacc): New
procedure.
* g++.dg/goacc-gomp/goacc-gomp.exp: New file.
* g++.dg/goacc/goacc.exp: Likewise.
* gcc.dg/goacc-gomp/goacc-gomp.exp: Likewise.
* gcc.dg/goacc/goacc.exp: Likewise.
* gfortran.dg/goacc/goacc.exp: Likewise.
* c-c++-common/cpp/openacc-define-1.c: New file.
* c-c++-common/cpp/openacc-define-2.c: Likewise.
* c-c++-common/cpp/openacc-define-3.c: Likewise.
* c-c++-common/goacc-gomp/nesting-1.c: Likewise.
* c-c++-common/goacc-gomp/nesting-fail-1.c: Likewise.
* c-c++-common/goacc/acc_on_device-2-off.c: Likewise.
* c-c++-common/goacc/acc_on_device-2.c: Likewise.
* c-c++-common/goacc/asyncwait-1.c: Likewise.
* c-c++-common/goacc/cache-1.c: Likewise.
* c-c++-common/goacc/clauses-fail.c: Likewise.
* c-c++-common/goacc/collapse-1.c: Likewise.
* c-c++-common/goacc/data-1.c: Likewise.
* c-c++-common/goacc/data-2.c: Likewise.
* c-c++-common/goacc/data-clause-duplicate-1.c: Likewise.
* c-c++-common/goacc/deviceptr-1.c: Likewise.
* c-c++-common/goacc/deviceptr-2.c: Likewise.
* c-c++-common/goacc/deviceptr-3.c: Likewise.
* c-c++-common/goacc/if-clause-1.c: Likewise.
* c-c++-common/goacc/if-clause-2.c: Likewise.
* c-c++-common/goacc/kernels-1.c: Likewise.
* c-c++-common/goacc/loop-1.c: Likewise.
* c-c++-common/goacc/loop-private-1.c: Likewise.
* c-c++-common/goacc/nesting-1.c: Likewise.
* c-c++-common/goacc/nesting-data-1.c: Likewise.
* c-c++-common/goacc/nesting-fail-1.c: Likewise.
* c-c++-common/goacc/parallel-1.c: Likewise.
* c-c++-common/goacc/pcopy.c: Likewise.
* c-c++-common/goacc/pcopyin.c: Likewise.
* c-c++-common/goacc/pcopyout.c: Likewise.
* c-c++-common/goacc/pcreate.c: Likewise.
* c-c++-common/goacc/pragma_context.c: Likewise.
* c-c++-common/goacc/present-1.c: Likewise.
* c-c++-common/goacc/reduction-1.c: Likewise.
* c-c++-common/goacc/reduction-2.c: Likewise.
* c-c++-common/goacc/reduction-3.c: Likewise.
* c-c++-common/goacc/reduction-4.c: Likewise.
* c-c++-common/goacc/sb-1.c: Likewise.
* c-c++-common/goacc/sb-2.c: Likewise.
* c-c++-common/goacc/sb-3.c: Likewise.
* c-c++-common/goacc/update-1.c: Likewise.
* gcc.dg/goacc/acc_on_device-1.c: Likewise.
* gfortran.dg/goacc/acc_on_device-1.f95: Likewise.
* gfortran.dg/goacc/acc_on_device-2-off.f95: Likewise.
* gfortran.dg/goacc/acc_on_device-2.f95: Likewise.
* gfortran.dg/goacc/assumed.f95: Likewise.
* gfortran.dg/goacc/asyncwait-1.f95: Likewise.
* gfortran.dg/goacc/asyncwait-2.f95: Likewise.
* gfortran.dg/goacc/asyncwait-3.f95: Likewise.
* gfortran.dg/goacc/asyncwait-4.f95: Likewise.
* gfortran.dg/goacc/branch.f95: Likewise.
* gfortran.dg/goacc/cache-1.f95: Likewise.
* gfortran.dg/goacc/coarray.f95: Likewise.
* gfortran.dg/goacc/continuation-free-form.f95: Likewise.
* gfortran.dg/goacc/cray.f95: Likewise.
* gfortran.dg/goacc/critical.f95: Likewise.
* gfortran.dg/goacc/data-clauses.f95: Likewise.
* gfortran.dg/goacc/data-tree.f95: Likewise.
* gfortran.dg/goacc/declare-1.f95: Likewise.
* gfortran.dg/goacc/enter-exit-data.f95: Likewise.
* gfortran.dg/goacc/fixed-1.f: Likewise.
* gfortran.dg/goacc/fixed-2.f: Likewise.
* gfortran.dg/goacc/fixed-3.f: Likewise.
* gfortran.dg/goacc/fixed-4.f: Likewise.
* gfortran.dg/goacc/host_data-tree.f95: Likewise.
* gfortran.dg/goacc/if.f95: Likewise.
* gfortran.dg/goacc/kernels-tree.f95: Likewise.
* gfortran.dg/goacc/list.f95: Likewise.
* gfortran.dg/goacc/literal.f95: Likewise.
* gfortran.dg/goacc/loop-1.f95: Likewise.
* gfortran.dg/goacc/loop-2.f95: Likewise.
* gfortran.dg/goacc/loop-3.f95: Likewise.
* gfortran.dg/goacc/loop-tree-1.f90: Likewise.
* gfortran.dg/goacc/omp.f95: Likewise.
* gfortran.dg/goacc/parallel-kernels-clauses.f95: Likewise.
* gfortran.dg/goacc/parallel-kernels-regions.f95: Likewise.
* gfortran.dg/goacc/parallel-tree.f95: Likewise.
* gfortran.dg/goacc/parameter.f95: Likewise.
* gfortran.dg/goacc/private-1.f95: Likewise.
* gfortran.dg/goacc/private-2.f95: Likewise.
* gfortran.dg/goacc/private-3.f95: Likewise.
* gfortran.dg/goacc/pure-elemental-procedures.f95: Likewise.
* gfortran.dg/goacc/reduction-2.f95: Likewise.
* gfortran.dg/goacc/reduction.f95: Likewise.
* gfortran.dg/goacc/routine-1.f90: Likewise.
* gfortran.dg/goacc/routine-2.f90: Likewise.
* gfortran.dg/goacc/sentinel-free-form.f95: Likewise.
* gfortran.dg/goacc/several-directives.f95: Likewise.
* gfortran.dg/goacc/sie.f95: Likewise.
* gfortran.dg/goacc/subarrays.f95: Likewise.
* gfortran.dg/gomp/map-1.f90: Likewise.
* gfortran.dg/openacc-define-1.f90: Likewise.
* gfortran.dg/openacc-define-2.f90: Likewise.
* gfortran.dg/openacc-define-3.f90: Likewise.
* g++.dg/gomp/block-1.C: Update for changed compiler output.
* g++.dg/gomp/block-2.C: Likewise.
* g++.dg/gomp/block-3.C: Likewise.
* g++.dg/gomp/block-5.C: Likewise.
* g++.dg/gomp/target-1.C: Likewise.
* g++.dg/gomp/target-2.C: Likewise.
* g++.dg/gomp/taskgroup-1.C: Likewise.
* g++.dg/gomp/teams-1.C: Likewise.
* gcc.dg/cilk-plus/jump-openmp.c: Likewise.
* gcc.dg/cilk-plus/jump.c: Likewise.
* gcc.dg/gomp/block-1.c: Likewise.
* gcc.dg/gomp/block-10.c: Likewise.
* gcc.dg/gomp/block-2.c: Likewise.
* gcc.dg/gomp/block-3.c: Likewise.
* gcc.dg/gomp/block-4.c: Likewise.
* gcc.dg/gomp/block-5.c: Likewise.
* gcc.dg/gomp/block-6.c: Likewise.
* gcc.dg/gomp/block-7.c: Likewise.
* gcc.dg/gomp/block-8.c: Likewise.
* gcc.dg/gomp/block-9.c: Likewise.
* gcc.dg/gomp/target-1.c: Likewise.
* gcc.dg/gomp/target-2.c: Likewise.
* gcc.dg/gomp/taskgroup-1.c: Likewise.
* gcc.dg/gomp/teams-1.c: Likewise.
2015-01-15 David Malcolm <dmalcolm@redhat.com>
* jit.dg/test-error-mismatching-types-in-assignment-op.c: New

View File

@ -0,0 +1,6 @@
/* { dg-do preprocess } */
/* { dg-require-effective-target fopenacc } */
#ifdef _OPENACC
# error _OPENACC defined
#endif

View File

@ -0,0 +1,7 @@
/* { dg-options "-fno-openacc" } */
/* { dg-do preprocess } */
/* { dg-require-effective-target fopenacc } */
#ifdef _OPENACC
# error _OPENACC defined
#endif

View File

@ -0,0 +1,11 @@
/* { dg-options "-fopenacc" } */
/* { dg-do preprocess } */
/* { dg-require-effective-target fopenacc } */
#ifndef _OPENACC
# error _OPENACC not defined
#endif
#if _OPENACC != 201306
# error _OPENACC defined to wrong value
#endif

View File

@ -0,0 +1,12 @@
void
f_omp_parallel (void)
{
#pragma omp parallel
{
int i;
#pragma acc loop
for (i = 0; i < 2; ++i)
;
}
}

View File

@ -0,0 +1,457 @@
extern int i;
void
f_omp (void)
{
#pragma omp parallel
{
#pragma acc parallel /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc enter data copyin(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc exit data delete(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
}
#pragma omp for
for (i = 0; i < 3; i++)
{
#pragma acc parallel /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc enter data copyin(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc exit data delete(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc loop /* { dg-error "may not be closely nested" } */
for (i = 0; i < 2; ++i)
;
}
#pragma omp sections
{
{
#pragma acc parallel /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
}
#pragma omp section
{
#pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
}
#pragma omp section
{
#pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
}
#pragma omp section
{
#pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
}
#pragma omp section
{
#pragma acc enter data copyin(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
}
#pragma omp section
{
#pragma acc exit data delete(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
}
#pragma omp section
{
#pragma acc loop /* { dg-error "may not be closely nested" } */
for (i = 0; i < 2; ++i)
;
}
}
#pragma omp single
{
#pragma acc parallel /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc enter data copyin(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc exit data delete(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc loop /* { dg-error "may not be closely nested" } */
for (i = 0; i < 2; ++i)
;
}
#pragma omp task
{
#pragma acc parallel /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc enter data copyin(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc exit data delete(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc loop /* { dg-error "may not be closely nested" } */
for (i = 0; i < 2; ++i)
;
}
#pragma omp master
{
#pragma acc parallel /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc enter data copyin(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc exit data delete(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc loop /* { dg-error "may not be closely nested" } */
for (i = 0; i < 2; ++i)
;
}
#pragma omp critical
{
#pragma acc parallel /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc enter data copyin(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc exit data delete(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc loop /* { dg-error "may not be closely nested" } */
for (i = 0; i < 2; ++i)
;
}
#pragma omp ordered
{
#pragma acc parallel /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
;
#pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc enter data copyin(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc exit data delete(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
#pragma acc loop /* { dg-error "may not be closely nested" } */
for (i = 0; i < 2; ++i)
;
}
#pragma omp target
{
#pragma acc parallel /* { dg-error "OpenACC parallel construct inside of OpenMP target region" } */
;
#pragma acc kernels /* { dg-error "OpenACC kernels construct inside of OpenMP target region" } */
;
#pragma acc data /* { dg-error "OpenACC data construct inside of OpenMP target region" } */
;
#pragma acc update host(i) /* { dg-error "OpenACC update construct inside of OpenMP target region" } */
#pragma acc enter data copyin(i) /* { dg-error "OpenACC enter/exit data construct inside of OpenMP target region" } */
#pragma acc exit data delete(i) /* { dg-error "OpenACC enter/exit data construct inside of OpenMP target region" } */
#pragma acc loop
for (i = 0; i < 2; ++i)
;
}
}
void
f_acc_parallel (void)
{
#pragma acc parallel
{
#pragma omp parallel /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc parallel
{
#pragma omp for /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
for (i = 0; i < 3; i++)
;
}
#pragma acc parallel
{
#pragma omp sections /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
{
;
}
}
#pragma acc parallel
{
#pragma omp single /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc parallel
{
#pragma omp task /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc parallel
{
#pragma omp master /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc parallel
{
#pragma omp critical /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc parallel
{
#pragma omp atomic write
i = 0; /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
}
#pragma acc parallel
{
#pragma omp ordered /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc parallel
{
#pragma omp target /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
#pragma omp target data /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
#pragma omp target update to(i) /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
}
}
void
f_acc_kernels (void)
{
#pragma acc kernels
{
#pragma omp parallel /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc kernels
{
#pragma omp for /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
for (i = 0; i < 3; i++)
;
}
#pragma acc kernels
{
#pragma omp sections /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
{
;
}
}
#pragma acc kernels
{
#pragma omp single /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc kernels
{
#pragma omp task /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc kernels
{
#pragma omp master /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc kernels
{
#pragma omp critical /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc kernels
{
#pragma omp atomic write
i = 0; /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
}
#pragma acc kernels
{
#pragma omp ordered /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc kernels
{
#pragma omp target /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
#pragma omp target data /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
#pragma omp target update to(i) /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
}
}
void
f_acc_data (void)
{
#pragma acc data
{
#pragma omp parallel /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc data
{
#pragma omp for /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
for (i = 0; i < 3; i++)
;
}
#pragma acc data
{
#pragma omp sections /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
{
;
}
}
#pragma acc data
{
#pragma omp single /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc data
{
#pragma omp task /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc data
{
#pragma omp master /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc data
{
#pragma omp critical /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc data
{
#pragma omp atomic write
i = 0; /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
}
#pragma acc data
{
#pragma omp ordered /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc data
{
#pragma omp target /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
#pragma omp target data /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
#pragma omp target update to(i) /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
}
}
void
f_acc_loop (void)
{
#pragma acc loop
for (i = 0; i < 2; ++i)
{
#pragma omp parallel /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc loop
for (i = 0; i < 2; ++i)
{
#pragma omp for /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
for (i = 0; i < 3; i++)
;
}
#pragma acc loop
for (i = 0; i < 2; ++i)
{
#pragma omp sections /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
{
;
}
}
#pragma acc loop
for (i = 0; i < 2; ++i)
{
#pragma omp single /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc loop
for (i = 0; i < 2; ++i)
{
#pragma omp task /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc loop
for (i = 0; i < 2; ++i)
{
#pragma omp master /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc loop
for (i = 0; i < 2; ++i)
{
#pragma omp critical /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc loop
for (i = 0; i < 2; ++i)
{
#pragma omp atomic write
i = 0; /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
}
#pragma acc loop
for (i = 0; i < 2; ++i)
{
#pragma omp ordered /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
}
#pragma acc loop
for (i = 0; i < 2; ++i)
{
#pragma omp target /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
#pragma omp target data /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
;
#pragma omp target update to(i) /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
}
}

View File

@ -0,0 +1,25 @@
/* Have to enable optimizations, as otherwise builtins won't be expanded. */
/* { dg-additional-options "-O -fdump-rtl-expand -fno-openacc" } */
#if __cplusplus
extern "C" {
#endif
typedef enum acc_device_t { acc_device_X = 123 } acc_device_t;
extern int acc_on_device (acc_device_t);
#if __cplusplus
}
#endif
int
f (void)
{
const acc_device_t dev = acc_device_X;
return acc_on_device (dev);
}
/* Without -fopenacc, we're expecting one call.
{ dg-final { scan-rtl-dump-times "\\\(call \[^\\n\]*\\\"acc_on_device" 1 "expand" } } */
/* { dg-final { cleanup-rtl-dump "expand" } } */

View File

@ -0,0 +1,29 @@
/* Have to enable optimizations, as otherwise builtins won't be expanded. */
/* { dg-additional-options "-O -fdump-rtl-expand" } */
#if __cplusplus
extern "C" {
#endif
typedef enum acc_device_t { acc_device_X = 123 } acc_device_t;
extern int acc_on_device (acc_device_t);
#if __cplusplus
}
#endif
int
f (void)
{
const acc_device_t dev = acc_device_X;
return acc_on_device (dev);
}
/* With -fopenacc, we're expecting the builtin to be expanded, so no calls.
TODO: in C++, even under extern "C", the use of enum for acc_device_t
perturbs expansion as a builtin, which expects an int parameter. It's fine
when changing acc_device_t to plain int, but that's not what we're doing in
<openacc.h>.
{ dg-final { scan-rtl-dump-times "\\\(call \[^\\n\]*\\\"acc_on_device" 0 "expand" { xfail c++ } } } */
/* { dg-final { cleanup-rtl-dump "expand" } } */

View File

@ -0,0 +1,213 @@
void
f (int N, float *a, float *b)
{
int ii;
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) async (1 2) /* { dg-error "expected '\\)' before numeric constant" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) async (1,) /* { dg-error "expected (primary-|)expression before" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) async (,1) /* { dg-error "expected (primary-|)expression before" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) async (1,2,) /* { dg-error "expected (primary-|)expression before" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) async (1,2 3) /* { dg-error "expected '\\)' before numeric constant" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) async (1,2,,) /* { dg-error "expected (primary-|)expression before" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) async (1 /* { dg-error "expected '\\)' before end of line" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) async (*) /* { dg-error "expected (primary-|)expression before" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) async (a)
/* { dg-error "expected integer expression before" "" { target c } 54 } */
/* { dg-error "'async' expression must be integral" "" { target c++ } 54 } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) async (1.0)
/* { dg-error "expected integer expression before" "" { target c } 62 } */
/* { dg-error "'async' expression must be integral" "" { target c++ } 62 } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) async () /* { dg-error "expected (primary-|)expression before" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) async
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait (1 2) /* { dg-error "expected '\\)' before numeric constant" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait (1,) /* { dg-error "expected (primary-|)expression before" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait (,1) /* { dg-error "expected (primary-|)expression before" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait (1,2,) /* { dg-error "expected (primary-|)expression before" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait (1,2 3) /* { dg-error "expected '\\)' before numeric constant" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait (1,2,,) /* { dg-error "expected (primary-|)expression before" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait (1 /* { dg-error "expected '\\\)' before end of line" } */
/* { dg-error "expected integer expression before '\\\)'" "" { target c++ } 118 } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait (1,*) /* { dg-error "expected (primary-|)expression before" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait (1,a) /*{ dg-error "must be integral" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait (a) /* { dg-error "must be integral" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait (1.0) /* { dg-error "must be integral" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait () /* { dg-error "expected (integer |)expression (list |)before" } */
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc parallel copyin (a[0:N]) copy (b[0:N]) wait
{
for (ii = 0; ii < N; ii++)
b[ii] = a[ii];
}
#pragma acc wait (1 2) /* { dg-error "expected '\\)' before numeric constant" } */
#pragma acc wait (1,) /* { dg-error "expected (primary-|)expression before" } */
#pragma acc wait (,1) /* { dg-error "expected (primary-|)expression before" } */
#pragma acc wait (1,2,) /* { dg-error "expected (primary-|)expression before" } */
#pragma acc wait (1,2 3) /* { dg-error "expected '\\)' before numeric constant" } */
#pragma acc wait (1,2,,) /* { dg-error "expected (primary-|)expression before" } */
#pragma acc wait (1 /* { dg-error "expected '\\\)' before end of line" } */
/* { dg-error "expected integer expression before '\\\)'" "" { target c++ } 173 } */
#pragma acc wait (1,*) /* { dg-error "expected (primary-|)expression before" } */
#pragma acc wait (1,a) /* { dg-error "expression must be integral" } */
#pragma acc wait (a) /* { dg-error "expression must be integral" } */
#pragma acc wait (1.0) /* { dg-error "expression must be integral" } */
#pragma acc wait 1 /* { dg-error "expected '#pragma acc' clause before numeric constant" } */
#pragma acc wait N /* { dg-error "expected '#pragma acc' clause before 'N'" } */
#pragma acc wait async (1 2) /* { dg-error "expected '\\)' before numeric constant" } */
#pragma acc wait async (1 2) /* { dg-error "expected '\\)' before numeric constant" } */
#pragma acc wait async (1,) /* { dg-error "expected (primary-|)expression before" } */
#pragma acc wait async (,1) /* { dg-error "expected (primary-|)expression before" } */
#pragma acc wait async (1,2,) /* { dg-error "expected (primary-|)expression before" } */
#pragma acc wait async (1,2 3) /* { dg-error "expected '\\)' before numeric constant" } */
#pragma acc wait async (1,2,,) /* { dg-error "expected (primary-|)expression before" } */
#pragma acc wait async (1 /* { dg-error "expected '\\)' before end of line" } */
#pragma acc wait async (*) /* { dg-error "expected (primary-|)expression before " } */
#pragma acc wait async (a)
/* { dg-error "expected integer expression before" "" { target c } 206 } */
/* { dg-error "expression must be integral" "" { target c++ } 206 } */
#pragma acc wait async (1.0)
/* { dg-error "expected integer expression before" "" { target c } 210 } */
/* { dg-error "expression must be integral" "" { target c++ } 210 } */
}

View File

@ -0,0 +1,88 @@
int
main (int argc, char **argv)
{
#define N 2
int a[N], b[N];
int i;
for (i = 0; i < N; i++)
{
a[i] = 3;
b[i] = 0;
}
#pragma acc parallel copyin (a[0:N]) copyout (b[0:N])
{
int ii;
for (ii = 0; ii < N; ii++)
{
const int idx = ii;
int n = 1;
const int len = n;
#pragma acc cache /* { dg-error "expected '\\\(' before end of line" } */
#pragma acc cache a[0:N] /* { dg-error "expected '\\\(' before 'a'" } */
/* { dg-bogus "expected end of line before 'a'" "" { xfail c++ } 26 } */
#pragma acc cache (a) /* { dg-error "expected '\\\['" } */
#pragma acc cache ( /* { dg-error "expected (identifier|unqualified-id) before end of line" } */
#pragma acc cache () /* { dg-error "expected (identifier|unqualified-id) before '\\\)' token" } */
#pragma acc cache (,) /* { dg-error "expected (identifier|unqualified-id) before '(,|\\\))' token" } */
#pragma acc cache (a[0:N] /* { dg-error "expected '\\\)' before end of line" } */
#pragma acc cache (a[0:N],) /* { dg-error "expected (identifier|unqualified-id) before '(,|\\\))' token" "" { xfail c } } */
#pragma acc cache (a[0:N]) copyin (a[0:N]) /* { dg-error "expected end of line before 'copyin'" } */
#pragma acc cache () /* { dg-error "expected (identifier|unqualified-id) before '\\\)' token" } */
#pragma acc cache (a[0:N] b[0:N]) /* { dg-error "expected '\\\)' before 'b'" } */
#pragma acc cache (a[0:N] b[0:N}) /* { dg-error "expected '\\\)' before 'b'" } */
/* { dg-bogus "expected end of line before '\\\}' token" "" { xfail c++ } 47 } */
#pragma acc cache (a[0:N] /* { dg-error "expected '\\\)' before end of line" } */
#pragma acc cache (a[ii]) /* { dg-error "'ii' is not a constant" } */
#pragma acc cache (a[idx:n]) /* { dg-error "'n' is not a constant" } */
#pragma acc cache (a[0:N]) ( /* { dg-error "expected end of line before '\\(' token" } */
#pragma acc cache (a[0:N]) ii /* { dg-error "expected end of line before 'ii'" } */
#pragma acc cache (a[0:N] ii) /* { dg-error "expected '\\)' before 'ii'" } */
#pragma acc cache (a[0:N])
#pragma acc cache (a[0:N], a[0:N])
#pragma acc cache (a[0:N], b[0:N])
#pragma acc cache (a[0])
#pragma acc cache (a[0], a[1], b[0:N])
#pragma acc cache (a[idx])
#pragma acc cache (a[idx:len])
b[ii] = a[ii];
}
}
for (i = 0; i < N; i++)
{
if (a[i] != b[i])
__builtin_abort ();
}
return 0;
}

View File

@ -0,0 +1,18 @@
void
f (void)
{
int i;
#pragma acc parallel one /* { dg-error "expected '#pragma acc' clause before 'one'" } */
;
#pragma acc kernels eins /* { dg-error "expected '#pragma acc' clause before 'eins'" } */
;
#pragma acc data two /* { dg-error "expected '#pragma acc' clause before 'two'" } */
;
#pragma acc loop deux /* { dg-error "expected '#pragma acc' clause before 'deux'" } */
for (i = 0; i < 2; ++i)
;
}

View File

@ -0,0 +1,97 @@
/* { dg-skip-if "not yet" { c++ } } */
int i, j, k;
extern int foo (void);
void
f1 (void)
{
#pragma acc parallel
#pragma acc loop collapse (2)
for (i = 0; i < 5; i++)
; /* { dg-error "not enough perfectly nested" } */
{
for (j = 0; j < 5; j++)
;
}
}
void
f2 (void)
{
#pragma acc parallel
#pragma acc loop collapse (2)
for (i = 0; i < 5; i++)
{
{
{
for (j = 0; j < 5; j++)
{
}
}
}
}
}
void
f3 (void)
{
#pragma acc parallel
#pragma acc loop collapse (2)
for (i = 0; i < 5; i++)
{
int k = foo (); /* { dg-error "not enough perfectly nested" } */
{
{
for (j = 0; j < 5; j++)
{
}
}
}
}
}
void
f4 (void)
{
#pragma acc parallel
#pragma acc loop collapse (2)
for (i = 0; i < 5; i++)
{
{
for (j = 0; j < 5; j++)
;
foo (); /* { dg-error "collapsed loops not perfectly nested before" } */
}
}
}
void
f5 (void)
{
#pragma acc parallel
#pragma acc loop collapse (2)
for (i = 0; i < 5; i++)
{
{
for (j = 0; j < 5; j++)
;
}
foo (); /* { dg-error "collapsed loops not perfectly nested before" } */
}
}
void
f6 (void)
{
#pragma acc parallel
#pragma acc loop collapse (2)
for (i = 0; i < 5; i++)
{
{
for (j = 0; j < 5; j++)
;
}
}
foo ();
}

View File

@ -0,0 +1,6 @@
void
foo (void)
{
#pragma acc data
;
}

View File

@ -0,0 +1,21 @@
void
foo (void)
{
int a, b[100];
int n;
#pragma acc enter data copyin (a, b) async wait
#pragma acc enter data create (b[20:30]) async wait
#pragma acc enter data (a) /* { dg-error "expected '#pragma acc' clause before '\\\(' token" } */
#pragma acc enter data create (b(1:10)) /* { dg-error "expected '\\\)' before '\\\(' token" } */
#pragma acc exit data delete (a) if (0)
#pragma acc exit data copyout (b) if (a)
#pragma acc exit data delete (b)
#pragma acc enter /* { dg-error "expected 'data' in" } */
#pragma acc exit /* { dg-error "expected 'data' in" } */
#pragma acc enter data /* { dg-error "has no data movement clause" } */
#pragma acc exit data /* { dg-error "has no data movement clause" } */
#pragma acc enter Data /* { dg-error "invalid pragma before" } */
#pragma acc exit copyout (b) /* { dg-error "invalid pragma before" } */
}
/* { dg-error "has no data movement clause" "" { target *-*-* } 8 } */

View File

@ -0,0 +1,13 @@
void
fun (void)
{
float *fp;
#pragma acc parallel copy(fp[0:2],fp[0:2]) /* { dg-error "'fp' appears more than once in map clauses" } */
;
#pragma acc kernels present_or_copyin(fp[3]) present_or_copyout(fp[7:4]) /* { dg-error "'fp' appears more than once in map clauses" } */
;
#pragma acc data create(fp[:10]) deviceptr(fp) /* { dg-error "'fp' appears more than once in map clauses" } */
;
#pragma acc data create(fp) present(fp) /* { dg-error "'fp' appears more than once in map clauses" } */
;
}

View File

@ -0,0 +1,86 @@
/* { dg-skip-if "not yet" { c++ } } */
void
fun1 (void)
{
#pragma acc parallel deviceptr(u) /* { dg-error "'u' undeclared" } */
;
#pragma acc kernels deviceptr(u[0:4]) /* { dg-error "expected '\\\)' before '\\\[' token" } */
;
#pragma acc data deviceptr(fun1) /* { dg-error "'fun1' is not a variable" } */
;
#pragma acc parallel deviceptr(fun1[2:5])
/* { dg-error "'fun1' is not a variable" "not a variable" { target *-*-* } 13 } */
/* { dg-error "expected '\\\)' before '\\\[' token" "array" { target *-*-* } 13 } */
;
int i;
#pragma acc kernels deviceptr(i) /* { dg-error "'i' is not a pointer variable" } */
;
#pragma acc data deviceptr(i[0:4])
/* { dg-error "'i' is not a pointer variable" "not a pointer variable" { target *-*-* } 21 } */
/* { dg-error "expected '\\\)' before '\\\[' token" "array" { target *-*-* } 21 } */
;
float fa[10];
#pragma acc parallel deviceptr(fa) /* { dg-error "'fa' is not a pointer variable" } */
;
#pragma acc kernels deviceptr(fa[1:5])
/* { dg-error "'fa' is not a pointer variable" "not a pointer variable" { target *-*-* } 29 } */
/* { dg-error "expected '\\\)' before '\\\[' token" "array" { target *-*-* } 29 } */
;
float *fp;
#pragma acc data deviceptr(fp)
;
#pragma acc parallel deviceptr(fp[0:4]) /* { dg-error "expected '\\\)' before '\\\[' token" } */
;
}
void
fun2 (void)
{
int i;
float *fp;
#pragma acc kernels deviceptr(fp,u,fun2,i,fp)
/* { dg-error "'u' undeclared" "u undeclared" { target *-*-* } 46 } */
/* { dg-error "'fun2' is not a variable" "fun2 not a variable" { target *-*-* } 46 } */
/* { dg-error "'i' is not a pointer variable" "i not a pointer variable" { target *-*-* } 46 } */
/* { dg-error "'fp' appears more than once in map clauses" "fp more than once" { target *-*-* } 46 } */
;
}
void
fun3 (void)
{
float *fp;
#pragma acc data deviceptr(fp,fp) /* { dg-error "'fp' appears more than once in map clauses" } */
;
#pragma acc parallel deviceptr(fp) deviceptr(fp) /* { dg-error "'fp' appears more than once in map clauses" } */
;
#pragma acc kernels copy(fp) deviceptr(fp) /* { dg-error "'fp' appears more than once in map clauses" } */
;
}
extern struct s s1;
extern struct s s2[1]; /* { dg-error "array type has incomplete element type" "" { target c } } */
void
fun4 (void)
{
struct s *s1_p = &s1;
struct s *s2_p = &s2;
#pragma acc parallel deviceptr(s1) /* { dg-error "'s1' is not a pointer variable" } */
;
#pragma acc parallel deviceptr(s2)
;
#pragma acc parallel deviceptr(s1_p)
s1_p = 0;
#pragma acc parallel deviceptr(s2_p)
s2_p = 0;
}

View File

@ -0,0 +1,23 @@
void
fun1 (void)
{
char *a = 0;
#pragma acc data deviceptr(a)
++a;
#pragma acc data deviceptr(a)
#pragma acc parallel
++a;
#pragma acc data deviceptr(a)
#pragma acc parallel deviceptr(a)
++a;
#pragma acc data
#pragma acc parallel deviceptr(a)
++a;
#pragma acc parallel deviceptr(a)
++a;
}

View File

@ -0,0 +1,11 @@
float *d_a;
void
f (float *a)
{
#pragma acc parallel copyout (a[3:10]) deviceptr (d_a)
d_a[2] += 1.0;
#pragma acc parallel deviceptr (d_a) copyout (a[3:10])
d_a[2] += 1.0;
}

View File

@ -0,0 +1,10 @@
/* { dg-skip-if "not yet" { c++ } } */
void
f (void)
{
struct { int i; } *p;
#pragma acc data copyout(p) if(1) if(1) /* { dg-error "too many 'if' clauses" } */
;
#pragma acc update device(p) if(*p) /* { dg-error "used struct type value where scalar is required" } */
}

View File

@ -0,0 +1,11 @@
void
f (short c)
{
#pragma acc parallel if(c)
;
#pragma acc kernels if(c)
;
#pragma acc data if(c)
;
#pragma acc update device(c) if(c)
}

View File

@ -0,0 +1,6 @@
void
foo (void)
{
#pragma acc kernels
;
}

View File

@ -0,0 +1,72 @@
/* { dg-skip-if "not yet" { c++ } } */
int test1()
{
int i, j, k, b[10];
int a[30];
double d;
float r;
i = 0;
#pragma acc loop
while(1) /* { dg-error "for statement expected" } */
{
if (i > 0) break;
i = i + 1;
}
i = 0;
#pragma acc loop
for(;;) /* { dg-error "expected iteration declaration or initialization" } */
{
if (i > 0) break; /* { dg-error "break statement used" } */
i = i + 1;
}
i = 0;
#pragma acc loop
do /* { dg-error "for statement expected" } */
{
i = i + 1;
}
while (i < 4);
#pragma acc loop
while (i < 8) /* { dg-error "for statement expected" } */
{
i = i + 1;
}
#pragma acc loop
for (d = 1; d < 30; d+= 6) /* { dg-error "invalid type for iteration variable" } */
{
i = d;
a[i] = 1;
}
#pragma acc loop
for (i = 1; i < 30; i++ )
if (i == 16) break; /* { dg-error "break statement used" } */
/* different types of for loop are allowed */
#pragma acc loop
for (i = 1; i < 10; i++)
{
}
#pragma acc loop
for (i = 1; i < 10; i+=2)
{
a[i] = i;
}
/* after loop directive must be loop */
#pragma acc loop
a[1] = 1; /* { dg-error "for statement expected" } */
for (i = 1; i < 10; i++)
;
/* combined directives may be used*/
#pragma acc parallel loop
for(i = 1; i < 10; i++)
{
}
#pragma acc kernels loop
for(i = 1; i < 10; i++)
{
}
return 0;
}
/* { dg-prune-output "sorry, unimplemented: directive not yet implemented" } */

View File

@ -0,0 +1,14 @@
/* { dg-additional-options "-fdump-tree-gimple" } */
void
f (int i, int j)
{
#pragma acc kernels
#pragma acc loop collapse(2)
for (i = 0; i < 20; ++i)
for (j = 0; j < 25; ++j)
;
}
/* { dg-final { scan-tree-dump-times "#pragma acc loop collapse\\(2\\) private\\(j\\) private\\(i\\)" 1 "gimple" } } */
/* { dg-final { cleanup-tree-dump "gimple" } } */

View File

@ -0,0 +1,101 @@
extern int i;
void
f_acc_parallel (void)
{
#pragma acc parallel
{
#pragma acc loop
for (i = 0; i < 2; ++i)
;
}
}
void
f_acc_kernels (void)
{
#pragma acc kernels
{
#pragma acc loop
for (i = 0; i < 2; ++i)
;
}
}
void
f_acc_data (void)
{
#pragma acc data
{
#pragma acc parallel
;
#pragma acc parallel
{
#pragma acc loop
for (i = 0; i < 2; ++i)
;
}
#pragma acc kernels
;
#pragma acc kernels
{
#pragma acc loop
for (i = 0; i < 2; ++i)
;
}
#pragma acc data
;
#pragma acc update host(i)
#pragma acc enter data copyin(i)
#pragma acc exit data delete(i)
#pragma acc loop
for (i = 0; i < 2; ++i)
;
#pragma acc data
{
#pragma acc parallel
;
#pragma acc parallel
{
#pragma acc loop
for (i = 0; i < 2; ++i)
;
}
#pragma acc kernels
;
#pragma acc kernels
{
#pragma acc loop
for (i = 0; i < 2; ++i)
;
}
#pragma acc data
;
#pragma acc update host(i)
#pragma acc enter data copyin(i)
#pragma acc exit data delete(i)
#pragma acc loop
for (i = 0; i < 2; ++i)
;
}
}
}

View File

@ -0,0 +1,61 @@
void
f (void)
{
unsigned char c, ca[15], caa[20][30];
#pragma acc data copyin(c)
{
c = 5;
ca[3] = c;
caa[3][12] = ca[3] + caa[3][12];
#pragma acc data copyin(ca[2:4])
{
c = 6;
ca[4] = c;
caa[3][12] = ca[3] + caa[3][12];
}
#pragma acc parallel copyout(ca[3:4])
{
c = 7;
ca[5] = c;
caa[3][12] = ca[3] + caa[3][12];
}
#pragma acc kernels copy(ca[4:4])
{
c = 8;
ca[6] = c;
caa[3][12] = ca[3] + caa[3][12];
}
#pragma acc data pcopy(ca[5:7])
{
c = 15;
ca[7] = c;
caa[3][12] = ca[3] + caa[3][12];
#pragma acc data pcopyin(caa[3:7][0:30])
{
c = 16;
ca[8] = c;
caa[3][12] = ca[3] + caa[3][12];
}
#pragma acc parallel pcopyout(caa[3:7][0:30])
{
c = 17;
ca[9] = c;
caa[3][12] = ca[3] + caa[3][12];
}
#pragma acc kernels pcopy(caa[3:7][0:30])
{
c = 18;
ca[10] = c;
caa[3][12] = ca[3] + caa[3][12];
}
}
}
}

View File

@ -0,0 +1,39 @@
extern int i;
/* While the OpenACC specification does allow for certain kinds of
nesting, we don't support many of these yet. */
void
f_acc_parallel (void)
{
#pragma acc parallel
{
#pragma acc parallel /* { dg-bogus "parallel construct inside of parallel region" "not implemented" { xfail *-*-* } } */
;
#pragma acc kernels /* { dg-bogus "kernels construct inside of parallel region" "not implemented" { xfail *-*-* } } */
;
#pragma acc data /* { dg-error "data construct inside of parallel region" } */
;
#pragma acc update host(i) /* { dg-error "update construct inside of parallel region" } */
#pragma acc enter data copyin(i) /* { dg-error "enter/exit data construct inside of parallel region" } */
#pragma acc exit data delete(i) /* { dg-error "enter/exit data construct inside of parallel region" } */
}
}
/* While the OpenACC specification does allow for certain kinds of
nesting, we don't support many of these yet. */
void
f_acc_kernels (void)
{
#pragma acc kernels
{
#pragma acc parallel /* { dg-bogus "parallel construct inside of kernels region" "not implemented" { xfail *-*-* } } */
;
#pragma acc kernels /* { dg-bogus "kernels construct inside of kernels region" "not implemented" { xfail *-*-* } } */
;
#pragma acc data /* { dg-error "data construct inside of kernels region" } */
;
#pragma acc update host(i) /* { dg-error "update construct inside of kernels region" } */
#pragma acc enter data copyin(i) /* { dg-error "enter/exit data construct inside of kernels region" } */
#pragma acc exit data delete(i) /* { dg-error "enter/exit data construct inside of kernels region" } */
}
}

Some files were not shown because too many files have changed in this diff Show More