target.c: New file.

libgomp/
	* target.c: New file.
	* Makefile.am (libgomp_la_SOURCES): Add target.c.
	* Makefile.in: Regenerated.
	* libgomp_g.h (GOMP_task): Add depend argument.
	(GOMP_barrier_cancel, GOMP_loop_end_cancel,
	GOMP_sections_end_cancel, GOMP_target, GOMP_target_data,
	GOMP_target_end_data, GOMP_target_update, GOMP_teams,
	GOMP_parallel_loop_static, GOMP_parallel_loop_dynamic,
	GOMP_parallel_loop_guided, GOMP_parallel_loop_runtime,
	GOMP_parallel, GOMP_cancel, GOMP_cancellation_point,
	GOMP_taskgroup_start, GOMP_taskgroup_end,
	GOMP_parallel_sections): New prototypes.
	* fortran.c (omp_is_initial_device): Add ialias_redirect.
	(omp_is_initial_device_): New function.
	(ULP, STR1, STR2, ialias_redirect): Removed.
	(omp_get_cancellation_, omp_get_proc_bind_, omp_set_default_device_,
	omp_set_default_device_8_, omp_get_default_device_,
	omp_get_num_devices_, omp_get_num_teams_, omp_get_team_num_): New
	functions.
	* libgomp.map (GOMP_barrier_cancel, GOMP_loop_end_cancel,
	GOMP_sections_end_cancel, GOMP_target, GOMP_target_data,
	GOMP_target_end_data, GOMP_target_update, GOMP_teams): Export
	@@GOMP_4.0.
	(omp_is_initial_device, omp_is_initial_device_, omp_get_cancellation,
	omp_get_cancellation_, omp_get_proc_bind, omp_get_proc_bind_,
	omp_set_default_device, omp_set_default_device_,
	omp_set_default_device_8_, omp_get_default_device,
	omp_get_default_device_, omp_get_num_devices, omp_get_num_devices_,
	omp_get_num_teams, omp_get_num_teams_, omp_get_team_num,
	omp_get_team_num_): Export @@OMP_4.0.
	* team.c (struct gomp_thread_start_data): Add place field.
	(gomp_thread_start): Clear thr->thread_pool and
	thr->task before returning.  Use gomp_team_barrier_wait_final
	instead of gomp_team_barrier_wait.  Initialize thr->place.
	(gomp_new_team): Initialize work_shares_to_free, work_share_cancelled,
	team_cancelled and task_queued_count fields.
	(gomp_free_pool_helper): Clear thr->thread_pool and thr->task
	before calling pthread_exit.
	(gomp_free_thread): No longer static.  Use
	gomp_managed_threads_lock instead of gomp_remaining_threads_lock.
	(gomp_team_start): Add flags argument.  Set
	thr->thread_pool->threads_busy to nthreads immediately after creating
	new pool.  Use gomp_managed_threads_lock instead of
	gomp_remaining_threads_lock.  Handle OpenMP 4.0 affinity.
	(gomp_team_end): Use gomp_managed_threads_lock instead of
	gomp_remaining_threads_lock.  Use gomp_team_barrier_wait_final instead
	of gomp_team_barrier_wait.  If team->team_cancelled, call
	gomp_fini_worshare on ws chain starting at team->work_shares_to_free
	rather than thr->ts.work_share.
	(initialize_team): Don't call gomp_sem_init here.
	* sections.c (GOMP_parallel_sections_start): Adjust gomp_team_start
	caller.
	(GOMP_parallel_sections, GOMP_sections_end_cancel): New functions.
	* env.c (gomp_global_icv): Add default_device_var, target_data and
	bind_var initializers.
	(gomp_cpu_affinity, gomp_cpu_affinity_len): Remove.
	(gomp_bind_var_list, gomp_bind_var_list_len, gomp_places_list,
	gomp_places_list_len): New variables.
	(parse_bind_var, parse_one_place, parse_places_var): New functions.
	(parse_affinity): Rewritten to construct OMP_PLACES list with unit
	sized places.
	(gomp_cancel_var): New global variable.
	(parse_int): New function.
	(handle_omp_display_env): New function.
	(initialize_env): Use it.  Initialize default_device_var.
	Parse OMP_CANCELLATION env var.  Use parse_bind_var to parse
	OMP_PROC_BIND instead of parse_boolean.  Use parse_places_var for
	OMP_PLACES parsing.  Don't call parse_affinity if OMP_PLACES has
	been successfully parsed (and call gomp_init_affinity in that case).
	(omp_get_cancellation, omp_get_proc_bind, omp_set_default_device,
	omp_get_default_device, omp_get_num_devices, omp_get_num_teams,
	omp_get_team_num, omp_is_initial_device): New functions.
	* libgomp.h: Include stdlib.h.
	(ialias_ulp, ialias_str1, ialias_str2, ialias_redirect, ialias_call):
	Define.
	(struct target_mem_desc): Forward declare.
	(struct gomp_task_icv): Add default_device_var, target_data, bind_var
	and thread_limit_var fields.
	(gomp_get_num_devices): New prototype.
	(gomp_cancel_var): New extern decl.
	(struct gomp_team): Add work_shares_to_free, work_share_cancelled,
	team_cancelled and task_queued_count fields.  Add comments about
	task_{,queued_,running_}count.
	(gomp_cancel_kind): New enum.
	(gomp_work_share_end_cancel): New prototype.
	(struct gomp_task): Add next_taskgroup, prev_taskgroup, taskgroup,
	copy_ctors_done, dependers, depend_hash, depend_count, num_dependees
	and depend fields.
	(struct gomp_taskgroup): New type.
	(struct gomp_task_depend_entry,
	struct gomp_dependers_vec): New types.
	(gomp_finish_task): Free depend_hash if non-NULL.
	(struct gomp_team_state): Add place_partition_off
	and place_partition_len fields.
	(gomp_bind_var_list, gomp_bind_var_list_len, gomp_places_list,
	gomp_places_list_len): New extern decls.
	(struct gomp_thread): Add place field.
	(gomp_cpu_affinity, gomp_cpu_affinity_len): Remove.
	(gomp_init_thread_affinity): Add place argument.
	(gomp_affinity_alloc, gomp_affinity_init_place, gomp_affinity_add_cpus,
	gomp_affinity_remove_cpu, gomp_affinity_copy_place,
	gomp_affinity_same_place, gomp_affinity_finalize_place_list,
	gomp_affinity_init_level, gomp_affinity_print_place): New
	prototypes.
	(gomp_team_start): Add flags argument.
	(gomp_thread_limit_var, gomp_remaining_threads_count,
	gomp_remaining_threads_lock): Remove.
	(gomp_managed_threads_lock): New variable.
	(struct gomp_thread_pool): Add threads_busy field.
	(gomp_free_thread): New prototype.
	* task.c: Include hashtab.h.
	(hash_entry_type): New typedef.
	(htab_alloc, htab_free, htab_hash, htab_eq): New inlines.
	(gomp_init_task): Clear dependers, depend_hash, depend_count,
	copy_ctors_done and taskgroup fields.
	(GOMP_task): Add depend argument, handle depend clauses.  If
	gomp_team_barrier_cancelled or if it's taskgroup has been
	cancelled, don't queue or start new tasks.  Set copy_ctors_done
	field if needed.  Initialize taskgroup field.  If copy_ctors_done
	and already cancelled, don't discard the task.  If taskgroup is
	non-NULL, enqueue the task into taskgroup queue.  Increment
	num_children field in taskgroup.  Increment task_queued_count.
	(gomp_task_run_pre, gomp_task_run_post_remove_parent,
	gomp_task_run_post_remove_taskgroup): New inline functions.
	(gomp_task_run_post_handle_depend_hash,
	gomp_task_run_post_handle_dependers,
	gomp_task_run_post_handle_depend): New functions.
	(GOMP_taskwait): Use them.  If more than one new tasks
	have been queued, wake other threads if needed.
	(gomp_barrier_handle_tasks): Likewise.  If
	gomp_team_barrier_cancelled, don't start any new tasks, just free
	all tasks.
	(GOMP_taskgroup_start, GOMP_taskgroup_end): New functions.
	* omp_lib.f90.in
	(omp_proc_bind_kind, omp_proc_bind_false,
	omp_proc_bind_true, omp_proc_bind_master, omp_proc_bind_close,
	omp_proc_bind_spread): New params.
	(omp_get_cancellation, omp_get_proc_bind, omp_set_default_device,
	omp_get_default_device, omp_get_num_devices, omp_get_num_teams,
	omp_get_team_num, omp_is_initial_device): New interfaces.
	(omp_get_dynamic, omp_get_nested, omp_in_parallel,
	omp_get_max_threads, omp_get_num_procs, omp_get_num_threads,
	omp_get_thread_num, omp_get_thread_limit, omp_set_max_active_levels,
	omp_get_max_active_levels, omp_get_level, omp_get_ancestor_thread_num,
	omp_get_team_size, omp_get_active_level, omp_in_final): Remove
	useless use omp_lib_kinds.
	* omp.h.in (omp_proc_bind_t): New typedef.
	(omp_get_cancellation, omp_get_proc_bind, omp_set_default_device,
	omp_get_default_device, omp_get_num_devices, omp_get_num_teams,
	omp_get_team_num, omp_is_initial_device): New prototypes.
	* loop.c (gomp_parallel_loop_start): Add flags argument, pass it
	through to gomp_team_start.
	(GOMP_parallel_loop_static_start, GOMP_parallel_loop_dynamic_start,
	GOMP_parallel_loop_guided_start, GOMP_parallel_loop_runtime_start):
	Adjust gomp_parallel_loop_start callers.
	(GOMP_parallel_loop_static, GOMP_parallel_loop_dynamic,
	GOMP_parallel_loop_guided, GOMP_parallel_loop_runtime,
	GOMP_loop_end_cancel): New functions.
	(GOMP_parallel_end): Add ialias_redirect.
	* hashtab.h: New file.
	* libgomp.texi (Environment Variables): Minor cleanup,
	update section refs to OpenMP 4.0rc2.
	(OMP_DISPLAY_ENV, GOMP_SPINCOUNT): Document these
	environment variables.
	* work.c (gomp_work_share_end, gomp_work_share_end_nowait): Set
	team->work_shares_to_free to thr->ts.work_share before calling
	free_work_share.
	(gomp_work_share_end_cancel): New function.
	* config/linux/proc.c: Include errno.h.
	(gomp_get_cpuset_size, gomp_cpuset_size, gomp_cpusetp): New variables.
	(gomp_cpuset_popcount): Add cpusetsize argument, use it instead of
	sizeof (cpu_set_t) to determine number of iterations.  Fix up check
	extern decl.  Use CPU_COUNT_S if available, or CPU_COUNT if
	gomp_cpuset_size is sizeof (cpu_set_t).
	(gomp_init_num_threads): Initialize gomp_cpuset_size,
	gomp_get_cpuset_size and gomp_cpusetp here, use gomp_cpusetp instead
	of &cpuset and pass gomp_cpuset_size instead of sizeof (cpu_set_t)
	to pthread_getaffinity_np.  Free and clear gomp_cpusetp if it didn't
	contain any logical CPUs.
	(get_num_procs): Don't call pthread_getaffinity_np if gomp_cpusetp
	is NULL.  Use gomp_cpusetp instead of &cpuset and pass
	gomp_get_cpuset_size instead of sizeof (cpu_set_t) to
	pthread_getaffinity_np.  Check gomp_places_list instead of
	gomp_cpu_affinity.  Adjust gomp_cpuset_popcount caller.
	* config/linux/bar.c (gomp_barrier_wait_end,
	gomp_barrier_wait_last): Use BAR_* defines.
	(gomp_team_barrier_wait_end): Likewise.  Clear BAR_CANCELLED
	from state where needed.  Set work_share_cancelled to 0 on last
	thread.
	(gomp_team_barrier_wait_final, gomp_team_barrier_wait_cancel_end,
	gomp_team_barrier_wait_cancel, gomp_team_barrier_cancel): New
	functions.
	* config/linux/proc.h (gomp_cpuset_popcount): Add attribute_hidden.
	Add cpusetsize argument.
	(gomp_cpuset_size, gomp_cpusetp): Declare.
	* config/linux/affinity.c: Include errno.h, stdio.h and string.h.
	(affinity_counter): Remove.
	(CPU_ISSET_S, CPU_ZERO_S, CPU_SET_S, CPU_CLR_S): Define
	if CPU_ALLOC_SIZE isn't defined.
	(gomp_init_affinity): Rewritten, if gomp_places_list is NULL, try
	silently create OMP_PLACES=threads, if it is non-NULL afterwards,
	bind current thread to the first place.
	(gomp_init_thread_affinity): Rewritten.  Add place argument, just
	pthread_setaffinity_np to gomp_places_list[place].
	(gomp_affinity_alloc, gomp_affinity_init_place, gomp_affinity_add_cpus,
	gomp_affinity_remove_cpu, gomp_affinity_copy_place,
	gomp_affinity_same_place, gomp_affinity_finalize_place_list,
	gomp_affinity_init_level, gomp_affinity_print_place): New functions.
	* config/linux/bar.h (BAR_TASK_PENDING, BAR_WAS_LAST,
	BAR_WAITING_FOR_TASK, BAR_INCR, BAR_CANCELLED): Define.
	(gomp_barrier_t): Add awaited_final field.
	(gomp_barrier_init): Initialize awaited_final field.
	(gomp_team_barrier_wait_final, gomp_team_barrier_wait_cancel,
	gomp_team_barrier_wait_cancel_end, gomp_team_barrier_cancel): New
	prototypes.
	(gomp_barrier_wait_start): Preserve BAR_CANCELLED bit.  Use BAR_*
	defines.
	(gomp_barrier_wait_cancel_start, gomp_team_barrier_wait_final_start,
	gomp_team_barrier_cancelled): New inline functions.
	(gomp_barrier_last_thread,
	gomp_team_barrier_set_task_pending,
	gomp_team_barrier_clear_task_pending,
	gomp_team_barrier_set_waiting_for_tasks,
	gomp_team_barrier_waiting_for_tasks,
	gomp_team_barrier_done): Use BAR_* defines.
	* config/posix/bar.c (gomp_barrier_init): Clear cancellable field.
	(gomp_barrier_wait_end): Use BAR_* defines.
	(gomp_team_barrier_wait_end): Clear BAR_CANCELLED from state.
	Set work_share_cancelled to 0 on last thread, use __atomic_load_n.
	Use BAR_* defines.
	(gomp_team_barrier_wait_cancel_end, gomp_team_barrier_wait_cancel,
	gomp_team_barrier_cancel): New functions.
	* config/posix/affinity.c (gomp_init_thread_affinity): Add place
	argument.
	(gomp_affinity_alloc, gomp_affinity_init_place, gomp_affinity_add_cpus,
	gomp_affinity_remove_cpu, gomp_affinity_copy_place,
	gomp_affinity_same_place, gomp_affinity_finalize_place_list,
	gomp_affinity_init_level, gomp_affinity_print_place): New stubs.
	* config/posix/bar.h (BAR_TASK_PENDING, BAR_WAS_LAST,
	BAR_WAITING_FOR_TASK, BAR_INCR, BAR_CANCELLED): Define.
	(gomp_barrier_t): Add cancellable field.
	(gomp_team_barrier_wait_cancel, gomp_team_barrier_wait_cancel_end,
	gomp_team_barrier_cancel): New prototypes.
	(gomp_barrier_wait_start): Preserve BAR_CANCELLED bit.
	(gomp_barrier_wait_cancel_start, gomp_team_barrier_wait_final,
	gomp_team_barrier_cancelled): New inline functions.
	(gomp_barrier_wait_start, gomp_barrier_last_thread,
	gomp_team_barrier_set_task_pending,
	gomp_team_barrier_clear_task_pending,
	gomp_team_barrier_set_waiting_for_tasks,
	gomp_team_barrier_waiting_for_tasks,
	gomp_team_barrier_done): Use BAR_* defines.
	* barrier.c (GOMP_barrier_cancel): New function.
	* omp_lib.h.in (omp_proc_bind_kind, omp_proc_bind_false,
	omp_proc_bind_true, omp_proc_bind_master, omp_proc_bind_close,
	omp_proc_bind_spread): New params.
	(omp_get_cancellation, omp_get_proc_bind, omp_set_default_device,
	omp_get_default_device, omp_get_num_devices, omp_get_num_teams,
	omp_get_team_num, omp_is_initial_device): New externals.
	* parallel.c (GOMP_parallel, GOMP_cancel, GOMP_cancellation_point):
	New functions.
	(gomp_resolve_num_threads): Adjust for thread_limit now being in
	icv->thread_limit_var.  Use UINT_MAX instead of ULONG_MAX as
	infinity.  If not nested, just return minimum of max_num_threads
	and icv->thread_limit_var and if thr->thread_pool, set threads_busy
	to the returned value.  Otherwise, don't update atomically
	gomp_remaining_threads_count, but instead thr->thread_pool->threads_busy.
	(GOMP_parallel_end): Adjust for thread_limit now being in
	icv->thread_limit_var.  Use UINT_MAX instead of ULONG_MAX as
	infinity.  Adjust threads_busy in the pool rather than
	gomp_remaining_threads_count.  Remember team->nthreads and call
	gomp_team_end before adjusting threads_busy, if not nested
	afterwards, just set it to 1 non-atomically.  Add ialias.
	(GOMP_parallel_start): Adjust gomp_team_start caller.
	* testsuite/libgomp.c/atomic-14.c: Add parens to make it valid.
	* testsuite/libgomp.c/affinity-1.c: New test.
	* testsuite/libgomp.c/atomic-15.c: New test.
	* testsuite/libgomp.c/atomic-16.c: New test.
	* testsuite/libgomp.c/atomic-17.c: New test.
	* testsuite/libgomp.c/cancel-for-1.c: New test.
	* testsuite/libgomp.c/cancel-for-2.c: New test.
	* testsuite/libgomp.c/cancel-parallel-1.c: New test.
	* testsuite/libgomp.c/cancel-parallel-2.c: New test.
	* testsuite/libgomp.c/cancel-parallel-3.c: New test.
	* testsuite/libgomp.c/cancel-sections-1.c: New test.
	* testsuite/libgomp.c/cancel-taskgroup-1.c: New test.
	* testsuite/libgomp.c/cancel-taskgroup-2.c: New test.
	* testsuite/libgomp.c/depend-1.c: New test.
	* testsuite/libgomp.c/depend-2.c: New test.
	* testsuite/libgomp.c/depend-3.c: New test.
	* testsuite/libgomp.c/depend-4.c: New test.
	* testsuite/libgomp.c/for-1.c: New test.
	* testsuite/libgomp.c/for-1.h: New file.
	* testsuite/libgomp.c/for-2.c: New test.
	* testsuite/libgomp.c/for-2.h: New file.
	* testsuite/libgomp.c/for-3.c: New test.
	* testsuite/libgomp.c/pr58392.c: New test.
	* testsuite/libgomp.c/simd-1.c: New test.
	* testsuite/libgomp.c/simd-2.c: New test.
	* testsuite/libgomp.c/simd-3.c: New test.
	* testsuite/libgomp.c/simd-4.c: New test.
	* testsuite/libgomp.c/simd-5.c: New test.
	* testsuite/libgomp.c/simd-6.c: New test.
	* testsuite/libgomp.c/target-1.c: New test.
	* testsuite/libgomp.c/target-2.c: New test.
	* testsuite/libgomp.c/target-3.c: New test.
	* testsuite/libgomp.c/target-4.c: New test.
	* testsuite/libgomp.c/target-5.c: New test.
	* testsuite/libgomp.c/target-6.c: New test.
	* testsuite/libgomp.c/target-7.c: New test.
	* testsuite/libgomp.c/taskgroup-1.c: New test.
	* testsuite/libgomp.c/thread-limit-1.c: New test.
	* testsuite/libgomp.c/thread-limit-2.c: New test.
	* testsuite/libgomp.c/thread-limit-3.c: New test.
	* testsuite/libgomp.c/udr-1.c: New test.
	* testsuite/libgomp.c/udr-2.c: New test.
	* testsuite/libgomp.c/udr-3.c: New test.
	* testsuite/libgomp.c++/affinity-1.C: New test.
	* testsuite/libgomp.c++/atomic-10.C: New test.
	* testsuite/libgomp.c++/atomic-11.C: New test.
	* testsuite/libgomp.c++/atomic-12.C: New test.
	* testsuite/libgomp.c++/atomic-13.C: New test.
	* testsuite/libgomp.c++/atomic-14.C: New test.
	* testsuite/libgomp.c++/atomic-15.C: New test.
	* testsuite/libgomp.c++/cancel-for-1.C: New test.
	* testsuite/libgomp.c++/cancel-for-2.C: New test.
	* testsuite/libgomp.c++/cancel-parallel-1.C: New test.
	* testsuite/libgomp.c++/cancel-parallel-2.C: New test.
	* testsuite/libgomp.c++/cancel-parallel-3.C: New test.
	* testsuite/libgomp.c++/cancel-sections-1.C: New test.
	* testsuite/libgomp.c++/cancel-taskgroup-1.C: New test.
	* testsuite/libgomp.c++/cancel-taskgroup-2.C: New test.
	* testsuite/libgomp.c++/cancel-taskgroup-3.C: New test.
	* testsuite/libgomp.c++/cancel-test.h: New file.
	* testsuite/libgomp.c++/for-9.C: New test.
	* testsuite/libgomp.c++/for-10.C: New test.
	* testsuite/libgomp.c++/for-11.C: New test.
	* testsuite/libgomp.c++/simd-1.C: New test.
	* testsuite/libgomp.c++/simd-2.C: New test.
	* testsuite/libgomp.c++/simd-3.C: New test.
	* testsuite/libgomp.c++/simd-4.C: New test.
	* testsuite/libgomp.c++/simd-5.C: New test.
	* testsuite/libgomp.c++/simd-6.C: New test.
	* testsuite/libgomp.c++/simd-7.C: New test.
	* testsuite/libgomp.c++/simd-8.C: New test.
	* testsuite/libgomp.c++/target-1.C: New test.
	* testsuite/libgomp.c++/target-2.C: New test.
	* testsuite/libgomp.c++/target-2-aux.cc: New file.
	* testsuite/libgomp.c++/target-3.C: New test.
	* testsuite/libgomp.c++/taskgroup-1.C: New test.
	* testsuite/libgomp.c++/udr-1.C: New test.
	* testsuite/libgomp.c++/udr-2.C: New test.
	* testsuite/libgomp.c++/udr-3.C: New test.
	* testsuite/libgomp.c++/udr-4.C: New test.
	* testsuite/libgomp.c++/udr-5.C: New test.
	* testsuite/libgomp.c++/udr-6.C: New test.
	* testsuite/libgomp.c++/udr-7.C: New test.
	* testsuite/libgomp.c++/udr-8.C: New test.
	* testsuite/libgomp.c++/udr-9.C: New test.
gcc/
	* tree-pretty-print.c (dump_omp_clause): Handle OMP_CLAUSE__LOOPTEMP_
	and new OpenMP 4.0 clauses, handle UDR OMP_CLAUSE_REDUCTION,
	formatting fixes, use pp_colon instead of pp_character (..., ':'),
	similarly pp_right_paren.
	(dump_generic_node): Handle OMP_DISTRIBUTE, OMP_TEAMS,
	OMP_TARGET_DATA, OMP_TARGET, OMP_TARGET_UPDATE, OMP_TASKGROUP,
	allow OMP_FOR_INIT to be NULL, handle OMP_ATOMIC_SEQ_CST.
	* tree.c (omp_clause_num_ops, omp_clause_code_name): Add OpenMP 4.0
	clauses.
	(omp_declare_simd_clauses_equal,
	omp_remove_redundant_declare_simd_attrs): New functions.
	(attribute_value_equal): Use omp_declare_simd_clauses_equal.
	(walk_tree_1): Handle new OpenMP 4.0 clauses.
	* tree.h (OMP_LOOP_CHECK): Define.
	(OMP_FOR_BODY, OMP_FOR_CLAUSES, OMP_FOR_INIT, OMP_FOR_COND,
	OMP_FOR_INCR, OMP_FOR_PRE_BODY): Use it.
	(OMP_TASKGROUP_BODY, OMP_TEAMS_BODY, OMP_TEAMS_CLAUSES,
	OMP_TARGET_DATA_BODY, OMP_TARGET_DATA_CLAUSES, OMP_TARGET_BODY,
	OMP_TARGET_CLAUSES, OMP_TARGET_UPDATE_CLAUSES, OMP_CLAUSE_SIZE,
	OMP_ATOMIC_SEQ_CST, OMP_CLAUSE_DEPEND_KIND, OMP_CLAUSE_MAP_KIND,
	OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION, OMP_CLAUSE_PROC_BIND_KIND,
	OMP_CLAUSE_REDUCTION_OMP_ORIG_REF, OMP_CLAUSE_ALIGNED_ALIGNMENT,
	OMP_CLAUSE_NUM_TEAMS_EXPR, OMP_CLAUSE_THREAD_LIMIT_EXPR,
	OMP_CLAUSE_DEVICE_ID, OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR,
	OMP_CLAUSE_SIMDLEN_EXPR): Define.
	(OMP_CLAUSE_DECL): Change range up to OMP_CLAUSE__LOOPTEMP_.
	(omp_remove_redundant_declare_simd_attrs): New prototype.
	* gimple.def (GIMPLE_OMP_TASKGROUP, GIMPLE_OMP_TARGET,
	GIMPLE_OMP_TEAMS): New codes.
	(GIMPLE_OMP_RETURN): Use GSS_OMP_ATOMIC_STORE instead of GSS_BASE.
	* omp-low.c (struct omp_context): Add cancel_label and cancellable
	fields.
	(target_nesting_level): New variable.
	(extract_omp_for_data): Handle GF_OMP_FOR_KIND_DISTRIBUTE and
	OMP_CLAUSE_DIST_SCHEDULE.  Don't fallback to library implementation
	for collapse > 1 static schedule unless ordered.
	(get_ws_args_for): Add par_stmt argument.  Handle combined loops.
	(determine_parallel_type): Adjust get_ws_args_for caller.
	(install_var_field): Handle mask & 4 for double indirection.
	(scan_sharing_clauses): Ignore shared clause on teams construct.
	Handle OMP_CLAUSE__LOOPTEMP_ and new OpenMP 4.0 clauses.
	(create_omp_child_function): If inside target or declare target
	constructs, set "omp declare target" attribute on the child
	function.
	(find_combined_for): New function.
	(scan_omp_parallel): Handle combined loops.
	(scan_omp_target, scan_omp_teams): New functions.
	(check_omp_nesting_restrictions): Check new OpenMP 4.0 nesting
	restrictions and set ctx->cancellable for cancellable constructs.
	(scan_omp_1_stmt): Call check_omp_nesting_restrictions also on
	selected builtin calls.  Handle GIMPLE_OMP_TASKGROUP,
	GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS.
	(build_omp_barrier): Add lhs argument, return gimple rather than
	tree.
	(omp_clause_aligned_alignment): New function.
	(lower_rec_simd_input_clauses): Only call SET_DECL_VALUE_EXPR
	on decls.
	(lower_rec_input_clauses): Add FD argument.  Ignore shared clauses
	on teams constructs.  Handle user defined reductions and new
	OpenMP 4.0 clauses.
	(lower_reduction_clauses): Don't set placeholder to address of ref
	if it has already the right type.
	(lower_send_clauses): Handle OMP_CLAUSE__LOOPTEMP_.
	(expand_parallel_call): Use the new non-_start suffixed builtins,
	handle OMP_CLAUSE_PROC_BIND, don't call the outlined function
	and GOMP_parallel_end after the call.
	(expand_task_call): Handle OMP_CLAUSE_DEPEND.
	(expand_omp_for_init_counts): Handle combined loops.
	(expand_omp_for_init_vars): Add inner_stmt argument, handle combined
	loops.
	(expand_omp_for_generic): Likewise.  Use GOMP_loop_end_cancel at the
	end of cancellable loops.
	(expand_omp_for_static_nochunk, expand_omp_for_static_chunk):
	Likewise.  Handle collapse > 1 loops.
	(expand_omp_simd): Handle combined loops.
	(expand_omp_for): Add inner_stmt argument, adjust callers of
	expand_omp_for* functions, use expand_omp_for_static*chunk even
	for collapse > 1 unless ordered.
	(expand_omp_sections): Use GOMP_sections_end_cancel at the end
	of cancellable sections.
	(expand_omp_single): Remove need_barrier variable, just rely on
	gimple_omp_return_nowait_p.  Adjust build_omp_barrier caller.
	(expand_omp_synch): Allow GIMPLE_OMP_TASKGROUP and GIMPLE_OMP_TEAMS.
	(expand_omp_atomic_load, expand_omp_atomic_store,
	expand_omp_atomic_fetch_op): Handle gimple_omp_atomic_seq_cst_p.
	(expand_omp_target): New function.
	(expand_omp): Handle combined loops.  Handle GIMPLE_OMP_TASKGROUP,
	GIMPLE_OMP_TEAMS, GIMPLE_OMP_TARGET.
	(build_omp_regions_1): Immediately close region for
	GF_OMP_TARGET_KIND_UPDATE.
	(maybe_add_implicit_barrier_cancel): New function.
	(lower_omp_sections): Adjust lower_rec_input_clauses caller.  Handle
	cancellation.
	(lower_omp_single): Likewise.  Add clobber after the barrier.
	(lower_omp_taskgroup): New function.
	(lower_omp_for): Handle combined loops.  Adjust
	lower_rec_input_clauses caller.  Handle cancellation.
	(lower_depend_clauses): New function.
	(lower_omp_taskreg): Lower depend clauses.  Adjust
	lower_rec_input_clauses caller.  Add clobber after the call.  Handle
	cancellation.
	(lower_omp_target, lower_omp_teams): New functions.
	(lower_omp_1): Handle cancellation.  Handle GIMPLE_OMP_TASKGROUP,
	GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS and GOMP_barrier, GOMP_cancel
	and GOMP_cancellation_point calls.
	(lower_omp): Fold stmts inside of target region.
	(diagnose_sb_1, diagnose_sb_2): Handle GIMPLE_OMP_TASKGROUP,
	GIMPLE_OMP_TARGET and GIMPLE_OMP_TEAMS.
	* builtin-types.def (DEF_FUNCTION_TYPE_8): Document.
	(BT_FN_VOID_OMPFN_PTR_UINT,
	BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
	BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
	BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT): Remove.
	(BT_FN_VOID_OMPFN_PTR_UINT_UINT_UINT,
	BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_UINT,
	BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG_UINT,
	BT_FN_BOOL_INT, BT_FN_BOOL_INT_BOOL, BT_FN_VOID_UINT_UINT,
	BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR,
	BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR,
	BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR): New.
	* tree-ssa-alias.c (ref_maybe_used_by_call_p_1,
	call_may_clobber_ref_p_1): Handle BUILT_IN_GOMP_BARRIER_CANCEL,
	BUILT_IN_GOMP_TASKGROUP_END, BUILT_IN_GOMP_LOOP_END_CANCEL,
	BUILT_IN_GOMP_SECTIONS_END_CANCEL.  Don't handle
	BUILT_IN_GOMP_PARALLEL_END.
	* gimple-low.c (lower_stmt): Handle GIMPLE_OMP_TASKGROUP,
	GIMPLE_OMP_TARGET and GIMPLE_OMP_TEAMS.
	* gimple-pretty-print.c (dump_gimple_omp_for): Handle
	GF_OMP_FOR_KIND_DISTRIBUTE.
	(dump_gimple_omp_target, dump_gimple_omp_teams): New functions.
	(dump_gimple_omp_block): Handle GIMPLE_OMP_TASKGROUP.
	(dump_gimple_omp_return): Print lhs if it has any.
	(dump_gimple_omp_atomic_load, dump_gimple_omp_atomic_store): Handle
	gimple_omp_atomic_seq_cst_p.
	(pp_gimple_stmt_1): Handle GIMPLE_OMP_TASKGROUP, GIMPLE_OMP_TARGET
	and GIMPLE_OMP_TEAMS.
	* langhooks.c (lhd_omp_mappable_type): New function.
	* tree-vectorizer.c (struct simd_array_to_simduid): Fix up comment.
	* langhooks.h (struct lang_hooks_for_types): Add omp_mappable_type
	hook.
	* gimplify.c (enum gimplify_omp_var_data): Add GOVD_MAP,
	GOVD_ALIGNED and GOVD_MAP_TO_ONLY.
	(enum omp_region_type): Add ORT_TEAMS, ORT_TARGET_DATA and
	ORT_TARGET.
	(struct gimplify_omp_ctx): Add combined_loop field.
	(gimplify_call_expr, gimplify_modify_expr): Don't call fold_stmt
	on stmts inside of target region.
	(is_gimple_stmt): Return true for OMP_DISTRIBUTE and OMP_TASKGROUP.
	(omp_firstprivatize_variable): Handle GOVD_MAP, GOVD_ALIGNED,
	ORT_TARGET and ORT_TARGET_DATA.
	(omp_add_variable): Avoid checks on readding var for GOVD_ALIGNED.
	Handle GOVD_MAP.
	(omp_notice_threadprivate_variable): Complain about threadprivate
	variables in target region.
	(omp_notice_variable): Complain about vars with non-mappable type
	in target region.  Handle ORT_TEAMS, ORT_TARGET and ORT_TARGET_DATA.
	(omp_check_private): Ignore ORT_TARGET* regions.
	(gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses_1,
	gimplify_adjust_omp_clauses): Handle new OpenMP 4.0 clauses.
	(find_combined_omp_for): New function.
	(gimplify_omp_for): Handle gimplification of combined loops.
	(gimplify_omp_workshare): Gimplify also OMP_TARGET, OMP_TARGET_DATA,
	OMP_TEAMS.
	(gimplify_omp_target_update): New function.
	(gimplify_omp_atomic): Handle OMP_ATOMIC_SEQ_CST.
	(gimplify_expr): Handle OMP_DISTRIBUTE, OMP_TARGET, OMP_TARGET_DATA,
	OMP_TARGET_UPDATE, OMP_TEAMS, OMP_TASKGROUP.
	(gimplify_body): If fndecl has "omp declare target" attribute, add
	implicit ORT_TARGET context around it.
	* tree.def (OMP_DISTRIBUTE, OMP_TEAMS, OMP_TARGET_DATA, OMP_TARGET,
	OMP_TASKGROUP, OMP_TARGET_UPDATE): New tree codes.
	* tree-nested.c (convert_nonlocal_reference_stmt,
	convert_local_reference_stmt, convert_gimple_call): Handle
	GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS and GIMPLE_OMP_TASKGROUP.
	* omp-builtins.def (BUILT_IN_GOMP_TASK): Use
	BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR
	instead of BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT.
	(BUILT_IN_GOMP_TARGET, BUILT_IN_GOMP_TARGET_DATA,
	BUILT_IN_GOMP_TARGET_END_DATA, BUILT_IN_GOMP_TARGET_UPDATE,
	BUILT_IN_GOMP_TEAMS, BUILT_IN_BARRIER_CANCEL,
	BUILT_IN_GOMP_LOOP_END_CANCEL,
	BUILT_IN_GOMP_SECTIONS_END_CANCEL, BUILT_IN_OMP_GET_TEAM_NUM,
	BUILT_IN_OMP_GET_NUM_TEAMS, BUILT_IN_GOMP_TASKGROUP_START,
	BUILT_IN_GOMP_TASKGROUP_END, BUILT_IN_GOMP_PARALLEL_LOOP_STATIC,
	BUILT_IN_GOMP_PARALLEL_LOOP_DYNAMIC,
	BUILT_IN_GOMP_PARALLEL_LOOP_GUIDED,
	BUILT_IN_GOMP_PARALLEL_LOOP_RUNTIME, BUILT_IN_GOMP_PARALLEL,
	BUILT_IN_GOMP_PARALLEL_SECTIONS, BUILT_IN_GOMP_CANCEL,
	BUILT_IN_GOMP_CANCELLATION_POINT): New built-ins.
	(BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START,
	BUILT_IN_GOMP_PARALLEL_LOOP_DYNAMIC_START,
	BUILT_IN_GOMP_PARALLEL_LOOP_GUIDED_START,
	BUILT_IN_GOMP_PARALLEL_LOOP_RUNTIME_START,
	BUILT_IN_GOMP_PARALLEL_START, BUILT_IN_GOMP_PARALLEL_END,
	BUILT_IN_GOMP_PARALLEL_SECTIONS_START): Remove.
	* tree-inline.c (remap_gimple_stmt, estimate_num_insns):
	Handle GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS and GIMPLE_OMP_TASKGROUP.
	* gimple.c (gimple_build_omp_taskgroup, gimple_build_omp_target,
	gimple_build_omp_teams): New functions.
	(walk_gimple_op): Handle GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS and
	GIMPLE_OMP_TASKGROUP.  Walk optional lhs on GIMPLE_OMP_RETURN.
	(walk_gimple_stmt, gimple_copy): Handle GIMPLE_OMP_TARGET,
	GIMPLE_OMP_TEAMS and GIMPLE_OMP_TASKGROUP.
	* gimple.h (enum gf_mask): GF_OMP_FOR_KIND_DISTRIBUTE,
	GF_OMP_FOR_COMBINED, GF_OMP_FOR_COMBINED_INTO,
	GF_OMP_TARGET_KIND_MASK, GF_OMP_TARGET_KIND_REGION,
	GF_OMP_TARGET_KIND_DATA, GF_OMP_TARGET_KIND_UPDATE,
	GF_OMP_ATOMIC_SEQ_CST): New.
	(gimple_build_omp_taskgroup, gimple_build_omp_target,
	gimple_build_omp_teams): New prototypes.
	(gimple_has_substatements): Handle GIMPLE_OMP_TARGET,
	GIMPLE_OMP_TEAMS and GIMPLE_OMP_TASKGROUP.
	(gimple_omp_subcode): Use GIMPLE_OMP_TEAMS instead of
	GIMPLE_OMP_SINGLE as end of range.
	(gimple_omp_return_set_lhs, gimple_omp_return_lhs,
	gimple_omp_return_lhs_ptr, gimple_omp_atomic_seq_cst_p,
	gimple_omp_atomic_set_seq_cst, gimple_omp_for_combined_p,
	gimple_omp_for_set_combined_p, gimple_omp_for_combined_into_p,
	gimple_omp_for_set_combined_into_p, gimple_omp_target_clauses,
	gimple_omp_target_clauses_ptr, gimple_omp_target_set_clauses,
	gimple_omp_target_kind, gimple_omp_target_set_kind,
	gimple_omp_target_child_fn, gimple_omp_target_child_fn_ptr,
	gimple_omp_target_set_child_fn, gimple_omp_target_data_arg,
	gimple_omp_target_data_arg_ptr, gimple_omp_target_set_data_arg,
	gimple_omp_teams_clauses, gimple_omp_teams_clauses_ptr,
	gimple_omp_teams_set_clauses): New inlines.
	(CASE_GIMPLE_OMP): Add GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS
	and GIMPLE_OMP_TASKGROUP.
	* tree-core.h (enum omp_clause_code): Add new OpenMP 4.0 clause
	codes.
	(enum omp_clause_depend_kind, enum omp_clause_map_kind,
	enum omp_clause_proc_bind_kind): New.
	(union omp_clause_subcode): Add depend_kind, map_kind and
	proc_bind_kind fields.
	* tree-cfg.c (make_edges): Handle GIMPLE_OMP_TARGET,
	GIMPLE_OMP_TEAMS and GIMPLE_OMP_TASKGROUP.
	* langhooks-def.h (lhd_omp_mappable_type): New prototype.
	(LANG_HOOKS_OMP_MAPPABLE_TYPE): Define.
	(LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it.
gcc/c-family/
	* c-cppbuiltin.c (c_cpp_builtins): Predefine _OPENMP to
	201307 instead of 201107.
	* c-common.c (DEF_FUNCTION_TYPE_8): Define.
	(c_common_attribute_table): Add "omp declare target" and
	"omp declare simd" attributes.
	(handle_omp_declare_target_attribute,
	handle_omp_declare_simd_attribute): New functions.
	* c-omp.c: Include c-pragma.h.
	(c_finish_omp_taskgroup): New function.
	(c_finish_omp_atomic): Add swapped argument, if true,
	build the operation first with rhs, lhs arguments and use NOP_EXPR
	build_modify_expr.
	(c_finish_omp_for): Add code argument, pass it down to make_code.
	(c_omp_split_clauses): New function.
	(c_split_parallel_clauses): Removed.
	(c_omp_declare_simd_clause_cmp, c_omp_declare_simd_clauses_to_numbers,
	c_omp_declare_simd_clauses_to_decls): New functions.
	* c-common.h (omp_clause_mask): New type.
	(OMP_CLAUSE_MASK_1): Define.
	(omp_clause_mask::omp_clause_mask, omp_clause_mask::operator &=,
	omp_clause_mask::operator |=, omp_clause_mask::operator ~,
	omp_clause_mask::operator |, omp_clause_mask::operator &,
	omp_clause_mask::operator <<, omp_clause_mask::operator >>,
	omp_clause_mask::operator ==): New methods.
	(enum c_omp_clause_split): New.
	(c_finish_omp_taskgroup): New prototype.
	(c_finish_omp_atomic): Add swapped argument.
	(c_finish_omp_for): Add code argument.
	(c_omp_split_clauses): New prototype.
	(c_split_parallel_clauses): Removed.
	(c_omp_declare_simd_clauses_to_numbers,
	c_omp_declare_simd_clauses_to_decls): New prototypes.
	* c-pragma.c (omp_pragmas): Add new OpenMP 4.0 constructs.
	* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_CANCEL,
	PRAGMA_OMP_CANCELLATION_POINT, PRAGMA_OMP_DECLARE_REDUCTION,
	PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_END_DECLARE_TARGET, PRAGMA_OMP_SIMD,
	PRAGMA_OMP_TARGET, PRAGMA_OMP_TASKGROUP and PRAGMA_OMP_TEAMS.
	Remove PRAGMA_OMP_PARALLEL_FOR and PRAGMA_OMP_PARALLEL_SECTIONS.
	(enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_ALIGNED,
	PRAGMA_OMP_CLAUSE_DEPEND, PRAGMA_OMP_CLAUSE_DEVICE,
	PRAGMA_OMP_CLAUSE_DIST_SCHEDULE, PRAGMA_OMP_CLAUSE_FOR,
	PRAGMA_OMP_CLAUSE_FROM, PRAGMA_OMP_CLAUSE_INBRANCH,
	PRAGMA_OMP_CLAUSE_LINEAR, PRAGMA_OMP_CLAUSE_MAP,
	PRAGMA_OMP_CLAUSE_NOTINBRANCH, PRAGMA_OMP_CLAUSE_NUM_TEAMS,
	PRAGMA_OMP_CLAUSE_PARALLEL, PRAGMA_OMP_CLAUSE_PROC_BIND,
	PRAGMA_OMP_CLAUSE_SAFELEN, PRAGMA_OMP_CLAUSE_SECTIONS,
	PRAGMA_OMP_CLAUSE_SIMDLEN, PRAGMA_OMP_CLAUSE_TASKGROUP,
	PRAGMA_OMP_CLAUSE_THREAD_LIMIT, PRAGMA_OMP_CLAUSE_TO and
	PRAGMA_OMP_CLAUSE_UNIFORM.
gcc/ada/
	* gcc-interface/utils.c (DEF_FUNCTION_TYPE_8): Define.
gcc/fortran/
	* trans-openmp.c (gfc_omp_clause_default_ctor,
	gfc_omp_clause_dtor): Return NULL for OMP_CLAUSE_REDUCTION.
	* f95-lang.c (ATTR_NULL, DEF_FUNCTION_TYPE_8): Define.
	* types.def (DEF_FUNCTION_TYPE_8): Document.
	(BT_FN_VOID_OMPFN_PTR_UINT,
	BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
	BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
	BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT): Remove.
	(BT_FN_VOID_OMPFN_PTR_UINT_UINT_UINT,
	BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_UINT,
	BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG_UINT,
	BT_FN_BOOL_INT, BT_FN_BOOL_INT_BOOL, BT_FN_VOID_UINT_UINT,
	BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR,
	BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR,
	BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR): New.
gcc/lto/
	* lto-lang.c (DEF_FUNCTION_TYPE_8): Define.
gcc/c/
	* c-lang.h (current_omp_declare_target_attribute): New extern
	decl.
	* c-parser.c: Include c-lang.h.
	(struct c_parser): Change tokens to c_token *.
	Add tokens_buf field.  Change tokens_avail type to unsigned int.
	(c_parser_consume_token): If parser->tokens isn't
	&parser->tokens_buf[0], increment parser->tokens.
	(c_parser_consume_pragma): Likewise.
	(enum pragma_context): Add pragma_struct and pragma_param.
	(c_parser_external_declaration): Adjust
	c_parser_declaration_or_fndef caller.
	(c_parser_declaration_or_fndef): Add omp_declare_simd_clauses
	argument, if it is non-vNULL vector, call c_finish_omp_declare_simd.
	Adjust recursive call.
	(c_parser_struct_or_union_specifier): Use pragma_struct instead
	of pragma_external.
	(c_parser_parameter_declaration): Use pragma_param instead of
	pragma_external.
	(c_parser_compound_statement_nostart, c_parser_label,
	c_parser_for_statement): Adjust
	c_parser_declaration_or_fndef callers.
	(c_parser_expr_no_commas): Add omp_atomic_lhs argument, pass
	it through to c_parser_conditional_expression.
	(c_parser_conditional_expression): Add omp_atomic_lhs argument,
	pass it through to c_parser_binary_expression.  Adjust recursive
	call.
	(c_parser_binary_expression): Remove prec argument, add
	omp_atomic_lhs argument instead.  Always start from PREC_NONE, if
	omp_atomic_lhs is non-NULL and one of the arguments of toplevel
	binop matches it, use build2 instead of parser_build_binary_op.
	(c_parser_pragma): Handle PRAGMA_OMP_CANCEL,
	PRAGMA_OMP_CANCELLATION_POINT, PRAGMA_OMP_TARGET,
	PRAGMA_OMP_END_DECLARE_TARGET, PRAGMA_OMP_DECLARE_REDUCTION.
	Handle pragma_struct and pragma_param the same as pragma_external.
	(c_parser_omp_clause_name): Parse new OpenMP 4.0 clause names.
	(c_parser_omp_variable_list): Parse array sections for
	OMP_CLAUSE_{DEPEND,MAP,TO,FROM} clauses.
	(c_parser_omp_clause_collapse): Fully fold collapse expression.
	(c_parser_omp_clause_reduction): Handle user defined reductions.
	(c_parser_omp_clause_branch, c_parser_omp_clause_cancelkind,
	c_parser_omp_clause_num_teams, c_parser_omp_clause_thread_limit,
	c_parser_omp_clause_aligned, c_parser_omp_clause_linear,
	c_parser_omp_clause_safelen, c_parser_omp_clause_simdlen,
	c_parser_omp_clause_depend, c_parser_omp_clause_map,
	c_parser_omp_clause_device, c_parser_omp_clause_dist_schedule,
	c_parser_omp_clause_proc_bind, c_parser_omp_clause_to,
	c_parser_omp_clause_from, c_parser_omp_clause_uniform): New functions.
	(c_parser_omp_all_clauses): Add finish_p argument.  Don't call
	c_finish_omp_clauses if it is false.  Handle new OpenMP 4.0 clauses.
	(c_parser_omp_atomic): Parse seq_cst clause, pass true if it is
	present to c_finish_omp_atomic.  Handle OpenMP 4.0 atomic forms.
	(c_parser_omp_for_loop): Add CODE argument, pass it through
	to c_finish_omp_for.  Change last argument to cclauses,
	and adjust uses to grab parallel clauses from the array of all
	the split clauses.  Adjust c_parser_binary_expression,
	c_parser_declaration_or_fndef and c_finish_omp_for callers.
	(omp_split_clauses): New function.
	(c_parser_omp_simd): New function.
	(c_parser_omp_for): Add p_name, mask and cclauses arguments.
	Allow the function to be called also when parsing combined constructs,
	and call c_parser_omp_simd when parsing for simd.
	(c_parser_omp_sections_scope): If section-sequence doesn't start with
	#pragma omp section, require exactly one structured-block instead of
	sequence of statements.
	(c_parser_omp_sections): Add p_name, mask and cclauses arguments.
	Allow the function to be called also when parsing combined constructs.
	(c_parser_omp_parallel): Add p_name, mask and cclauses arguments.
	Allow the function to be called also when parsing combined
	constructs.
	(c_parser_omp_taskgroup, c_parser_omp_cancel,
	c_parser_omp_cancellation_point, c_parser_omp_distribute,
	c_parser_omp_teams, c_parser_omp_target_data,
	c_parser_omp_target_update, c_parser_omp_target,
	c_parser_omp_declare_simd, c_finish_omp_declare_simd,
	c_parser_omp_declare_target, c_parser_omp_end_declare_target,
	c_parser_omp_declare_reduction, c_parser_omp_declare): New functions.
	(c_parser_omp_construct): Add p_name and mask vars.  Handle
	PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_SIMD, PRAGMA_OMP_TASKGROUP,
	PRAGMA_OMP_TEAMS.  Adjust c_parser_omp_for, c_parser_omp_parallel
	and c_parser_omp_sections callers.
	(c_parse_file): Initialize tparser.tokens and the_parser->tokens here.
	(OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK,
	OMP_SINGLE_CLAUSE_MASK): Use OMP_CLAUSE_MASK_1 instead of 1.
	(OMP_PARALLEL_CLAUSE_MASK): Likewise.  Add OMP_CLAUSE_PROC_BIND.
	(OMP_TASK_CLAUSE_MASK): Use OMP_CLAUSE_MASK_1 instead of 1.  Add
	OMP_CLAUSE_DEPEND.
	(OMP_SIMD_CLAUSE_MASK, OMP_CANCEL_CLAUSE_MASK,
	OMP_CANCELLATION_POINT_CLAUSE_MASK, OMP_DISTRIBUTE_CLAUSE_MASK,
	OMP_TEAMS_CLAUSE_MASK, OMP_TARGET_DATA_CLAUSE_MASK,
	OMP_TARGET_UPDATE_CLAUSE_MASK, OMP_TARGET_CLAUSE_MASK,
	OMP_DECLARE_SIMD_CLAUSE_MASK): Define.
	* c-typeck.c: Include tree-inline.h.
	(c_finish_omp_cancel, c_finish_omp_cancellation_point,
	handle_omp_array_sections_1, handle_omp_array_sections,
	c_clone_omp_udr, c_find_omp_placeholder_r): New functions.
	(c_finish_omp_clauses): Handle new OpenMP 4.0 clauses and
	user defined reductions.
	(c_tree_equal): New function.
	* c-tree.h (temp_store_parm_decls, temp_pop_parm_decls,
	c_finish_omp_cancel, c_finish_omp_cancellation_point, c_tree_equal,
	c_omp_reduction_id, c_omp_reduction_decl, c_omp_reduction_lookup,
	c_check_omp_declare_reduction_r): New prototypes.
	* c-decl.c (current_omp_declare_target_attribute): New variable.
	(c_decl_attributes): New function.
	(start_decl, start_function): Use it instead of decl_attributes.
	(temp_store_parm_decls, temp_pop_parm_decls, c_omp_reduction_id,
	c_omp_reduction_decl, c_omp_reduction_lookup,
	c_check_omp_declare_reduction_r): New functions.
gcc/cp/
	* decl.c (duplicate_decls): Error out for redeclaration of UDRs.
	(declare_simd_adjust_this): New function.
	(grokfndecl): If "omp declare simd" attribute is present,
	call declare_simd_adjust_this if needed and
	c_omp_declare_simd_clauses_to_numbers.
	* cp-array-notation.c (expand_array_notation_exprs): Handle
	OMP_TASKGROUP.
	* cp-gimplify.c (cp_gimplify_expr): Handle OMP_SIMD and
	OMP_DISTRIBUTE.  Handle is_invisiref_parm decls in
	OMP_CLAUSE_REDUCTION.
	(cp_genericize_r): Handle OMP_SIMD and OMP_DISTRIBUTE like
	OMP_FOR.
	(cxx_omp_privatize_by_reference): Return true for
	is_invisiref_parm decls.
	(cxx_omp_finish_clause): Adjust cxx_omp_create_clause_info
	caller.
	* pt.c (apply_late_template_attributes): For "omp declare simd"
	attribute call tsubst_omp_clauses,
	c_omp_declare_simd_clauses_to_decls, finish_omp_clauses
	and c_omp_declare_simd_clauses_to_numbers.
	(instantiate_class_template_1): Call cp_check_omp_declare_reduction
	for UDRs.
	(tsubst_decl): Handle UDRs.
	(tsubst_omp_clauses): Add declare_simd argument, if true don't
	call finish_omp_clauses.  Handle new OpenMP 4.0 clauses.
	Handle non-NULL OMP_CLAUSE_REDUCTION_PLACEHOLDER on
	OMP_CLAUSE_REDUCTION.
	(tsubst_expr): For UDRs call pushdecl and
	cp_check_omp_declare_reduction.  Adjust tsubst_omp_clauses
	callers.  Handle OMP_SIMD, OMP_DISTRIBUTE, OMP_TEAMS,
	OMP_TARGET_DATA, OMP_TARGET_UPDATE, OMP_TARGET, OMP_TASKGROUP.
	Adjust finish_omp_atomic caller.
	(tsubst_omp_udr): New function.
	(instantiate_decl): For UDRs at block scope, don't call
	start_preparsed_function/finish_function.  Call tsubst_omp_udr.
	* semantics.c (cxx_omp_create_clause_info): Add need_dtor argument,
	use it instead of need_default_ctor || need_copy_ctor.
	(struct cp_check_omp_declare_reduction_data): New type.
	(handle_omp_array_sections_1, handle_omp_array_sections,
	omp_reduction_id, omp_reduction_lookup,
	cp_remove_omp_priv_cleanup_stmt, cp_check_omp_declare_reduction_r,
	cp_check_omp_declare_reduction, clone_omp_udr,
	find_omp_placeholder_r, finish_omp_reduction_clause): New functions.
	(finish_omp_clauses): Handle new OpenMP 4.0 clauses and user defined
	reductions.
	(finish_omp_for): Add CODE argument, use it instead of hardcoded
	OMP_FOR.  Adjust c_finish_omp_for caller.
	(finish_omp_atomic): Add seq_cst argument, adjust
	c_finish_omp_atomic callers, handle seq_cst and new OpenMP 4.0
	atomic variants.
	(finish_omp_cancel, finish_omp_cancellation_point): New functions.
	* decl2.c (mark_used): Force immediate instantiation of
	DECL_OMP_DECLARE_REDUCTION_P decls.
	(is_late_template_attribute): Return true for "omp declare simd"
	attribute.
	(cp_omp_mappable_type): New function.
	(cplus_decl_attributes): Add implicit "omp declare target" attribute
	if requested.
	* parser.c (cp_debug_parser): Print
	parser->colon_doesnt_start_class_def_p.
	(cp_ensure_no_omp_declare_simd, cp_finalize_omp_declare_simd): New
	functions.
	(enum pragma_context): Add pragma_member and pragma_objc_icode.
	(cp_parser_binary_expression): Handle no_toplevel_fold_p
	even for binary operations other than comparison.
	(cp_parser_linkage_specification): Call
	cp_ensure_no_omp_declare_simd if needed.
	(cp_parser_namespace_definition): Likewise.
	(cp_parser_init_declarator): Call cp_finalize_omp_declare_simd.
	(cp_parser_direct_declarator): Pass declarator to
	cp_parser_late_return_type_opt.
	(cp_parser_late_return_type_opt): Add declarator argument,
	call cp_parser_late_parsing_omp_declare_simd for declare simd.
	(cp_parser_class_specifier_1): Call cp_ensure_no_omp_declare_simd.
	Parse UDRs before all other methods.
	(cp_parser_member_specification_opt): Use pragma_member instead of
	pragma_external.
	(cp_parser_member_declaration): Call cp_finalize_omp_declare_simd.
	(cp_parser_function_definition_from_specifiers_and_declarator,
	cp_parser_save_member_function_body): Likewise.
	(cp_parser_late_parsing_for_member): Handle UDRs specially.
	(cp_parser_next_token_starts_class_definition_p): Don't allow
	CPP_COLON if colon_doesnt_start_class_def_p flag is true.
	(cp_parser_objc_interstitial_code): Use pragma_objc_icode
	instead of pragma_external.
	(cp_parser_omp_clause_name): Parse new OpenMP 4.0 clause names.
	(cp_parser_omp_var_list_no_open): Parse array sections for
	OMP_CLAUSE_{DEPEND,MAP,TO,FROM} clauses.  Add COLON argument,
	if non-NULL, allow parsing to end with a colon rather than close
	paren.
	(cp_parser_omp_var_list): Adjust cp_parser_omp_var_list_no_open
	caller.
	(cp_parser_omp_clause_reduction): Handle user defined reductions.
	(cp_parser_omp_clause_branch, cp_parser_omp_clause_cancelkind,
	cp_parser_omp_clause_num_teams, cp_parser_omp_clause_thread_limit,
	cp_parser_omp_clause_aligned, cp_parser_omp_clause_linear,
	cp_parser_omp_clause_safelen, cp_parser_omp_clause_simdlen,
	cp_parser_omp_clause_depend, cp_parser_omp_clause_map,
	cp_parser_omp_clause_device, cp_parser_omp_clause_dist_schedule,
	cp_parser_omp_clause_proc_bind, cp_parser_omp_clause_to,
	cp_parser_omp_clause_from, cp_parser_omp_clause_uniform): New
	functions.
	(cp_parser_omp_all_clauses): Add finish_p argument.  Don't call
	finish_omp_clauses if it is false.  Handle new OpenMP 4.0 clauses.
	(cp_parser_omp_atomic): Parse seq_cst clause, pass
	true if it is present to finish_omp_atomic.  Handle new OpenMP 4.0
	atomic forms.
	(cp_parser_omp_for_loop): Add CODE argument, pass it through
	to finish_omp_for.  Change last argument to cclauses,
	and adjust uses to grab parallel clauses from the array of all
	the split clauses.
	(cp_omp_split_clauses): New function.
	(cp_parser_omp_simd): New function.
	(cp_parser_omp_for): Add p_name, mask and cclauses arguments.
	Allow the function to be called also when parsing combined constructs,
	and call c_parser_omp_simd when parsing for simd.
	(cp_parser_omp_sections_scope): If section-sequence doesn't start with
	#pragma omp section, require exactly one structured-block instead of
	sequence of statements.
	(cp_parser_omp_sections): Add p_name, mask and cclauses arguments.
	Allow the function to be called also when parsing combined constructs.
	(cp_parser_omp_parallel): Add p_name, mask and cclauses arguments.
	Allow the function to be called also when parsing combined
	constructs.
	(cp_parser_omp_taskgroup, cp_parser_omp_cancel,
	cp_parser_omp_cancellation_point, cp_parser_omp_distribute,
	cp_parser_omp_teams, cp_parser_omp_target_data,
	cp_parser_omp_target_update, cp_parser_omp_target,
	cp_parser_omp_declare_simd, cp_parser_late_parsing_omp_declare_simd,
	cp_parser_omp_declare_target, cp_parser_omp_end_declare_target,
	cp_parser_omp_declare_reduction_exprs, cp_parser_omp_declare_reduction,
	cp_parser_omp_declare): New functions.
	(cp_parser_omp_construct): Add p_name and mask vars.  Handle
	PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_SIMD, PRAGMA_OMP_TASKGROUP,
	PRAGMA_OMP_TEAMS.  Adjust cp_parser_omp_for, cp_parser_omp_parallel
	and cp_parser_omp_sections callers.
	(cp_parser_pragma): Handle PRAGMA_OMP_CANCEL,
	PRAGMA_OMP_CANCELLATION_POINT, PRAGMA_OMP_DECLARE_REDUCTION,
	PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_SIMD, PRAGMA_OMP_TASKGROUP,
	PRAGMA_OMP_TEAMS, PRAGMA_OMP_TARGET, PRAGMA_OMP_END_DECLARE_TARGET.
	Handle pragma_member and pragma_objc_icode like pragma_external.
	(OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK,
	OMP_SINGLE_CLAUSE_MASK): Use OMP_CLAUSE_MASK_1 instead of 1.
	(OMP_PARALLEL_CLAUSE_MASK): Likewise.  Add OMP_CLAUSE_PROC_BIND.
	(OMP_TASK_CLAUSE_MASK): Use OMP_CLAUSE_MASK_1 instead of 1.  Add
	OMP_CLAUSE_DEPEND.
	(OMP_SIMD_CLAUSE_MASK, OMP_CANCEL_CLAUSE_MASK,
	OMP_CANCELLATION_POINT_CLAUSE_MASK, OMP_DISTRIBUTE_CLAUSE_MASK,
	OMP_TEAMS_CLAUSE_MASK, OMP_TARGET_DATA_CLAUSE_MASK,
	OMP_TARGET_UPDATE_CLAUSE_MASK, OMP_TARGET_CLAUSE_MASK,
	OMP_DECLARE_SIMD_CLAUSE_MASK): Define.
	* parser.h (struct cp_omp_declare_simd_data): New type.
	(struct cp_parser): Add colon_doesnt_start_class_def_p and
	omp_declare_simd fields.
	* cp-objcp-common.h (LANG_HOOKS_OMP_MAPPABLE_TYPE): Define.
	* cp-tree.h (struct lang_decl_fn): Add omp_declare_reduction_p
	bit.
	(DECL_OMP_DECLARE_REDUCTION_P): Define.
	(OMP_FOR_GIMPLIFYING_P): Use OMP_LOOP_CHECK macro.
	(struct saved_scope): Add omp_declare_target_attribute field.
	(cp_omp_mappable_type, omp_reduction_id,
	cp_remove_omp_priv_cleanup_stmt, cp_check_omp_declare_reduction,
	finish_omp_cancel, finish_omp_cancellation_point): New prototypes.
	(finish_omp_for): Add CODE argument.
	(finish_omp_atomic): Add seq_cst argument.
	(cxx_omp_create_clause_info): Add need_dtor argument.
gcc/testsuite/
	* c-c++-common/gomp/atomic-15.c: Adjust for C diagnostics.
	Remove error test that is now valid in OpenMP 4.0.
	* c-c++-common/gomp/atomic-16.c: New test.
	* c-c++-common/gomp/cancel-1.c: New test.
	* c-c++-common/gomp/depend-1.c: New test.
	* c-c++-common/gomp/depend-2.c: New test.
	* c-c++-common/gomp/map-1.c: New test.
	* c-c++-common/gomp/pr58472.c: New test.
	* c-c++-common/gomp/sections1.c: New test.
	* c-c++-common/gomp/simd1.c: New test.
	* c-c++-common/gomp/simd2.c: New test.
	* c-c++-common/gomp/simd3.c: New test.
	* c-c++-common/gomp/simd4.c: New test.
	* c-c++-common/gomp/simd5.c: New test.
	* c-c++-common/gomp/single1.c: New test.
	* g++.dg/gomp/block-0.C: Adjust for stricter #pragma omp sections
	parser.
	* g++.dg/gomp/block-3.C: Likewise.
	* g++.dg/gomp/clause-3.C: Adjust error messages.
	* g++.dg/gomp/declare-simd-1.C: New test.
	* g++.dg/gomp/declare-simd-2.C: New test.
	* g++.dg/gomp/depend-1.C: New test.
	* g++.dg/gomp/depend-2.C: New test.
	* g++.dg/gomp/target-1.C: New test.
	* g++.dg/gomp/target-2.C: New test.
	* g++.dg/gomp/taskgroup-1.C: New test.
	* g++.dg/gomp/teams-1.C: New test.
	* g++.dg/gomp/udr-1.C: New test.
	* g++.dg/gomp/udr-2.C: New test.
	* g++.dg/gomp/udr-3.C: New test.
	* g++.dg/gomp/udr-4.C: New test.
	* g++.dg/gomp/udr-5.C: New test.
	* g++.dg/gomp/udr-6.C: New test.
	* gcc.dg/autopar/outer-1.c: Expect 4 instead of 5 loopfn matches.
	* gcc.dg/autopar/outer-2.c: Likewise.
	* gcc.dg/autopar/outer-3.c: Likewise.
	* gcc.dg/autopar/outer-4.c: Likewise.
	* gcc.dg/autopar/outer-5.c: Likewise.
	* gcc.dg/autopar/outer-6.c: Likewise.
	* gcc.dg/autopar/parallelization-1.c: Likewise.
	* gcc.dg/gomp/block-3.c: Adjust for stricter #pragma omp sections
	parser.
	* gcc.dg/gomp/clause-1.c: Adjust error messages.
	* gcc.dg/gomp/combined-1.c: Look for GOMP_parallel_loop_runtime
	instead of GOMP_parallel_loop_runtime_start.
	* gcc.dg/gomp/declare-simd-1.c: New test.
	* gcc.dg/gomp/declare-simd-2.c: New test.
	* gcc.dg/gomp/nesting-1.c: Adjust for stricter #pragma omp sections
	parser.  Add further #pragma omp sections nesting tests.
	* gcc.dg/gomp/target-1.c: New test.
	* gcc.dg/gomp/target-2.c: New test.
	* gcc.dg/gomp/taskgroup-1.c: New test.
	* gcc.dg/gomp/teams-1.c: New test.
	* gcc.dg/gomp/udr-1.c: New test.
	* gcc.dg/gomp/udr-2.c: New test.
	* gcc.dg/gomp/udr-3.c: New test.
	* gcc.dg/gomp/udr-4.c: New test.
	* gfortran.dg/gomp/appendix-a/a.35.5.f90: Add dg-error.

Co-Authored-By: Richard Henderson <rth@redhat.com>
Co-Authored-By: Tobias Burnus <burnus@net-b.de>

From-SVN: r203408
This commit is contained in:
Jakub Jelinek 2013-10-11 11:26:50 +02:00 committed by Jakub Jelinek
parent f7191ecdbd
commit acf0174b6f
223 changed files with 26129 additions and 1644 deletions

View file

@ -1,3 +1,245 @@
2013-10-11 Jakub Jelinek <jakub@redhat.com>
* tree-pretty-print.c (dump_omp_clause): Handle OMP_CLAUSE__LOOPTEMP_
and new OpenMP 4.0 clauses, handle UDR OMP_CLAUSE_REDUCTION,
formatting fixes, use pp_colon instead of pp_character (..., ':'),
similarly pp_right_paren.
(dump_generic_node): Handle OMP_DISTRIBUTE, OMP_TEAMS,
OMP_TARGET_DATA, OMP_TARGET, OMP_TARGET_UPDATE, OMP_TASKGROUP,
allow OMP_FOR_INIT to be NULL, handle OMP_ATOMIC_SEQ_CST.
* tree.c (omp_clause_num_ops, omp_clause_code_name): Add OpenMP 4.0
clauses.
(omp_declare_simd_clauses_equal,
omp_remove_redundant_declare_simd_attrs): New functions.
(attribute_value_equal): Use omp_declare_simd_clauses_equal.
(walk_tree_1): Handle new OpenMP 4.0 clauses.
* tree.h (OMP_LOOP_CHECK): Define.
(OMP_FOR_BODY, OMP_FOR_CLAUSES, OMP_FOR_INIT, OMP_FOR_COND,
OMP_FOR_INCR, OMP_FOR_PRE_BODY): Use it.
(OMP_TASKGROUP_BODY, OMP_TEAMS_BODY, OMP_TEAMS_CLAUSES,
OMP_TARGET_DATA_BODY, OMP_TARGET_DATA_CLAUSES, OMP_TARGET_BODY,
OMP_TARGET_CLAUSES, OMP_TARGET_UPDATE_CLAUSES, OMP_CLAUSE_SIZE,
OMP_ATOMIC_SEQ_CST, OMP_CLAUSE_DEPEND_KIND, OMP_CLAUSE_MAP_KIND,
OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION, OMP_CLAUSE_PROC_BIND_KIND,
OMP_CLAUSE_REDUCTION_OMP_ORIG_REF, OMP_CLAUSE_ALIGNED_ALIGNMENT,
OMP_CLAUSE_NUM_TEAMS_EXPR, OMP_CLAUSE_THREAD_LIMIT_EXPR,
OMP_CLAUSE_DEVICE_ID, OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR,
OMP_CLAUSE_SIMDLEN_EXPR): Define.
(OMP_CLAUSE_DECL): Change range up to OMP_CLAUSE__LOOPTEMP_.
(omp_remove_redundant_declare_simd_attrs): New prototype.
* gimple.def (GIMPLE_OMP_TASKGROUP, GIMPLE_OMP_TARGET,
GIMPLE_OMP_TEAMS): New codes.
(GIMPLE_OMP_RETURN): Use GSS_OMP_ATOMIC_STORE instead of GSS_BASE.
* omp-low.c (struct omp_context): Add cancel_label and cancellable
fields.
(target_nesting_level): New variable.
(extract_omp_for_data): Handle GF_OMP_FOR_KIND_DISTRIBUTE and
OMP_CLAUSE_DIST_SCHEDULE. Don't fallback to library implementation
for collapse > 1 static schedule unless ordered.
(get_ws_args_for): Add par_stmt argument. Handle combined loops.
(determine_parallel_type): Adjust get_ws_args_for caller.
(install_var_field): Handle mask & 4 for double indirection.
(scan_sharing_clauses): Ignore shared clause on teams construct.
Handle OMP_CLAUSE__LOOPTEMP_ and new OpenMP 4.0 clauses.
(create_omp_child_function): If inside target or declare target
constructs, set "omp declare target" attribute on the child
function.
(find_combined_for): New function.
(scan_omp_parallel): Handle combined loops.
(scan_omp_target, scan_omp_teams): New functions.
(check_omp_nesting_restrictions): Check new OpenMP 4.0 nesting
restrictions and set ctx->cancellable for cancellable constructs.
(scan_omp_1_stmt): Call check_omp_nesting_restrictions also on
selected builtin calls. Handle GIMPLE_OMP_TASKGROUP,
GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS.
(build_omp_barrier): Add lhs argument, return gimple rather than
tree.
(omp_clause_aligned_alignment): New function.
(lower_rec_simd_input_clauses): Only call SET_DECL_VALUE_EXPR
on decls.
(lower_rec_input_clauses): Add FD argument. Ignore shared clauses
on teams constructs. Handle user defined reductions and new
OpenMP 4.0 clauses.
(lower_reduction_clauses): Don't set placeholder to address of ref
if it has already the right type.
(lower_send_clauses): Handle OMP_CLAUSE__LOOPTEMP_.
(expand_parallel_call): Use the new non-_start suffixed builtins,
handle OMP_CLAUSE_PROC_BIND, don't call the outlined function
and GOMP_parallel_end after the call.
(expand_task_call): Handle OMP_CLAUSE_DEPEND.
(expand_omp_for_init_counts): Handle combined loops.
(expand_omp_for_init_vars): Add inner_stmt argument, handle combined
loops.
(expand_omp_for_generic): Likewise. Use GOMP_loop_end_cancel at the
end of cancellable loops.
(expand_omp_for_static_nochunk, expand_omp_for_static_chunk):
Likewise. Handle collapse > 1 loops.
(expand_omp_simd): Handle combined loops.
(expand_omp_for): Add inner_stmt argument, adjust callers of
expand_omp_for* functions, use expand_omp_for_static*chunk even
for collapse > 1 unless ordered.
(expand_omp_sections): Use GOMP_sections_end_cancel at the end
of cancellable sections.
(expand_omp_single): Remove need_barrier variable, just rely on
gimple_omp_return_nowait_p. Adjust build_omp_barrier caller.
(expand_omp_synch): Allow GIMPLE_OMP_TASKGROUP and GIMPLE_OMP_TEAMS.
(expand_omp_atomic_load, expand_omp_atomic_store,
expand_omp_atomic_fetch_op): Handle gimple_omp_atomic_seq_cst_p.
(expand_omp_target): New function.
(expand_omp): Handle combined loops. Handle GIMPLE_OMP_TASKGROUP,
GIMPLE_OMP_TEAMS, GIMPLE_OMP_TARGET.
(build_omp_regions_1): Immediately close region for
GF_OMP_TARGET_KIND_UPDATE.
(maybe_add_implicit_barrier_cancel): New function.
(lower_omp_sections): Adjust lower_rec_input_clauses caller. Handle
cancellation.
(lower_omp_single): Likewise. Add clobber after the barrier.
(lower_omp_taskgroup): New function.
(lower_omp_for): Handle combined loops. Adjust
lower_rec_input_clauses caller. Handle cancellation.
(lower_depend_clauses): New function.
(lower_omp_taskreg): Lower depend clauses. Adjust
lower_rec_input_clauses caller. Add clobber after the call. Handle
cancellation.
(lower_omp_target, lower_omp_teams): New functions.
(lower_omp_1): Handle cancellation. Handle GIMPLE_OMP_TASKGROUP,
GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS and GOMP_barrier, GOMP_cancel
and GOMP_cancellation_point calls.
(lower_omp): Fold stmts inside of target region.
(diagnose_sb_1, diagnose_sb_2): Handle GIMPLE_OMP_TASKGROUP,
GIMPLE_OMP_TARGET and GIMPLE_OMP_TEAMS.
* builtin-types.def (DEF_FUNCTION_TYPE_8): Document.
(BT_FN_VOID_OMPFN_PTR_UINT,
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT): Remove.
(BT_FN_VOID_OMPFN_PTR_UINT_UINT_UINT,
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_UINT,
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG_UINT,
BT_FN_BOOL_INT, BT_FN_BOOL_INT_BOOL, BT_FN_VOID_UINT_UINT,
BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR,
BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR,
BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR): New.
* tree-ssa-alias.c (ref_maybe_used_by_call_p_1,
call_may_clobber_ref_p_1): Handle BUILT_IN_GOMP_BARRIER_CANCEL,
BUILT_IN_GOMP_TASKGROUP_END, BUILT_IN_GOMP_LOOP_END_CANCEL,
BUILT_IN_GOMP_SECTIONS_END_CANCEL. Don't handle
BUILT_IN_GOMP_PARALLEL_END.
* gimple-low.c (lower_stmt): Handle GIMPLE_OMP_TASKGROUP,
GIMPLE_OMP_TARGET and GIMPLE_OMP_TEAMS.
* gimple-pretty-print.c (dump_gimple_omp_for): Handle
GF_OMP_FOR_KIND_DISTRIBUTE.
(dump_gimple_omp_target, dump_gimple_omp_teams): New functions.
(dump_gimple_omp_block): Handle GIMPLE_OMP_TASKGROUP.
(dump_gimple_omp_return): Print lhs if it has any.
(dump_gimple_omp_atomic_load, dump_gimple_omp_atomic_store): Handle
gimple_omp_atomic_seq_cst_p.
(pp_gimple_stmt_1): Handle GIMPLE_OMP_TASKGROUP, GIMPLE_OMP_TARGET
and GIMPLE_OMP_TEAMS.
* langhooks.c (lhd_omp_mappable_type): New function.
* tree-vectorizer.c (struct simd_array_to_simduid): Fix up comment.
* langhooks.h (struct lang_hooks_for_types): Add omp_mappable_type
hook.
* gimplify.c (enum gimplify_omp_var_data): Add GOVD_MAP,
GOVD_ALIGNED and GOVD_MAP_TO_ONLY.
(enum omp_region_type): Add ORT_TEAMS, ORT_TARGET_DATA and
ORT_TARGET.
(struct gimplify_omp_ctx): Add combined_loop field.
(gimplify_call_expr, gimplify_modify_expr): Don't call fold_stmt
on stmts inside of target region.
(is_gimple_stmt): Return true for OMP_DISTRIBUTE and OMP_TASKGROUP.
(omp_firstprivatize_variable): Handle GOVD_MAP, GOVD_ALIGNED,
ORT_TARGET and ORT_TARGET_DATA.
(omp_add_variable): Avoid checks on readding var for GOVD_ALIGNED.
Handle GOVD_MAP.
(omp_notice_threadprivate_variable): Complain about threadprivate
variables in target region.
(omp_notice_variable): Complain about vars with non-mappable type
in target region. Handle ORT_TEAMS, ORT_TARGET and ORT_TARGET_DATA.
(omp_check_private): Ignore ORT_TARGET* regions.
(gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses_1,
gimplify_adjust_omp_clauses): Handle new OpenMP 4.0 clauses.
(find_combined_omp_for): New function.
(gimplify_omp_for): Handle gimplification of combined loops.
(gimplify_omp_workshare): Gimplify also OMP_TARGET, OMP_TARGET_DATA,
OMP_TEAMS.
(gimplify_omp_target_update): New function.
(gimplify_omp_atomic): Handle OMP_ATOMIC_SEQ_CST.
(gimplify_expr): Handle OMP_DISTRIBUTE, OMP_TARGET, OMP_TARGET_DATA,
OMP_TARGET_UPDATE, OMP_TEAMS, OMP_TASKGROUP.
(gimplify_body): If fndecl has "omp declare target" attribute, add
implicit ORT_TARGET context around it.
* tree.def (OMP_DISTRIBUTE, OMP_TEAMS, OMP_TARGET_DATA, OMP_TARGET,
OMP_TASKGROUP, OMP_TARGET_UPDATE): New tree codes.
* tree-nested.c (convert_nonlocal_reference_stmt,
convert_local_reference_stmt, convert_gimple_call): Handle
GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS and GIMPLE_OMP_TASKGROUP.
* omp-builtins.def (BUILT_IN_GOMP_TASK): Use
BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR
instead of BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT.
(BUILT_IN_GOMP_TARGET, BUILT_IN_GOMP_TARGET_DATA,
BUILT_IN_GOMP_TARGET_END_DATA, BUILT_IN_GOMP_TARGET_UPDATE,
BUILT_IN_GOMP_TEAMS, BUILT_IN_BARRIER_CANCEL,
BUILT_IN_GOMP_LOOP_END_CANCEL,
BUILT_IN_GOMP_SECTIONS_END_CANCEL, BUILT_IN_OMP_GET_TEAM_NUM,
BUILT_IN_OMP_GET_NUM_TEAMS, BUILT_IN_GOMP_TASKGROUP_START,
BUILT_IN_GOMP_TASKGROUP_END, BUILT_IN_GOMP_PARALLEL_LOOP_STATIC,
BUILT_IN_GOMP_PARALLEL_LOOP_DYNAMIC,
BUILT_IN_GOMP_PARALLEL_LOOP_GUIDED,
BUILT_IN_GOMP_PARALLEL_LOOP_RUNTIME, BUILT_IN_GOMP_PARALLEL,
BUILT_IN_GOMP_PARALLEL_SECTIONS, BUILT_IN_GOMP_CANCEL,
BUILT_IN_GOMP_CANCELLATION_POINT): New built-ins.
(BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START,
BUILT_IN_GOMP_PARALLEL_LOOP_DYNAMIC_START,
BUILT_IN_GOMP_PARALLEL_LOOP_GUIDED_START,
BUILT_IN_GOMP_PARALLEL_LOOP_RUNTIME_START,
BUILT_IN_GOMP_PARALLEL_START, BUILT_IN_GOMP_PARALLEL_END,
BUILT_IN_GOMP_PARALLEL_SECTIONS_START): Remove.
* tree-inline.c (remap_gimple_stmt, estimate_num_insns):
Handle GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS and GIMPLE_OMP_TASKGROUP.
* gimple.c (gimple_build_omp_taskgroup, gimple_build_omp_target,
gimple_build_omp_teams): New functions.
(walk_gimple_op): Handle GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS and
GIMPLE_OMP_TASKGROUP. Walk optional lhs on GIMPLE_OMP_RETURN.
(walk_gimple_stmt, gimple_copy): Handle GIMPLE_OMP_TARGET,
GIMPLE_OMP_TEAMS and GIMPLE_OMP_TASKGROUP.
* gimple.h (enum gf_mask): GF_OMP_FOR_KIND_DISTRIBUTE,
GF_OMP_FOR_COMBINED, GF_OMP_FOR_COMBINED_INTO,
GF_OMP_TARGET_KIND_MASK, GF_OMP_TARGET_KIND_REGION,
GF_OMP_TARGET_KIND_DATA, GF_OMP_TARGET_KIND_UPDATE,
GF_OMP_ATOMIC_SEQ_CST): New.
(gimple_build_omp_taskgroup, gimple_build_omp_target,
gimple_build_omp_teams): New prototypes.
(gimple_has_substatements): Handle GIMPLE_OMP_TARGET,
GIMPLE_OMP_TEAMS and GIMPLE_OMP_TASKGROUP.
(gimple_omp_subcode): Use GIMPLE_OMP_TEAMS instead of
GIMPLE_OMP_SINGLE as end of range.
(gimple_omp_return_set_lhs, gimple_omp_return_lhs,
gimple_omp_return_lhs_ptr, gimple_omp_atomic_seq_cst_p,
gimple_omp_atomic_set_seq_cst, gimple_omp_for_combined_p,
gimple_omp_for_set_combined_p, gimple_omp_for_combined_into_p,
gimple_omp_for_set_combined_into_p, gimple_omp_target_clauses,
gimple_omp_target_clauses_ptr, gimple_omp_target_set_clauses,
gimple_omp_target_kind, gimple_omp_target_set_kind,
gimple_omp_target_child_fn, gimple_omp_target_child_fn_ptr,
gimple_omp_target_set_child_fn, gimple_omp_target_data_arg,
gimple_omp_target_data_arg_ptr, gimple_omp_target_set_data_arg,
gimple_omp_teams_clauses, gimple_omp_teams_clauses_ptr,
gimple_omp_teams_set_clauses): New inlines.
(CASE_GIMPLE_OMP): Add GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS
and GIMPLE_OMP_TASKGROUP.
* tree-core.h (enum omp_clause_code): Add new OpenMP 4.0 clause
codes.
(enum omp_clause_depend_kind, enum omp_clause_map_kind,
enum omp_clause_proc_bind_kind): New.
(union omp_clause_subcode): Add depend_kind, map_kind and
proc_bind_kind fields.
* tree-cfg.c (make_edges): Handle GIMPLE_OMP_TARGET,
GIMPLE_OMP_TEAMS and GIMPLE_OMP_TASKGROUP.
* langhooks-def.h (lhd_omp_mappable_type): New prototype.
(LANG_HOOKS_OMP_MAPPABLE_TYPE): Define.
(LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it.
2013-10-10 Teresa Johnson <tejohnson@google.com>
* predict.c (tree_estimate_probability): Add new parameter

View file

@ -1,3 +1,7 @@
2013-10-11 Jakub Jelinek <jakub@redhat.com>
* gcc-interface/utils.c (DEF_FUNCTION_TYPE_8): Define.
2013-10-10 Robert Dewar <dewar@adacore.com>
* par-ch6.adb (Check_Junk_Semicolon_Before_Return): Remove

View file

@ -5765,6 +5765,7 @@ enum c_builtin_type
#define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
#define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) NAME,
#define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) NAME,
#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_1(NAME, RETURN, ARG1) NAME,
#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
@ -5783,6 +5784,7 @@ enum c_builtin_type
#undef DEF_FUNCTION_TYPE_5
#undef DEF_FUNCTION_TYPE_6
#undef DEF_FUNCTION_TYPE_7
#undef DEF_FUNCTION_TYPE_8
#undef DEF_FUNCTION_TYPE_VAR_0
#undef DEF_FUNCTION_TYPE_VAR_1
#undef DEF_FUNCTION_TYPE_VAR_2
@ -5878,6 +5880,10 @@ install_builtin_function_types (void)
#define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7) \
def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
#define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) \
def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
ARG7, ARG8);
#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
def_fn_type (ENUM, RETURN, 1, 0);
#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \

View file

@ -34,6 +34,8 @@ along with GCC; see the file COPYING3. If not see
DEF_FUNCTION_TYPE_5 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)
DEF_FUNCTION_TYPE_6 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6)
DEF_FUNCTION_TYPE_7 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7)
DEF_FUNCTION_TYPE_8 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7,
ARG8)
These macros describe function types. ENUM is as above. The
RETURN type is one of the enumerals already defined. ARG1, ARG2,
@ -230,6 +232,7 @@ DEF_FUNCTION_TYPE_1 (BT_FN_ULONGLONG_ULONGLONG, BT_ULONGLONG, BT_ULONGLONG)
DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_UINT16, BT_UINT16, BT_UINT16)
DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_UINT32, BT_UINT32, BT_UINT32)
DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_UINT64, BT_UINT64, BT_UINT64)
DEF_FUNCTION_TYPE_1 (BT_FN_BOOL_INT, BT_BOOL, BT_INT)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR, BT_FN_VOID_PTR)
@ -341,6 +344,8 @@ DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VPTR_INT, BT_VOID, BT_VOLATILE_PTR, BT_INT)
DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_VPTR_INT, BT_BOOL, BT_VOLATILE_PTR, BT_INT)
DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_SIZE_CONST_VPTR, BT_BOOL, BT_SIZE,
BT_CONST_VOLATILE_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_INT_BOOL, BT_BOOL, BT_INT, BT_BOOL)
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT_UINT, BT_VOID, BT_UINT, BT_UINT)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
@ -411,8 +416,6 @@ DEF_FUNCTION_TYPE_3 (BT_FN_I4_VPTR_I4_I4, BT_I4, BT_VOLATILE_PTR, BT_I4, BT_I4)
DEF_FUNCTION_TYPE_3 (BT_FN_I8_VPTR_I8_I8, BT_I8, BT_VOLATILE_PTR, BT_I8, BT_I8)
DEF_FUNCTION_TYPE_3 (BT_FN_I16_VPTR_I16_I16, BT_I16, BT_VOLATILE_PTR,
BT_I16, BT_I16)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_OMPFN_PTR_UINT, BT_VOID, BT_PTR_FN_VOID_PTR,
BT_PTR, BT_UINT)
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_CONST_PTR_INT_SIZE, BT_PTR,
BT_CONST_PTR, BT_INT, BT_SIZE)
DEF_FUNCTION_TYPE_3 (BT_FN_I1_VPTR_I1_INT, BT_I1, BT_VOLATILE_PTR, BT_I1, BT_INT)
@ -467,6 +470,9 @@ DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I8_INT_INT,
BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I8, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I16_INT_INT,
BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I16, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_5 (BT_FN_VOID_OMPFN_PTR_UINT_UINT_UINT,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT, BT_UINT,
BT_UINT)
DEF_FUNCTION_TYPE_6 (BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG,
BT_INT, BT_STRING, BT_SIZE, BT_INT, BT_SIZE,
@ -474,9 +480,6 @@ DEF_FUNCTION_TYPE_6 (BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG,
DEF_FUNCTION_TYPE_6 (BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
BT_BOOL, BT_LONG, BT_LONG, BT_LONG, BT_LONG,
BT_PTR_LONG, BT_PTR_LONG)
DEF_FUNCTION_TYPE_6 (BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT,
BT_LONG, BT_LONG, BT_LONG)
DEF_FUNCTION_TYPE_6 (BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULLPTR_ULLPTR,
BT_BOOL, BT_BOOL, BT_ULONGLONG, BT_ULONGLONG,
BT_ULONGLONG, BT_PTR_ULONGLONG, BT_PTR_ULONGLONG)
@ -497,19 +500,27 @@ DEF_FUNCTION_TYPE_6 (BT_FN_BOOL_VPTR_PTR_I16_BOOL_INT_INT,
BT_INT)
DEF_FUNCTION_TYPE_6 (BT_FN_BOOL_SIZE_VPTR_PTR_PTR_INT_INT, BT_BOOL, BT_SIZE,
BT_VOLATILE_PTR, BT_PTR, BT_PTR, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_6 (BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR,
BT_VOID, BT_INT, BT_PTR, BT_SIZE, BT_PTR, BT_PTR, BT_PTR)
DEF_FUNCTION_TYPE_7 (BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
DEF_FUNCTION_TYPE_7 (BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_UINT,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT,
BT_LONG, BT_LONG, BT_LONG, BT_LONG)
DEF_FUNCTION_TYPE_7 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR,
BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
BT_BOOL, BT_UINT)
BT_LONG, BT_LONG, BT_LONG, BT_UINT)
DEF_FUNCTION_TYPE_7 (BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULL_ULLPTR_ULLPTR,
BT_BOOL, BT_BOOL, BT_ULONGLONG, BT_ULONGLONG,
BT_ULONGLONG, BT_ULONGLONG,
BT_PTR_ULONGLONG, BT_PTR_ULONGLONG)
DEF_FUNCTION_TYPE_7 (BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR,
BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_PTR, BT_SIZE,
BT_PTR, BT_PTR, BT_PTR)
DEF_FUNCTION_TYPE_8 (BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG_UINT,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT,
BT_LONG, BT_LONG, BT_LONG, BT_LONG, BT_UINT)
DEF_FUNCTION_TYPE_8 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR,
BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
BT_BOOL, BT_UINT, BT_PTR)
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_INT_VAR, BT_INT)

View file

@ -1,3 +1,55 @@
2013-10-11 Jakub Jelinek <jakub@redhat.com>
* c-cppbuiltin.c (c_cpp_builtins): Predefine _OPENMP to
201307 instead of 201107.
* c-common.c (DEF_FUNCTION_TYPE_8): Define.
(c_common_attribute_table): Add "omp declare target" and
"omp declare simd" attributes.
(handle_omp_declare_target_attribute,
handle_omp_declare_simd_attribute): New functions.
* c-omp.c: Include c-pragma.h.
(c_finish_omp_taskgroup): New function.
(c_finish_omp_atomic): Add swapped argument, if true,
build the operation first with rhs, lhs arguments and use NOP_EXPR
build_modify_expr.
(c_finish_omp_for): Add code argument, pass it down to make_code.
(c_omp_split_clauses): New function.
(c_split_parallel_clauses): Removed.
(c_omp_declare_simd_clause_cmp, c_omp_declare_simd_clauses_to_numbers,
c_omp_declare_simd_clauses_to_decls): New functions.
* c-common.h (omp_clause_mask): New type.
(OMP_CLAUSE_MASK_1): Define.
(omp_clause_mask::omp_clause_mask, omp_clause_mask::operator &=,
omp_clause_mask::operator |=, omp_clause_mask::operator ~,
omp_clause_mask::operator |, omp_clause_mask::operator &,
omp_clause_mask::operator <<, omp_clause_mask::operator >>,
omp_clause_mask::operator ==): New methods.
(enum c_omp_clause_split): New.
(c_finish_omp_taskgroup): New prototype.
(c_finish_omp_atomic): Add swapped argument.
(c_finish_omp_for): Add code argument.
(c_omp_split_clauses): New prototype.
(c_split_parallel_clauses): Removed.
(c_omp_declare_simd_clauses_to_numbers,
c_omp_declare_simd_clauses_to_decls): New prototypes.
* c-pragma.c (omp_pragmas): Add new OpenMP 4.0 constructs.
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_CANCEL,
PRAGMA_OMP_CANCELLATION_POINT, PRAGMA_OMP_DECLARE_REDUCTION,
PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_END_DECLARE_TARGET, PRAGMA_OMP_SIMD,
PRAGMA_OMP_TARGET, PRAGMA_OMP_TASKGROUP and PRAGMA_OMP_TEAMS.
Remove PRAGMA_OMP_PARALLEL_FOR and PRAGMA_OMP_PARALLEL_SECTIONS.
(enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_ALIGNED,
PRAGMA_OMP_CLAUSE_DEPEND, PRAGMA_OMP_CLAUSE_DEVICE,
PRAGMA_OMP_CLAUSE_DIST_SCHEDULE, PRAGMA_OMP_CLAUSE_FOR,
PRAGMA_OMP_CLAUSE_FROM, PRAGMA_OMP_CLAUSE_INBRANCH,
PRAGMA_OMP_CLAUSE_LINEAR, PRAGMA_OMP_CLAUSE_MAP,
PRAGMA_OMP_CLAUSE_NOTINBRANCH, PRAGMA_OMP_CLAUSE_NUM_TEAMS,
PRAGMA_OMP_CLAUSE_PARALLEL, PRAGMA_OMP_CLAUSE_PROC_BIND,
PRAGMA_OMP_CLAUSE_SAFELEN, PRAGMA_OMP_CLAUSE_SECTIONS,
PRAGMA_OMP_CLAUSE_SIMDLEN, PRAGMA_OMP_CLAUSE_TASKGROUP,
PRAGMA_OMP_CLAUSE_THREAD_LIMIT, PRAGMA_OMP_CLAUSE_TO and
PRAGMA_OMP_CLAUSE_UNIFORM.
2013-10-09 Marc Glisse <marc.glisse@inria.fr>
PR tree-optimization/20318

View file

@ -372,6 +372,10 @@ static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *);
static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
static tree handle_warn_unused_attribute (tree *, tree, tree, int, bool *);
static tree handle_returns_nonnull_attribute (tree *, tree, tree, int, bool *);
static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int,
bool *);
static tree handle_omp_declare_target_attribute (tree *, tree, tree, int,
bool *);
static void check_function_nonnull (tree, int, tree *);
static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
@ -750,6 +754,10 @@ const struct attribute_spec c_common_attribute_table[] =
handle_warn_unused_attribute, false },
{ "returns_nonnull", 0, 0, false, true, true,
handle_returns_nonnull_attribute, false },
{ "omp declare simd", 0, -1, true, false, false,
handle_omp_declare_simd_attribute, false },
{ "omp declare target", 0, 0, true, false, false,
handle_omp_declare_target_attribute, false },
{ NULL, 0, 0, false, false, false, NULL, false }
};
@ -5057,6 +5065,7 @@ enum c_builtin_type
#define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
#define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) NAME,
#define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) NAME,
#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_1(NAME, RETURN, ARG1) NAME,
#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
@ -5075,6 +5084,7 @@ enum c_builtin_type
#undef DEF_FUNCTION_TYPE_5
#undef DEF_FUNCTION_TYPE_6
#undef DEF_FUNCTION_TYPE_7
#undef DEF_FUNCTION_TYPE_8
#undef DEF_FUNCTION_TYPE_VAR_0
#undef DEF_FUNCTION_TYPE_VAR_1
#undef DEF_FUNCTION_TYPE_VAR_2
@ -5157,6 +5167,10 @@ c_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node)
#define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7) \
def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
#define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) \
def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
ARG7, ARG8);
#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
def_fn_type (ENUM, RETURN, 1, 0);
#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
@ -8024,6 +8038,24 @@ handle_warn_unused_attribute (tree *node, tree name,
return NULL_TREE;
}
/* Handle an "omp declare simd" attribute; arguments as in
struct attribute_spec.handler. */
static tree
handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *)
{
return NULL_TREE;
}
/* Handle an "omp declare target" attribute; arguments as in
struct attribute_spec.handler. */
static tree
handle_omp_declare_target_attribute (tree *, tree, tree, int, bool *)
{
return NULL_TREE;
}
/* Handle a "returns_twice" attribute; arguments as in
struct attribute_spec.handler. */

View file

@ -1034,17 +1034,159 @@ extern void pp_dir_change (cpp_reader *, const char *);
extern bool check_missing_format_attribute (tree, tree);
/* In c-omp.c */
#if HOST_BITS_PER_WIDE_INT >= 64
typedef unsigned HOST_WIDE_INT omp_clause_mask;
# define OMP_CLAUSE_MASK_1 ((omp_clause_mask) 1)
#else
struct omp_clause_mask
{
inline omp_clause_mask ();
inline omp_clause_mask (unsigned HOST_WIDE_INT l);
inline omp_clause_mask (unsigned HOST_WIDE_INT l,
unsigned HOST_WIDE_INT h);
inline omp_clause_mask &operator &= (omp_clause_mask);
inline omp_clause_mask &operator |= (omp_clause_mask);
inline omp_clause_mask operator ~ () const;
inline omp_clause_mask operator & (omp_clause_mask) const;
inline omp_clause_mask operator | (omp_clause_mask) const;
inline omp_clause_mask operator >> (int);
inline omp_clause_mask operator << (int);
inline bool operator == (omp_clause_mask) const;
unsigned HOST_WIDE_INT low, high;
};
inline
omp_clause_mask::omp_clause_mask ()
{
}
inline
omp_clause_mask::omp_clause_mask (unsigned HOST_WIDE_INT l)
: low (l), high (0)
{
}
inline
omp_clause_mask::omp_clause_mask (unsigned HOST_WIDE_INT l,
unsigned HOST_WIDE_INT h)
: low (l), high (h)
{
}
inline omp_clause_mask &
omp_clause_mask::operator &= (omp_clause_mask b)
{
low &= b.low;
high &= b.high;
return *this;
}
inline omp_clause_mask &
omp_clause_mask::operator |= (omp_clause_mask b)
{
low |= b.low;
high |= b.high;
return *this;
}
inline omp_clause_mask
omp_clause_mask::operator ~ () const
{
omp_clause_mask ret (~low, ~high);
return ret;
}
inline omp_clause_mask
omp_clause_mask::operator | (omp_clause_mask b) const
{
omp_clause_mask ret (low | b.low, high | b.high);
return ret;
}
inline omp_clause_mask
omp_clause_mask::operator & (omp_clause_mask b) const
{
omp_clause_mask ret (low & b.low, high & b.high);
return ret;
}
inline omp_clause_mask
omp_clause_mask::operator << (int amount)
{
omp_clause_mask ret;
if (amount >= HOST_BITS_PER_WIDE_INT)
{
ret.low = 0;
ret.high = low << (amount - HOST_BITS_PER_WIDE_INT);
}
else if (amount == 0)
ret = *this;
else
{
ret.low = low << amount;
ret.high = (low >> (HOST_BITS_PER_WIDE_INT - amount))
| (high << amount);
}
return ret;
}
inline omp_clause_mask
omp_clause_mask::operator >> (int amount)
{
omp_clause_mask ret;
if (amount >= HOST_BITS_PER_WIDE_INT)
{
ret.low = high >> (amount - HOST_BITS_PER_WIDE_INT);
ret.high = 0;
}
else if (amount == 0)
ret = *this;
else
{
ret.low = (high << (HOST_BITS_PER_WIDE_INT - amount))
| (low >> amount);
ret.high = high >> amount;
}
return ret;
}
inline bool
omp_clause_mask::operator == (omp_clause_mask b) const
{
return low == b.low && high == b.high;
}
# define OMP_CLAUSE_MASK_1 omp_clause_mask (1)
#endif
enum c_omp_clause_split
{
C_OMP_CLAUSE_SPLIT_TARGET = 0,
C_OMP_CLAUSE_SPLIT_TEAMS,
C_OMP_CLAUSE_SPLIT_DISTRIBUTE,
C_OMP_CLAUSE_SPLIT_PARALLEL,
C_OMP_CLAUSE_SPLIT_FOR,
C_OMP_CLAUSE_SPLIT_SIMD,
C_OMP_CLAUSE_SPLIT_COUNT,
C_OMP_CLAUSE_SPLIT_SECTIONS = C_OMP_CLAUSE_SPLIT_FOR
};
extern tree c_finish_omp_master (location_t, tree);
extern tree c_finish_omp_taskgroup (location_t, tree);
extern tree c_finish_omp_critical (location_t, tree, tree);
extern tree c_finish_omp_ordered (location_t, tree);
extern void c_finish_omp_barrier (location_t);
extern tree c_finish_omp_atomic (location_t, enum tree_code, enum tree_code,
tree, tree, tree, tree, tree);
tree, tree, tree, tree, tree, bool, bool);
extern void c_finish_omp_flush (location_t);
extern void c_finish_omp_taskwait (location_t);
extern void c_finish_omp_taskyield (location_t);
extern tree c_finish_omp_for (location_t, tree, tree, tree, tree, tree, tree);
extern void c_split_parallel_clauses (location_t, tree, tree *, tree *);
extern tree c_finish_omp_for (location_t, enum tree_code, tree, tree, tree,
tree, 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);
extern void c_omp_declare_simd_clauses_to_decls (tree, tree);
extern enum omp_clause_default_kind c_omp_predetermined_sharing (tree);
/* Not in c-omp.c; provided by the front end. */

View file

@ -896,7 +896,7 @@ c_cpp_builtins (cpp_reader *pfile)
cpp_define (pfile, "__SSP__=1");
if (flag_openmp)
cpp_define (pfile, "_OPENMP=201107");
cpp_define (pfile, "_OPENMP=201307");
if (int128_integer_type_node != NULL_TREE)
builtin_define_type_sizeof ("__SIZEOF_INT128__",

View file

@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "c-common.h"
#include "c-pragma.h"
#include "gimple.h" /* For create_tmp_var_raw. */
#include "langhooks.h"
@ -41,6 +42,17 @@ c_finish_omp_master (location_t loc, tree stmt)
return t;
}
/* Complete a #pragma omp taskgroup construct. STMT is the structured-block
that follows the pragma. LOC is the l*/
tree
c_finish_omp_taskgroup (location_t loc, tree stmt)
{
tree t = add_stmt (build1 (OMP_TASKGROUP, void_type_node, stmt));
SET_EXPR_LOCATION (t, loc);
return t;
}
/* Complete a #pragma omp critical construct. STMT is the structured-block
that follows the pragma, NAME is the identifier in the pragma, or null
if it was omitted. LOC is the location of the #pragma. */
@ -122,7 +134,7 @@ c_finish_omp_taskyield (location_t loc)
tree
c_finish_omp_atomic (location_t loc, enum tree_code code,
enum tree_code opcode, tree lhs, tree rhs,
tree v, tree lhs1, tree rhs1)
tree v, tree lhs1, tree rhs1, bool swapped, bool seq_cst)
{
tree x, type, addr;
@ -168,6 +180,7 @@ c_finish_omp_atomic (location_t loc, enum tree_code code,
{
x = build1 (OMP_ATOMIC_READ, type, addr);
SET_EXPR_LOCATION (x, loc);
OMP_ATOMIC_SEQ_CST (x) = seq_cst;
return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
loc, x, NULL_TREE);
return x;
@ -176,8 +189,12 @@ c_finish_omp_atomic (location_t loc, enum tree_code code,
/* There are lots of warnings, errors, and conversions that need to happen
in the course of interpreting a statement. Use the normal mechanisms
to do this, and then take it apart again. */
x = build_modify_expr (input_location, lhs, NULL_TREE, opcode,
input_location, rhs, NULL_TREE);
if (swapped)
{
rhs = build2_loc (loc, opcode, TREE_TYPE (lhs), rhs, lhs);
opcode = NOP_EXPR;
}
x = build_modify_expr (loc, lhs, NULL_TREE, opcode, loc, rhs, NULL_TREE);
if (x == error_mark_node)
return error_mark_node;
gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
@ -188,6 +205,7 @@ c_finish_omp_atomic (location_t loc, enum tree_code code,
type = void_type_node;
x = build2 (code, type, addr, rhs);
SET_EXPR_LOCATION (x, loc);
OMP_ATOMIC_SEQ_CST (x) = seq_cst;
/* Generally it is hard to prove lhs1 and lhs are the same memory
location, just diagnose different variables. */
@ -339,8 +357,8 @@ check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
the loop. */
tree
c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
tree incrv, tree body, tree pre_body)
c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
tree initv, tree condv, tree incrv, tree body, tree pre_body)
{
location_t elocus;
bool fail = false;
@ -565,7 +583,7 @@ c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
return NULL;
else
{
tree t = make_node (OMP_FOR);
tree t = make_node (code);
TREE_TYPE (t) = void_type_node;
OMP_FOR_INIT (t) = initv;
@ -579,21 +597,55 @@ c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
}
}
/* Divide CLAUSES into two lists: those that apply to a parallel
construct, and those that apply to a work-sharing construct. Place
the results in *PAR_CLAUSES and *WS_CLAUSES respectively. In
addition, add a nowait clause to the work-sharing list. LOC is the
location of the OMP_PARALLEL*. */
/* Right now we have 14 different combined constructs, this
function attempts to split or duplicate clauses for combined
constructs. CODE is the innermost construct in the combined construct,
and MASK allows to determine which constructs are combined together,
as every construct has at least one clause that no other construct
has (except for OMP_SECTIONS, but that can be only combined with parallel).
Combined constructs are:
#pragma omp parallel for
#pragma omp parallel sections
#pragma omp parallel for simd
#pragma omp for simd
#pragma omp distribute simd
#pragma omp distribute parallel for
#pragma omp distribute parallel for simd
#pragma omp teams distribute
#pragma omp teams distribute parallel for
#pragma omp teams distribute parallel for simd
#pragma omp target teams
#pragma omp target teams distribute
#pragma omp target teams distribute parallel for
#pragma omp target teams distribute parallel for simd */
void
c_split_parallel_clauses (location_t loc, tree clauses,
tree *par_clauses, tree *ws_clauses)
c_omp_split_clauses (location_t loc, enum tree_code code,
omp_clause_mask mask, tree clauses, tree *cclauses)
{
tree next;
tree next, c;
enum c_omp_clause_split s;
int i;
*par_clauses = NULL;
*ws_clauses = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
cclauses[i] = NULL;
/* Add implicit nowait clause on
#pragma omp parallel {for,for simd,sections}. */
if (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
switch (code)
{
case OMP_FOR:
case OMP_SIMD:
cclauses[C_OMP_CLAUSE_SPLIT_FOR]
= build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
break;
case OMP_SECTIONS:
cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]
= build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
break;
default:
break;
}
for (; clauses ; clauses = next)
{
@ -601,32 +653,326 @@ c_split_parallel_clauses (location_t loc, tree clauses,
switch (OMP_CLAUSE_CODE (clauses))
{
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_SHARED:
case OMP_CLAUSE_FIRSTPRIVATE:
case OMP_CLAUSE_LASTPRIVATE:
case OMP_CLAUSE_REDUCTION:
/* First the clauses that are unique to some constructs. */
case OMP_CLAUSE_DEVICE:
case OMP_CLAUSE_MAP:
s = C_OMP_CLAUSE_SPLIT_TARGET;
break;
case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_THREAD_LIMIT:
s = C_OMP_CLAUSE_SPLIT_TEAMS;
break;
case OMP_CLAUSE_DIST_SCHEDULE:
s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
break;
case OMP_CLAUSE_COPYIN:
case OMP_CLAUSE_IF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_DEFAULT:
OMP_CLAUSE_CHAIN (clauses) = *par_clauses;
*par_clauses = clauses;
case OMP_CLAUSE_PROC_BIND:
s = C_OMP_CLAUSE_SPLIT_PARALLEL;
break;
case OMP_CLAUSE_SCHEDULE:
case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_COLLAPSE:
OMP_CLAUSE_CHAIN (clauses) = *ws_clauses;
*ws_clauses = clauses;
case OMP_CLAUSE_SCHEDULE:
case OMP_CLAUSE_NOWAIT:
s = C_OMP_CLAUSE_SPLIT_FOR;
break;
case OMP_CLAUSE_SAFELEN:
case OMP_CLAUSE_LINEAR:
case OMP_CLAUSE_ALIGNED:
s = C_OMP_CLAUSE_SPLIT_SIMD;
break;
/* Duplicate this to all of distribute, for and simd. */
case OMP_CLAUSE_COLLAPSE:
if (code == OMP_SIMD)
{
c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
OMP_CLAUSE_COLLAPSE);
OMP_CLAUSE_COLLAPSE_EXPR (c)
= OMP_CLAUSE_COLLAPSE_EXPR (clauses);
OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
}
if (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE))
{
if (mask & (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE))
{
c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
OMP_CLAUSE_COLLAPSE);
OMP_CLAUSE_COLLAPSE_EXPR (c)
= OMP_CLAUSE_COLLAPSE_EXPR (clauses);
OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c;
s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
}
else
s = C_OMP_CLAUSE_SPLIT_FOR;
}
else
s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
break;
/* Private clause is supported on all constructs but target,
it is enough to put it on the innermost one. For
#pragma omp {for,sections} put it on parallel though,
as that's what we did for OpenMP 3.1. */
case OMP_CLAUSE_PRIVATE:
switch (code)
{
case OMP_SIMD: s = C_OMP_CLAUSE_SPLIT_SIMD; break;
case OMP_FOR: case OMP_SECTIONS:
case OMP_PARALLEL: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
case OMP_DISTRIBUTE: s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break;
case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break;
default: gcc_unreachable ();
}
break;
/* Firstprivate clause is supported on all constructs but
target and simd. Put it on the outermost of those and
duplicate on parallel. */
case OMP_CLAUSE_FIRSTPRIVATE:
if (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
{
if (mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)
| (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)))
{
c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
if (mask & (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_TEAMS))
s = C_OMP_CLAUSE_SPLIT_TEAMS;
else
s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
}
else
/* This must be
#pragma omp parallel{, for{, simd}, sections}. */
s = C_OMP_CLAUSE_SPLIT_PARALLEL;
}
else if (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
{
/* This must be #pragma omp {,target }teams distribute. */
gcc_assert (code == OMP_DISTRIBUTE);
s = C_OMP_CLAUSE_SPLIT_TEAMS;
}
else if (mask & (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE))
{
/* This must be #pragma omp distribute simd. */
gcc_assert (code == OMP_SIMD);
s = C_OMP_CLAUSE_SPLIT_TEAMS;
}
else
{
/* This must be #pragma omp for simd. */
gcc_assert (code == OMP_SIMD);
s = C_OMP_CLAUSE_SPLIT_FOR;
}
break;
/* Lastprivate is allowed on for, sections and simd. In
parallel {for{, simd},sections} we actually want to put it on
parallel rather than for or sections. */
case OMP_CLAUSE_LASTPRIVATE:
if (code == OMP_FOR || code == OMP_SECTIONS)
{
if (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
s = C_OMP_CLAUSE_SPLIT_PARALLEL;
else
s = C_OMP_CLAUSE_SPLIT_FOR;
break;
}
gcc_assert (code == OMP_SIMD);
if (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE))
{
c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
OMP_CLAUSE_LASTPRIVATE);
OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
if (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
s = C_OMP_CLAUSE_SPLIT_PARALLEL;
else
s = C_OMP_CLAUSE_SPLIT_FOR;
OMP_CLAUSE_CHAIN (c) = cclauses[s];
cclauses[s] = c;
}
s = C_OMP_CLAUSE_SPLIT_SIMD;
break;
/* Shared and default clauses are allowed on private and teams. */
case OMP_CLAUSE_SHARED:
case OMP_CLAUSE_DEFAULT:
if (code == OMP_TEAMS)
{
s = C_OMP_CLAUSE_SPLIT_TEAMS;
break;
}
if (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
{
c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
OMP_CLAUSE_CODE (clauses));
if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED)
OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
else
OMP_CLAUSE_DEFAULT_KIND (c)
= OMP_CLAUSE_DEFAULT_KIND (clauses);
OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
}
s = C_OMP_CLAUSE_SPLIT_PARALLEL;
break;
/* Reduction is allowed on simd, for, parallel, sections and teams.
Duplicate it on all of them, but omit on for or sections if
parallel is present. */
case OMP_CLAUSE_REDUCTION:
if (code == OMP_SIMD)
{
c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
OMP_CLAUSE_REDUCTION);
OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
OMP_CLAUSE_REDUCTION_CODE (c)
= OMP_CLAUSE_REDUCTION_CODE (clauses);
OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
}
if (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE))
{
if (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
{
c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
OMP_CLAUSE_REDUCTION);
OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
OMP_CLAUSE_REDUCTION_CODE (c)
= OMP_CLAUSE_REDUCTION_CODE (clauses);
OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
s = C_OMP_CLAUSE_SPLIT_TEAMS;
}
else if (mask & (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS))
s = C_OMP_CLAUSE_SPLIT_PARALLEL;
else
s = C_OMP_CLAUSE_SPLIT_FOR;
}
else if (code == OMP_SECTIONS)
s = C_OMP_CLAUSE_SPLIT_PARALLEL;
else
s = C_OMP_CLAUSE_SPLIT_TEAMS;
break;
case OMP_CLAUSE_IF:
/* FIXME: This is currently being discussed. */
if (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
s = C_OMP_CLAUSE_SPLIT_PARALLEL;
else
s = C_OMP_CLAUSE_SPLIT_TARGET;
break;
default:
gcc_unreachable ();
}
OMP_CLAUSE_CHAIN (clauses) = cclauses[s];
cclauses[s] = clauses;
}
}
/* qsort callback to compare #pragma omp declare simd clauses. */
static int
c_omp_declare_simd_clause_cmp (const void *p, const void *q)
{
tree a = *(const tree *) p;
tree b = *(const tree *) q;
if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_CODE (b))
{
if (OMP_CLAUSE_CODE (a) > OMP_CLAUSE_CODE (b))
return -1;
return 1;
}
if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_SIMDLEN
&& OMP_CLAUSE_CODE (a) != OMP_CLAUSE_INBRANCH
&& OMP_CLAUSE_CODE (a) != OMP_CLAUSE_NOTINBRANCH)
{
int c = tree_low_cst (OMP_CLAUSE_DECL (a), 0);
int d = tree_low_cst (OMP_CLAUSE_DECL (b), 0);
if (c < d)
return 1;
if (c > d)
return -1;
}
return 0;
}
/* Change PARM_DECLs in OMP_CLAUSE_DECL of #pragma omp declare simd
CLAUSES on FNDECL into argument indexes and sort them. */
tree
c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses)
{
tree c;
vec<tree> clvec = vNULL;
for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
{
if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
{
tree decl = OMP_CLAUSE_DECL (c);
tree arg;
int idx;
for (arg = parms, idx = 0; arg;
arg = TREE_CHAIN (arg), idx++)
if (arg == decl)
break;
if (arg == NULL_TREE)
{
error_at (OMP_CLAUSE_LOCATION (c),
"%qD is not an function argument", decl);
continue;
}
OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, idx);
}
clvec.safe_push (c);
}
if (!clvec.is_empty ())
{
unsigned int len = clvec.length (), i;
clvec.qsort (c_omp_declare_simd_clause_cmp);
clauses = clvec[0];
for (i = 0; i < len; i++)
OMP_CLAUSE_CHAIN (clvec[i]) = (i < len - 1) ? clvec[i + 1] : NULL_TREE;
}
clvec.release ();
return clauses;
}
/* Change argument indexes in CLAUSES of FNDECL back to PARM_DECLs. */
void
c_omp_declare_simd_clauses_to_decls (tree fndecl, tree clauses)
{
tree c;
for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
{
int idx = tree_low_cst (OMP_CLAUSE_DECL (c), 0), i;
tree arg;
for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
arg = TREE_CHAIN (arg), i++)
if (i == idx)
break;
gcc_assert (arg);
OMP_CLAUSE_DECL (c) = arg;
}
}
/* True if OpenMP sharing attribute of DECL is predetermined. */
enum omp_clause_default_kind

View file

@ -1167,7 +1167,12 @@ struct omp_pragma_def { const char *name; unsigned int id; };
static const struct omp_pragma_def omp_pragmas[] = {
{ "atomic", PRAGMA_OMP_ATOMIC },
{ "barrier", PRAGMA_OMP_BARRIER },
{ "cancel", PRAGMA_OMP_CANCEL },
{ "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
{ "critical", PRAGMA_OMP_CRITICAL },
{ "declare", PRAGMA_OMP_DECLARE_REDUCTION },
{ "distribute", PRAGMA_OMP_DISTRIBUTE },
{ "end", PRAGMA_OMP_END_DECLARE_TARGET },
{ "flush", PRAGMA_OMP_FLUSH },
{ "for", PRAGMA_OMP_FOR },
{ "master", PRAGMA_OMP_MASTER },
@ -1175,10 +1180,14 @@ static const struct omp_pragma_def omp_pragmas[] = {
{ "parallel", PRAGMA_OMP_PARALLEL },
{ "section", PRAGMA_OMP_SECTION },
{ "sections", PRAGMA_OMP_SECTIONS },
{ "simd", PRAGMA_OMP_SIMD },
{ "single", PRAGMA_OMP_SINGLE },
{ "target", PRAGMA_OMP_TARGET },
{ "task", PRAGMA_OMP_TASK },
{ "taskgroup", PRAGMA_OMP_TASKGROUP },
{ "taskwait", PRAGMA_OMP_TASKWAIT },
{ "taskyield", PRAGMA_OMP_TASKYIELD },
{ "teams", PRAGMA_OMP_TEAMS },
{ "threadprivate", PRAGMA_OMP_THREADPRIVATE }
};

View file

@ -29,21 +29,28 @@ typedef enum pragma_kind {
PRAGMA_OMP_ATOMIC,
PRAGMA_OMP_BARRIER,
PRAGMA_OMP_CANCEL,
PRAGMA_OMP_CANCELLATION_POINT,
PRAGMA_OMP_CRITICAL,
PRAGMA_OMP_DECLARE_REDUCTION,
PRAGMA_OMP_DISTRIBUTE,
PRAGMA_OMP_END_DECLARE_TARGET,
PRAGMA_OMP_FLUSH,
PRAGMA_OMP_FOR,
PRAGMA_OMP_MASTER,
PRAGMA_OMP_ORDERED,
PRAGMA_OMP_PARALLEL,
PRAGMA_OMP_PARALLEL_FOR,
PRAGMA_OMP_PARALLEL_SECTIONS,
PRAGMA_OMP_SECTION,
PRAGMA_OMP_SECTIONS,
PRAGMA_OMP_SIMD,
PRAGMA_OMP_SINGLE,
PRAGMA_OMP_TARGET,
PRAGMA_OMP_TASK,
PRAGMA_OMP_TASKGROUP,
PRAGMA_OMP_TASKWAIT,
PRAGMA_OMP_TASKYIELD,
PRAGMA_OMP_THREADPRIVATE,
PRAGMA_OMP_TEAMS,
PRAGMA_GCC_PCH_PREPROCESS,
@ -51,28 +58,48 @@ typedef enum pragma_kind {
} pragma_kind;
/* All clauses defined by OpenMP 2.5 and 3.0.
/* All clauses defined by 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,
PRAGMA_OMP_CLAUSE_ALIGNED,
PRAGMA_OMP_CLAUSE_COLLAPSE,
PRAGMA_OMP_CLAUSE_COPYIN,
PRAGMA_OMP_CLAUSE_COPYPRIVATE,
PRAGMA_OMP_CLAUSE_DEFAULT,
PRAGMA_OMP_CLAUSE_DEPEND,
PRAGMA_OMP_CLAUSE_DEVICE,
PRAGMA_OMP_CLAUSE_DIST_SCHEDULE,
PRAGMA_OMP_CLAUSE_FINAL,
PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
PRAGMA_OMP_CLAUSE_FOR,
PRAGMA_OMP_CLAUSE_FROM,
PRAGMA_OMP_CLAUSE_IF,
PRAGMA_OMP_CLAUSE_INBRANCH,
PRAGMA_OMP_CLAUSE_LASTPRIVATE,
PRAGMA_OMP_CLAUSE_LINEAR,
PRAGMA_OMP_CLAUSE_MAP,
PRAGMA_OMP_CLAUSE_MERGEABLE,
PRAGMA_OMP_CLAUSE_NOTINBRANCH,
PRAGMA_OMP_CLAUSE_NOWAIT,
PRAGMA_OMP_CLAUSE_NUM_TEAMS,
PRAGMA_OMP_CLAUSE_NUM_THREADS,
PRAGMA_OMP_CLAUSE_ORDERED,
PRAGMA_OMP_CLAUSE_PARALLEL,
PRAGMA_OMP_CLAUSE_PRIVATE,
PRAGMA_OMP_CLAUSE_PROC_BIND,
PRAGMA_OMP_CLAUSE_REDUCTION,
PRAGMA_OMP_CLAUSE_SAFELEN,
PRAGMA_OMP_CLAUSE_SCHEDULE,
PRAGMA_OMP_CLAUSE_SECTIONS,
PRAGMA_OMP_CLAUSE_SHARED,
PRAGMA_OMP_CLAUSE_UNTIED,
PRAGMA_OMP_CLAUSE_FINAL,
PRAGMA_OMP_CLAUSE_MERGEABLE
PRAGMA_OMP_CLAUSE_SIMDLEN,
PRAGMA_OMP_CLAUSE_TASKGROUP,
PRAGMA_OMP_CLAUSE_THREAD_LIMIT,
PRAGMA_OMP_CLAUSE_TO,
PRAGMA_OMP_CLAUSE_UNIFORM,
PRAGMA_OMP_CLAUSE_UNTIED
} pragma_omp_clause;
extern struct cpp_reader* parse_in;

View file

@ -1,3 +1,114 @@
2013-10-11 Jakub Jelinek <jakub@redhat.com>
* c-lang.h (current_omp_declare_target_attribute): New extern
decl.
* c-parser.c: Include c-lang.h.
(struct c_parser): Change tokens to c_token *.
Add tokens_buf field. Change tokens_avail type to unsigned int.
(c_parser_consume_token): If parser->tokens isn't
&parser->tokens_buf[0], increment parser->tokens.
(c_parser_consume_pragma): Likewise.
(enum pragma_context): Add pragma_struct and pragma_param.
(c_parser_external_declaration): Adjust
c_parser_declaration_or_fndef caller.
(c_parser_declaration_or_fndef): Add omp_declare_simd_clauses
argument, if it is non-vNULL vector, call c_finish_omp_declare_simd.
Adjust recursive call.
(c_parser_struct_or_union_specifier): Use pragma_struct instead
of pragma_external.
(c_parser_parameter_declaration): Use pragma_param instead of
pragma_external.
(c_parser_compound_statement_nostart, c_parser_label,
c_parser_for_statement): Adjust
c_parser_declaration_or_fndef callers.
(c_parser_expr_no_commas): Add omp_atomic_lhs argument, pass
it through to c_parser_conditional_expression.
(c_parser_conditional_expression): Add omp_atomic_lhs argument,
pass it through to c_parser_binary_expression. Adjust recursive
call.
(c_parser_binary_expression): Remove prec argument, add
omp_atomic_lhs argument instead. Always start from PREC_NONE, if
omp_atomic_lhs is non-NULL and one of the arguments of toplevel
binop matches it, use build2 instead of parser_build_binary_op.
(c_parser_pragma): Handle PRAGMA_OMP_CANCEL,
PRAGMA_OMP_CANCELLATION_POINT, PRAGMA_OMP_TARGET,
PRAGMA_OMP_END_DECLARE_TARGET, PRAGMA_OMP_DECLARE_REDUCTION.
Handle pragma_struct and pragma_param the same as pragma_external.
(c_parser_omp_clause_name): Parse new OpenMP 4.0 clause names.
(c_parser_omp_variable_list): Parse array sections for
OMP_CLAUSE_{DEPEND,MAP,TO,FROM} clauses.
(c_parser_omp_clause_collapse): Fully fold collapse expression.
(c_parser_omp_clause_reduction): Handle user defined reductions.
(c_parser_omp_clause_branch, c_parser_omp_clause_cancelkind,
c_parser_omp_clause_num_teams, c_parser_omp_clause_thread_limit,
c_parser_omp_clause_aligned, c_parser_omp_clause_linear,
c_parser_omp_clause_safelen, c_parser_omp_clause_simdlen,
c_parser_omp_clause_depend, c_parser_omp_clause_map,
c_parser_omp_clause_device, c_parser_omp_clause_dist_schedule,
c_parser_omp_clause_proc_bind, c_parser_omp_clause_to,
c_parser_omp_clause_from, c_parser_omp_clause_uniform): New functions.
(c_parser_omp_all_clauses): Add finish_p argument. Don't call
c_finish_omp_clauses if it is false. Handle new OpenMP 4.0 clauses.
(c_parser_omp_atomic): Parse seq_cst clause, pass true if it is
present to c_finish_omp_atomic. Handle OpenMP 4.0 atomic forms.
(c_parser_omp_for_loop): Add CODE argument, pass it through
to c_finish_omp_for. Change last argument to cclauses,
and adjust uses to grab parallel clauses from the array of all
the split clauses. Adjust c_parser_binary_expression,
c_parser_declaration_or_fndef and c_finish_omp_for callers.
(omp_split_clauses): New function.
(c_parser_omp_simd): New function.
(c_parser_omp_for): Add p_name, mask and cclauses arguments.
Allow the function to be called also when parsing combined constructs,
and call c_parser_omp_simd when parsing for simd.
(c_parser_omp_sections_scope): If section-sequence doesn't start with
#pragma omp section, require exactly one structured-block instead of
sequence of statements.
(c_parser_omp_sections): Add p_name, mask and cclauses arguments.
Allow the function to be called also when parsing combined constructs.
(c_parser_omp_parallel): Add p_name, mask and cclauses arguments.
Allow the function to be called also when parsing combined
constructs.
(c_parser_omp_taskgroup, c_parser_omp_cancel,
c_parser_omp_cancellation_point, c_parser_omp_distribute,
c_parser_omp_teams, c_parser_omp_target_data,
c_parser_omp_target_update, c_parser_omp_target,
c_parser_omp_declare_simd, c_finish_omp_declare_simd,
c_parser_omp_declare_target, c_parser_omp_end_declare_target,
c_parser_omp_declare_reduction, c_parser_omp_declare): New functions.
(c_parser_omp_construct): Add p_name and mask vars. Handle
PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_SIMD, PRAGMA_OMP_TASKGROUP,
PRAGMA_OMP_TEAMS. Adjust c_parser_omp_for, c_parser_omp_parallel
and c_parser_omp_sections callers.
(c_parse_file): Initialize tparser.tokens and the_parser->tokens here.
(OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK,
OMP_SINGLE_CLAUSE_MASK): Use OMP_CLAUSE_MASK_1 instead of 1.
(OMP_PARALLEL_CLAUSE_MASK): Likewise. Add OMP_CLAUSE_PROC_BIND.
(OMP_TASK_CLAUSE_MASK): Use OMP_CLAUSE_MASK_1 instead of 1. Add
OMP_CLAUSE_DEPEND.
(OMP_SIMD_CLAUSE_MASK, OMP_CANCEL_CLAUSE_MASK,
OMP_CANCELLATION_POINT_CLAUSE_MASK, OMP_DISTRIBUTE_CLAUSE_MASK,
OMP_TEAMS_CLAUSE_MASK, OMP_TARGET_DATA_CLAUSE_MASK,
OMP_TARGET_UPDATE_CLAUSE_MASK, OMP_TARGET_CLAUSE_MASK,
OMP_DECLARE_SIMD_CLAUSE_MASK): Define.
* c-typeck.c: Include tree-inline.h.
(c_finish_omp_cancel, c_finish_omp_cancellation_point,
handle_omp_array_sections_1, handle_omp_array_sections,
c_clone_omp_udr, c_find_omp_placeholder_r): New functions.
(c_finish_omp_clauses): Handle new OpenMP 4.0 clauses and
user defined reductions.
(c_tree_equal): New function.
* c-tree.h (temp_store_parm_decls, temp_pop_parm_decls,
c_finish_omp_cancel, c_finish_omp_cancellation_point, c_tree_equal,
c_omp_reduction_id, c_omp_reduction_decl, c_omp_reduction_lookup,
c_check_omp_declare_reduction_r): New prototypes.
* c-decl.c (current_omp_declare_target_attribute): New variable.
(c_decl_attributes): New function.
(start_decl, start_function): Use it instead of decl_attributes.
(temp_store_parm_decls, temp_pop_parm_decls, c_omp_reduction_id,
c_omp_reduction_decl, c_omp_reduction_lookup,
c_check_omp_declare_reduction_r): New functions.
2013-09-25 Tom Tromey <tromey@redhat.com>
* Make-lang.in (c/gccspec.o): Remove.

View file

@ -147,6 +147,9 @@ static bool undef_nested_function;
enum machine_mode c_default_pointer_mode = VOIDmode;
/* If non-zero, implicit "omp declare target" attribute is added into the
attribute lists. */
int current_omp_declare_target_attribute;
/* Each c_binding structure describes one binding of an identifier to
a decl. All the decls in a scope - irrespective of namespace - are
@ -3971,6 +3974,35 @@ groktypename (struct c_type_name *type_name, tree *expr,
return type;
}
/* Wrapper for decl_attributes that adds some implicit attributes
to VAR_DECLs or FUNCTION_DECLs. */
static tree
c_decl_attributes (tree *node, tree attributes, int flags)
{
/* Add implicit "omp declare target" attribute if requested. */
if (current_omp_declare_target_attribute
&& ((TREE_CODE (*node) == VAR_DECL && TREE_STATIC (*node))
|| TREE_CODE (*node) == FUNCTION_DECL))
{
if (TREE_CODE (*node) == VAR_DECL
&& ((DECL_CONTEXT (*node)
&& TREE_CODE (DECL_CONTEXT (*node)) == FUNCTION_DECL)
|| (current_function_decl && !DECL_EXTERNAL (*node))))
error ("%q+D in block scope inside of declare target directive",
*node);
else if (TREE_CODE (*node) == VAR_DECL
&& !COMPLETE_TYPE_P (TREE_TYPE (*node)))
error ("%q+D in declare target directive does not have mappable type",
*node);
else
attributes = tree_cons (get_identifier ("omp declare target"),
NULL_TREE, attributes);
}
return decl_attributes (node, attributes, flags);
}
/* Decode a declarator in an ordinary declaration or data definition.
This is called as soon as the type information and variable name
have been parsed, before parsing the initializer if any.
@ -4105,7 +4137,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
DECL_COMMON (decl) = 1;
/* Set attributes here so if duplicate decl, will have proper attributes. */
decl_attributes (&decl, attributes, 0);
c_decl_attributes (&decl, attributes, 0);
/* Handle gnu_inline attribute. */
if (declspecs->inline_p
@ -7727,7 +7759,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
loc = DECL_SOURCE_LOCATION (decl1);
decl_attributes (&decl1, attributes, 0);
c_decl_attributes (&decl1, attributes, 0);
if (DECL_DECLARED_INLINE_P (decl1)
&& DECL_UNINLINABLE (decl1)
@ -8324,6 +8356,44 @@ store_parm_decls (void)
if (arg_info->pending_sizes)
add_stmt (arg_info->pending_sizes);
}
/* Store PARM_DECLs in PARMS into scope temporarily. Used for
c_finish_omp_declare_simd for function prototypes. No diagnostics
should be done. */
void
temp_store_parm_decls (tree fndecl, tree parms)
{
push_scope ();
for (tree p = parms; p; p = DECL_CHAIN (p))
{
DECL_CONTEXT (p) = fndecl;
if (DECL_NAME (p))
bind (DECL_NAME (p), p, current_scope,
/*invisible=*/false, /*nested=*/false,
UNKNOWN_LOCATION);
}
}
/* Undo what temp_store_parm_decls did. */
void
temp_pop_parm_decls (void)
{
/* Clear all bindings in this temporary scope, so that
pop_scope doesn't create a BLOCK. */
struct c_binding *b = current_scope->bindings;
current_scope->bindings = NULL;
for (; b; b = free_binding_and_advance (b))
{
gcc_assert (TREE_CODE (b->decl) == PARM_DECL);
gcc_assert (I_SYMBOL_BINDING (b->id) == b);
I_SYMBOL_BINDING (b->id) = b->shadowed;
if (b->shadowed && b->shadowed->u.type)
TREE_TYPE (b->shadowed->decl) = b->shadowed->u.type;
}
pop_scope ();
}
/* Finish up a function declaration and compile that function
@ -10158,4 +10228,106 @@ c_register_addr_space (const char *word, addr_space_t as)
ridpointers [rid] = id;
}
/* Return identifier to look up for omp declare reduction. */
tree
c_omp_reduction_id (enum tree_code reduction_code, tree reduction_id)
{
const char *p = NULL;
switch (reduction_code)
{
case PLUS_EXPR: p = "+"; break;
case MULT_EXPR: p = "*"; break;
case MINUS_EXPR: p = "-"; break;
case BIT_AND_EXPR: p = "&"; break;
case BIT_XOR_EXPR: p = "^"; break;
case BIT_IOR_EXPR: p = "|"; break;
case TRUTH_ANDIF_EXPR: p = "&&"; break;
case TRUTH_ORIF_EXPR: p = "||"; break;
case MIN_EXPR: p = "min"; break;
case MAX_EXPR: p = "max"; break;
default:
break;
}
if (p == NULL)
{
if (TREE_CODE (reduction_id) != IDENTIFIER_NODE)
return error_mark_node;
p = IDENTIFIER_POINTER (reduction_id);
}
const char prefix[] = "omp declare reduction ";
size_t lenp = sizeof (prefix);
size_t len = strlen (p);
char *name = XALLOCAVEC (char, lenp + len);
memcpy (name, prefix, lenp - 1);
memcpy (name + lenp - 1, p, len + 1);
return get_identifier (name);
}
/* Lookup REDUCTION_ID in the current scope, or create an artificial
VAR_DECL, bind it into the current scope and return it. */
tree
c_omp_reduction_decl (tree reduction_id)
{
struct c_binding *b = I_SYMBOL_BINDING (reduction_id);
if (b != NULL && B_IN_CURRENT_SCOPE (b))
return b->decl;
tree decl = build_decl (BUILTINS_LOCATION, VAR_DECL,
reduction_id, integer_type_node);
DECL_ARTIFICIAL (decl) = 1;
DECL_EXTERNAL (decl) = 1;
TREE_STATIC (decl) = 1;
TREE_PUBLIC (decl) = 0;
bind (reduction_id, decl, current_scope, true, false, BUILTINS_LOCATION);
return decl;
}
/* Lookup REDUCTION_ID in the first scope where it has entry for TYPE. */
tree
c_omp_reduction_lookup (tree reduction_id, tree type)
{
struct c_binding *b = I_SYMBOL_BINDING (reduction_id);
while (b)
{
tree t;
for (t = DECL_INITIAL (b->decl); t; t = TREE_CHAIN (t))
if (comptypes (TREE_PURPOSE (t), type))
return TREE_VALUE (t);
b = b->shadowed;
}
return error_mark_node;
}
/* Helper function called via walk_tree, to diagnose invalid
#pragma omp declare reduction combiners or initializers. */
tree
c_check_omp_declare_reduction_r (tree *tp, int *, void *data)
{
tree *vars = (tree *) data;
if (SSA_VAR_P (*tp)
&& !DECL_ARTIFICIAL (*tp)
&& *tp != vars[0]
&& *tp != vars[1])
{
location_t loc = DECL_SOURCE_LOCATION (vars[0]);
if (strcmp (IDENTIFIER_POINTER (DECL_NAME (vars[0])), "omp_out") == 0)
error_at (loc, "%<#pragma omp declare reduction%> combiner refers to "
"variable %qD which is not %<omp_out%> nor %<omp_in%>",
*tp);
else
error_at (loc, "%<#pragma omp declare reduction%> initializer refers "
"to variable %qD which is not %<omp_priv%> nor "
"%<omp_orig%>",
*tp);
return *tp;
}
return NULL_TREE;
}
#include "gt-c-c-decl.h"

View file

@ -55,5 +55,8 @@ struct GTY(()) language_function {
int warn_about_return_type;
};
/* If non-zero, implicit "omp declare target" attribute is added into the
attribute lists. */
extern GTY(()) int current_omp_declare_target_attribute;
#endif /* ! GCC_C_LANG_H */

File diff suppressed because it is too large Load diff

View file

@ -526,6 +526,8 @@ extern tree start_struct (location_t, enum tree_code, tree,
struct c_struct_parse_info **);
extern void store_parm_decls (void);
extern void store_parm_decls_from (struct c_arg_info *);
extern void temp_store_parm_decls (tree, tree);
extern void temp_pop_parm_decls (void);
extern tree xref_tag (enum tree_code, tree);
extern struct c_typespec parser_xref_tag (location_t, enum tree_code, tree);
extern struct c_parm *build_c_parm (struct c_declspecs *, tree,
@ -637,9 +639,12 @@ extern tree c_begin_omp_parallel (void);
extern tree c_finish_omp_parallel (location_t, tree, tree);
extern tree c_begin_omp_task (void);
extern tree c_finish_omp_task (location_t, tree, tree);
extern void c_finish_omp_cancel (location_t, tree);
extern void c_finish_omp_cancellation_point (location_t, tree);
extern tree c_finish_omp_clauses (tree);
extern tree c_build_va_arg (location_t, tree, tree);
extern tree c_finish_transaction (location_t, tree, int);
extern bool c_tree_equal (tree, tree);
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement that specifies a return value is seen. */
@ -663,6 +668,10 @@ extern enum machine_mode c_default_pointer_mode;
/* In c-decl.c */
extern void c_finish_incomplete_decl (tree);
extern void c_write_global_declarations (void);
extern tree c_omp_reduction_id (enum tree_code, tree);
extern tree c_omp_reduction_decl (tree);
extern tree c_omp_reduction_lookup (tree, tree);
extern tree c_check_omp_declare_reduction_r (tree *, int *, void *);
/* In c-errors.c */
extern void pedwarn_c90 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,172 @@
2013-10-11 Jakub Jelinek <jakub@redhat.com>
* decl.c (duplicate_decls): Error out for redeclaration of UDRs.
(declare_simd_adjust_this): New function.
(grokfndecl): If "omp declare simd" attribute is present,
call declare_simd_adjust_this if needed and
c_omp_declare_simd_clauses_to_numbers.
* cp-array-notation.c (expand_array_notation_exprs): Handle
OMP_TASKGROUP.
* cp-gimplify.c (cp_gimplify_expr): Handle OMP_SIMD and
OMP_DISTRIBUTE. Handle is_invisiref_parm decls in
OMP_CLAUSE_REDUCTION.
(cp_genericize_r): Handle OMP_SIMD and OMP_DISTRIBUTE like
OMP_FOR.
(cxx_omp_privatize_by_reference): Return true for
is_invisiref_parm decls.
(cxx_omp_finish_clause): Adjust cxx_omp_create_clause_info
caller.
* pt.c (apply_late_template_attributes): For "omp declare simd"
attribute call tsubst_omp_clauses,
c_omp_declare_simd_clauses_to_decls, finish_omp_clauses
and c_omp_declare_simd_clauses_to_numbers.
(instantiate_class_template_1): Call cp_check_omp_declare_reduction
for UDRs.
(tsubst_decl): Handle UDRs.
(tsubst_omp_clauses): Add declare_simd argument, if true don't
call finish_omp_clauses. Handle new OpenMP 4.0 clauses.
Handle non-NULL OMP_CLAUSE_REDUCTION_PLACEHOLDER on
OMP_CLAUSE_REDUCTION.
(tsubst_expr): For UDRs call pushdecl and
cp_check_omp_declare_reduction. Adjust tsubst_omp_clauses
callers. Handle OMP_SIMD, OMP_DISTRIBUTE, OMP_TEAMS,
OMP_TARGET_DATA, OMP_TARGET_UPDATE, OMP_TARGET, OMP_TASKGROUP.
Adjust finish_omp_atomic caller.
(tsubst_omp_udr): New function.
(instantiate_decl): For UDRs at block scope, don't call
start_preparsed_function/finish_function. Call tsubst_omp_udr.
* semantics.c (cxx_omp_create_clause_info): Add need_dtor argument,
use it instead of need_default_ctor || need_copy_ctor.
(struct cp_check_omp_declare_reduction_data): New type.
(handle_omp_array_sections_1, handle_omp_array_sections,
omp_reduction_id, omp_reduction_lookup,
cp_remove_omp_priv_cleanup_stmt, cp_check_omp_declare_reduction_r,
cp_check_omp_declare_reduction, clone_omp_udr,
find_omp_placeholder_r, finish_omp_reduction_clause): New functions.
(finish_omp_clauses): Handle new OpenMP 4.0 clauses and user defined
reductions.
(finish_omp_for): Add CODE argument, use it instead of hardcoded
OMP_FOR. Adjust c_finish_omp_for caller.
(finish_omp_atomic): Add seq_cst argument, adjust
c_finish_omp_atomic callers, handle seq_cst and new OpenMP 4.0
atomic variants.
(finish_omp_cancel, finish_omp_cancellation_point): New functions.
* decl2.c (mark_used): Force immediate instantiation of
DECL_OMP_DECLARE_REDUCTION_P decls.
(is_late_template_attribute): Return true for "omp declare simd"
attribute.
(cp_omp_mappable_type): New function.
(cplus_decl_attributes): Add implicit "omp declare target" attribute
if requested.
* parser.c (cp_debug_parser): Print
parser->colon_doesnt_start_class_def_p.
(cp_ensure_no_omp_declare_simd, cp_finalize_omp_declare_simd): New
functions.
(enum pragma_context): Add pragma_member and pragma_objc_icode.
(cp_parser_binary_expression): Handle no_toplevel_fold_p
even for binary operations other than comparison.
(cp_parser_linkage_specification): Call
cp_ensure_no_omp_declare_simd if needed.
(cp_parser_namespace_definition): Likewise.
(cp_parser_init_declarator): Call cp_finalize_omp_declare_simd.
(cp_parser_direct_declarator): Pass declarator to
cp_parser_late_return_type_opt.
(cp_parser_late_return_type_opt): Add declarator argument,
call cp_parser_late_parsing_omp_declare_simd for declare simd.
(cp_parser_class_specifier_1): Call cp_ensure_no_omp_declare_simd.
Parse UDRs before all other methods.
(cp_parser_member_specification_opt): Use pragma_member instead of
pragma_external.
(cp_parser_member_declaration): Call cp_finalize_omp_declare_simd.
(cp_parser_function_definition_from_specifiers_and_declarator,
cp_parser_save_member_function_body): Likewise.
(cp_parser_late_parsing_for_member): Handle UDRs specially.
(cp_parser_next_token_starts_class_definition_p): Don't allow
CPP_COLON if colon_doesnt_start_class_def_p flag is true.
(cp_parser_objc_interstitial_code): Use pragma_objc_icode
instead of pragma_external.
(cp_parser_omp_clause_name): Parse new OpenMP 4.0 clause names.
(cp_parser_omp_var_list_no_open): Parse array sections for
OMP_CLAUSE_{DEPEND,MAP,TO,FROM} clauses. Add COLON argument,
if non-NULL, allow parsing to end with a colon rather than close
paren.
(cp_parser_omp_var_list): Adjust cp_parser_omp_var_list_no_open
caller.
(cp_parser_omp_clause_reduction): Handle user defined reductions.
(cp_parser_omp_clause_branch, cp_parser_omp_clause_cancelkind,
cp_parser_omp_clause_num_teams, cp_parser_omp_clause_thread_limit,
cp_parser_omp_clause_aligned, cp_parser_omp_clause_linear,
cp_parser_omp_clause_safelen, cp_parser_omp_clause_simdlen,
cp_parser_omp_clause_depend, cp_parser_omp_clause_map,
cp_parser_omp_clause_device, cp_parser_omp_clause_dist_schedule,
cp_parser_omp_clause_proc_bind, cp_parser_omp_clause_to,
cp_parser_omp_clause_from, cp_parser_omp_clause_uniform): New
functions.
(cp_parser_omp_all_clauses): Add finish_p argument. Don't call
finish_omp_clauses if it is false. Handle new OpenMP 4.0 clauses.
(cp_parser_omp_atomic): Parse seq_cst clause, pass
true if it is present to finish_omp_atomic. Handle new OpenMP 4.0
atomic forms.
(cp_parser_omp_for_loop): Add CODE argument, pass it through
to finish_omp_for. Change last argument to cclauses,
and adjust uses to grab parallel clauses from the array of all
the split clauses.
(cp_omp_split_clauses): New function.
(cp_parser_omp_simd): New function.
(cp_parser_omp_for): Add p_name, mask and cclauses arguments.
Allow the function to be called also when parsing combined constructs,
and call c_parser_omp_simd when parsing for simd.
(cp_parser_omp_sections_scope): If section-sequence doesn't start with
#pragma omp section, require exactly one structured-block instead of
sequence of statements.
(cp_parser_omp_sections): Add p_name, mask and cclauses arguments.
Allow the function to be called also when parsing combined constructs.
(cp_parser_omp_parallel): Add p_name, mask and cclauses arguments.
Allow the function to be called also when parsing combined
constructs.
(cp_parser_omp_taskgroup, cp_parser_omp_cancel,
cp_parser_omp_cancellation_point, cp_parser_omp_distribute,
cp_parser_omp_teams, cp_parser_omp_target_data,
cp_parser_omp_target_update, cp_parser_omp_target,
cp_parser_omp_declare_simd, cp_parser_late_parsing_omp_declare_simd,
cp_parser_omp_declare_target, cp_parser_omp_end_declare_target,
cp_parser_omp_declare_reduction_exprs, cp_parser_omp_declare_reduction,
cp_parser_omp_declare): New functions.
(cp_parser_omp_construct): Add p_name and mask vars. Handle
PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_SIMD, PRAGMA_OMP_TASKGROUP,
PRAGMA_OMP_TEAMS. Adjust cp_parser_omp_for, cp_parser_omp_parallel
and cp_parser_omp_sections callers.
(cp_parser_pragma): Handle PRAGMA_OMP_CANCEL,
PRAGMA_OMP_CANCELLATION_POINT, PRAGMA_OMP_DECLARE_REDUCTION,
PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_SIMD, PRAGMA_OMP_TASKGROUP,
PRAGMA_OMP_TEAMS, PRAGMA_OMP_TARGET, PRAGMA_OMP_END_DECLARE_TARGET.
Handle pragma_member and pragma_objc_icode like pragma_external.
(OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK,
OMP_SINGLE_CLAUSE_MASK): Use OMP_CLAUSE_MASK_1 instead of 1.
(OMP_PARALLEL_CLAUSE_MASK): Likewise. Add OMP_CLAUSE_PROC_BIND.
(OMP_TASK_CLAUSE_MASK): Use OMP_CLAUSE_MASK_1 instead of 1. Add
OMP_CLAUSE_DEPEND.
(OMP_SIMD_CLAUSE_MASK, OMP_CANCEL_CLAUSE_MASK,
OMP_CANCELLATION_POINT_CLAUSE_MASK, OMP_DISTRIBUTE_CLAUSE_MASK,
OMP_TEAMS_CLAUSE_MASK, OMP_TARGET_DATA_CLAUSE_MASK,
OMP_TARGET_UPDATE_CLAUSE_MASK, OMP_TARGET_CLAUSE_MASK,
OMP_DECLARE_SIMD_CLAUSE_MASK): Define.
* parser.h (struct cp_omp_declare_simd_data): New type.
(struct cp_parser): Add colon_doesnt_start_class_def_p and
omp_declare_simd fields.
* cp-objcp-common.h (LANG_HOOKS_OMP_MAPPABLE_TYPE): Define.
* cp-tree.h (struct lang_decl_fn): Add omp_declare_reduction_p
bit.
(DECL_OMP_DECLARE_REDUCTION_P): Define.
(OMP_FOR_GIMPLIFYING_P): Use OMP_LOOP_CHECK macro.
(struct saved_scope): Add omp_declare_target_attribute field.
(cp_omp_mappable_type, omp_reduction_id,
cp_remove_omp_priv_cleanup_stmt, cp_check_omp_declare_reduction,
finish_omp_cancel, finish_omp_cancellation_point): New prototypes.
(finish_omp_for): Add CODE argument.
(finish_omp_atomic): Add seq_cst argument.
(cxx_omp_create_clause_info): Add need_dtor argument.
2013-10-09 Marek Polacek <polacek@redhat.com>
PR c++/58635

View file

@ -1193,6 +1193,7 @@ expand_array_notation_exprs (tree t)
case OMP_SECTION:
case OMP_SECTIONS:
case OMP_MASTER:
case OMP_TASKGROUP:
case OMP_ORDERED:
case OMP_CRITICAL:
case OMP_ATOMIC:

View file

@ -669,6 +669,8 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
gcc_unreachable ();
case OMP_FOR:
case OMP_SIMD:
case OMP_DISTRIBUTE:
ret = cp_gimplify_omp_for (expr_p, pre_p);
break;
@ -934,7 +936,19 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
*walk_subtrees = 0;
break;
case OMP_CLAUSE_REDUCTION:
gcc_assert (!is_invisiref_parm (OMP_CLAUSE_DECL (stmt)));
/* Don't dereference an invisiref in reduction clause's
OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE}
still needs to be genericized. */
if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
{
*walk_subtrees = 0;
if (OMP_CLAUSE_REDUCTION_INIT (stmt))
cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
cp_genericize_r, data, NULL);
if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
cp_genericize_r, data, NULL);
}
break;
default:
break;
@ -1116,7 +1130,9 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
genericize_continue_stmt (stmt_p);
else if (TREE_CODE (stmt) == BREAK_STMT)
genericize_break_stmt (stmt_p);
else if (TREE_CODE (stmt) == OMP_FOR)
else if (TREE_CODE (stmt) == OMP_FOR
|| TREE_CODE (stmt) == OMP_SIMD
|| TREE_CODE (stmt) == OMP_DISTRIBUTE)
genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
else if (TREE_CODE (stmt) == SIZEOF_EXPR)
{
@ -1402,7 +1418,8 @@ cxx_omp_clause_dtor (tree clause, tree decl)
bool
cxx_omp_privatize_by_reference (const_tree decl)
{
return is_invisiref_parm (decl);
return (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
|| is_invisiref_parm (decl));
}
/* Return true if DECL is const qualified var having no mutable member. */
@ -1505,7 +1522,7 @@ cxx_omp_finish_clause (tree c)
for making these queries. */
if (!make_shared
&& CLASS_TYPE_P (inner_type)
&& cxx_omp_create_clause_info (c, inner_type, false, true, false))
&& cxx_omp_create_clause_info (c, inner_type, false, true, false, true))
make_shared = true;
if (make_shared)

View file

@ -145,6 +145,8 @@ extern void cp_common_init_ts (void);
#define LANG_HOOKS_OMP_FINISH_CLAUSE cxx_omp_finish_clause
#undef LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE
#define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE cxx_omp_privatize_by_reference
#undef LANG_HOOKS_OMP_MAPPABLE_TYPE
#define LANG_HOOKS_OMP_MAPPABLE_TYPE cp_omp_mappable_type
#undef LANG_HOOKS_EH_USE_CXA_END_CLEANUP
#define LANG_HOOKS_EH_USE_CXA_END_CLEANUP true

View file

@ -60,7 +60,7 @@ c-common.h, not after.
STMT_EXPR_NO_SCOPE (in STMT_EXPR)
BIND_EXPR_TRY_BLOCK (in BIND_EXPR)
TYPENAME_IS_ENUM_P (in TYPENAME_TYPE)
OMP_FOR_GIMPLIFYING_P (in OMP_FOR)
OMP_FOR_GIMPLIFYING_P (in OMP_FOR, OMP_SIMD and OMP_DISTRIBUTE)
BASELINK_QUALIFIED_P (in BASELINK)
TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR)
TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX)
@ -1037,6 +1037,9 @@ struct GTY(()) saved_scope {
int unevaluated_operand;
int inhibit_evaluation_warnings;
/* If non-zero, implicit "omp declare target" attribute is added into the
attribute lists. */
int omp_declare_target_attribute;
struct stmt_tree_s x_stmt_tree;
@ -1979,7 +1982,8 @@ struct GTY(()) lang_decl_fn {
unsigned thunk_p : 1;
unsigned this_thunk_p : 1;
unsigned hidden_friend_p : 1;
/* 1 spare bit. */
unsigned omp_declare_reduction_p : 1;
/* No spare bits on 32-bit hosts, 32 on 64-bit hosts. */
/* For a non-thunk function decl, this is a tree list of
friendly classes. For a thunk function decl, it is the
@ -3181,6 +3185,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define DECL_HIDDEN_FRIEND_P(NODE) \
(LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->hidden_friend_p)
/* Nonzero if NODE is an artificial FUNCTION_DECL for
#pragma omp declare reduction. */
#define DECL_OMP_DECLARE_REDUCTION_P(NODE) \
(LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->omp_declare_reduction_p)
/* Nonzero if DECL has been declared threadprivate by
#pragma omp threadprivate. */
#define CP_DECL_THREADPRIVATE_P(DECL) \
@ -4011,7 +4020,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
/* Used while gimplifying continue statements bound to OMP_FOR nodes. */
#define OMP_FOR_GIMPLIFYING_P(NODE) \
(TREE_LANG_FLAG_0 (OMP_FOR_CHECK (NODE)))
(TREE_LANG_FLAG_0 (OMP_LOOP_CHECK (NODE)))
/* A language-specific token attached to the OpenMP data clauses to
hold code (or code fragments) related to ctors, dtors, and op=.
@ -5299,6 +5308,7 @@ extern bool possibly_inlined_p (tree);
extern int parm_index (tree);
extern tree vtv_start_verification_constructor_init_function (void);
extern tree vtv_finish_verification_constructor_init_function (tree);
extern bool cp_omp_mappable_type (tree);
/* in error.c */
extern void init_error (void);
@ -5774,6 +5784,9 @@ extern tree finish_qualified_id_expr (tree, tree, bool, bool,
extern void simplify_aggr_init_expr (tree *);
extern void finalize_nrv (tree *, tree, tree);
extern void note_decl_for_pch (tree);
extern tree omp_reduction_id (enum tree_code, tree, tree);
extern tree cp_remove_omp_priv_cleanup_stmt (tree *, int *, void *);
extern void cp_check_omp_declare_reduction (tree);
extern tree finish_omp_clauses (tree);
extern void finish_omp_threadprivate (tree);
extern tree begin_omp_structured_block (void);
@ -5782,18 +5795,23 @@ extern tree begin_omp_parallel (void);
extern tree finish_omp_parallel (tree, tree);
extern tree begin_omp_task (void);
extern tree finish_omp_task (tree, tree);
extern tree finish_omp_for (location_t, tree, tree,
tree, tree, tree, tree, tree);
extern tree finish_omp_for (location_t, enum tree_code,
tree, tree, tree, tree, tree,
tree, tree);
extern void finish_omp_atomic (enum tree_code, enum tree_code,
tree, tree, tree, tree, tree);
tree, tree, tree, tree, tree,
bool);
extern void finish_omp_barrier (void);
extern void finish_omp_flush (void);
extern void finish_omp_taskwait (void);
extern void finish_omp_taskyield (void);
extern void finish_omp_cancel (tree);
extern void finish_omp_cancellation_point (tree);
extern tree begin_transaction_stmt (location_t, tree *, int);
extern void finish_transaction_stmt (tree, tree, int, tree);
extern tree build_transaction_expr (location_t, tree, int, tree);
extern void finish_omp_taskyield (void);
extern bool cxx_omp_create_clause_info (tree, tree, bool, bool, bool);
extern bool cxx_omp_create_clause_info (tree, tree, bool, bool,
bool, bool);
extern tree baselink_for_fns (tree);
extern void finish_static_assert (tree, tree, location_t,
bool);

View file

@ -1341,6 +1341,15 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
}
return NULL_TREE;
}
else if (DECL_OMP_DECLARE_REDUCTION_P (olddecl))
{
gcc_assert (DECL_OMP_DECLARE_REDUCTION_P (newdecl));
error_at (DECL_SOURCE_LOCATION (newdecl),
"redeclaration of %<pragma omp declare reduction%>");
error_at (DECL_SOURCE_LOCATION (olddecl),
"previous %<pragma omp declare reduction%> declaration");
return error_mark_node;
}
else if (!types_match)
{
/* Avoid warnings redeclaring built-ins which have not been
@ -7302,6 +7311,22 @@ check_static_quals (tree decl, cp_cv_quals quals)
decl);
}
/* Helper function. Replace the temporary this parameter injected
during cp_finish_omp_declare_simd with the real this parameter. */
static tree
declare_simd_adjust_this (tree *tp, int *walk_subtrees, void *data)
{
tree this_parm = (tree) data;
if (TREE_CODE (*tp) == PARM_DECL
&& DECL_NAME (*tp) == this_identifier
&& *tp != this_parm)
*tp = this_parm;
else if (TYPE_P (*tp))
*walk_subtrees = 0;
return NULL_TREE;
}
/* CTYPE is class type, or null if non-class.
TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
or METHOD_TYPE.
@ -7620,6 +7645,33 @@ grokfndecl (tree ctype,
if (TYPE_NOTHROW_P (type) || nothrow_libfn_p (decl))
TREE_NOTHROW (decl) = 1;
if (flag_openmp)
{
/* Adjust "omp declare simd" attributes. */
tree ods = lookup_attribute ("omp declare simd", *attrlist);
if (ods)
{
tree attr;
for (attr = ods; attr;
attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr)))
{
if (TREE_CODE (type) == METHOD_TYPE)
walk_tree (&TREE_VALUE (attr), declare_simd_adjust_this,
DECL_ARGUMENTS (decl), NULL);
if (TREE_VALUE (attr) != NULL_TREE)
{
tree cl = TREE_VALUE (TREE_VALUE (attr));
cl = c_omp_declare_simd_clauses_to_numbers
(DECL_ARGUMENTS (decl), cl);
if (cl)
TREE_VALUE (TREE_VALUE (attr)) = cl;
else
TREE_VALUE (attr) = NULL_TREE;
}
}
}
}
/* Caller will do the rest of this. */
if (check < 0)
return decl;

View file

@ -101,7 +101,6 @@ static GTY(()) vec<tree, va_gc> *no_linkage_decls;
/* Nonzero if we're done parsing and into end-of-file activities. */
int at_eof;
/* Return a member function type (a METHOD_TYPE), given FNTYPE (a
@ -1135,6 +1134,11 @@ is_late_template_attribute (tree attr, tree decl)
if (is_attribute_p ("unused", name))
return false;
/* #pragma omp declare simd attribute needs to be always deferred. */
if (flag_openmp
&& is_attribute_p ("omp declare simd", name))
return true;
/* If any of the arguments are dependent expressions, we can't evaluate
the attribute until instantiation time. */
for (arg = args; arg; arg = TREE_CHAIN (arg))
@ -1336,6 +1340,34 @@ cp_check_const_attributes (tree attributes)
}
}
/* Return true if TYPE is an OpenMP mappable type. */
bool
cp_omp_mappable_type (tree type)
{
/* Mappable type has to be complete. */
if (type == error_mark_node || !COMPLETE_TYPE_P (type))
return false;
/* Arrays have mappable type if the elements have mappable type. */
while (TREE_CODE (type) == ARRAY_TYPE)
type = TREE_TYPE (type);
/* A mappable type cannot contain virtual members. */
if (CLASS_TYPE_P (type) && CLASSTYPE_VTABLES (type))
return false;
/* All data members must be non-static. */
if (CLASS_TYPE_P (type))
{
tree field;
for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
if (TREE_CODE (field) == VAR_DECL)
return false;
/* All fields must have mappable types. */
else if (TREE_CODE (field) == FIELD_DECL
&& !cp_omp_mappable_type (TREE_TYPE (field)))
return false;
}
return true;
}
/* Like decl_attributes, but handle C++ complexity. */
void
@ -1345,6 +1377,30 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
|| *decl == error_mark_node)
return;
/* Add implicit "omp declare target" attribute if requested. */
if (scope_chain->omp_declare_target_attribute
&& ((TREE_CODE (*decl) == VAR_DECL && TREE_STATIC (*decl))
|| TREE_CODE (*decl) == FUNCTION_DECL))
{
if (TREE_CODE (*decl) == VAR_DECL
&& DECL_CLASS_SCOPE_P (*decl))
error ("%q+D static data member inside of declare target directive",
*decl);
else if (TREE_CODE (*decl) == VAR_DECL
&& (DECL_FUNCTION_SCOPE_P (*decl)
|| (current_function_decl && !DECL_EXTERNAL (*decl))))
error ("%q+D in block scope inside of declare target directive",
*decl);
else if (!processing_template_decl
&& TREE_CODE (*decl) == VAR_DECL
&& !cp_omp_mappable_type (TREE_TYPE (*decl)))
error ("%q+D in declare target directive does not have mappable type",
*decl);
else
attributes = tree_cons (get_identifier ("omp declare target"),
NULL_TREE, attributes);
}
if (processing_template_decl)
{
if (check_for_bare_parameter_packs (attributes))
@ -4623,13 +4679,16 @@ mark_used (tree decl, tsubst_flags_t complain)
or a constexpr function, we need it right now because a reference to
such a data member or a call to such function is not value-dependent.
For a function that uses auto in the return type, we need to instantiate
it to find out its type. */
if ((decl_maybe_constant_var_p (decl)
|| (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_CONSTEXPR_P (decl))
|| undeduced_auto_decl (decl))
&& DECL_LANG_SPECIFIC (decl)
it to find out its type. For OpenMP user defined reductions, we need
them instantiated for reduction clauses which inline them by hand
directly. */
if (DECL_LANG_SPECIFIC (decl)
&& DECL_TEMPLATE_INFO (decl)
&& (decl_maybe_constant_var_p (decl)
|| (TREE_CODE (decl) == FUNCTION_DECL
&& (DECL_DECLARED_CONSTEXPR_P (decl)
|| DECL_OMP_DECLARE_REDUCTION_P (decl)))
|| undeduced_auto_decl (decl))
&& !uses_template_parms (DECL_TI_ARGS (decl)))
{
/* Instantiating a function will result in garbage collection. We

File diff suppressed because it is too large Load diff

View file

@ -196,6 +196,14 @@ typedef struct GTY (()) cp_parser_context {
} cp_parser_context;
/* Control structure for #pragma omp declare simd parsing. */
struct cp_omp_declare_simd_data {
bool error_seen; /* Set if error has been reported. */
bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
vec<cp_token_cache_ptr> tokens;
};
/* The cp_parser structure represents the C++ parser. */
typedef struct GTY(()) cp_parser {
@ -324,6 +332,12 @@ typedef struct GTY(()) cp_parser {
/* TRUE if we can auto-correct a colon to a scope operator. */
bool colon_corrects_to_scope_p;
/* TRUE if : doesn't start a class definition. Should be only used
together with type_definition_forbidden_message non-NULL, in
contexts where new types may not be defined, and the type list
is terminated by colon. */
bool colon_doesnt_start_class_def_p;
/* If non-NULL, then we are parsing a construct where new type
definitions are not permitted. The string stored here will be
issued as an error message if a type is defined. */
@ -342,6 +356,10 @@ typedef struct GTY(()) cp_parser {
current declaration. */
unsigned num_template_parameter_lists;
/* When parsing #pragma omp declare simd, this is a pointer to a
data structure with everything needed for parsing the clauses. */
cp_omp_declare_simd_data * GTY((skip)) omp_declare_simd;
/* TRUE if the function being declared was made a template due to its
parameter list containing generic type specifiers (`auto' or concept
identifiers) rather than an explicit template parameter list. */

View file

@ -8545,6 +8545,8 @@ can_complete_type_without_circularity (tree type)
return 1;
}
static tree tsubst_omp_clauses (tree, bool, tree, tsubst_flags_t, tree);
/* Apply any attributes which had to be deferred until instantiation
time. DECL_P, ATTRIBUTES and ATTR_FLAGS are as cplus_decl_attributes;
ARGS, COMPLAIN, IN_DECL are as tsubst. */
@ -8586,14 +8588,32 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
{
*p = TREE_CHAIN (t);
TREE_CHAIN (t) = NULL_TREE;
if (flag_openmp
&& is_attribute_p ("omp declare simd",
get_attribute_name (t))
&& TREE_VALUE (t))
{
tree clauses = TREE_VALUE (TREE_VALUE (t));
clauses = tsubst_omp_clauses (clauses, true, args,
complain, in_decl);
c_omp_declare_simd_clauses_to_decls (*decl_p, clauses);
clauses = finish_omp_clauses (clauses);
tree parms = DECL_ARGUMENTS (*decl_p);
clauses
= c_omp_declare_simd_clauses_to_numbers (parms, clauses);
if (clauses)
TREE_VALUE (TREE_VALUE (t)) = clauses;
else
TREE_VALUE (t) = NULL_TREE;
}
/* If the first attribute argument is an identifier, don't
pass it through tsubst. Attributes like mode, format,
cleanup and several target specific attributes expect it
unmodified. */
if (TREE_VALUE (t)
&& TREE_CODE (TREE_VALUE (t)) == TREE_LIST
&& TREE_VALUE (TREE_VALUE (t))
&& (identifier_p (TREE_VALUE (TREE_VALUE (t)))))
else if (TREE_VALUE (t)
&& TREE_CODE (TREE_VALUE (t)) == TREE_LIST
&& TREE_VALUE (TREE_VALUE (t))
&& identifier_p (TREE_VALUE (TREE_VALUE (t))))
{
tree chain
= tsubst_expr (TREE_CHAIN (TREE_VALUE (t)), args, complain,
@ -8915,6 +8935,9 @@ instantiate_class_template_1 (tree type)
/* Instantiate members marked with attribute used. */
if (r != error_mark_node && DECL_PRESERVE_P (r))
mark_used (r);
if (TREE_CODE (r) == FUNCTION_DECL
&& DECL_OMP_DECLARE_REDUCTION_P (r))
cp_check_omp_declare_reduction (r);
}
else
{
@ -10383,6 +10406,24 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
DECL_INITIAL (r) = NULL_TREE;
DECL_CONTEXT (r) = ctx;
/* OpenMP UDRs have the only argument a reference to the declared
type. We want to diagnose if the declared type is a reference,
which is invalid, but as references to references are usually
quietly merged, diagnose it here. */
if (DECL_OMP_DECLARE_REDUCTION_P (t))
{
tree argtype
= TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (t))));
argtype = tsubst (argtype, args, complain, in_decl);
if (TREE_CODE (argtype) == REFERENCE_TYPE)
error_at (DECL_SOURCE_LOCATION (t),
"reference type %qT in "
"%<#pragma omp declare reduction%>", argtype);
if (strchr (IDENTIFIER_POINTER (DECL_NAME (t)), '~') == NULL)
DECL_NAME (r) = omp_reduction_id (ERROR_MARK, DECL_NAME (t),
argtype);
}
if (member && DECL_CONV_FN_P (r))
/* Type-conversion operator. Reconstruct the name, in
case it's the name of one of the template's parameters. */
@ -12815,8 +12856,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
/* Like tsubst_copy, but specifically for OpenMP clauses. */
static tree
tsubst_omp_clauses (tree clauses, tree args, tsubst_flags_t complain,
tree in_decl)
tsubst_omp_clauses (tree clauses, bool declare_simd,
tree args, tsubst_flags_t complain, tree in_decl)
{
tree new_clauses = NULL, nc, oc;
@ -12841,7 +12882,6 @@ tsubst_omp_clauses (tree clauses, tree args, tsubst_flags_t complain,
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_SHARED:
case OMP_CLAUSE_FIRSTPRIVATE:
case OMP_CLAUSE_REDUCTION:
case OMP_CLAUSE_COPYIN:
case OMP_CLAUSE_COPYPRIVATE:
case OMP_CLAUSE_IF:
@ -12849,22 +12889,73 @@ tsubst_omp_clauses (tree clauses, tree args, tsubst_flags_t complain,
case OMP_CLAUSE_SCHEDULE:
case OMP_CLAUSE_COLLAPSE:
case OMP_CLAUSE_FINAL:
case OMP_CLAUSE_DEPEND:
case OMP_CLAUSE_FROM:
case OMP_CLAUSE_TO:
case OMP_CLAUSE_UNIFORM:
case OMP_CLAUSE_MAP:
case OMP_CLAUSE_DEVICE:
case OMP_CLAUSE_DIST_SCHEDULE:
case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_THREAD_LIMIT:
case OMP_CLAUSE_SAFELEN:
case OMP_CLAUSE_SIMDLEN:
OMP_CLAUSE_OPERAND (nc, 0)
= tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain,
in_decl, /*integral_constant_expression_p=*/false);
break;
case OMP_CLAUSE_REDUCTION:
if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (oc))
{
tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (oc);
if (TREE_CODE (placeholder) == SCOPE_REF)
{
tree scope = tsubst (TREE_OPERAND (placeholder, 0), args,
complain, in_decl);
OMP_CLAUSE_REDUCTION_PLACEHOLDER (nc)
= build_qualified_name (NULL_TREE, scope,
TREE_OPERAND (placeholder, 1),
false);
}
else
gcc_assert (identifier_p (placeholder));
}
OMP_CLAUSE_OPERAND (nc, 0)
= tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain,
in_decl, /*integral_constant_expression_p=*/false);
break;
case OMP_CLAUSE_LINEAR:
case OMP_CLAUSE_ALIGNED:
OMP_CLAUSE_OPERAND (nc, 0)
= tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain,
in_decl, /*integral_constant_expression_p=*/false);
OMP_CLAUSE_OPERAND (nc, 1)
= tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain,
in_decl, /*integral_constant_expression_p=*/false);
break;
case OMP_CLAUSE_NOWAIT:
case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_DEFAULT:
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_MERGEABLE:
case OMP_CLAUSE_INBRANCH:
case OMP_CLAUSE_NOTINBRANCH:
case OMP_CLAUSE_PROC_BIND:
case OMP_CLAUSE_FOR:
case OMP_CLAUSE_PARALLEL:
case OMP_CLAUSE_SECTIONS:
case OMP_CLAUSE_TASKGROUP:
break;
default:
gcc_unreachable ();
}
}
return finish_omp_clauses (nreverse (new_clauses));
new_clauses = nreverse (new_clauses);
if (!declare_simd)
new_clauses = finish_omp_clauses (new_clauses);
return new_clauses;
}
/* Like tsubst_copy_and_build, but unshare TREE_LIST nodes. */
@ -13169,6 +13260,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
}
else if (DECL_IMPLICIT_TYPEDEF_P (t))
/* We already did a pushtag. */;
else if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_OMP_DECLARE_REDUCTION_P (decl)
&& DECL_FUNCTION_SCOPE_P (pattern_decl))
{
DECL_CONTEXT (decl) = NULL_TREE;
pushdecl (decl);
DECL_CONTEXT (decl) = current_function_decl;
cp_check_omp_declare_reduction (decl);
}
else
{
int const_init = false;
@ -13440,7 +13540,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
break;
case OMP_PARALLEL:
tmp = tsubst_omp_clauses (OMP_PARALLEL_CLAUSES (t),
tmp = tsubst_omp_clauses (OMP_PARALLEL_CLAUSES (t), false,
args, complain, in_decl);
stmt = begin_omp_parallel ();
RECUR (OMP_PARALLEL_BODY (t));
@ -13449,7 +13549,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
break;
case OMP_TASK:
tmp = tsubst_omp_clauses (OMP_TASK_CLAUSES (t),
tmp = tsubst_omp_clauses (OMP_TASK_CLAUSES (t), false,
args, complain, in_decl);
stmt = begin_omp_task ();
RECUR (OMP_TASK_BODY (t));
@ -13457,17 +13557,23 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
break;
case OMP_FOR:
case OMP_SIMD:
case OMP_DISTRIBUTE:
{
tree clauses, body, pre_body;
tree declv, initv, condv, incrv;
tree declv = NULL_TREE, initv = NULL_TREE, condv = NULL_TREE;
tree incrv = NULL_TREE;
int i;
clauses = tsubst_omp_clauses (OMP_FOR_CLAUSES (t),
clauses = tsubst_omp_clauses (OMP_FOR_CLAUSES (t), false,
args, complain, in_decl);
declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
initv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
condv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
incrv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
if (OMP_FOR_INIT (t) != NULL_TREE)
{
declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
initv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
condv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
incrv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
}
stmt = begin_omp_structured_block ();
@ -13475,17 +13581,29 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
RECUR (OMP_FOR_PRE_BODY (t));
pre_body = pop_stmt_list (pre_body);
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (t)); i++)
tsubst_omp_for_iterator (t, i, declv, initv, condv, incrv,
&clauses, args, complain, in_decl,
integral_constant_expression_p);
if (OMP_FOR_INIT (t) != NULL_TREE)
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (t)); i++)
tsubst_omp_for_iterator (t, i, declv, initv, condv, incrv,
&clauses, args, complain, in_decl,
integral_constant_expression_p);
body = push_stmt_list ();
RECUR (OMP_FOR_BODY (t));
body = pop_stmt_list (body);
t = finish_omp_for (EXPR_LOCATION (t), declv, initv, condv, incrv,
body, pre_body, clauses);
if (OMP_FOR_INIT (t) != NULL_TREE)
t = finish_omp_for (EXPR_LOCATION (t), TREE_CODE (t), declv, initv,
condv, incrv, body, pre_body, clauses);
else
{
t = make_node (TREE_CODE (t));
TREE_TYPE (t) = void_type_node;
OMP_FOR_BODY (t) = body;
OMP_FOR_PRE_BODY (t) = pre_body;
OMP_FOR_CLAUSES (t) = clauses;
SET_EXPR_LOCATION (t, EXPR_LOCATION (t));
add_stmt (t);
}
add_stmt (finish_omp_structured_block (stmt));
}
@ -13493,7 +13611,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OMP_SECTIONS:
case OMP_SINGLE:
tmp = tsubst_omp_clauses (OMP_CLAUSES (t), args, complain, in_decl);
case OMP_TEAMS:
case OMP_TARGET_DATA:
case OMP_TARGET:
tmp = tsubst_omp_clauses (OMP_CLAUSES (t), false,
args, complain, in_decl);
stmt = push_stmt_list ();
RECUR (OMP_BODY (t));
stmt = pop_stmt_list (stmt);
@ -13504,9 +13626,18 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
add_stmt (t);
break;
case OMP_TARGET_UPDATE:
tmp = tsubst_omp_clauses (OMP_TARGET_UPDATE_CLAUSES (t), false,
args, complain, in_decl);
t = copy_node (t);
OMP_CLAUSES (t) = tmp;
add_stmt (t);
break;
case OMP_SECTION:
case OMP_CRITICAL:
case OMP_MASTER:
case OMP_TASKGROUP:
case OMP_ORDERED:
stmt = push_stmt_list ();
RECUR (OMP_BODY (t));
@ -13532,7 +13663,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
lhs = RECUR (TREE_OPERAND (op1, 0));
rhs = RECUR (TREE_OPERAND (op1, 1));
finish_omp_atomic (OMP_ATOMIC, TREE_CODE (op1), lhs, rhs,
NULL_TREE, NULL_TREE, rhs1);
NULL_TREE, NULL_TREE, rhs1,
OMP_ATOMIC_SEQ_CST (t));
}
else
{
@ -13560,6 +13692,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
lhs = RECUR (TREE_OPERAND (op11, 0));
rhs = RECUR (TREE_OPERAND (op11, 1));
opcode = TREE_CODE (op11);
if (opcode == MODIFY_EXPR)
opcode = NOP_EXPR;
}
else
{
@ -13567,7 +13701,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
lhs = RECUR (TREE_OPERAND (op1, 0));
rhs = RECUR (TREE_OPERAND (op1, 1));
}
finish_omp_atomic (code, opcode, lhs, rhs, v, lhs1, rhs1);
finish_omp_atomic (code, opcode, lhs, rhs, v, lhs1, rhs1,
OMP_ATOMIC_SEQ_CST (t));
}
break;
@ -13639,6 +13774,73 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
#undef RETURN
}
/* Instantiate the special body of the artificial DECL_OMP_DECLARE_REDUCTION
function. For description of the body see comment above
cp_parser_omp_declare_reduction_exprs. */
static void
tsubst_omp_udr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
if (t == NULL_TREE || t == error_mark_node)
return;
gcc_assert (TREE_CODE (t) == STATEMENT_LIST);
tree_stmt_iterator tsi;
int i;
tree stmts[7];
memset (stmts, 0, sizeof stmts);
for (i = 0, tsi = tsi_start (t);
i < 7 && !tsi_end_p (tsi);
i++, tsi_next (&tsi))
stmts[i] = tsi_stmt (tsi);
gcc_assert (tsi_end_p (tsi));
if (i >= 3)
{
gcc_assert (TREE_CODE (stmts[0]) == DECL_EXPR
&& TREE_CODE (stmts[1]) == DECL_EXPR);
tree omp_out = tsubst (DECL_EXPR_DECL (stmts[0]),
args, complain, in_decl);
tree omp_in = tsubst (DECL_EXPR_DECL (stmts[1]),
args, complain, in_decl);
DECL_CONTEXT (omp_out) = current_function_decl;
DECL_CONTEXT (omp_in) = current_function_decl;
keep_next_level (true);
tree block = begin_omp_structured_block ();
tsubst_expr (stmts[2], args, complain, in_decl, false);
block = finish_omp_structured_block (block);
block = maybe_cleanup_point_expr_void (block);
add_decl_expr (omp_out);
if (TREE_NO_WARNING (DECL_EXPR_DECL (stmts[0])))
TREE_NO_WARNING (omp_out) = 1;
add_decl_expr (omp_in);
finish_expr_stmt (block);
}
if (i >= 6)
{
gcc_assert (TREE_CODE (stmts[3]) == DECL_EXPR
&& TREE_CODE (stmts[4]) == DECL_EXPR);
tree omp_priv = tsubst (DECL_EXPR_DECL (stmts[3]),
args, complain, in_decl);
tree omp_orig = tsubst (DECL_EXPR_DECL (stmts[4]),
args, complain, in_decl);
DECL_CONTEXT (omp_priv) = current_function_decl;
DECL_CONTEXT (omp_orig) = current_function_decl;
keep_next_level (true);
tree block = begin_omp_structured_block ();
tsubst_expr (stmts[5], args, complain, in_decl, false);
block = finish_omp_structured_block (block);
block = maybe_cleanup_point_expr_void (block);
cp_walk_tree (&block, cp_remove_omp_priv_cleanup_stmt, omp_priv, NULL);
add_decl_expr (omp_priv);
add_decl_expr (omp_orig);
finish_expr_stmt (block);
if (i == 7)
add_decl_expr (omp_orig);
}
}
/* T is a postfix-expression that is not being used in a function
call. Return the substituted version of T. */
@ -19340,6 +19542,7 @@ instantiate_decl (tree d, int defer_ok,
tree subst_decl;
tree tmpl_parm;
tree spec_parm;
tree block = NULL_TREE;
/* Save away the current list, in case we are instantiating one
template from within the body of another. */
@ -19349,7 +19552,11 @@ instantiate_decl (tree d, int defer_ok,
local_specializations = pointer_map_create ();
/* Set up context. */
start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED);
if (DECL_OMP_DECLARE_REDUCTION_P (code_pattern)
&& TREE_CODE (DECL_CONTEXT (code_pattern)) == FUNCTION_DECL)
block = push_stmt_list ();
else
start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED);
/* Some typedefs referenced from within the template code need to be
access checked at template instantiation time, i.e now. These
@ -19386,21 +19593,37 @@ instantiate_decl (tree d, int defer_ok,
gcc_assert (!spec_parm);
/* Substitute into the body of the function. */
tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
tf_warning_or_error, tmpl,
/*integral_constant_expression_p=*/false);
if (DECL_OMP_DECLARE_REDUCTION_P (code_pattern))
tsubst_omp_udr (DECL_SAVED_TREE (code_pattern), args,
tf_warning_or_error, tmpl);
else
{
tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
tf_warning_or_error, tmpl,
/*integral_constant_expression_p=*/false);
/* Set the current input_location to the end of the function
so that finish_function knows where we are. */
input_location = DECL_STRUCT_FUNCTION (code_pattern)->function_end_locus;
/* Set the current input_location to the end of the function
so that finish_function knows where we are. */
input_location
= DECL_STRUCT_FUNCTION (code_pattern)->function_end_locus;
}
/* We don't need the local specializations any more. */
pointer_map_destroy (local_specializations);
local_specializations = saved_local_specializations;
/* Finish the function. */
d = finish_function (0);
expand_or_defer_fn (d);
if (DECL_OMP_DECLARE_REDUCTION_P (code_pattern)
&& TREE_CODE (DECL_CONTEXT (code_pattern)) == FUNCTION_DECL)
DECL_SAVED_TREE (d) = pop_stmt_list (block);
else
{
d = finish_function (0);
expand_or_defer_fn (d);
}
if (DECL_OMP_DECLARE_REDUCTION_P (code_pattern))
cp_check_omp_declare_reduction (d);
}
/* We're not deferring instantiation any more. */

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,21 @@
2013-10-11 Jakub Jelinek <jakub@redhat.com>
* trans-openmp.c (gfc_omp_clause_default_ctor,
gfc_omp_clause_dtor): Return NULL for OMP_CLAUSE_REDUCTION.
* f95-lang.c (ATTR_NULL, DEF_FUNCTION_TYPE_8): Define.
* types.def (DEF_FUNCTION_TYPE_8): Document.
(BT_FN_VOID_OMPFN_PTR_UINT,
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT): Remove.
(BT_FN_VOID_OMPFN_PTR_UINT_UINT_UINT,
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_UINT,
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG_UINT,
BT_FN_BOOL_INT, BT_FN_BOOL_INT_BOOL, BT_FN_VOID_UINT_UINT,
BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR,
BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR,
BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR): New.
2013-10-10 Tobias Burnus <burnus@net-b.de>
PR fortran/58226

View file

@ -531,7 +531,8 @@ gfc_builtin_function (tree decl)
return decl;
}
/* So far we need just these 4 attribute types. */
/* So far we need just these 6 attribute types. */
#define ATTR_NULL 0
#define ATTR_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF)
#define ATTR_NOTHROW_LEAF_MALLOC_LIST (ECF_NOTHROW | ECF_LEAF | ECF_MALLOC)
#define ATTR_CONST_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF | ECF_CONST)
@ -618,6 +619,7 @@ gfc_init_builtin_functions (void)
#define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
#define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) NAME,
#define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) NAME,
#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_POINTER_TYPE(NAME, TYPE) NAME,
#include "types.def"
@ -630,6 +632,7 @@ gfc_init_builtin_functions (void)
#undef DEF_FUNCTION_TYPE_5
#undef DEF_FUNCTION_TYPE_6
#undef DEF_FUNCTION_TYPE_7
#undef DEF_FUNCTION_TYPE_8
#undef DEF_FUNCTION_TYPE_VAR_0
#undef DEF_POINTER_TYPE
BT_LAST
@ -992,6 +995,19 @@ gfc_init_builtin_functions (void)
builtin_types[(int) ARG6], \
builtin_types[(int) ARG7], \
NULL_TREE);
#define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) \
builtin_types[(int) ENUM] \
= build_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_0(ENUM, RETURN) \
builtin_types[(int) ENUM] \
= build_varargs_function_type_list (builtin_types[(int) RETURN], \

View file

@ -159,6 +159,9 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
|| GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
return NULL;
if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION)
return NULL;
gcc_assert (outer != NULL);
gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_PRIVATE
|| OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LASTPRIVATE);
@ -323,6 +326,9 @@ gfc_omp_clause_dtor (tree clause ATTRIBUTE_UNUSED, tree decl)
|| GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
return NULL;
if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION)
return NULL;
/* Allocatable arrays in FIRSTPRIVATE/LASTPRIVATE etc. clauses need
to be deallocated if they were allocated. */
return gfc_trans_dealloc_allocated (decl, false, NULL);

View file

@ -34,6 +34,8 @@ along with GCC; see the file COPYING3. If not see
DEF_FUNCTION_TYPE_5 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)
DEF_FUNCTION_TYPE_6 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6)
DEF_FUNCTION_TYPE_7 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7)
DEF_FUNCTION_TYPE_8 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7,
ARG8)
These macros describe function types. ENUM is as above. The
RETURN type is one of the enumerals already defined. ARG1, ARG2,
@ -89,7 +91,7 @@ DEF_FUNCTION_TYPE_1 (BT_FN_VOID_VPTR, BT_VOID, BT_VOLATILE_PTR)
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)
DEF_FUNCTION_TYPE_1 (BT_FN_BOOL_INT, BT_BOOL, BT_INT)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR, BT_FN_VOID_PTR)
@ -117,7 +119,8 @@ DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VPTR_INT, BT_VOID, BT_VOLATILE_PTR, BT_INT)
DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_VPTR_INT, BT_BOOL, BT_VOLATILE_PTR, BT_INT)
DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_SIZE_CONST_VPTR, BT_BOOL, BT_SIZE,
BT_CONST_VOLATILE_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_INT_BOOL, BT_BOOL, BT_INT, BT_BOOL)
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT_UINT, BT_VOID, BT_UINT, BT_UINT)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
@ -137,8 +140,6 @@ DEF_FUNCTION_TYPE_3 (BT_FN_I4_VPTR_I4_I4, BT_I4, BT_VOLATILE_PTR, BT_I4, BT_I4)
DEF_FUNCTION_TYPE_3 (BT_FN_I8_VPTR_I8_I8, BT_I8, BT_VOLATILE_PTR, BT_I8, BT_I8)
DEF_FUNCTION_TYPE_3 (BT_FN_I16_VPTR_I16_I16, BT_I16, BT_VOLATILE_PTR,
BT_I16, BT_I16)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_OMPFN_PTR_UINT, BT_VOID, BT_PTR_FN_VOID_PTR,
BT_PTR, BT_UINT)
DEF_FUNCTION_TYPE_3 (BT_FN_I1_VPTR_I1_INT, BT_I1, BT_VOLATILE_PTR, BT_I1, BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_I2_VPTR_I2_INT, BT_I2, BT_VOLATILE_PTR, BT_I2, BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_I4_VPTR_I4_INT, BT_I4, BT_VOLATILE_PTR, BT_I4, BT_INT)
@ -159,6 +160,9 @@ DEF_FUNCTION_TYPE_4 (BT_FN_VOID_SIZE_VPTR_PTR_INT, BT_VOID, BT_SIZE,
DEF_FUNCTION_TYPE_4 (BT_FN_VOID_SIZE_CONST_VPTR_PTR_INT, BT_VOID, BT_SIZE,
BT_CONST_VOLATILE_PTR, BT_PTR, BT_INT)
DEF_FUNCTION_TYPE_5 (BT_FN_VOID_OMPFN_PTR_UINT_UINT_UINT,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT, BT_UINT,
BT_UINT)
DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_LONG_LONG_LONG_LONGPTR_LONGPTR,
BT_BOOL, BT_LONG, BT_LONG, BT_LONG,
BT_PTR_LONG, BT_PTR_LONG)
@ -168,9 +172,6 @@ DEF_FUNCTION_TYPE_5 (BT_FN_VOID_SIZE_VPTR_PTR_PTR_INT, BT_VOID, BT_SIZE,
DEF_FUNCTION_TYPE_6 (BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
BT_BOOL, BT_LONG, BT_LONG, BT_LONG, BT_LONG,
BT_PTR_LONG, BT_PTR_LONG)
DEF_FUNCTION_TYPE_6 (BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT,
BT_LONG, BT_LONG, BT_LONG)
DEF_FUNCTION_TYPE_6 (BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULLPTR_ULLPTR,
BT_BOOL, BT_BOOL, BT_ULONGLONG, BT_ULONGLONG,
BT_ULONGLONG, BT_PTR_ULONGLONG, BT_PTR_ULONGLONG)
@ -191,17 +192,26 @@ DEF_FUNCTION_TYPE_6 (BT_FN_BOOL_VPTR_PTR_I16_BOOL_INT_INT,
BT_INT)
DEF_FUNCTION_TYPE_6 (BT_FN_BOOL_SIZE_VPTR_PTR_PTR_INT_INT, BT_BOOL, BT_SIZE,
BT_VOLATILE_PTR, BT_PTR, BT_PTR, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_6 (BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR,
BT_VOID, BT_INT, BT_PTR, BT_SIZE, BT_PTR, BT_PTR, BT_PTR)
DEF_FUNCTION_TYPE_7 (BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
DEF_FUNCTION_TYPE_7 (BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_UINT,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT,
BT_LONG, BT_LONG, BT_LONG, BT_LONG)
DEF_FUNCTION_TYPE_7 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR,
BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
BT_BOOL, BT_UINT)
BT_LONG, BT_LONG, BT_LONG, BT_UINT)
DEF_FUNCTION_TYPE_7 (BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULL_ULLPTR_ULLPTR,
BT_BOOL, BT_BOOL, BT_ULONGLONG, BT_ULONGLONG,
BT_ULONGLONG, BT_ULONGLONG,
BT_PTR_ULONGLONG, BT_PTR_ULONGLONG)
DEF_FUNCTION_TYPE_7 (BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR,
BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_PTR, BT_SIZE,
BT_PTR, BT_PTR, BT_PTR)
DEF_FUNCTION_TYPE_8 (BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG_UINT,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT,
BT_LONG, BT_LONG, BT_LONG, BT_LONG, BT_UINT)
DEF_FUNCTION_TYPE_8 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR,
BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
BT_BOOL, BT_UINT, BT_PTR)
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)

View file

@ -425,6 +425,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_SINGLE:
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
case GIMPLE_OMP_RETURN:
@ -466,6 +467,8 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
case GIMPLE_OMP_PARALLEL:
case GIMPLE_OMP_TASK:
case GIMPLE_OMP_TARGET:
case GIMPLE_OMP_TEAMS:
data->cannot_fallthru = false;
lower_omp_directive (gsi, data);
data->cannot_fallthru = false;

View file

@ -1097,6 +1097,9 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
case GF_OMP_FOR_KIND_SIMD:
kind = " simd";
break;
case GF_OMP_FOR_KIND_DISTRIBUTE:
kind = " distribute";
break;
default:
gcc_unreachable ();
}
@ -1125,6 +1128,9 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
case GF_OMP_FOR_KIND_SIMD:
pp_string (buffer, "#pragma omp simd");
break;
case GF_OMP_FOR_KIND_DISTRIBUTE:
pp_string (buffer, "#pragma omp distribute");
break;
default:
gcc_unreachable ();
}
@ -1239,6 +1245,85 @@ dump_gimple_omp_single (pretty_printer *buffer, gimple gs, int spc, int flags)
}
}
/* Dump a GIMPLE_OMP_TARGET tuple on the pretty_printer BUFFER. */
static void
dump_gimple_omp_target (pretty_printer *buffer, gimple gs, int spc, int flags)
{
const char *kind;
switch (gimple_omp_target_kind (gs))
{
case GF_OMP_TARGET_KIND_REGION:
kind = "";
break;
case GF_OMP_TARGET_KIND_DATA:
kind = " data";
break;
case GF_OMP_TARGET_KIND_UPDATE:
kind = " update";
break;
default:
gcc_unreachable ();
}
if (flags & TDF_RAW)
{
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, " >");
}
else
{
pp_string (buffer, "#pragma omp target");
pp_string (buffer, kind);
dump_omp_clauses (buffer, gimple_omp_target_clauses (gs), spc, flags);
if (gimple_omp_target_child_fn (gs))
{
pp_string (buffer, " [child fn: ");
dump_generic_node (buffer, gimple_omp_target_child_fn (gs),
spc, flags, false);
pp_right_bracket (buffer);
}
if (!gimple_seq_empty_p (gimple_omp_body (gs)))
{
newline_and_indent (buffer, spc + 2);
pp_character (buffer, '{');
pp_newline (buffer);
dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
newline_and_indent (buffer, spc + 2);
pp_character (buffer, '}');
}
}
}
/* Dump a GIMPLE_OMP_TEAMS tuple on the pretty_printer BUFFER. */
static void
dump_gimple_omp_teams (pretty_printer *buffer, gimple gs, int spc, int flags)
{
if (flags & TDF_RAW)
{
dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
gimple_omp_body (gs));
dump_omp_clauses (buffer, gimple_omp_teams_clauses (gs), spc, flags);
dump_gimple_fmt (buffer, spc, flags, " >");
}
else
{
pp_string (buffer, "#pragma omp teams");
dump_omp_clauses (buffer, gimple_omp_teams_clauses (gs), spc, flags);
if (!gimple_seq_empty_p (gimple_omp_body (gs)))
{
newline_and_indent (buffer, spc + 2);
pp_character (buffer, '{');
pp_newline (buffer);
dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
newline_and_indent (buffer, spc + 2);
pp_character (buffer, '}');
}
}
}
/* Dump a GIMPLE_OMP_SECTIONS tuple on the pretty_printer BUFFER. */
static void
@ -1275,8 +1360,8 @@ dump_gimple_omp_sections (pretty_printer *buffer, gimple gs, int spc,
}
}
/* Dump a GIMPLE_OMP_{MASTER,ORDERED,SECTION} tuple on the pretty_printer
BUFFER. */
/* Dump a GIMPLE_OMP_{MASTER,TASKGROUP,ORDERED,SECTION} tuple on the
pretty_printer BUFFER. */
static void
dump_gimple_omp_block (pretty_printer *buffer, gimple gs, int spc, int flags)
@ -1291,6 +1376,9 @@ dump_gimple_omp_block (pretty_printer *buffer, gimple gs, int spc, int flags)
case GIMPLE_OMP_MASTER:
pp_string (buffer, "#pragma omp master");
break;
case GIMPLE_OMP_TASKGROUP:
pp_string (buffer, "#pragma omp taskgroup");
break;
case GIMPLE_OMP_ORDERED:
pp_string (buffer, "#pragma omp ordered");
break;
@ -1350,14 +1438,26 @@ dump_gimple_omp_return (pretty_printer *buffer, gimple gs, int spc, int flags)
{
if (flags & TDF_RAW)
{
dump_gimple_fmt (buffer, spc, flags, "%G <nowait=%d>", gs,
dump_gimple_fmt (buffer, spc, flags, "%G <nowait=%d", gs,
(int) gimple_omp_return_nowait_p (gs));
if (gimple_omp_return_lhs (gs))
dump_gimple_fmt (buffer, spc, flags, ", lhs=%T>",
gimple_omp_return_lhs (gs));
else
dump_gimple_fmt (buffer, spc, flags, ">");
}
else
{
pp_string (buffer, "#pragma omp return");
if (gimple_omp_return_nowait_p (gs))
pp_string (buffer, "(nowait)");
if (gimple_omp_return_lhs (gs))
{
pp_string (buffer, " (set ");
dump_generic_node (buffer, gimple_omp_return_lhs (gs),
spc, flags, false);
pp_character (buffer, ')');
}
}
}
@ -1826,6 +1926,8 @@ dump_gimple_omp_atomic_load (pretty_printer *buffer, gimple gs, int spc,
else
{
pp_string (buffer, "#pragma omp atomic_load");
if (gimple_omp_atomic_seq_cst_p (gs))
pp_string (buffer, " seq_cst");
if (gimple_omp_atomic_need_value_p (gs))
pp_string (buffer, " [needed]");
newline_and_indent (buffer, spc + 2);
@ -1856,6 +1958,8 @@ dump_gimple_omp_atomic_store (pretty_printer *buffer, gimple gs, int spc,
else
{
pp_string (buffer, "#pragma omp atomic_store ");
if (gimple_omp_atomic_seq_cst_p (gs))
pp_string (buffer, "seq_cst ");
if (gimple_omp_atomic_need_value_p (gs))
pp_string (buffer, "[needed] ");
pp_left_paren (buffer);
@ -2023,6 +2127,14 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
dump_gimple_omp_single (buffer, gs, spc, flags);
break;
case GIMPLE_OMP_TARGET:
dump_gimple_omp_target (buffer, gs, spc, flags);
break;
case GIMPLE_OMP_TEAMS:
dump_gimple_omp_teams (buffer, gs, spc, flags);
break;
case GIMPLE_OMP_RETURN:
dump_gimple_omp_return (buffer, gs, spc, flags);
break;
@ -2036,6 +2148,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
break;
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_SECTION:
dump_gimple_omp_block (buffer, gs, spc, flags);

View file

@ -1007,6 +1007,22 @@ gimple_build_omp_master (gimple_seq body)
}
/* Build a GIMPLE_OMP_TASKGROUP statement.
BODY is the sequence of statements to be executed by the taskgroup
construct. */
gimple
gimple_build_omp_taskgroup (gimple_seq body)
{
gimple p = gimple_alloc (GIMPLE_OMP_TASKGROUP, 0);
if (body)
gimple_omp_set_body (p, body);
return p;
}
/* Build a GIMPLE_OMP_CONTINUE statement.
CONTROL_DEF is the definition of the control variable.
@ -1096,6 +1112,41 @@ 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. */
gimple
gimple_build_omp_target (gimple_seq body, int kind, tree clauses)
{
gimple p = gimple_alloc (GIMPLE_OMP_TARGET, 0);
if (body)
gimple_omp_set_body (p, body);
gimple_omp_target_set_clauses (p, clauses);
gimple_omp_target_set_kind (p, kind);
return p;
}
/* Build a GIMPLE_OMP_TEAMS statement.
BODY is the sequence of statements that will be executed.
CLAUSES are any of the OMP teams construct's clauses. */
gimple
gimple_build_omp_teams (gimple_seq body, tree clauses)
{
gimple p = gimple_alloc (GIMPLE_OMP_TEAMS, 0);
if (body)
gimple_omp_set_body (p, body);
gimple_omp_teams_set_clauses (p, clauses);
return p;
}
/* Build a GIMPLE_OMP_ATOMIC_LOAD statement. */
gimple
@ -1612,6 +1663,20 @@ walk_gimple_op (gimple stmt, walk_tree_fn callback_op,
return ret;
break;
case GIMPLE_OMP_TARGET:
ret = walk_tree (gimple_omp_target_clauses_ptr (stmt), callback_op, wi,
pset);
if (ret)
return ret;
break;
case GIMPLE_OMP_TEAMS:
ret = walk_tree (gimple_omp_teams_clauses_ptr (stmt), callback_op, wi,
pset);
if (ret)
return ret;
break;
case GIMPLE_OMP_ATOMIC_LOAD:
ret = walk_tree (gimple_omp_atomic_load_lhs_ptr (stmt), callback_op, wi,
pset);
@ -1638,10 +1703,16 @@ walk_gimple_op (gimple stmt, walk_tree_fn callback_op,
return ret;
break;
case GIMPLE_OMP_RETURN:
ret = walk_tree (gimple_omp_return_lhs_ptr (stmt), callback_op, wi,
pset);
if (ret)
return ret;
break;
/* Tuples that do not have operands. */
case GIMPLE_NOP:
case GIMPLE_RESX:
case GIMPLE_OMP_RETURN:
case GIMPLE_PREDICT:
break;
@ -1782,12 +1853,15 @@ walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt,
/* FALL THROUGH. */
case GIMPLE_OMP_CRITICAL:
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_PARALLEL:
case GIMPLE_OMP_TASK:
case GIMPLE_OMP_SECTIONS:
case GIMPLE_OMP_SINGLE:
case GIMPLE_OMP_TARGET:
case GIMPLE_OMP_TEAMS:
ret = walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), callback_stmt,
callback_op, wi);
if (ret)
@ -2277,8 +2351,11 @@ gimple_copy (gimple stmt)
/* FALLTHRU */
case GIMPLE_OMP_SINGLE:
case GIMPLE_OMP_TARGET:
case GIMPLE_OMP_TEAMS:
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
copy_omp_body:
new_seq = gimple_seq_copy (gimple_omp_body (stmt));

View file

@ -276,6 +276,10 @@ DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", GSS_OMP_FOR)
BODY is the sequence of statements to execute in the master section. */
DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", GSS_OMP)
/* GIMPLE_OMP_TASKGROUP <BODY> represents #pragma omp taskgroup.
BODY is the sequence of statements to execute in the taskgroup section. */
DEFGSCODE(GIMPLE_OMP_TASKGROUP, "gimple_omp_taskgroup", GSS_OMP)
/* GIMPLE_OMP_ORDERED <BODY> represents #pragma omp ordered.
BODY is the sequence of statements to execute in the ordered section. */
DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP)
@ -325,7 +329,7 @@ DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL)
DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK)
/* OMP_RETURN marks the end of an OpenMP directive. */
DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_BASE)
DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_OMP_ATOMIC_STORE)
/* OMP_SECTION <BODY> represents #pragma omp section.
BODY is the sequence of statements in the section body. */
@ -349,6 +353,24 @@ DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE)
CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */
DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE)
/* GIMPLE_OMP_TARGET <BODY, CLAUSES, CHILD_FN> represents
#pragma omp target {,data,update}
BODY is the sequence of statements inside the target construct
(NULL for target update).
CLAUSES is an OMP_CLAUSE chain holding the associated clauses.
CHILD_FN is set when outlining the body of the target 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
containing data to be mapped to CHILD_FN. This is used to
implement the MAP clauses. */
DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL)
/* GIMPLE_OMP_TEAMS <BODY, CLAUSES> represents #pragma omp teams
BODY is the sequence of statements inside the single section.
CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */
DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams", GSS_OMP_SINGLE)
/* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction.
PREDICT is one of the predictors from predict.def.

View file

@ -105,6 +105,13 @@ enum gf_mask {
GF_OMP_FOR_KIND_MASK = 3 << 0,
GF_OMP_FOR_KIND_FOR = 0 << 0,
GF_OMP_FOR_KIND_SIMD = 1 << 0,
GF_OMP_FOR_KIND_DISTRIBUTE = 2 << 0,
GF_OMP_FOR_COMBINED = 1 << 2,
GF_OMP_FOR_COMBINED_INTO = 1 << 3,
GF_OMP_TARGET_KIND_MASK = 3 << 0,
GF_OMP_TARGET_KIND_REGION = 0 << 0,
GF_OMP_TARGET_KIND_DATA = 1 << 0,
GF_OMP_TARGET_KIND_UPDATE = 2 << 0,
/* True on an GIMPLE_OMP_RETURN statement if the return does not require
a thread synchronization via some sort of barrier. The exact barrier
@ -114,6 +121,7 @@ enum gf_mask {
GF_OMP_SECTION_LAST = 1 << 0,
GF_OMP_ATOMIC_NEED_VALUE = 1 << 0,
GF_OMP_ATOMIC_SEQ_CST = 1 << 1,
GF_PREDICT_TAKEN = 1 << 15
};
@ -607,7 +615,7 @@ struct GTY(()) gimple_statement_omp_continue {
tree control_use;
};
/* GIMPLE_OMP_SINGLE */
/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS */
struct GTY(()) gimple_statement_omp_single {
/* [ WORD 1-7 ] */
@ -786,11 +794,14 @@ gimple gimple_build_omp_critical (gimple_seq, tree);
gimple gimple_build_omp_section (gimple_seq);
gimple gimple_build_omp_continue (tree, tree);
gimple gimple_build_omp_master (gimple_seq);
gimple gimple_build_omp_taskgroup (gimple_seq);
gimple gimple_build_omp_return (bool);
gimple gimple_build_omp_ordered (gimple_seq);
gimple gimple_build_omp_sections (gimple_seq, tree);
gimple gimple_build_omp_sections_switch (void);
gimple gimple_build_omp_single (gimple_seq, tree);
gimple gimple_build_omp_target (gimple_seq, int, tree);
gimple gimple_build_omp_teams (gimple_seq, tree);
gimple gimple_build_cdt (tree, tree);
gimple gimple_build_omp_atomic_load (tree, tree);
gimple gimple_build_omp_atomic_store (tree);
@ -1250,12 +1261,15 @@ gimple_has_substatements (gimple g)
case GIMPLE_TRY:
case GIMPLE_OMP_FOR:
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_PARALLEL:
case GIMPLE_OMP_TASK:
case GIMPLE_OMP_SECTIONS:
case GIMPLE_OMP_SINGLE:
case GIMPLE_OMP_TARGET:
case GIMPLE_OMP_TEAMS:
case GIMPLE_OMP_CRITICAL:
case GIMPLE_WITH_CLEANUP_EXPR:
case GIMPLE_TRANSACTION:
@ -1634,7 +1648,7 @@ static inline unsigned
gimple_omp_subcode (const_gimple s)
{
gcc_gimple_checking_assert (gimple_code (s) >= GIMPLE_OMP_ATOMIC_LOAD
&& gimple_code (s) <= GIMPLE_OMP_SINGLE);
&& gimple_code (s) <= GIMPLE_OMP_TEAMS);
return s->gsbase.subcode;
}
@ -1670,6 +1684,36 @@ gimple_omp_return_nowait_p (const_gimple g)
}
/* Set the LHS of OMP return. */
static inline void
gimple_omp_return_set_lhs (gimple g, tree lhs)
{
GIMPLE_CHECK (g, GIMPLE_OMP_RETURN);
g->gimple_omp_atomic_store.val = lhs;
}
/* Get the LHS of OMP return. */
static inline tree
gimple_omp_return_lhs (const_gimple g)
{
GIMPLE_CHECK (g, GIMPLE_OMP_RETURN);
return g->gimple_omp_atomic_store.val;
}
/* Return a pointer to the LHS of OMP return. */
static inline tree *
gimple_omp_return_lhs_ptr (gimple g)
{
GIMPLE_CHECK (g, GIMPLE_OMP_RETURN);
return &g->gimple_omp_atomic_store.val;
}
/* Return true if OMP section statement G has the GF_OMP_SECTION_LAST
flag set. */
@ -1739,6 +1783,29 @@ gimple_omp_atomic_set_need_value (gimple g)
}
/* Return true if OMP atomic load/store statement G has the
GF_OMP_ATOMIC_SEQ_CST flag set. */
static inline bool
gimple_omp_atomic_seq_cst_p (const_gimple g)
{
if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD)
GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE);
return (gimple_omp_subcode (g) & GF_OMP_ATOMIC_SEQ_CST) != 0;
}
/* Set the GF_OMP_ATOMIC_SEQ_CST flag on G. */
static inline void
gimple_omp_atomic_set_seq_cst (gimple g)
{
if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD)
GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE);
g->gsbase.subcode |= GF_OMP_ATOMIC_SEQ_CST;
}
/* Return the number of operands for statement GS. */
static inline unsigned
@ -4022,6 +4089,56 @@ gimple_omp_for_set_kind (gimple g, int kind)
}
/* Return true if OMP for statement G has the
GF_OMP_FOR_COMBINED flag set. */
static inline bool
gimple_omp_for_combined_p (const_gimple g)
{
GIMPLE_CHECK (g, GIMPLE_OMP_FOR);
return (gimple_omp_subcode (g) & GF_OMP_FOR_COMBINED) != 0;
}
/* Set the GF_OMP_FOR_COMBINED field in G depending on the boolean
value of COMBINED_P. */
static inline void
gimple_omp_for_set_combined_p (gimple g, bool combined_p)
{
GIMPLE_CHECK (g, GIMPLE_OMP_FOR);
if (combined_p)
g->gsbase.subcode |= GF_OMP_FOR_COMBINED;
else
g->gsbase.subcode &= ~GF_OMP_FOR_COMBINED;
}
/* Return true if OMP for statement G has the
GF_OMP_FOR_COMBINED_INTO flag set. */
static inline bool
gimple_omp_for_combined_into_p (const_gimple g)
{
GIMPLE_CHECK (g, GIMPLE_OMP_FOR);
return (gimple_omp_subcode (g) & GF_OMP_FOR_COMBINED_INTO) != 0;
}
/* Set the GF_OMP_FOR_COMBINED_INTO field in G depending on the boolean
value of COMBINED_P. */
static inline void
gimple_omp_for_set_combined_into_p (gimple g, bool combined_p)
{
GIMPLE_CHECK (g, GIMPLE_OMP_FOR);
if (combined_p)
g->gsbase.subcode |= GF_OMP_FOR_COMBINED_INTO;
else
g->gsbase.subcode &= ~GF_OMP_FOR_COMBINED_INTO;
}
/* Return the clauses associated with OMP_FOR GS. */
static inline tree
@ -4631,6 +4748,148 @@ gimple_omp_single_set_clauses (gimple gs, tree clauses)
}
/* Return the clauses associated with OMP_TARGET GS. */
static inline tree
gimple_omp_target_clauses (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET);
return gs->gimple_omp_parallel.clauses;
}
/* Return a pointer to the clauses associated with OMP_TARGET GS. */
static inline tree *
gimple_omp_target_clauses_ptr (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET);
return &gs->gimple_omp_parallel.clauses;
}
/* Set CLAUSES to be the clauses associated with OMP_TARGET GS. */
static inline void
gimple_omp_target_set_clauses (gimple gs, tree clauses)
{
GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET);
gs->gimple_omp_parallel.clauses = clauses;
}
/* Return the kind of OMP target statemement. */
static inline int
gimple_omp_target_kind (const_gimple g)
{
GIMPLE_CHECK (g, GIMPLE_OMP_TARGET);
return (gimple_omp_subcode (g) & GF_OMP_TARGET_KIND_MASK);
}
/* Set the OMP target kind. */
static inline void
gimple_omp_target_set_kind (gimple g, int kind)
{
GIMPLE_CHECK (g, GIMPLE_OMP_TARGET);
g->gsbase.subcode = (g->gsbase.subcode & ~GF_OMP_TARGET_KIND_MASK)
| (kind & GF_OMP_TARGET_KIND_MASK);
}
/* Return the child function used to hold the body of OMP_TARGET GS. */
static inline tree
gimple_omp_target_child_fn (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET);
return gs->gimple_omp_parallel.child_fn;
}
/* Return a pointer to the child function used to hold the body of
OMP_TARGET GS. */
static inline tree *
gimple_omp_target_child_fn_ptr (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET);
return &gs->gimple_omp_parallel.child_fn;
}
/* Set CHILD_FN to be the child function for OMP_TARGET GS. */
static inline void
gimple_omp_target_set_child_fn (gimple gs, tree child_fn)
{
GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET);
gs->gimple_omp_parallel.child_fn = child_fn;
}
/* Return the artificial argument used to send variables and values
from the parent to the children threads in OMP_TARGET GS. */
static inline tree
gimple_omp_target_data_arg (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET);
return gs->gimple_omp_parallel.data_arg;
}
/* Return a pointer to the data argument for OMP_TARGET GS. */
static inline tree *
gimple_omp_target_data_arg_ptr (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET);
return &gs->gimple_omp_parallel.data_arg;
}
/* Set DATA_ARG to be the data argument for OMP_TARGET GS. */
static inline void
gimple_omp_target_set_data_arg (gimple gs, tree data_arg)
{
GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET);
gs->gimple_omp_parallel.data_arg = data_arg;
}
/* Return the clauses associated with OMP_TEAMS GS. */
static inline tree
gimple_omp_teams_clauses (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_OMP_TEAMS);
return gs->gimple_omp_single.clauses;
}
/* Return a pointer to the clauses associated with OMP_TEAMS GS. */
static inline tree *
gimple_omp_teams_clauses_ptr (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_OMP_TEAMS);
return &gs->gimple_omp_single.clauses;
}
/* Set CLAUSES to be the clauses associated with OMP_TEAMS GS. */
static inline void
gimple_omp_teams_set_clauses (gimple gs, tree clauses)
{
GIMPLE_CHECK (gs, GIMPLE_OMP_TEAMS);
gs->gimple_omp_single.clauses = clauses;
}
/* Return the clauses associated with OMP_SECTIONS GS. */
static inline tree
@ -4973,8 +5232,11 @@ gimple_return_set_retval (gimple gs, tree retval)
case GIMPLE_OMP_SECTIONS: \
case GIMPLE_OMP_SECTIONS_SWITCH: \
case GIMPLE_OMP_SINGLE: \
case GIMPLE_OMP_TARGET: \
case GIMPLE_OMP_TEAMS: \
case GIMPLE_OMP_SECTION: \
case GIMPLE_OMP_MASTER: \
case GIMPLE_OMP_TASKGROUP: \
case GIMPLE_OMP_ORDERED: \
case GIMPLE_OMP_CRITICAL: \
case GIMPLE_OMP_RETURN: \

View file

@ -59,9 +59,12 @@ enum gimplify_omp_var_data
GOVD_LASTPRIVATE = 32,
GOVD_REDUCTION = 64,
GOVD_LOCAL = 128,
GOVD_DEBUG_PRIVATE = 256,
GOVD_PRIVATE_OUTER_REF = 512,
GOVD_MAP = 256,
GOVD_DEBUG_PRIVATE = 512,
GOVD_PRIVATE_OUTER_REF = 1024,
GOVD_LINEAR = 2048,
GOVD_ALIGNED = 4096,
GOVD_MAP_TO_ONLY = 8192,
GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
| GOVD_LOCAL)
@ -75,7 +78,10 @@ enum omp_region_type
ORT_PARALLEL = 2,
ORT_COMBINED_PARALLEL = 3,
ORT_TASK = 4,
ORT_UNTIED_TASK = 5
ORT_UNTIED_TASK = 5,
ORT_TEAMS = 8,
ORT_TARGET_DATA = 16,
ORT_TARGET = 32
};
struct gimplify_omp_ctx
@ -86,6 +92,7 @@ struct gimplify_omp_ctx
location_t location;
enum omp_clause_default_kind default_kind;
enum omp_region_type region_type;
bool combined_loop;
};
static struct gimplify_ctx *gimplify_ctxp;
@ -2701,7 +2708,14 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
notice_special_calls (call);
gimplify_seq_add_stmt (pre_p, call);
gsi = gsi_last (*pre_p);
fold_stmt (&gsi);
/* Don't fold stmts inside of target construct. We'll do it
during omplower pass instead. */
struct gimplify_omp_ctx *ctx;
for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
if (ctx->region_type == ORT_TARGET)
break;
if (ctx == NULL)
fold_stmt (&gsi);
*expr_p = NULL_TREE;
}
else
@ -4591,10 +4605,12 @@ is_gimple_stmt (tree t)
case OMP_PARALLEL:
case OMP_FOR:
case OMP_SIMD:
case OMP_DISTRIBUTE:
case OMP_SECTIONS:
case OMP_SECTION:
case OMP_SINGLE:
case OMP_MASTER:
case OMP_TASKGROUP:
case OMP_ORDERED:
case OMP_CRITICAL:
case OMP_TASK:
@ -4835,7 +4851,14 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
gimplify_seq_add_stmt (pre_p, assign);
gsi = gsi_last (*pre_p);
fold_stmt (&gsi);
/* Don't fold stmts inside of target construct. We'll do it
during omplower pass instead. */
struct gimplify_omp_ctx *ctx;
for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
if (ctx->region_type == ORT_TARGET)
break;
if (ctx == NULL)
fold_stmt (&gsi);
if (want_value)
{
@ -5610,11 +5633,16 @@ omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
{
if (n->value & GOVD_SHARED)
n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
else if (n->value & GOVD_MAP)
n->value |= GOVD_MAP_TO_ONLY;
else
return;
}
else if (ctx->region_type == ORT_TARGET)
omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
else if (ctx->region_type != ORT_WORKSHARE
&& ctx->region_type != ORT_SIMD)
&& ctx->region_type != ORT_SIMD
&& ctx->region_type != ORT_TARGET_DATA)
omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
ctx = ctx->outer_context;
@ -5697,7 +5725,7 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
flags |= GOVD_SEEN;
n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
if (n != NULL)
if (n != NULL && n->value != GOVD_ALIGNED)
{
/* We shouldn't be re-adding the decl with the same data
sharing class. */
@ -5723,7 +5751,9 @@ 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_PRIVATE ? GOVD_PRIVATE : GOVD_FIRSTPRIVATE;
nflags = flags & GOVD_MAP
? GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT
: flags & GOVD_PRIVATE ? GOVD_PRIVATE : GOVD_FIRSTPRIVATE;
nflags |= flags & GOVD_SEEN;
t = DECL_VALUE_EXPR (decl);
gcc_assert (TREE_CODE (t) == INDIRECT_REF);
@ -5752,13 +5782,13 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
For local variables TYPE_SIZE_UNIT might not be gimplified yet,
in this case omp_notice_variable will be called later
on when it is gimplified. */
else if (! (flags & GOVD_LOCAL)
else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
&& DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
}
else if (lang_hooks.decls.omp_privatize_by_reference (decl))
else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
&& lang_hooks.decls.omp_privatize_by_reference (decl))
{
gcc_assert ((flags & GOVD_LOCAL) == 0);
omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
/* Similar to the direct variable sized case above, we'll need the
@ -5787,6 +5817,22 @@ omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
tree decl2)
{
splay_tree_node n;
struct gimplify_omp_ctx *octx;
for (octx = ctx; octx; octx = octx->outer_context)
if (octx->region_type == ORT_TARGET)
{
n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
if (n == NULL)
{
error ("threadprivate variable %qE used in target region",
DECL_NAME (decl));
error_at (octx->location, "enclosing target region");
splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
}
if (decl2)
splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
}
if (ctx->region_type != ORT_UNTIED_TASK)
return false;
@ -5835,13 +5881,33 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
}
n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
if (ctx->region_type == ORT_TARGET)
{
if (n == NULL)
{
if (!lang_hooks.types.omp_mappable_type (TREE_TYPE (decl)))
{
error ("%qD referenced in target region does not have "
"a mappable type", decl);
omp_add_variable (ctx, decl, GOVD_MAP | GOVD_EXPLICIT | flags);
}
else
omp_add_variable (ctx, decl, GOVD_MAP | flags);
}
else
n->value |= flags;
ret = lang_hooks.decls.omp_disregard_value_expr (decl, true);
goto do_outer;
}
if (n == NULL)
{
enum omp_clause_default_kind default_kind, kind;
struct gimplify_omp_ctx *octx;
if (ctx->region_type == ORT_WORKSHARE
|| ctx->region_type == ORT_SIMD)
|| ctx->region_type == ORT_SIMD
|| ctx->region_type == ORT_TARGET_DATA)
goto do_outer;
/* ??? Some compiler-generated variables (like SAVE_EXPRs) could be
@ -5855,12 +5921,24 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
switch (default_kind)
{
case OMP_CLAUSE_DEFAULT_NONE:
error ("%qE not specified in enclosing parallel",
DECL_NAME (lang_hooks.decls.omp_report_decl (decl)));
if ((ctx->region_type & ORT_TASK) != 0)
error_at (ctx->location, "enclosing task");
{
error ("%qE not specified in enclosing task",
DECL_NAME (lang_hooks.decls.omp_report_decl (decl)));
error_at (ctx->location, "enclosing task");
}
else if (ctx->region_type == ORT_TEAMS)
{
error ("%qE not specified in enclosing teams construct",
DECL_NAME (lang_hooks.decls.omp_report_decl (decl)));
error_at (ctx->location, "enclosing teams construct");
}
else
error_at (ctx->location, "enclosing parallel");
{
error ("%qE not specified in enclosing parallel",
DECL_NAME (lang_hooks.decls.omp_report_decl (decl)));
error_at (ctx->location, "enclosing parallel");
}
/* FALLTHRU */
case OMP_CLAUSE_DEFAULT_SHARED:
flags |= GOVD_SHARED;
@ -5880,13 +5958,15 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
{
splay_tree_node n2;
if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0)
continue;
n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
{
flags |= GOVD_FIRSTPRIVATE;
break;
}
if ((octx->region_type & ORT_PARALLEL) != 0)
if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
break;
}
if (flags & GOVD_FIRSTPRIVATE)
@ -6028,6 +6108,9 @@ omp_check_private (struct gimplify_omp_ctx *ctx, tree decl)
/* References might be private, but might be shared too. */
|| lang_hooks.decls.omp_privatize_by_reference (decl));
if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0)
continue;
n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
if (n != NULL)
return (n->value & GOVD_SHARED) == 0;
@ -6086,15 +6169,87 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
check_non_private = "reduction";
goto do_add;
case OMP_CLAUSE_LINEAR:
if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
is_gimple_val, fb_rvalue) == GS_ERROR)
{
remove = true;
break;
}
flags = GOVD_LINEAR | GOVD_EXPLICIT;
goto do_add;
case OMP_CLAUSE_LINEAR:
if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
is_gimple_val, fb_rvalue) == GS_ERROR)
{
remove = true;
break;
}
flags = GOVD_LINEAR | GOVD_EXPLICIT;
goto do_add;
case OMP_CLAUSE_MAP:
if (OMP_CLAUSE_SIZE (c)
&& gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
{
remove = true;
break;
}
decl = OMP_CLAUSE_DECL (c);
if (!DECL_P (decl))
{
if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
NULL, is_gimple_lvalue, fb_lvalue)
== GS_ERROR)
{
remove = true;
break;
}
break;
}
flags = GOVD_MAP | GOVD_EXPLICIT;
goto do_add;
case OMP_CLAUSE_DEPEND:
if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
{
gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
NULL, is_gimple_val, fb_rvalue);
OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
}
if (error_operand_p (OMP_CLAUSE_DECL (c)))
{
remove = true;
break;
}
OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
is_gimple_val, fb_rvalue) == GS_ERROR)
{
remove = true;
break;
}
break;
case OMP_CLAUSE_TO:
case OMP_CLAUSE_FROM:
if (OMP_CLAUSE_SIZE (c)
&& gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
{
remove = true;
break;
}
decl = OMP_CLAUSE_DECL (c);
if (error_operand_p (decl))
{
remove = true;
break;
}
if (!DECL_P (decl))
{
if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
NULL, is_gimple_lvalue, fb_lvalue)
== GS_ERROR)
{
remove = true;
break;
}
break;
}
goto do_notice;
do_add:
decl = OMP_CLAUSE_DECL (c);
@ -6183,9 +6338,13 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
case OMP_CLAUSE_SCHEDULE:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_THREAD_LIMIT:
case OMP_CLAUSE_DIST_SCHEDULE:
case OMP_CLAUSE_DEVICE:
if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
is_gimple_val, fb_rvalue) == GS_ERROR)
remove = true;
remove = true;
break;
case OMP_CLAUSE_NOWAIT:
@ -6193,9 +6352,22 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_COLLAPSE:
case OMP_CLAUSE_MERGEABLE:
case OMP_CLAUSE_PROC_BIND:
case OMP_CLAUSE_SAFELEN:
break;
case OMP_CLAUSE_ALIGNED:
decl = OMP_CLAUSE_DECL (c);
if (error_operand_p (decl))
{
remove = true;
break;
}
if (!is_global_var (decl)
&& TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
omp_add_variable (ctx, decl, GOVD_ALIGNED);
break;
case OMP_CLAUSE_DEFAULT:
ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
break;
@ -6235,12 +6407,16 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_PRIVATE);
private_debug = true;
}
else if (flags & GOVD_MAP)
private_debug = false;
else
private_debug
= lang_hooks.decls.omp_private_debug_clause (decl,
!!(flags & GOVD_SHARED));
if (private_debug)
code = OMP_CLAUSE_PRIVATE;
else if (flags & GOVD_MAP)
code = OMP_CLAUSE_MAP;
else if (flags & GOVD_SHARED)
{
if (is_global_var (decl))
@ -6267,6 +6443,8 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
code = OMP_CLAUSE_FIRSTPRIVATE;
else if (flags & GOVD_LASTPRIVATE)
code = OMP_CLAUSE_LASTPRIVATE;
else if (flags & GOVD_ALIGNED)
return 0;
else
gcc_unreachable ();
@ -6277,6 +6455,36 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
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;
if (DECL_SIZE (decl)
&& TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
{
tree decl2 = DECL_VALUE_EXPR (decl);
gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
decl2 = TREE_OPERAND (decl2, 0);
gcc_assert (DECL_P (decl2));
tree mem = build_simple_mem_ref (decl2);
OMP_CLAUSE_DECL (clause) = mem;
OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
if (gimplify_omp_ctxp->outer_context)
{
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
omp_notice_variable (ctx, decl2, true);
omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
}
tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
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_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
OMP_CLAUSE_CHAIN (clause) = nc;
}
}
*list_p = clause;
lang_hooks.decls.omp_finish_clause (clause);
@ -6352,11 +6560,116 @@ gimplify_adjust_omp_clauses (tree *list_p)
= (n->value & GOVD_FIRSTPRIVATE) != 0;
break;
case OMP_CLAUSE_ALIGNED:
decl = OMP_CLAUSE_DECL (c);
if (!is_global_var (decl))
{
n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
remove = n == NULL || !(n->value & GOVD_SEEN);
if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
{
struct gimplify_omp_ctx *octx;
if (n != NULL
&& (n->value & (GOVD_DATA_SHARE_CLASS
& ~GOVD_FIRSTPRIVATE)))
remove = true;
else
for (octx = ctx->outer_context; octx;
octx = octx->outer_context)
{
n = splay_tree_lookup (octx->variables,
(splay_tree_key) decl);
if (n == NULL)
continue;
if (n->value & GOVD_LOCAL)
break;
/* We have to avoid assigning a shared variable
to itself when trying to add
__builtin_assume_aligned. */
if (n->value & GOVD_SHARED)
{
remove = true;
break;
}
}
}
}
else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
{
n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
remove = true;
}
break;
case OMP_CLAUSE_MAP:
decl = OMP_CLAUSE_DECL (c);
if (!DECL_P (decl))
break;
n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
if (ctx->region_type == ORT_TARGET && !(n->value & GOVD_SEEN))
remove = true;
else if (DECL_SIZE (decl)
&& TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
&& OMP_CLAUSE_MAP_KIND (c) != OMP_CLAUSE_MAP_POINTER)
{
tree decl2 = DECL_VALUE_EXPR (decl);
gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
decl2 = TREE_OPERAND (decl2, 0);
gcc_assert (DECL_P (decl2));
tree mem = build_simple_mem_ref (decl2);
OMP_CLAUSE_DECL (c) = mem;
OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
if (ctx->outer_context)
{
omp_notice_variable (ctx->outer_context, decl2, true);
omp_notice_variable (ctx->outer_context,
OMP_CLAUSE_SIZE (c), true);
}
tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
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_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
OMP_CLAUSE_CHAIN (c) = nc;
c = nc;
}
break;
case OMP_CLAUSE_TO:
case OMP_CLAUSE_FROM:
decl = OMP_CLAUSE_DECL (c);
if (!DECL_P (decl))
break;
if (DECL_SIZE (decl)
&& TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
{
tree decl2 = DECL_VALUE_EXPR (decl);
gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
decl2 = TREE_OPERAND (decl2, 0);
gcc_assert (DECL_P (decl2));
tree mem = build_simple_mem_ref (decl2);
OMP_CLAUSE_DECL (c) = mem;
OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
if (ctx->outer_context)
{
omp_notice_variable (ctx->outer_context, decl2, true);
omp_notice_variable (ctx->outer_context,
OMP_CLAUSE_SIZE (c), true);
}
}
break;
case OMP_CLAUSE_REDUCTION:
case OMP_CLAUSE_COPYIN:
case OMP_CLAUSE_COPYPRIVATE:
case OMP_CLAUSE_IF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_THREAD_LIMIT:
case OMP_CLAUSE_DIST_SCHEDULE:
case OMP_CLAUSE_DEVICE:
case OMP_CLAUSE_SCHEDULE:
case OMP_CLAUSE_NOWAIT:
case OMP_CLAUSE_ORDERED:
@ -6365,7 +6678,9 @@ gimplify_adjust_omp_clauses (tree *list_p)
case OMP_CLAUSE_COLLAPSE:
case OMP_CLAUSE_FINAL:
case OMP_CLAUSE_MERGEABLE:
case OMP_CLAUSE_PROC_BIND:
case OMP_CLAUSE_SAFELEN:
case OMP_CLAUSE_DEPEND:
break;
default:
@ -6458,12 +6773,39 @@ gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
*expr_p = NULL_TREE;
}
/* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
with non-NULL OMP_FOR_INIT. */
static tree
find_combined_omp_for (tree *tp, int *walk_subtrees, void *)
{
*walk_subtrees = 0;
switch (TREE_CODE (*tp))
{
case OMP_FOR:
*walk_subtrees = 1;
/* FALLTHRU */
case OMP_SIMD:
if (OMP_FOR_INIT (*tp) != NULL_TREE)
return *tp;
break;
case BIND_EXPR:
case STATEMENT_LIST:
case OMP_PARALLEL:
*walk_subtrees = 1;
break;
default:
break;
}
return NULL_TREE;
}
/* Gimplify the gross structure of an OMP_FOR statement. */
static enum gimplify_status
gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
tree for_stmt, decl, var, t;
tree for_stmt, orig_for_stmt, decl, var, t;
enum gimplify_status ret = GS_ALL_DONE;
enum gimplify_status tret;
gimple gfor;
@ -6472,9 +6814,9 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
bool simd;
bitmap has_decl_expr = NULL;
for_stmt = *expr_p;
orig_for_stmt = for_stmt = *expr_p;
simd = TREE_CODE (for_stmt) == OMP_SIMD;
simd = TREE_CODE (for_stmt) == OMP_SIMD;
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p,
simd ? ORT_SIMD : ORT_WORKSHARE);
@ -6485,7 +6827,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
has_decl_expr = BITMAP_ALLOC (NULL);
if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
&& TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
== VAR_DECL)
== VAR_DECL)
{
t = OMP_FOR_PRE_BODY (for_stmt);
bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
@ -6506,6 +6848,14 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
{
for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt), find_combined_omp_for,
NULL, NULL);
gcc_assert (for_stmt != NULL_TREE);
gimplify_omp_ctxp->combined_loop = true;
}
for_body = NULL;
gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
== TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
@ -6522,7 +6872,9 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
/* Make sure the iteration variable is private. */
tree c = NULL_TREE;
if (simd)
if (orig_for_stmt != for_stmt)
/* Do this only on innermost construct for combined ones. */;
else if (simd)
{
splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
(splay_tree_key)decl);
@ -6566,7 +6918,9 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
/* If DECL is not a gimple register, create a temporary variable to act
as an iteration counter. This is valid, since DECL cannot be
modified in the body of the loop. */
if (!is_gimple_reg (decl))
if (orig_for_stmt != for_stmt)
var = decl;
else if (!is_gimple_reg (decl))
{
var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
TREE_OPERAND (t, 0) = var;
@ -6599,6 +6953,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
case PREINCREMENT_EXPR:
case POSTINCREMENT_EXPR:
if (orig_for_stmt != for_stmt)
break;
t = build_int_cst (TREE_TYPE (decl), 1);
if (c)
OMP_CLAUSE_LINEAR_STEP (c) = t;
@ -6609,6 +6965,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
case PREDECREMENT_EXPR:
case POSTDECREMENT_EXPR:
if (orig_for_stmt != for_stmt)
break;
t = build_int_cst (TREE_TYPE (decl), -1);
if (c)
OMP_CLAUSE_LINEAR_STEP (c) = t;
@ -6665,9 +7023,9 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gcc_unreachable ();
}
if (var != decl || TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
if ((var != decl || TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
&& orig_for_stmt == for_stmt)
{
tree c;
for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_DECL (c) == decl
@ -6691,21 +7049,49 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
BITMAP_FREE (has_decl_expr);
gimplify_and_add (OMP_FOR_BODY (for_stmt), &for_body);
gimplify_and_add (OMP_FOR_BODY (orig_for_stmt), &for_body);
gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt));
if (orig_for_stmt != for_stmt)
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
{
t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
decl = TREE_OPERAND (t, 0);
var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
TREE_OPERAND (t, 0) = var;
t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
}
gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt));
int kind;
switch (TREE_CODE (for_stmt))
switch (TREE_CODE (orig_for_stmt))
{
case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
default:
gcc_unreachable ();
}
gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (for_stmt),
gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
for_pre_body);
if (orig_for_stmt != for_stmt)
gimple_omp_for_set_combined_p (gfor, true);
if (gimplify_omp_ctxp
&& (gimplify_omp_ctxp->combined_loop
|| (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
&& gimplify_omp_ctxp->outer_context
&& gimplify_omp_ctxp->outer_context->combined_loop)))
{
gimple_omp_for_set_combined_into_p (gfor, true);
if (gimplify_omp_ctxp->combined_loop)
gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
else
gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
}
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
{
@ -6726,8 +7112,9 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
return GS_ALL_DONE;
}
/* Gimplify the gross structure of other OpenMP worksharing constructs.
In particular, OMP_SECTIONS and OMP_SINGLE. */
/* Gimplify the gross structure of other OpenMP constructs.
In particular, OMP_SECTIONS, OMP_SINGLE, OMP_TARGET, OMP_TARGET_DATA
and OMP_TEAMS. */
static void
gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
@ -6735,19 +7122,93 @@ 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;
gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ORT_WORKSHARE);
gimplify_and_add (OMP_BODY (expr), &body);
switch (TREE_CODE (expr))
{
case OMP_SECTIONS:
case OMP_SINGLE:
break;
case OMP_TARGET:
ort = ORT_TARGET;
break;
case OMP_TARGET_DATA:
ort = ORT_TARGET_DATA;
break;
case OMP_TEAMS:
ort = ORT_TEAMS;
break;
default:
gcc_unreachable ();
}
gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort);
if (ort == ORT_TARGET || ort == ORT_TARGET_DATA)
{
struct gimplify_ctx gctx;
push_gimplify_context (&gctx);
gimple g = gimplify_and_return_first (OMP_BODY (expr), &body);
if (gimple_code (g) == GIMPLE_BIND)
pop_gimplify_context (g);
else
pop_gimplify_context (NULL);
if (ort == ORT_TARGET_DATA)
{
gimple_seq cleanup = NULL;
tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TARGET_END_DATA);
g = gimple_build_call (fn, 0);
gimple_seq_add_stmt (&cleanup, g);
g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
body = NULL;
gimple_seq_add_stmt (&body, g);
}
}
else
gimplify_and_add (OMP_BODY (expr), &body);
gimplify_adjust_omp_clauses (&OMP_CLAUSES (expr));
if (TREE_CODE (expr) == OMP_SECTIONS)
stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
else if (TREE_CODE (expr) == OMP_SINGLE)
stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
else
gcc_unreachable ();
switch (TREE_CODE (expr))
{
case OMP_SECTIONS:
stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
break;
case OMP_SINGLE:
stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
break;
case OMP_TARGET:
stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
OMP_CLAUSES (expr));
break;
case OMP_TARGET_DATA:
stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
OMP_CLAUSES (expr));
break;
case OMP_TEAMS:
stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
break;
default:
gcc_unreachable ();
}
gimplify_seq_add_stmt (pre_p, stmt);
*expr_p = NULL_TREE;
}
/* Gimplify the gross structure of OpenMP target update construct. */
static void
gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
{
tree expr = *expr_p;
gimple stmt;
gimplify_scan_omp_clauses (&OMP_TARGET_UPDATE_CLAUSES (expr), pre_p,
ORT_WORKSHARE);
gimplify_adjust_omp_clauses (&OMP_TARGET_UPDATE_CLAUSES (expr));
stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_UPDATE,
OMP_TARGET_UPDATE_CLAUSES (expr));
gimplify_seq_add_stmt (pre_p, stmt);
*expr_p = NULL_TREE;
}
/* A subroutine of gimplify_omp_atomic. The front end is supposed to have
@ -6886,6 +7347,11 @@ gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
rhs = tmp_load;
storestmt = gimple_build_omp_atomic_store (rhs);
gimplify_seq_add_stmt (pre_p, storestmt);
if (OMP_ATOMIC_SEQ_CST (*expr_p))
{
gimple_omp_atomic_set_seq_cst (loadstmt);
gimple_omp_atomic_set_seq_cst (storestmt);
}
switch (TREE_CODE (*expr_p))
{
case OMP_ATOMIC_READ:
@ -6902,7 +7368,7 @@ gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
break;
}
return GS_ALL_DONE;
return GS_ALL_DONE;
}
/* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
@ -7642,17 +8108,27 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
case OMP_FOR:
case OMP_SIMD:
case OMP_DISTRIBUTE:
ret = gimplify_omp_for (expr_p, pre_p);
break;
case OMP_SECTIONS:
case OMP_SINGLE:
case OMP_TARGET:
case OMP_TARGET_DATA:
case OMP_TEAMS:
gimplify_omp_workshare (expr_p, pre_p);
ret = GS_ALL_DONE;
break;
case OMP_TARGET_UPDATE:
gimplify_omp_target_update (expr_p, pre_p);
ret = GS_ALL_DONE;
break;
case OMP_SECTION:
case OMP_MASTER:
case OMP_TASKGROUP:
case OMP_ORDERED:
case OMP_CRITICAL:
{
@ -7668,6 +8144,19 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
case OMP_MASTER:
g = gimple_build_omp_master (body);
break;
case OMP_TASKGROUP:
{
gimple_seq cleanup = NULL;
tree fn
= builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
g = gimple_build_call (fn, 0);
gimple_seq_add_stmt (&cleanup, g);
g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
body = NULL;
gimple_seq_add_stmt (&body, g);
g = gimple_build_omp_taskgroup (body);
}
break;
case OMP_ORDERED:
g = gimple_build_omp_ordered (body);
break;
@ -8000,6 +8489,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
&& code != OMP_CRITICAL
&& code != OMP_FOR
&& code != OMP_MASTER
&& code != OMP_TASKGROUP
&& code != OMP_ORDERED
&& code != OMP_PARALLEL
&& code != OMP_SECTIONS
@ -8224,6 +8714,13 @@ gimplify_body (tree fndecl, bool do_parms)
gcc_assert (gimplify_ctxp == NULL);
push_gimplify_context (&gctx);
if (flag_openmp)
{
gcc_assert (gimplify_omp_ctxp == NULL);
if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
gimplify_omp_ctxp = new_omp_context (ORT_TARGET);
}
/* Unshare most shared trees in the body and in that of any nested functions.
It would seem we don't have to do this for nested functions because
they are supposed to be output and then the outer function gimplified
@ -8286,6 +8783,12 @@ gimplify_body (tree fndecl, bool do_parms)
nonlocal_vlas = NULL;
}
if (flag_openmp && gimplify_omp_ctxp)
{
delete_omp_context (gimplify_omp_ctxp);
gimplify_omp_ctxp = NULL;
}
pop_gimplify_context (outer_bind);
gcc_assert (gimplify_ctxp == NULL);

View file

@ -77,6 +77,7 @@ extern tree lhd_omp_assignment (tree, tree, tree);
struct gimplify_omp_ctx;
extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
tree);
extern bool lhd_omp_mappable_type (tree);
#define LANG_HOOKS_NAME "GNU unknown"
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
@ -166,6 +167,7 @@ extern tree lhd_make_node (enum tree_code);
#define LANG_HOOKS_TYPE_MAX_SIZE lhd_return_null_const_tree
#define LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES \
lhd_omp_firstprivatize_type_sizes
#define LANG_HOOKS_OMP_MAPPABLE_TYPE lhd_omp_mappable_type
#define LANG_HOOKS_TYPE_HASH_EQ NULL
#define LANG_HOOKS_GET_ARRAY_DESCR_INFO NULL
#define LANG_HOOKS_GET_SUBRANGE_BOUNDS NULL
@ -184,6 +186,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_INCOMPLETE_TYPE_ERROR, \
LANG_HOOKS_TYPE_MAX_SIZE, \
LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES, \
LANG_HOOKS_OMP_MAPPABLE_TYPE, \
LANG_HOOKS_TYPE_HASH_EQ, \
LANG_HOOKS_GET_ARRAY_DESCR_INFO, \
LANG_HOOKS_GET_SUBRANGE_BOUNDS, \

View file

@ -523,6 +523,15 @@ lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *c ATTRIBUTE_UNUSED,
{
}
/* Return true if TYPE is an OpenMP mappable type. By default return true
if type is complete. */
bool
lhd_omp_mappable_type (tree type)
{
return COMPLETE_TYPE_P (type);
}
/* Common function for add_builtin_function and
add_builtin_function_ext_scope. */
static tree

View file

@ -111,6 +111,9 @@ struct lang_hooks_for_types
firstprivate variables. */
void (*omp_firstprivatize_type_sizes) (struct gimplify_omp_ctx *, tree);
/* Return true if TYPE is a mappable type. */
bool (*omp_mappable_type) (tree type);
/* Return TRUE if TYPE1 and TYPE2 are identical for type hashing purposes.
Called only after doing all language independent checks.
At present, this function is only called when both TYPE1 and TYPE2 are

View file

@ -1,3 +1,7 @@
2013-10-11 Jakub Jelinek <jakub@redhat.com>
* lto-lang.c (DEF_FUNCTION_TYPE_8): Define.
2013-09-25 Tom Tromey <tromey@redhat.com>
* Make-lang.in (LTO_H, LINKER_PLUGIN_API_H, LTO_TREE_H)

View file

@ -140,6 +140,7 @@ enum lto_builtin_type
#define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
#define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) NAME,
#define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) NAME,
#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_1(NAME, RETURN, ARG1) NAME,
#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
@ -158,6 +159,7 @@ enum lto_builtin_type
#undef DEF_FUNCTION_TYPE_5
#undef DEF_FUNCTION_TYPE_6
#undef DEF_FUNCTION_TYPE_7
#undef DEF_FUNCTION_TYPE_8
#undef DEF_FUNCTION_TYPE_VAR_0
#undef DEF_FUNCTION_TYPE_VAR_1
#undef DEF_FUNCTION_TYPE_VAR_2
@ -631,6 +633,10 @@ lto_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
#define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7) \
def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
#define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7, ARG8) \
def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
ARG7, ARG8);
#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
def_fn_type (ENUM, RETURN, 1, 0);
#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \

View file

@ -28,6 +28,10 @@ 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",
BT_FN_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_OMP_GET_TEAM_NUM, "omp_get_team_num",
BT_FN_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_OMP_GET_NUM_TEAMS, "omp_get_num_teams",
BT_FN_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ATOMIC_START, "GOMP_atomic_start",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
@ -35,10 +39,20 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ATOMIC_END, "GOMP_atomic_end",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BARRIER, "GOMP_barrier",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BARRIER_CANCEL, "GOMP_barrier_cancel",
BT_FN_BOOL, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKWAIT, "GOMP_taskwait",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKYIELD, "GOMP_taskyield",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKGROUP_START, "GOMP_taskgroup_start",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKGROUP_END, "GOMP_taskgroup_end",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CANCEL, "GOMP_cancel",
BT_FN_BOOL_INT_BOOL, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CANCELLATION_POINT, "GOMP_cancellation_point",
BT_FN_BOOL_INT, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CRITICAL_START, "GOMP_critical_start",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CRITICAL_END, "GOMP_critical_end",
@ -156,49 +170,52 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT,
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT,
"GOMP_loop_ull_ordered_runtime_next",
BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
/* NOTE: Do not change the order of BUILT_IN_GOMP_PARALLEL_LOOP_*_START.
/* NOTE: Do not change the order of BUILT_IN_GOMP_PARALLEL_LOOP_*.
They are used in index arithmetic with enum omp_clause_schedule_kind
in omp-low.c. */
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START,
"GOMP_parallel_loop_static_start",
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_STATIC,
"GOMP_parallel_loop_static",
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG_UINT,
ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_DYNAMIC_START,
"GOMP_parallel_loop_dynamic_start",
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_DYNAMIC,
"GOMP_parallel_loop_dynamic",
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG_UINT,
ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_GUIDED_START,
"GOMP_parallel_loop_guided_start",
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_GUIDED,
"GOMP_parallel_loop_guided",
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG_UINT,
ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_RUNTIME_START,
"GOMP_parallel_loop_runtime_start",
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_RUNTIME,
"GOMP_parallel_loop_runtime",
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_UINT,
ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_END, "GOMP_loop_end",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_END_CANCEL, "GOMP_loop_end_cancel",
BT_FN_BOOL, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_END_NOWAIT, "GOMP_loop_end_nowait",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ORDERED_START, "GOMP_ordered_start",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ORDERED_END, "GOMP_ordered_end",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_START, "GOMP_parallel_start",
BT_FN_VOID_OMPFN_PTR_UINT, ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_END, "GOMP_parallel_end",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL, "GOMP_parallel",
BT_FN_VOID_OMPFN_PTR_UINT_UINT, ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASK, "GOMP_task",
BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT,
BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR,
ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_START, "GOMP_sections_start",
BT_FN_UINT_UINT, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_NEXT, "GOMP_sections_next",
BT_FN_UINT, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_SECTIONS_START,
"GOMP_parallel_sections_start",
BT_FN_VOID_OMPFN_PTR_UINT_UINT, ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_SECTIONS,
"GOMP_parallel_sections",
BT_FN_VOID_OMPFN_PTR_UINT_UINT_UINT, ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_END, "GOMP_sections_end",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_END_CANCEL,
"GOMP_sections_end_cancel",
BT_FN_BOOL, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_END_NOWAIT,
"GOMP_sections_end_nowait",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
@ -208,3 +225,14 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_COPY_START, "GOMP_single_copy_start",
BT_FN_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_COPY_END, "GOMP_single_copy_end",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TARGET, "GOMP_target",
BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR,
ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TARGET_DATA, "GOMP_target_data",
BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR, ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TARGET_END_DATA, "GOMP_target_end_data",
BT_FN_VOID, ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TARGET_UPDATE, "GOMP_target_update",
BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR, ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TEAMS, "GOMP_teams",
BT_FN_VOID_UINT_UINT, ATTR_NOTHROW_LIST)

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,64 @@
2013-10-11 Jakub Jelinek <jakub@redhat.com>
* c-c++-common/gomp/atomic-15.c: Adjust for C diagnostics.
Remove error test that is now valid in OpenMP 4.0.
* c-c++-common/gomp/atomic-16.c: New test.
* c-c++-common/gomp/cancel-1.c: New test.
* c-c++-common/gomp/depend-1.c: New test.
* c-c++-common/gomp/depend-2.c: New test.
* c-c++-common/gomp/map-1.c: New test.
* c-c++-common/gomp/pr58472.c: New test.
* c-c++-common/gomp/sections1.c: New test.
* c-c++-common/gomp/simd1.c: New test.
* c-c++-common/gomp/simd2.c: New test.
* c-c++-common/gomp/simd3.c: New test.
* c-c++-common/gomp/simd4.c: New test.
* c-c++-common/gomp/simd5.c: New test.
* c-c++-common/gomp/single1.c: New test.
* g++.dg/gomp/block-0.C: Adjust for stricter #pragma omp sections
parser.
* g++.dg/gomp/block-3.C: Likewise.
* g++.dg/gomp/clause-3.C: Adjust error messages.
* g++.dg/gomp/declare-simd-1.C: New test.
* g++.dg/gomp/declare-simd-2.C: New test.
* g++.dg/gomp/depend-1.C: New test.
* g++.dg/gomp/depend-2.C: New test.
* g++.dg/gomp/target-1.C: New test.
* g++.dg/gomp/target-2.C: New test.
* g++.dg/gomp/taskgroup-1.C: New test.
* g++.dg/gomp/teams-1.C: New test.
* g++.dg/gomp/udr-1.C: New test.
* g++.dg/gomp/udr-2.C: New test.
* g++.dg/gomp/udr-3.C: New test.
* g++.dg/gomp/udr-4.C: New test.
* g++.dg/gomp/udr-5.C: New test.
* g++.dg/gomp/udr-6.C: New test.
* gcc.dg/autopar/outer-1.c: Expect 4 instead of 5 loopfn matches.
* gcc.dg/autopar/outer-2.c: Likewise.
* gcc.dg/autopar/outer-3.c: Likewise.
* gcc.dg/autopar/outer-4.c: Likewise.
* gcc.dg/autopar/outer-5.c: Likewise.
* gcc.dg/autopar/outer-6.c: Likewise.
* gcc.dg/autopar/parallelization-1.c: Likewise.
* gcc.dg/gomp/block-3.c: Adjust for stricter #pragma omp sections
parser.
* gcc.dg/gomp/clause-1.c: Adjust error messages.
* gcc.dg/gomp/combined-1.c: Look for GOMP_parallel_loop_runtime
instead of GOMP_parallel_loop_runtime_start.
* gcc.dg/gomp/declare-simd-1.c: New test.
* gcc.dg/gomp/declare-simd-2.c: New test.
* gcc.dg/gomp/nesting-1.c: Adjust for stricter #pragma omp sections
parser. Add further #pragma omp sections nesting tests.
* gcc.dg/gomp/target-1.c: New test.
* gcc.dg/gomp/target-2.c: New test.
* gcc.dg/gomp/taskgroup-1.c: New test.
* gcc.dg/gomp/teams-1.c: New test.
* gcc.dg/gomp/udr-1.c: New test.
* gcc.dg/gomp/udr-2.c: New test.
* gcc.dg/gomp/udr-3.c: New test.
* gcc.dg/gomp/udr-4.c: New test.
* gfortran.dg/gomp/appendix-a/a.35.5.f90: Add dg-error.
2013-10-10 Jan Hubicka <jh@suse.cz>
* gcc.target/i386/avx256-unaligned-store-3.c: Update template for

View file

@ -8,39 +8,37 @@ main ()
{
int v;
#pragma omp atomic
x = x * 7 + 6; /* { dg-error "expected" } */
x = x * 7 + 6; /* { dg-error "expected|invalid form of" } */
#pragma omp atomic
x = x * 7 ^ 6; /* { dg-error "expected" } */
x = x * 7 ^ 6; /* { dg-error "expected|invalid form of" } */
#pragma omp atomic update
x = x - 8 + 6; /* { dg-error "expected" } */
x = x - 8 + 6; /* { dg-error "expected|invalid form of" } */
#pragma omp atomic
x = x ^ 7 | 2; /* { dg-error "expected" } */
x = x ^ 7 | 2; /* { dg-error "expected|invalid form of" } */
#pragma omp atomic
x = x / 7 * 2; /* { dg-error "expected" } */
x = x / 7 * 2; /* { dg-error "expected|invalid form of" } */
#pragma omp atomic
x = x / 7 / 2; /* { dg-error "expected" } */
x = x / 7 / 2; /* { dg-error "expected|invalid form of" } */
#pragma omp atomic capture
v = x = x | 6; /* { dg-error "invalid operator" } */
{ v = x; x = x * 7 + 6; } /* { dg-error "expected" "" { target c++ } } */
#pragma omp atomic capture
{ v = x; x = x * 7 + 6; } /* { dg-error "expected" } */
{ v = x; x = x * 7 ^ 6; } /* { dg-error "expected" "" { target c++ } } */
#pragma omp atomic capture
{ v = x; x = x * 7 ^ 6; } /* { dg-error "expected" } */
{ v = x; x = x - 8 + 6; } /* { dg-error "expected" "" { target c++ } } */
#pragma omp atomic capture
{ v = x; x = x - 8 + 6; } /* { dg-error "expected" } */
{ v = x; x = x ^ 7 | 2; } /* { dg-error "expected" "" { target c++ } } */
#pragma omp atomic capture
{ v = x; x = x ^ 7 | 2; } /* { dg-error "expected" } */
{ v = x; x = x / 7 * 2; } /* { dg-error "expected" "" { target c++ } } */
#pragma omp atomic capture
{ v = x; x = x / 7 * 2; } /* { dg-error "expected" } */
{ v = x; x = x / 7 / 2; } /* { dg-error "expected" "" { target c++ } } */
#pragma omp atomic capture
{ v = x; x = x / 7 / 2; } /* { dg-error "expected" } */
{ x = x * 7 + 6; v = x; } /* { dg-error "expected|uses two different expressions for memory" } */
#pragma omp atomic capture
{ x = x * 7 + 6; v = x; } /* { dg-error "expected" } */
{ x = x * 7 ^ 6; v = x; } /* { dg-error "expected|uses two different expressions for memory" } */
#pragma omp atomic capture
{ x = x * 7 ^ 6; v = x; } /* { dg-error "expected" } */
{ x = x - 8 + 6; v = x; } /* { dg-error "expected|uses two different expressions for memory" } */
#pragma omp atomic capture
{ x = x - 8 + 6; v = x; } /* { dg-error "expected" } */
#pragma omp atomic capture
{ x = x ^ 7 | 2; v = x; } /* { dg-error "expected" } */
{ x = x ^ 7 | 2; v = x; } /* { dg-error "expected|uses two different expressions for memory" } */
(void) v;
return 0;
}

View file

@ -0,0 +1,34 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
int x = 6;
void
foo ()
{
int v;
#pragma omp atomic seq_cst load /* { dg-error "expected end of line" } */
v = x; /* { dg-error "invalid form" } */
#pragma omp atomic seq_cst, load /* { dg-error "expected end of line" } */
v = x; /* { dg-error "invalid form" } */
#pragma omp atomic seq_cst store /* { dg-error "expected end of line" } */
x = v; /* { dg-error "invalid form" } */
#pragma omp atomic seq_cst ,store /* { dg-error "expected end of line" } */
x = v; /* { dg-error "invalid form" } */
#pragma omp atomic seq_cst update /* { dg-error "expected end of line" } */
x += v;
#pragma omp atomic seq_cst , update /* { dg-error "expected end of line" } */
x += v;
#pragma omp atomic seq_cst capture /* { dg-error "expected end of line" } */
v = x += 2; /* { dg-error "invalid form" } */
#pragma omp atomic seq_cst, capture /* { dg-error "expected end of line" } */
v = x += 2; /* { dg-error "invalid form" } */
#pragma omp atomic load , seq_cst /* { dg-error "expected end of line" } */
v = x; /* { dg-error "invalid form" } */
#pragma omp atomic store ,seq_cst /* { dg-error "expected end of line" } */
x = v; /* { dg-error "invalid form" } */
#pragma omp atomic update, seq_cst /* { dg-error "expected end of line" } */
x += v;
#pragma omp atomic capture, seq_cst /* { dg-error "expected end of line" } */
v = x += 2;
}

View file

@ -0,0 +1,396 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
void
f1 (void)
{
#pragma omp cancel parallel /* { dg-error "orphaned" } */
#pragma omp cancel for /* { dg-error "orphaned" } */
#pragma omp cancel sections /* { dg-error "orphaned" } */
#pragma omp cancel taskgroup /* { dg-error "orphaned" } */
#pragma omp cancellation point parallel /* { dg-error "orphaned" } */
#pragma omp cancellation point for /* { dg-error "orphaned" } */
#pragma omp cancellation point sections /* { dg-error "orphaned" } */
#pragma omp cancellation point taskgroup /* { dg-error "orphaned" } */
}
void
f2 (void)
{
int i;
#pragma omp parallel
{
#pragma omp cancel parallel
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp master
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp single
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp critical
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp taskgroup
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp task
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup
}
#pragma omp for
for (i = 0; i < 10; i++)
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup/* { dg-error "not closely nested inside" } */
}
#pragma omp for ordered
for (i = 0; i < 10; i++)
#pragma omp ordered
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup/* { dg-error "not closely nested inside" } */
}
#pragma omp sections
{
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections
#pragma omp cancellation point taskgroup/* { dg-error "not closely nested inside" } */
}
#pragma omp section
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections
#pragma omp cancellation point taskgroup/* { dg-error "not closely nested inside" } */
}
}
#pragma omp target data
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp target
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
}
#pragma omp target data
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp target
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp target teams
{
#pragma omp cancel parallel /* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
#pragma omp cancel for /* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
#pragma omp cancel sections /* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
#pragma omp cancel taskgroup /* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
#pragma omp cancellation point parallel /* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
#pragma omp cancellation point for /* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
#pragma omp cancellation point sections /* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
#pragma omp cancellation point taskgroup /* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
}
#pragma omp target teams distribute
for (i = 0; i < 10; i++)
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp for
for (i = 0; i < 10; i++)
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp for
for (i = 0; i < 10; i++)
#pragma omp target data
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp for
for (i = 0; i < 10; i++)
#pragma omp target
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp for ordered
for (i = 0; i < 10; i++)
#pragma omp ordered
#pragma omp target data
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup/* { dg-error "not closely nested inside" } */
}
#pragma omp for ordered
for (i = 0; i < 10; i++)
#pragma omp ordered
#pragma omp target
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup/* { dg-error "not closely nested inside" } */
}
#pragma omp sections
{
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp section
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
}
#pragma omp sections
{
#pragma omp target data
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp section
#pragma omp target data
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
}
#pragma omp sections
{
#pragma omp target
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
#pragma omp section
#pragma omp target
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
}
#pragma omp task
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup
#pragma omp taskgroup
{
#pragma omp cancel parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancel for /* { dg-error "not closely nested inside" } */
#pragma omp cancel sections /* { dg-error "not closely nested inside" } */
#pragma omp cancel taskgroup /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point parallel /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point for /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point sections /* { dg-error "not closely nested inside" } */
#pragma omp cancellation point taskgroup /* { dg-error "not closely nested inside" } */
}
}
}
void
f3 (void)
{
int i;
#pragma omp for nowait
for (i = 0; i < 10; i++)
{
#pragma omp cancel for /* { dg-warning "nowait" } */
}
#pragma omp sections nowait
{
{
#pragma omp cancel sections /* { dg-warning "nowait" } */
}
#pragma omp section
{
#pragma omp cancel sections /* { dg-warning "nowait" } */
}
}
#pragma omp for ordered
for (i = 0; i < 10; i++)
{
#pragma omp cancel for /* { dg-warning "ordered" } */
#pragma omp ordered
{
}
}
}

View file

@ -0,0 +1,79 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
extern int a[][10], a2[][10];
int b[10], c[10][2], d[10], e[10], f[10];
int b2[10], c2[10][2], d2[10], e2[10], f2[10];
int k[10], l[10], m[10], n[10], o;
int *p;
void bar (void);
int t[10];
#pragma omp threadprivate (t)
void
foo (int g[3][10], int h[4][8], int i[2][10], int j[][9],
int g2[3][10], int h2[4][8], int i2[2][10], int j2[][9])
{
#pragma omp task depend(in: bar[2:5]) /* { dg-error "is not a variable" } */
;
#pragma omp task depend(out: t[2:5])
;
#pragma omp task depend(inout: k[0.5:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
;
#pragma omp task depend(in: l[:7.5f]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
;
#pragma omp task depend(out: m[p:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
;
#pragma omp task depend(inout: n[:p]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
;
#pragma omp task depend(in: o[2:5]) /* { dg-error "does not have pointer or array type" } */
;
#pragma omp task depend(out: a[:][2:4]) /* { dg-error "array type length expression must be specified" } */
;
#pragma omp task depend(inout: b[-1:]) /* { dg-error "negative low bound in array section" } */
;
#pragma omp task depend(inout: c[:-3][1:1]) /* { dg-error "negative length in array section" } */
;
#pragma omp task depend(in: d[11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
;
#pragma omp task depend(out: e[:11]) /* { dg-error "length \[^\n\r]* above array section size" } */
;
#pragma omp task depend(out: f[1:10]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
;
#pragma omp task depend(in: g[:][2:4]) /* { dg-error "for pointer type length expression must be specified" } */
;
#pragma omp task depend(in: h[2:2][-1:]) /* { dg-error "negative low bound in array section" } */
;
#pragma omp task depend(inout: h[:1][:-3]) /* { dg-error "negative length in array section" } */
;
#pragma omp task depend(out: i[:1][11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
;
#pragma omp task depend(in: j[3:4][:10]) /* { dg-error "length \[^\n\r]* above array section size" } */
;
#pragma omp task depend(out: j[30:10][5:5]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
;
#pragma omp task depend(out: a2[:3][2:4])
;
#pragma omp task depend(inout: b2[0:])
;
#pragma omp task depend(inout: c2[:3][1:1])
;
#pragma omp task depend(in: d2[9:])
;
#pragma omp task depend(out: e2[:10])
;
#pragma omp task depend(out: f2[1:9])
;
#pragma omp task depend(in: g2[:2][2:4])
;
#pragma omp task depend(in: h2[2:2][0:])
;
#pragma omp task depend(inout: h2[:1][:3])
;
#pragma omp task depend(out: i2[:1][9:])
;
#pragma omp task depend(in: j2[3:4][:9])
;
#pragma omp task depend(out: j2[30:10][5:4])
;
}

View file

@ -0,0 +1,19 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
void bar (int a[10][10][10]);
void
foo (int a[10][10][10], int **b)
{
int c[10][10][10];
#pragma omp task depend(out: a[2:4][3:][:7], b[1:7][2:8])
bar (a);
int i = 1, j = 3, k = 2, l = 6;
#pragma omp task depend(in: a[++i:++j][++k:][:++l])
bar (a);
#pragma omp task depend(out: a[7:2][:][:], c[5:2][:][:])
{
bar (c);
bar (a);
}
}

View file

@ -0,0 +1,103 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
extern int a[][10], a2[][10];
int b[10], c[10][2], d[10], e[10], f[10];
int b2[10], c2[10][2], d2[10], e2[10], f2[10];
int k[10], l[10], m[10], n[10], o;
int *p;
int **q;
int r[4][4][4][4][4];
int t[10];
#pragma omp threadprivate (t)
#pragma omp declare target
void bar (int *);
#pragma omp end declare target
void
foo (int g[3][10], int h[4][8], int i[2][10], int j[][9],
int g2[3][10], int h2[4][8], int i2[2][10], int j2[][9])
{
#pragma omp target map(to: bar[2:5]) /* { dg-error "is not a variable" } */
;
#pragma omp target map(from: t[2:5]) /* { dg-error "is threadprivate variable" } */
;
#pragma omp target map(tofrom: k[0.5:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
;
#pragma omp target map(from: l[:7.5f]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
;
#pragma omp target map(to: m[p:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
;
#pragma omp target map(tofrom: n[:p]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
;
#pragma omp target map(to: o[2:5]) /* { dg-error "does not have pointer or array type" } */
;
#pragma omp target map(to: a[:][:]) /* { dg-error "array type length expression must be specified" } */
bar (&a[0][0]); /* { dg-error "referenced in target region does not have a mappable type" } */
#pragma omp target map(tofrom: b[-1:]) /* { dg-error "negative low bound in array section" } */
bar (b);
#pragma omp target map(tofrom: c[:-3][:]) /* { dg-error "negative length in array section" } */
bar (&c[0][0]);
#pragma omp target map(from: d[11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
bar (d);
#pragma omp target map(to: e[:11]) /* { dg-error "length \[^\n\r]* above array section size" } */
bar (e);
#pragma omp target map(to: f[1:10]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
bar (f);
#pragma omp target map(from: g[:][0:10]) /* { dg-error "for pointer type length expression must be specified" } */
bar (&g[0][0]);
#pragma omp target map(from: h[2:1][-1:]) /* { dg-error "negative low bound in array section" } */
bar (&h[0][0]);
#pragma omp target map(tofrom: h[:1][:-3]) /* { dg-error "negative length in array section" } */
bar (&h[0][0]);
#pragma omp target map(i[:1][11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
bar (&i[0][0]);
#pragma omp target map(from: j[3:1][:10]) /* { dg-error "length \[^\n\r]* above array section size" } */
bar (&j[0][0]);
#pragma omp target map(to: j[30:1][5:5]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
bar (&j[0][0]);
#pragma omp target map(to: a2[:1][2:4])
bar (&a2[0][0]);
#pragma omp target map(a2[3:5][:])
bar (&a2[0][0]);
#pragma omp target map(to: a2[3:5][:10])
bar (&a2[0][0]);
#pragma omp target map(tofrom: b2[0:])
bar (b2);
#pragma omp target map(tofrom: c2[:3][:])
bar (&c2[0][0]);
#pragma omp target map(from: d2[9:])
bar (d2);
#pragma omp target map(to: e2[:10])
bar (e2);
#pragma omp target map(to: f2[1:9])
bar (f2);
#pragma omp target map(g2[:1][2:4])
bar (&g2[0][0]);
#pragma omp target map(from: h2[2:2][0:])
bar (&h2[0][0]);
#pragma omp target map(tofrom: h2[:1][:3])
bar (&h2[0][0]);
#pragma omp target map(to: i2[:1][9:])
bar (&i2[0][0]);
#pragma omp target map(from: j2[3:4][:9])
bar (&j2[0][0]);
#pragma omp target map(to: j2[30:1][5:4])
bar (&j2[0][0]);
#pragma omp target map(q[1:2])
;
#pragma omp target map(tofrom: q[3:5][:10]) /* { dg-error "array section is not contiguous" } */
;
#pragma omp target map(r[3:][2:1][1:2])
;
#pragma omp target map(r[3:][2:1][1:2][:][0:4])
;
#pragma omp target map(r[3:][2:1][1:2][1:][0:4]) /* { dg-error "array section is not contiguous" } */
;
#pragma omp target map(r[3:][2:1][1:2][:3][0:4]) /* { dg-error "array section is not contiguous" } */
;
#pragma omp target map(r[3:][2:1][1:2][:][1:]) /* { dg-error "array section is not contiguous" } */
;
#pragma omp target map(r[3:][2:1][1:2][:][:3]) /* { dg-error "array section is not contiguous" } */
;
}

View file

@ -0,0 +1,16 @@
/* PR tree-optimization/58472 */
/* { dg-do compile } */
/* { dg-options "-O2 -Wall -fopenmp" } */
float a[1024], b[1024];
float
foo ()
{
float s = 0.f;
unsigned int i;
#pragma omp simd reduction(+:s)
for (i = 0; i < 1024; ++i)
s += a[i] * b[i];
return s;
}

View file

@ -0,0 +1,73 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
void bar (int);
void
foo ()
{
#pragma omp sections
{
bar (1);
#pragma omp section
{
bar (2);
}
}
#pragma omp sections
{
#pragma omp section
bar (3);
#pragma omp section
{
bar (4);
bar (5);
}
}
#pragma omp sections
{
{
bar (6);
bar (7);
}
#pragma omp section
bar (8);
}
#pragma omp sections
{
#pragma omp section
{
bar (9);
}
#pragma omp section
bar (10);
#pragma omp section
bar (11);
}
#pragma omp sections
{
} /* { dg-error "expression before" } */
#pragma omp sections
{
bar (12);
bar (13); /* { dg-error "pragma omp section" } */
#pragma omp section
bar (14);
}
#pragma omp sections
{
#pragma omp section
} /* { dg-error "expression before" } */
#pragma omp sections
{
bar (15);
#pragma omp section
bar (16);
bar (17); /* { dg-error "pragma omp section" } */
}
#pragma omp sections
{
bar (18);
#pragma omp section
} /* { dg-error "expression before" } */
}

View file

@ -0,0 +1,31 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
/* { dg-additional-options "-std=c99" { target c } } */
extern int a[1024], b[1024], k, l, m;
void
foo ()
{
int i;
#pragma omp simd safelen(16) aligned(a, b : 32)
for (i = 0; i < 1024; i++)
a[i] *= b[i];
}
void
bar (int *p)
{
int i;
#pragma omp simd safelen(16) aligned(a, p : 32) linear(k, l : m + 1)
for (i = 0; i < 1024; i++)
a[i] *= p[i], k += m + 1;
}
void
baz (int *p)
{
#pragma omp simd safelen(16) aligned(a, p : 32) linear(k, l : m + 1)
for (int i = 0; i < 1024; i++)
a[i] *= p[i], k += m + 1;
}

View file

@ -0,0 +1,29 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
/* { dg-additional-options "-std=c99" { target c } } */
extern int a[13][13][13][13], k, l, m;
void
foo (int *q, float *p)
{
int i, j, n, o;
#pragma omp simd collapse (4) linear(k : m + 1) aligned(p, q)
for (i = 0; i < 13; i++)
for (j = 0; j < 13; j++)
for (n = 0; n < 13; n++)
for (o = 0; o < 13; o += 2)
q[k] *= p[k] + 7 * i + 14 * j + 21 * n + 28 * o, k += m + 1;
}
void
bar (float *p)
{
int i, j, n, o;
#pragma omp simd collapse (4) linear(k : m + 1)
for (i = 0; i < 13; i++)
for (j = 0; j < 13; j++)
for (n = 0; n < 13; n++)
for (o = 0; o < 13; o += 2)
a[i][j][n][o] *= p[k], k += m + 1;
}

View file

@ -0,0 +1,26 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
/* { dg-additional-options "-std=c99" { target c } } */
extern int a[13*13*13*13*2], b[1024], *k, l, m;
void
foo (int *q, float *p)
{
int *i, *j, *n, *o;
#pragma omp simd collapse (4) linear(k : m + 1) aligned(p, q)
for (i = &a[0]; i < &a[13*13*13*13*2]; i += 13*13*13*2)
for (j = &a[0]; j < &a[13*13*13*2]; j += 13*13*2)
for (n = &a[0]; n < &a[13*13*2]; n += 13*2)
for (o = &a[0]; o < &a[13*2]; o += 2)
q[k - &a[0]] *= p[k - &a[0]] + 7 * (i-&a[0]) + 14 * (j-&a[0]) + 21 * (n-&a[0]) + 28 * (o-&a[0]), k += m + 1;
}
void
bar ()
{
int *i;
#pragma omp simd safelen(16) aligned(a, b : 32)
for (i = &a[0]; i < &a[1024]; i++)
*i *= b[i - &a[0]];
}

View file

@ -0,0 +1,21 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
/* { dg-additional-options "-std=c99" { target c } } */
struct S *p; /* { dg-error "forward declaration" "" { target c++ } } */
float f;
int j;
void
foo (void)
{
#pragma omp simd linear(p) linear(f : 1)
for (int i = 0; i < 10; i++)
;
#pragma omp simd linear(j : 7.0) /* { dg-error "step expression must be integral" } */
for (int i = 0; i < 10; i++)
;
}
/* { dg-error "linear clause applied to" "" { target *-*-* } 12 } */
/* { dg-error "(incomplete|undefined) type" "" { target *-*-* } 12 } */

View file

@ -0,0 +1,19 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
/* { dg-additional-options "-std=c99" { target c } } */
void baz (void) __attribute__((noreturn));
void
foo (int x)
{
if (x)
#pragma omp simd
for (int i = 0; i < 10; i++)
baz ();
#pragma omp simd collapse(3)
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
for (int k = 0; k < 10; k++)
baz ();
}

View file

@ -0,0 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
void
foo (int i)
{
#pragma omp single copyprivate (i)
;
#pragma omp single nowait
;
#pragma omp single copyprivate (i) nowait /* { dg-error "clause must not be used together with" } */
;
#pragma omp single nowait copyprivate (i) /* { dg-error "clause must not be used together with" } */
;
}

View file

@ -22,8 +22,10 @@ void foo()
bar ();
#pragma omp parallel sections
{
bar ();
bar ();
{
bar ();
bar ();
}
#pragma omp section
bar ();
}

View file

@ -35,8 +35,10 @@ void foo()
#pragma omp sections
{
goto ok1;
ok1:;
{
goto ok1;
ok1:;
}
#pragma omp section
for (i = 0; i < 10; ++i)

View file

@ -11,7 +11,7 @@ int t;
void
foo (int x)
{
char *p;
char *pp;
struct S { int i; int j; } s;
char a[32];
double d;
@ -42,18 +42,18 @@ foo (int x)
;
#pragma omp p firstprivate (bar) // { dg-error "is not a variable" }
;
#pragma omp p reduction (+:p) // { dg-error "has invalid type for" }
#pragma omp p reduction (+:pp) // { dg-error "user defined reduction not found for" }
;
#pragma omp p reduction (*:s) // { dg-error "has invalid type for" }
#pragma omp p reduction (*:s) // { dg-error "user defined reduction not found for" }
;
#pragma omp p reduction (-:a) // { dg-error "has invalid type for" }
;
d = 0;
#pragma omp p reduction (*:d)
;
#pragma omp p reduction (|:d) // { dg-error "has invalid type for" }
#pragma omp p reduction (|:d) // { dg-error "user defined reduction not found for" }
;
#pragma omp p reduction (&&:d) // { dg-error "has invalid type for" }
#pragma omp p reduction (&&:d) // { dg-error "user defined reduction not found for" }
;
#pragma omp p copyin (d) // { dg-error "must be 'threadprivate'" }
;

View file

@ -0,0 +1,243 @@
// Test parsing of #pragma omp declare simd
// { dg-do compile }
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) \
linear (c : 4) simdlen (8) notinbranch
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a \
: 4) simdlen (4) inbranch
int f1 (int a, int *b, int c);
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
int f2 (int a, int *b, int c)
{
return a + *b + c;
}
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) simdlen (4)
template <typename T>
T f3 (int a, int *b, T c);
template <>
int f3 (int, int *, int);
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) notinbranch simdlen (4)
template <typename T>
int f4 (int a, int *b, T c)
{
return a + *b + c;
}
template <>
int f4 (int, int *, int);
template <typename T>
int f5 (int a, int *b, T c);
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) simdlen (4)
template <>
int f5 (int a, int *b, int c);
template <int N>
int f6 (int a, int *b, int c);
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) inbranch simdlen (4)
template <>
int f6<3> (int a, int *b, int c);
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (long long)) linear (c : 4) simdlen (8)
__extension__
long long f7 (long long a, long long *b, long long c);
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) notinbranch simdlen (8)
extern "C"
int f8 (int a, int *b, int c);
extern "C"
{
#pragma omp declare simd
int f9 (int a, int *b, int c);
}
namespace N1
{
namespace N2
{
#pragma omp declare simd simdlen (2) aligned (b : sizeof (long long) * 2)
__extension__ long long
f10 (long long *b)
{
return *b;
}
}
}
struct A
{
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) simdlen (4)
int f11 (int a, int *b, int c);
#pragma omp declare simd
template <int N>
int f12 (int a, int *b, int c);
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) notinbranch simdlen (8)
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) simdlen (4) inbranch
static int f13 (int a, int *b, int c);
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) simdlen (4)
int f14 (int a, int *b, int c) { return a + *b + c; }
#pragma omp declare simd
template <int N>
int f15 (int a, int *b, int c) { return a + *b + c; }
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) simdlen (4)
static int f16 (int a, int *b, int c) { return a + *b + c; }
};
template <>
int A::f12<2> (int, int *, int);
template <>
int A::f15<2> (int, int *, int);
template <typename T>
struct B
{
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8) notinbranch
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) simdlen (4) inbranch
int f17 (int a, int *b, int c);
#pragma omp declare simd
template <int N>
int f18 (int a, int *b, int c);
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) simdlen (4)
static int f19 (int a, int *b, int c);
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) simdlen (4)
int f20 (int a, int *b, int c) { return a + *b + c; }
#pragma omp declare simd
template <int N>
int f21 (int a, int *b, int c) { return a + *b + c; }
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) simdlen (4)
static int f22 (int a, int *b, int c) { return a + *b + c; }
template <int N>
int f23 (int, int *, int);
template <int N>
static int f24 (int, int *, int);
template <int N>
int f25 (int, int *, int);
template <int N>
static int f26 (int, int *, int);
};
B <int> b;
template <>
template <>
int B<int>::f18<0> (int, int *, int);
template <>
template <>
int B<int>::f21<9> (int, int *, int);
#pragma omp declare simd simdlen (8) aligned (b : 8 * sizeof (int)) uniform (a, c)
template <>
template <>
int B<int>::f23<7> (int a, int *b, int c);
#pragma omp declare simd simdlen (4) aligned (b : 8 * sizeof (int)) linear (a, c : 2)
template <>
template <>
int B<int>::f24<-1> (int a, int *b, int c);
#pragma omp declare simd simdlen (8) aligned (b : 8 * sizeof (int)) uniform (a, c)
template <>
template <>
int B<int>::f25<7> (int a, int *b, int c)
{
return a + *b + c;
}
#pragma omp declare simd simdlen (4) aligned (b : 8 * sizeof (int)) linear (a, c : 2)
template <>
template <>
int B<int>::f26<-1> (int a, int *b, int c)
{
return a + *b + c;
}
int
f27 (int x)
{
#pragma omp declare simd simdlen (8) aligned (b : 8 * sizeof (int))
extern int f28 (int a, int *b, int c);
{
x++;
#pragma omp declare simd simdlen (4) linear (c)
extern int f29 (int a, int *b, int c);
}
return x;
}
#pragma omp declare simd simdlen (16)
int
f30 (int x)
{
#pragma omp declare simd simdlen (8) aligned (b : 8 * sizeof (int))
extern int f31 (int a, int *b, int c);
return x;
}
template <int N>
struct C
{
#pragma omp declare simd simdlen (N) aligned (a : N * sizeof (int)) linear (c : N) notinbranch
int f32 (int a, int *b, int c);
};
C <2> c;
int
f33 (int x)
{
if (x)
#pragma omp declare simd simdlen (8) aligned (b : 8 * sizeof (int))
extern int f34 (int a, int *b, int c);
while (x < 10)
#pragma omp declare simd simdlen (8) aligned (b : 8 * sizeof (int))
extern int f35 (int a, int *b, int c);
return x;
}
#pragma omp declare simd simdlen (N)
template <int N>
int f36 (int);
struct D
{
int d;
#pragma omp declare simd simdlen (N) linear (a : sizeof (a) + sizeof (d) + sizeof (this) + sizeof (this->d))
template <int N>
int f37 (int a);
int e;
};
void
f38 (D &d)
{
d.f37 <12> (6);
}

View file

@ -0,0 +1,67 @@
// Test parsing of #pragma omp declare simd
// { dg-do compile }
#pragma omp declare simd
int a; // { dg-error "not immediately followed by function declaration or definition" }
#pragma omp declare simd
int fn1 (int a), fn2 (int a); // { dg-error "not immediately followed by a single function declaration or definition" }
#pragma omp declare simd
int b, fn3 (int a); // { dg-error "not immediately followed by function declaration or definition" }
#pragma omp declare simd linear (a)
int fn4 (int a), c; // { dg-error "not immediately followed by function declaration or definition" }
#pragma omp declare simd
extern "C" // { dg-error "not immediately followed by function declaration or definition" }
{
int fn5 (int a);
}
#pragma omp declare simd // { dg-error "not immediately followed by function declaration or definition" }
namespace N1
{
int fn6 (int a);
}
#pragma omp declare simd simdlen (4)
struct A
{ // { dg-error "not immediately followed by function declaration or definition" }
int fn7 (int a);
};
#pragma omp declare simd
template <typename T>
struct B
{ // { dg-error "not immediately followed by function declaration or definition" }
int fn8 (int a);
};
struct C
{
#pragma omp declare simd // { dg-error "not immediately followed by function declaration or definition" }
public: // { dg-error "expected unqualified-id before" }
int fn9 (int a);
};
int t;
#pragma omp declare simd
#pragma omp declare simd
#pragma omp threadprivate(t) // { dg-error "not immediately followed by function declaration or definition" }
int fn10 (int a);
#pragma omp declare simd inbranch notinbranch // { dg-error "clause is incompatible with" }
int fn11 (int);
struct D
{
int d;
#pragma omp declare simd simdlen (N) linear (a : sizeof (e) + sizeof (this->e)) // { dg-error "was not declared" }
template <int N>
int fn12 (int a);
int e;
};
// { dg-error "has no member" "" { target *-*-* } 61 }

View file

@ -0,0 +1,70 @@
// { dg-do compile }
// { dg-options "-fopenmp" }
extern int a[][10], a2[][10];
int b[10], c[10][2], d[10], e[10], f[10];
int b2[10], c2[10][2], d2[10], e2[10], f2[10];
int k[10], l[10], m[10], n[10], o;
int *p;
void bar (void);
int t[10];
#pragma omp threadprivate (t)
template <int N>
void
foo (int g[3][10], int h[4][8], int i[2][10], int j[][9],
int g2[3][10], int h2[4][8], int i2[2][10], int j2[][9])
{
#pragma omp task depend(out: t[2:5])
;
#pragma omp task depend(inout: k[0.5:]) // { dg-error "low bound \[^\n\r]* of array section does not have integral type" }
;
#pragma omp task depend(in: l[:7.5f]) // { dg-error "length \[^\n\r]* of array section does not have integral type" }
;
#pragma omp task depend(out: m[p:]) // { dg-error "low bound \[^\n\r]* of array section does not have integral type" }
;
#pragma omp task depend(inout: n[:p]) // { dg-error "length \[^\n\r]* of array section does not have integral type" }
;
#pragma omp task depend(in: o[2:5]) // { dg-error "does not have pointer or array type" }
;
#pragma omp task depend(out: a[:][2:4]) // { dg-error "array type length expression must be specified" }
;
#pragma omp task depend(in: d[11:]) // { dg-error "low bound \[^\n\r]* above array section size" }
;
#pragma omp task depend(out: e[:11]) // { dg-error "length \[^\n\r]* above array section size" }
;
#pragma omp task depend(out: f[1:10]) // { dg-error "high bound \[^\n\r]* above array section size" }
;
#pragma omp task depend(in: g[:][2:4]) // { dg-error "for pointer type length expression must be specified" }
;
#pragma omp task depend(out: i[:1][11:]) // { dg-error "low bound \[^\n\r]* above array section size" }
;
#pragma omp task depend(in: j[3:4][:10]) // { dg-error "length \[^\n\r]* above array section size" }
;
#pragma omp task depend(out: j[30:10][5:5]) // { dg-error "high bound \[^\n\r]* above array section size" }
;
#pragma omp task depend(out: a2[:3][2:4])
;
#pragma omp task depend(inout: b2[0:])
;
#pragma omp task depend(inout: c2[:3][1:1])
;
#pragma omp task depend(in: d2[9:])
;
#pragma omp task depend(out: e2[:10])
;
#pragma omp task depend(out: f2[1:9])
;
#pragma omp task depend(in: g2[:2][2:4])
;
#pragma omp task depend(in: h2[2:2][0:])
;
#pragma omp task depend(inout: h2[:1][:3])
;
#pragma omp task depend(out: i2[:1][9:])
;
#pragma omp task depend(in: j2[3:4][:9])
;
#pragma omp task depend(out: j2[30:10][5:4])
;
}

View file

@ -0,0 +1,87 @@
// { dg-do compile }
// { dg-options "-fopenmp" }
extern int a[][10], a2[][10];
int b[10], c[10][2], d[10], e[10], f[10];
int b2[10], c2[10][2], d2[10], e2[10], f2[10];
int k[10], l[10], m[10], n[10], o;
int *p;
void bar (void);
int t[10];
#pragma omp threadprivate (t)
template <int N>
void
foo (int g[3][10], int h[4][8], int i[2][10], int j[][9],
int g2[3][10], int h2[4][8], int i2[2][10], int j2[][9])
{
#pragma omp task depend(in: bar[2:5]) // { dg-error "is not a variable" }
;
#pragma omp task depend(out: t[2:5])
;
#pragma omp task depend(inout: k[0.5:]) // { dg-error "low bound \[^\n\r]* of array section does not have integral type" }
;
#pragma omp task depend(in: l[:7.5f]) // { dg-error "length \[^\n\r]* of array section does not have integral type" }
;
#pragma omp task depend(out: m[p:]) // { dg-error "low bound \[^\n\r]* of array section does not have integral type" }
;
#pragma omp task depend(inout: n[:p]) // { dg-error "length \[^\n\r]* of array section does not have integral type" }
;
#pragma omp task depend(in: o[2:5]) // { dg-error "does not have pointer or array type" }
;
#pragma omp task depend(out: a[:][2:4]) // { dg-error "array type length expression must be specified" }
;
#pragma omp task depend(inout: b[-1:]) // { dg-error "negative low bound in array section" }
;
#pragma omp task depend(inout: c[:-3][1:1]) // { dg-error "negative length in array section" }
;
#pragma omp task depend(in: d[11:]) // { dg-error "low bound \[^\n\r]* above array section size" }
;
#pragma omp task depend(out: e[:11]) // { dg-error "length \[^\n\r]* above array section size" }
;
#pragma omp task depend(out: f[1:10]) // { dg-error "high bound \[^\n\r]* above array section size" }
;
#pragma omp task depend(in: g[:][2:4]) // { dg-error "for pointer type length expression must be specified" }
;
#pragma omp task depend(in: h[2:2][-1:]) // { dg-error "negative low bound in array section" }
;
#pragma omp task depend(inout: h[:1][:-3]) // { dg-error "negative length in array section" }
;
#pragma omp task depend(out: i[:1][11:]) // { dg-error "low bound \[^\n\r]* above array section size" }
;
#pragma omp task depend(in: j[3:4][:10]) // { dg-error "length \[^\n\r]* above array section size" }
;
#pragma omp task depend(out: j[30:10][5:5]) // { dg-error "high bound \[^\n\r]* above array section size" }
;
#pragma omp task depend(out: a2[:3][2:4])
;
#pragma omp task depend(inout: b2[0:])
;
#pragma omp task depend(inout: c2[:3][1:1])
;
#pragma omp task depend(in: d2[9:])
;
#pragma omp task depend(out: e2[:10])
;
#pragma omp task depend(out: f2[1:9])
;
#pragma omp task depend(in: g2[:2][2:4])
;
#pragma omp task depend(in: h2[2:2][0:])
;
#pragma omp task depend(inout: h2[:1][:3])
;
#pragma omp task depend(out: i2[:1][9:])
;
#pragma omp task depend(in: j2[3:4][:9])
;
#pragma omp task depend(out: j2[30:10][5:4])
;
}
void
baz (int g[3][10], int h[4][8], int i[2][10], int j[][9],
int g2[3][10], int h2[4][8], int i2[2][10], int j2[][9])
{
foo<0> (g, h, i, j, g2, h2, i2, j2);
}

View file

@ -0,0 +1,32 @@
// { dg-do compile }
void
foo (int x)
{
bad1: // { dg-error "jump to label" }
#pragma omp target
goto bad1; // { dg-error "from here|exits OpenMP" }
goto bad2; // { dg-error "from here" }
#pragma omp target
{
bad2: ; // { dg-error "jump to label|enters OpenMP" }
}
#pragma omp target
{
int i;
goto ok1;
for (i = 0; i < 10; ++i)
{ ok1: break; }
}
switch (x)
{
#pragma omp target
{ case 0:; } // { dg-error "jump|enters" }
}
}
// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
// { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }

View file

@ -0,0 +1,32 @@
// { dg-do compile }
void
foo (int x, int y)
{
bad1: // { dg-error "jump to label" }
#pragma omp target data map(tofrom: y)
goto bad1; // { dg-error "from here|exits OpenMP" }
goto bad2; // { dg-error "from here" }
#pragma omp target data map(tofrom: y)
{
bad2: ; // { dg-error "jump to label|enters OpenMP" }
}
#pragma omp target data map(tofrom: y)
{
int i;
goto ok1;
for (i = 0; i < 10; ++i)
{ ok1: break; }
}
switch (x)
{
#pragma omp target data map(tofrom: y)
{ case 0:; } // { dg-error "jump|enters" }
}
}
// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
// { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }

View file

@ -0,0 +1,32 @@
// { dg-do compile }
void
foo (int x)
{
bad1: // { dg-error "jump to label" }
#pragma omp taskgroup
goto bad1; // { dg-error "from here|exits OpenMP" }
goto bad2; // { dg-error "from here" }
#pragma omp taskgroup
{
bad2: ; // { dg-error "jump to label|enters OpenMP" }
}
#pragma omp taskgroup
{
int i;
goto ok1;
for (i = 0; i < 10; ++i)
{ ok1: break; }
}
switch (x)
{
#pragma omp taskgroup
{ case 0:; } // { dg-error "jump|enters" }
}
}
// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
// { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }

View file

@ -0,0 +1,66 @@
// { dg-do compile }
void
foo (int x)
{
bad1: // { dg-error "jump to label" }
#pragma omp target teams
goto bad1; // { dg-error "from here|exits OpenMP" }
goto bad2; // { dg-error "from here" }
#pragma omp target teams
{
bad2: ; // { dg-error "jump to label|enters OpenMP" }
}
#pragma omp target teams
{
int i;
goto ok1;
for (i = 0; i < 10; ++i)
{ ok1: break; }
}
switch (x)
{
#pragma omp target teams
{ case 0:; } // { dg-error "jump|enters" }
}
}
void
bar (int x)
{
bad1: // { dg-error "jump to label" }
#pragma omp target
#pragma omp teams
goto bad1; // { dg-error "from here|exits OpenMP" }
goto bad2; // { dg-error "from here" }
#pragma omp target
#pragma omp teams
{
bad2: ; // { dg-error "jump to label|enters OpenMP" }
}
#pragma omp target
#pragma omp teams
{
int i;
goto ok1;
for (i = 0; i < 10; ++i)
{ ok1: break; }
}
switch (x)
{
#pragma omp target
#pragma omp teams
{ case 0:; } // { dg-error "jump|enters" }
}
}
// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
// { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 37 }
// { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 39 }

View file

@ -0,0 +1,119 @@
// { dg-do compile }
// { dg-options "-fopenmp" }
namespace N1
{
#pragma omp declare reduction (| : long int : omp_out |= omp_in) // { dg-error "predeclared arithmetic type" }
#pragma omp declare reduction (+ : char : omp_out += omp_in) // { dg-error "predeclared arithmetic type" }
typedef short T;
#pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "predeclared arithmetic type" }
#pragma omp declare reduction (* : _Complex double : omp_out *= omp_in)// { dg-error "predeclared arithmetic type" }
}
namespace N2
{
template <typename T1, typename T2, typename T3, typename T4>
struct S
{
#pragma omp declare reduction (| : T1 : omp_out |= omp_in) // { dg-error "predeclared arithmetic type" }
#pragma omp declare reduction (+ : T2 : omp_out += omp_in) // { dg-error "predeclared arithmetic type" }
typedef T3 T;
#pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "predeclared arithmetic type" }
#pragma omp declare reduction (* : T4 : omp_out *= omp_in) // { dg-error "predeclared arithmetic type" }
};
S<long int, char, short, _Complex double> s;
template <typename T1, typename T2, typename T3, typename T4>
int foo ()
{
#pragma omp declare reduction (| : T1 : omp_out |= omp_in) // { dg-error "predeclared arithmetic type" }
#pragma omp declare reduction (+ : T2 : omp_out += omp_in) // { dg-error "predeclared arithmetic type" }
typedef T3 T;
#pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "predeclared arithmetic type" }
#pragma omp declare reduction (* : T4 : omp_out *= omp_in) // { dg-error "predeclared arithmetic type" }
return 0;
}
int x = foo <long int, char, short, _Complex double> ();
}
namespace N3
{
void bar ();
#pragma omp declare reduction (| : __typeof (bar) : omp_out |= omp_in)// { dg-error "function or array type" }
#pragma omp declare reduction (+ : char () : omp_out += omp_in) // { dg-error "function or array type" }
typedef short T;
#pragma omp declare reduction (min : T[2] : omp_out += omp_in) // { dg-error "function or array type" }
#pragma omp declare reduction (baz : char & : omp_out *= omp_in) // { dg-error "reference type" }
}
namespace N4
{
void bar ();
template <typename T1, typename T2, typename T3, typename T4>
struct S
{
#pragma omp declare reduction (| : T1 : omp_out |= omp_in) // { dg-error "function or array type" }
#pragma omp declare reduction (+ : T2 : omp_out += omp_in) // { dg-error "function or array type" }
typedef T3 T;
#pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "function or array type" }
#pragma omp declare reduction (baz : T4 : omp_out *= omp_in) // { dg-error "function or array type" }
};
S<__typeof (bar), char (), short [3], char []> s;
template <typename T1, typename T2, typename T3, typename T4>
int foo ()
{
#pragma omp declare reduction (| : T1 : omp_out |= omp_in) // { dg-error "function or array type" }
#pragma omp declare reduction (+ : T2 : omp_out += omp_in) // { dg-error "function or array type" }
typedef T3 T;
#pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "function or array type" }
#pragma omp declare reduction (baz : T4 : omp_out *= omp_in) // { dg-error "function or array type" }
return 0;
}
int x = foo <__typeof (bar), char (), short[], char [2]> ();
}
namespace N5
{
template <typename T>
struct S
{
#pragma omp declare reduction (baz : T : omp_out *= omp_in) // { dg-error "reference type" }
};
S<char &> s;
template <typename T>
int foo ()
{
#pragma omp declare reduction (baz : T : omp_out *= omp_in) // { dg-error "reference type" }
return 0;
}
int x = foo <char &> ();
}
namespace N6
{
struct A { int a; A () : a (0) {} };
#pragma omp declare reduction (| : const A : omp_out.a |= omp_in.a) // { dg-error "const, volatile or __restrict" }
#pragma omp declare reduction (+ : __const A : omp_out.a += omp_in.a) // { dg-error "const, volatile or __restrict" }
typedef volatile A T;
#pragma omp declare reduction (min : T : omp_out.a += omp_in.a) // { dg-error "const, volatile or __restrict" }
#pragma omp declare reduction (* : A *__restrict : omp_out->a *= omp_in->a)// { dg-error "const, volatile or __restrict" }
}
namespace N7
{
struct A { int a; A () : a (0) {} };
template <typename T1, typename T2, typename T3, typename T4>
struct S
{
#pragma omp declare reduction (| : T1 : omp_out |= omp_in) // { dg-error "const, volatile or __restrict" }
#pragma omp declare reduction (+ : T2 : omp_out += omp_in) // { dg-error "const, volatile or __restrict" }
typedef T3 T;
#pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "const, volatile or __restrict" }
#pragma omp declare reduction (* : T4 : omp_out *= omp_in) // { dg-error "const, volatile or __restrict" }
};
S<const A, __const A, volatile A, A *__restrict> s;
template <typename T1, typename T2, typename T3, typename T4>
int foo ()
{
#pragma omp declare reduction (| : T1 : omp_out |= omp_in) // { dg-error "const, volatile or __restrict" }
#pragma omp declare reduction (+ : T2 : omp_out += omp_in) // { dg-error "const, volatile or __restrict" }
typedef T3 T;
#pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "const, volatile or __restrict" }
#pragma omp declare reduction (* : T4 : omp_out *= omp_in) // { dg-error "const, volatile or __restrict" }
return 0;
}
int x = foo <const A, __const A, volatile A, A *__restrict> ();
}

View file

@ -0,0 +1,119 @@
// { dg-do compile }
// { dg-options "-fopenmp" }
struct W { int w; W () : w (0) {} W (int x) : w (x) {} };
namespace N1
{
int v;
#pragma omp declare reduction (foo : long int : omp_out |= v) // { dg-error "combiner refers to variable" }
#pragma omp declare reduction (foo : char : omp_out = v) // { dg-error "combiner refers to variable" }
typedef short T;
#pragma omp declare reduction (foo : T : omp_out += N1::v) // { dg-error "combiner refers to variable" }
#pragma omp declare reduction (foo : int : v *= omp_in) // { dg-error "combiner refers to variable" }
#pragma omp declare reduction (foo : W : omp_out.w *= omp_in.w + v) // { dg-error "combiner refers to variable" }
}
namespace N2
{
int v;
template <typename T1, typename T2, typename T3, typename T4, typename T5>
struct S
{
#pragma omp declare reduction (foo : T1 : omp_out |= v) // { dg-error "combiner refers to variable" }
#pragma omp declare reduction (foo : T2 : omp_out = v) // { dg-error "combiner refers to variable" }
typedef T3 T;
#pragma omp declare reduction (foo : T : omp_out += N1::v) // { dg-error "combiner refers to variable" }
#pragma omp declare reduction (foo : T4 : v *= omp_in) // { dg-error "combiner refers to variable" }
#pragma omp declare reduction (foo : T5 : omp_out.w *= omp_in.w + v) // { dg-error "combiner refers to variable" }
};
S<long int, char, short, _Complex double, W> s;
template <typename T1, typename T2, typename T3, typename T4, typename T5>
int foo ()
{
#pragma omp declare reduction (foo : T1 : omp_out |= v) // { dg-error "combiner refers to variable" }
#pragma omp declare reduction (foo : T2 : omp_out = v) // { dg-error "combiner refers to variable" }
typedef T3 T;
#pragma omp declare reduction (foo : T : omp_out += N1::v) // { dg-error "combiner refers to variable" }
#pragma omp declare reduction (foo : T4 : v *= omp_in) // { dg-error "combiner refers to variable" }
#pragma omp declare reduction (foo : T5 : omp_out.w *= omp_in.w + v) // { dg-error "combiner refers to variable" }
return 0;
}
int x = foo <long int, char, short, _Complex double, W> ();
}
namespace N3
{
int v;
#pragma omp declare reduction (foo : long int : omp_out |= omp_in) initializer (omp_priv = v) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : char : omp_out += omp_in) initializer (omp_priv ((char) N3::v)) // { dg-error "initializer refers to variable" }
typedef short T;
#pragma omp declare reduction (foo : T : omp_out += omp_in) initializer (omp_priv = (short) v) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : _Complex double : omp_out *= omp_in) initializer (omp_priv (v)) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : W : omp_out.w *= omp_in.w) initializer (omp_priv (N3::v)) // { dg-error "initializer refers to variable" }
}
namespace N4
{
int v;
template <typename T1, typename T2, typename T3, typename T4, typename T5>
struct S
{
#pragma omp declare reduction (foo : T1 : omp_out |= omp_in) initializer (omp_priv = v) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : T2 : omp_out += omp_in) initializer (omp_priv ((char) N3::v)) // { dg-error "initializer refers to variable" }
typedef T3 T;
#pragma omp declare reduction (foo : T : omp_out += omp_in) initializer (omp_priv = (short) v) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : T4 : omp_out *= omp_in) initializer (omp_priv (v)) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : T5 : omp_out.w *= omp_in.w) initializer (omp_priv (N3::v)) // { dg-error "initializer refers to variable" }
};
S<long int, char, short, _Complex double, W> s;
template <typename T1, typename T2, typename T3, typename T4, typename T5>
int foo ()
{
#pragma omp declare reduction (foo : T1 : omp_out |= omp_in) initializer (omp_priv = v) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : T2 : omp_out += omp_in) initializer (omp_priv ((char) N3::v)) // { dg-error "initializer refers to variable" }
typedef T3 T;
#pragma omp declare reduction (foo : T : omp_out += omp_in) initializer (omp_priv = (short) v) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : T4 : omp_out *= omp_in) initializer (omp_priv (v)) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : T5 : omp_out.w *= omp_in.w) initializer (omp_priv (N3::v)) // { dg-error "initializer refers to variable" }
return 0;
}
int x = foo <long int, char, short, _Complex double, W> ();
}
template <typename T>
void init (T &, int &);
template <typename T>
void initializer (T, int &);
namespace N5
{
int v;
#pragma omp declare reduction (foo : long int : omp_out |= omp_in) initializer (init (omp_priv, v)) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : char : omp_out += omp_in) initializer (initializer (&omp_priv, N3::v)) // { dg-error "initializer refers to variable" }
typedef short T;
#pragma omp declare reduction (foo : T : omp_out += omp_in) initializer (init (omp_priv, v)) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : _Complex double : omp_out *= omp_in) initializer (initializer (&omp_priv, v)) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : W : omp_out.w *= omp_in.w) initializer (init (omp_priv, N3::v)) // { dg-error "initializer refers to variable" }
}
namespace N6
{
int v;
template <typename T1, typename T2, typename T3, typename T4, typename T5>
struct S
{
#pragma omp declare reduction (foo : T1 : omp_out |= omp_in) initializer (initializer (&omp_priv, v)) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : T2 : omp_out += omp_in) initializer (init (omp_priv, N3::v)) // { dg-error "initializer refers to variable" }
typedef T3 T;
#pragma omp declare reduction (foo : T : omp_out += omp_in) initializer (init (omp_priv, v)) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : T4 : omp_out *= omp_in) initializer (init (omp_priv, v)) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : T5 : omp_out.w *= omp_in.w) initializer (initializer (&omp_priv, N3::v)) // { dg-error "initializer refers to variable" }
};
S<long int, char, short, _Complex double, W> s;
template <typename T1, typename T2, typename T3, typename T4, typename T5>
int foo ()
{
#pragma omp declare reduction (foo : T1 : omp_out |= omp_in) initializer (init (omp_priv, v)) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : T2 : omp_out += omp_in) initializer (init (omp_priv, N3::v)) // { dg-error "initializer refers to variable" }
typedef T3 T;
#pragma omp declare reduction (foo : T : omp_out += omp_in) initializer (initializer (&omp_priv, v)) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : T4 : omp_out *= omp_in) initializer (init (omp_priv, v)) // { dg-error "initializer refers to variable" }
#pragma omp declare reduction (foo : T5 : omp_out.w *= omp_in.w) initializer (initializer (omp_priv, N3::v)) // { dg-error "initializer refers to variable" }
return 0;
}
int x = foo <long int, char, short, _Complex double, W> ();
}

View file

@ -0,0 +1,191 @@
// { dg-do compile }
// { dg-options "-fopenmp" }
struct S { int s; S () : s (0) {} S (int x) : s (x) {} ~S () {} };
struct T { int t; T () : t (0) {} T (int x) : t (x) {} ~T () {} };
#pragma omp declare reduction (+: ::S: omp_out.s += omp_in.s)
#pragma omp declare reduction (*: S: omp_out.s *= omp_in.s) \
initializer (omp_priv (1))
#pragma omp declare reduction (foo: S: omp_out.s += omp_in.s)
void
f1 ()
{
S s, s2;
T t;
#pragma omp declare reduction (+: T: omp_out.t += omp_in.t)
#pragma omp parallel reduction (+: t) reduction (foo: s) reduction (*: s2)
s.s = 1, t.t = 1, s2.s = 2;
#pragma omp parallel reduction (::operator +: s)
s.s = 1;
#pragma omp parallel reduction (+: s)
s.s = 1;
}
template <int N>
int
f2 ()
{
S s, s2;
T t;
#pragma omp declare reduction (+: T: omp_out.t += omp_in.t)
#pragma omp parallel reduction (+: t) reduction (foo: s) reduction (*: s2)
s.s = 1, t.t = 1, s2.s = 2;
#pragma omp parallel reduction (::operator +: s)
s.s = 1;
#pragma omp parallel reduction (+: s)
s.s = 1;
return 0;
}
int x = f2<0> ();
void bar (S &);
void
f3 ()
{
#pragma omp declare reduction (foo: S: omp_out.s += omp_in.s) initializer (bar (omp_priv))
#pragma omp declare reduction (bar: S: omp_out.s += omp_in.s) initializer (bar (omp_orig)) // { dg-error "one of the initializer call arguments should be" }
}
template <typename T>
int
f4 ()
{
#pragma omp declare reduction (foo: T: omp_out.s += omp_in.s) initializer (bar (omp_priv))
#pragma omp declare reduction (bar: T: omp_out.s += omp_in.s) initializer (bar (omp_orig)) // { dg-error "one of the initializer call arguments should be" }
return 0;
}
int y = f4 <S> ();
namespace N1
{
#pragma omp declare reduction (+: ::S: omp_out.s *= omp_in.s) // { dg-error "previous" }
#pragma omp declare reduction (+: S: omp_out.s += omp_in.s) // { dg-error "redeclaration of" }
void
f5 ()
{
#pragma omp declare reduction (f5: S: omp_out.s *= omp_in.s) // { dg-error "previous" }
#pragma omp declare reduction (f5: ::S: omp_out.s += omp_in.s) // { dg-error "redeclaration of" }
}
}
namespace N2
{
struct U
{
#pragma omp declare reduction (bar: S: omp_out.s *= omp_in.s) // { dg-error "with" }
#pragma omp declare reduction (bar: S: omp_out.s += omp_in.s) // { dg-error "cannot be overloaded" }
};
}
namespace N3
{
#pragma omp declare reduction (+: ::S: omp_out.s *= omp_in.s) // { dg-error "previous" }
#pragma omp declare reduction (+: T: omp_out.t += omp_in.t)
#pragma omp declare reduction (+: S: omp_out.s += omp_in.s) // { dg-error "redeclaration of" }
#pragma omp declare reduction (n3: long: omp_out += omp_in) // { dg-error "previous" }
#pragma omp declare reduction (n3: long int: omp_out += omp_in) // { dg-error "redeclaration of" }
#pragma omp declare reduction (n3: short unsigned: omp_out += omp_in)
#pragma omp declare reduction (n3: short int: omp_out += omp_in)
void
f6 ()
{
#pragma omp declare reduction (f6: T: omp_out.t += omp_in.t)
#pragma omp declare reduction (f6: S: omp_out.s *= omp_in.s) // { dg-error "previous" }
#pragma omp declare reduction (f6: ::S: omp_out.s += omp_in.s) // { dg-error "redeclaration of" }
#pragma omp declare reduction (f6: long: omp_out += omp_in) // { dg-error "previous" }
#pragma omp declare reduction (f6: long int: omp_out += omp_in) // { dg-error "redeclaration of" }
#pragma omp declare reduction (f6: short unsigned: omp_out += omp_in)
#pragma omp declare reduction (f6: short int: omp_out += omp_in)
}
}
namespace N4
{
struct U
{
#pragma omp declare reduction (bar: T: omp_out.t += omp_in.t)
#pragma omp declare reduction (bar: S: omp_out.s *= omp_in.s) // { dg-error "with" }
#pragma omp declare reduction (bar: S: omp_out.s += omp_in.s) // { dg-error "cannot be overloaded" }
#pragma omp declare reduction (bar: long: omp_out += omp_in) // { dg-error "with" }
#pragma omp declare reduction (bar: long int: omp_out += omp_in) // { dg-error "cannot be overloaded" }
#pragma omp declare reduction (bar: short unsigned: omp_out += omp_in)
#pragma omp declare reduction (bar: short int: omp_out += omp_in)
};
}
namespace N5
{
template <typename T>
int
f7 ()
{
#pragma omp declare reduction (f7: T: omp_out.s *= omp_in.s) // { dg-error "previous" }
#pragma omp declare reduction (f7: T: omp_out.s += omp_in.s) // { dg-error "redeclaration of" }
return 0;
}
int x = f7 <S> ();
template <typename T>
struct U
{
#pragma omp declare reduction (bar: T: omp_out.s *= omp_in.s) // { dg-error "with" }
#pragma omp declare reduction (bar: T: omp_out.s += omp_in.s) // { dg-error "cannot be overloaded" }
};
U<S> u;
}
namespace N6
{
template <typename U>
int
f8 ()
{
#pragma omp declare reduction (f8: T: omp_out.t += omp_in.t)
#pragma omp declare reduction (f8: U: omp_out.s *= omp_in.s) // { dg-error "previous" }
#pragma omp declare reduction (f8: ::S: omp_out.s += omp_in.s) // { dg-error "redeclaration of" }
#pragma omp declare reduction (f8: long: omp_out += omp_in) // { dg-error "previous" }
#pragma omp declare reduction (f8: long int: omp_out += omp_in) // { dg-error "redeclaration of" }
#pragma omp declare reduction (f8: short unsigned: omp_out += omp_in)
#pragma omp declare reduction (f8: short int: omp_out += omp_in)
return 0;
}
int x = f8 <S> ();
template <typename V>
struct U
{
typedef V V2;
#pragma omp declare reduction (bar: T: omp_out.t += omp_in.t)
#pragma omp declare reduction (bar: V: omp_out.s *= omp_in.s) // { dg-error "with" }
#pragma omp declare reduction (bar: V2: omp_out.s += omp_in.s) // { dg-error "cannot be overloaded" }
#pragma omp declare reduction (bar: long: omp_out += omp_in) // { dg-error "with" }
#pragma omp declare reduction (bar: long int: omp_out += omp_in) // { dg-error "cannot be overloaded" }
#pragma omp declare reduction (bar: short unsigned: omp_out += omp_in)
#pragma omp declare reduction (bar: short int: omp_out += omp_in)
};
U<S> u;
}
namespace N7
{
#pragma omp declare reduction (+: S: omp_out.s += omp_in.s) initializer (omp_priv) // { dg-error "invalid initializer clause" }
#pragma omp declare reduction (+: T: omp_out.t += omp_in.t) initializer (omp_priv ()) // { dg-error "invalid initializer clause" }
}
namespace N8
{
struct A { int a; A (); ~A (); };
struct B { int b; B (); ~B (); B (int); };
struct C : public A, B { int c; C (); ~C (); };
#pragma omp declare reduction (+:B:omp_out.b += omp_in.b) initializer (omp_priv (4))
void bar (C &);
void baz ()
{
C a;
#pragma omp parallel reduction (+:a) // { dg-error "user defined reduction with constructor initializer for base class" }
bar (a);
}
}

View file

@ -0,0 +1,14 @@
// { dg-do compile }
struct S; // { dg-error "forward declaration" }
#pragma omp declare reduction (+:S:omp_out.s += omp_in.s) // { dg-error "invalid use of incomplete type" }
struct S { int s; S () : s (1) {} };
#pragma omp declare reduction (*:S:omp_out.s *= omp_in.s)
void
foo ()
{
S s;
#pragma omp parallel reduction (S::~S:s) // { dg-error "invalid reduction-identifier" }
s.s = 1;
}

View file

@ -0,0 +1,41 @@
// { dg-do compile }
struct S
{
int s;
S () : s (0) {}
private:
#pragma omp declare reduction (+:S:omp_out.s += omp_in.s) // { dg-error "is private" }
protected:
#pragma omp declare reduction (-:S:omp_out.s += omp_in.s) // { dg-error "is protected" }
};
struct T : public S
{
void foo ()
{
S s;
#pragma omp parallel reduction (S::operator +:s) // { dg-error "within this context" }
s.s = 1;
S t;
#pragma omp parallel reduction (S::operator -:t)
t.s = 1;
S u;
#pragma omp parallel reduction (+:u) // { dg-error "within this context" }
u.s = 1;
S v;
#pragma omp parallel reduction (-:v)
v.s = 1;
}
};
void
foo ()
{
S s;
#pragma omp parallel reduction (S::operator +:s) // { dg-error "within this context" }
s.s = 1;
S t;
#pragma omp parallel reduction (S::operator -:t) // { dg-error "within this context" }
t.s = 1;
}

View file

@ -0,0 +1,59 @@
// { dg-do compile }
struct A { int a; A () : a (0) {} };
struct B { int b; B () : b (0) {} };
struct C : public A, B { int c; C () : c (0) {} };
struct D { int d; D () : d (0) {} };
struct E { int e; E () : e (0) {} };
struct F : public D, E { int f; F () : f (0) {} };
struct G : public C, F { int g; G () : g (0) {} };
#pragma omp declare reduction (+: A : omp_out.a += omp_in.a) // { dg-message "operator" }
#pragma omp declare reduction (+: B : omp_out.b += omp_in.b) // { dg-message "operator" }
#pragma omp declare reduction (+: D : omp_out.d += omp_in.d)
#pragma omp declare reduction (+: E : omp_out.e += omp_in.e)
#pragma omp declare reduction (+: F : omp_out.f += omp_in.f) // { dg-message "operator" }
void
f1 ()
{
G g;
#pragma omp parallel reduction (+: g) // { dg-error "user defined reduction lookup is ambiguous" }
{
g.g++;
}
}
#pragma omp declare reduction (*: A : omp_out.a += omp_in.a)
#pragma omp declare reduction (*: B : omp_out.b += omp_in.b)
#pragma omp declare reduction (*: D : omp_out.d += omp_in.d)
#pragma omp declare reduction (*: E : omp_out.e += omp_in.e)
#pragma omp declare reduction (*: F : omp_out.f += omp_in.f)
#pragma omp declare reduction (*: G : omp_out.g += omp_in.g)
void
f2 ()
{
G g;
#pragma omp parallel reduction (*: g)
{
g.g++;
}
}
#pragma omp declare reduction (|: A : omp_out.a += omp_in.a)
#pragma omp declare reduction (|: B : omp_out.b += omp_in.b)
#pragma omp declare reduction (|: C : omp_out.c += omp_in.c) // { dg-message "operator" }
#pragma omp declare reduction (|: D : omp_out.d += omp_in.d)
#pragma omp declare reduction (|: E : omp_out.e += omp_in.e)
#pragma omp declare reduction (|: F : omp_out.f += omp_in.f) // { dg-message "operator" }
void
f3 ()
{
G g;
#pragma omp parallel reduction (|: g) // { dg-error "user defined reduction lookup is ambiguous" }
{
g.g++;
}
}

View file

@ -28,6 +28,6 @@ int main(void)
/* Check that outer loop is parallelized. */
/* { dg-final { scan-tree-dump-times "parallelizing outer loop" 1 "parloops" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 4 "optimized" } } */
/* { dg-final { cleanup-tree-dump "parloops" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

View file

@ -28,6 +28,6 @@ int main(void)
}
/* { dg-final { scan-tree-dump-times "parallelizing outer loop" 1 "parloops" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 4 "optimized" } } */
/* { dg-final { cleanup-tree-dump "parloops" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

View file

@ -28,6 +28,6 @@ int main(void)
/* Check that outer loop is parallelized. */
/* { dg-final { scan-tree-dump-times "parallelizing outer loop" 1 "parloops" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 4 "optimized" } } */
/* { dg-final { cleanup-tree-dump "parloops" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

View file

@ -32,6 +32,6 @@ int main(void)
/* { dg-final { scan-tree-dump-times "parallelizing outer loop" 1 "parloops" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 4 "optimized" } } */
/* { dg-final { cleanup-tree-dump "parloops" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

View file

@ -45,6 +45,6 @@ int main(void)
}
/* { dg-final { scan-tree-dump-times "parallelizing outer loop" 1 "parloops" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 4 "optimized" } } */
/* { dg-final { cleanup-tree-dump "parloops" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

View file

@ -46,6 +46,6 @@ int main(void)
/* Check that outer loop is parallelized. */
/* { dg-final { scan-tree-dump-times "parallelizing outer loop" 1 "parloops" } } */
/* { dg-final { scan-tree-dump-times "parallelizing inner loop" 0 "parloops" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 4 "optimized" } } */
/* { dg-final { cleanup-tree-dump "parloops" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

View file

@ -28,6 +28,6 @@ int main(void)
/* Check that the first loop in parloop got parallelized. */
/* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 1 "parloops" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 4 "optimized" } } */
/* { dg-final { cleanup-tree-dump "parloops" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

View file

@ -35,9 +35,10 @@ void foo()
#pragma omp sections
{
goto ok1;
ok1:;
{
goto ok1;
ok1:;
}
#pragma omp section
for (i = 0; i < 10; ++i)
if (test(i))

View file

@ -11,7 +11,7 @@ int t;
void
foo (int x)
{
char *p;
char *pp;
struct S { int i; int j; } s;
char a[32];
double d;
@ -42,11 +42,11 @@ foo (int x)
;
#pragma omp p firstprivate (bar) /* { dg-error "is not a variable" } */
;
#pragma omp p reduction (+:p) /* { dg-error "has invalid type for" } */
#pragma omp p reduction (+:pp) /* { dg-error "user defined reduction not found for" } */
;
#pragma omp p reduction (*:s) /* { dg-error "has invalid type for" } */
#pragma omp p reduction (*:s) /* { dg-error "user defined reduction not found for" } */
;
#pragma omp p reduction (-:a) /* { dg-error "has invalid type for" } */
#pragma omp p reduction (-:a) /* { dg-error "user defined reduction not found for" } */
;
d = 0;
#pragma omp p reduction (*:d)

View file

@ -20,5 +20,5 @@ int foo (void)
}
}
/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop_runtime_start" 3 "optimized" } } */
/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop_runtime" 3 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

View file

@ -0,0 +1,100 @@
/* Test parsing of #pragma omp declare simd */
/* { dg-do compile } */
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) \
linear (c : 4) simdlen (8) notinbranch
#pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a \
: 4) simdlen (4) inbranch
int f1 (int a, int *b, int c);
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
int f2 (int a, int *b, int c)
{
return a + *b + c;
}
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (long long)) linear (c : 4) simdlen (8)
__extension__
long long f3 (long long a, long long *b, long long c);
int
f4 (int x)
{
#pragma omp declare simd simdlen (8) aligned (b : 8 * sizeof (int))
__extension__ __extension__ __extension__
extern int f5 (int a, int *b, int c);
{
x++;
#pragma omp declare simd simdlen (4) linear (c)
extern int f6 (int a, int *b, int c);
}
return x;
}
#pragma omp declare simd simdlen (16)
int
f7 (int x)
{
#pragma omp declare simd simdlen (8) aligned (b : 8 * sizeof (int))
extern int f8 (int a, int *b, int c);
return x;
}
int
f9 (int x)
{
if (x)
#pragma omp declare simd simdlen (8) aligned (b : 8 * sizeof (int))
extern int f10 (int a, int *b, int c);
while (x < 10)
#pragma omp declare simd simdlen (8) aligned (b : 8 * sizeof (int))
extern int f11 (int a, int *b, int c);
return x;
}
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
int f12 (int c; int *b; int a; int a, int *b, int c);
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
int
f13 (int c; int *b; int a; int a, int *b, int c)
{
return a + *b + c;
}
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
int
f14 (a, b, c)
int a, c;
int *b;
{
return a + *b + c;
}
#pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
int
f15 (int a, int *b, int c)
{
return a + *b + c;
}
#pragma omp declare simd uniform (d) aligned (e : 8 * sizeof (int)) linear (f : 4) simdlen (8)
int f15 (int d, int *e, int f);
#pragma omp declare simd aligned (g : sizeof (*g)) linear (h : 2 * sizeof (g[0]) + sizeof (h)) simdlen (4)
int f16 (long *g, int h);
#pragma omp declare simd aligned (h : sizeof (*h)) linear (g : 2 * sizeof (h[0]) + sizeof (g)) simdlen (4)
int f17 (int g, long *h)
{
return g + h[0];
}
#pragma omp declare simd aligned (i : sizeof (*i)) linear (j : 2 * sizeof (i[0]) + sizeof (j)) simdlen (4)
int
f18 (j, i)
long *i;
int j;
{
return j + i[0];
}

View file

@ -0,0 +1,24 @@
/* Test parsing of #pragma omp declare simd */
/* { dg-do compile } */
#pragma omp declare simd
int a; /* { dg-error "not immediately followed by a function declaration or definition" } */
#pragma omp declare simd
int fn1 (int a), fn2 (int a); /* { dg-error "not immediately followed by a single function declaration or definition" } */
#pragma omp declare simd
int b, fn3 (int a); /* { dg-error "not immediately followed by a function declaration or definition" } */
#pragma omp declare simd linear (a)
int fn4 (int a), c; /* { dg-error "not immediately followed by a function declaration or definition" } */
int t;
#pragma omp declare simd
#pragma omp declare simd
#pragma omp threadprivate(t) /* { dg-error "must be followed by function declaration or definition or another" } */
int fn5 (int a);
#pragma omp declare simd inbranch notinbranch /* { dg-error "clause is incompatible with" } */
int fn6 (int);

View file

@ -28,19 +28,60 @@ f1 (void)
#pragma omp for /* { dg-error "may not be closely nested" } */
for (j = 0; j < 3; j++)
;
}
#pragma omp sections
{
#pragma omp sections /* { dg-error "may not be closely nested" } */
{
;
#pragma omp section
;
}
}
#pragma omp sections
{
#pragma omp single /* { dg-error "may not be closely nested" } */
;
}
#pragma omp sections
{
#pragma omp master /* { dg-error "may not be closely nested" } */
;
}
#pragma omp sections
{
#pragma omp section
;
}
#pragma omp sections
{
#pragma omp section
#pragma omp for /* { dg-error "may not be closely nested" } */
for (j = 0; j < 3; j++)
;
}
#pragma omp sections
{
#pragma omp section
#pragma omp sections /* { dg-error "may not be closely nested" } */
{
;
#pragma omp section
;
}
}
#pragma omp sections
{
#pragma omp section
#pragma omp single /* { dg-error "may not be closely nested" } */
;
}
#pragma omp sections
{
#pragma omp section
#pragma omp master /* { dg-error "may not be closely nested" } */
;
}
#pragma omp single
{
#pragma omp for /* { dg-error "may not be closely nested" } */

View file

@ -0,0 +1,29 @@
/* { dg-do compile } */
void
foo (int x)
{
bad1:
#pragma omp target
goto bad1; /* { dg-error "invalid branch" } */
goto bad2; /* { dg-error "invalid entry" } */
#pragma omp target
{
bad2: ;
}
#pragma omp target
{
int i;
goto ok1;
for (i = 0; i < 10; ++i)
{ ok1: break; }
}
switch (x) /* { dg-error "invalid entry" } */
{
#pragma omp target
{ case 0:; }
}
}

View file

@ -0,0 +1,29 @@
/* { dg-do compile } */
void
foo (int x, int y)
{
bad1:
#pragma omp target data map(tofrom: y)
goto bad1; /* { dg-error "invalid branch" } */
goto bad2; /* { dg-error "invalid entry" } */
#pragma omp target data map(tofrom: y)
{
bad2: ;
}
#pragma omp target data map(tofrom: y)
{
int i;
goto ok1;
for (i = 0; i < 10; ++i)
{ ok1: break; }
}
switch (x) /* { dg-error "invalid entry" } */
{
#pragma omp target data map(tofrom: y)
{ case 0:; }
}
}

View file

@ -0,0 +1,29 @@
/* { dg-do compile } */
void
foo (int x)
{
bad1:
#pragma omp taskgroup
goto bad1; /* { dg-error "invalid branch" } */
goto bad2; /* { dg-error "invalid entry" } */
#pragma omp taskgroup
{
bad2: ;
}
#pragma omp taskgroup
{
int i;
goto ok1;
for (i = 0; i < 10; ++i)
{ ok1: break; }
}
switch (x) /* { dg-error "invalid entry" } */
{
#pragma omp taskgroup
{ case 0:; }
}
}

View file

@ -0,0 +1,61 @@
/* { dg-do compile } */
void
foo (int x)
{
bad1:
#pragma omp target teams
goto bad1; /* { dg-error "invalid branch" } */
goto bad2; /* { dg-error "invalid entry" } */
#pragma omp target teams
{
bad2: ;
}
#pragma omp target teams
{
int i;
goto ok1;
for (i = 0; i < 10; ++i)
{ ok1: break; }
}
switch (x) /* { dg-error "invalid entry" } */
{
#pragma omp target teams
{ case 0:; }
}
}
void
bar (int x)
{
bad1:
#pragma omp target
#pragma omp teams
goto bad1; /* { dg-error "invalid branch" } */
goto bad2; /* { dg-error "invalid entry" } */
#pragma omp target
#pragma omp teams
{
bad2: ;
}
#pragma omp target
#pragma omp teams
{
int i;
goto ok1;
for (i = 0; i < 10; ++i)
{ ok1: break; }
}
switch (x) /* { dg-error "invalid entry" } */
{
#pragma omp target
#pragma omp teams
{ case 0:; }
}
}

View file

@ -0,0 +1,46 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
#pragma omp declare reduction (| : long int : omp_out |= omp_in) /* { dg-error "predeclared arithmetic type" } */
#pragma omp declare reduction (+ : char : omp_out += omp_in) /* { dg-error "predeclared arithmetic type" } */
typedef short T;
#pragma omp declare reduction (min : T : omp_out += omp_in) /* { dg-error "predeclared arithmetic type" } */
#pragma omp declare reduction (* : _Complex double : omp_out *= omp_in) /* { dg-error "predeclared arithmetic type" } */
void
foo (void)
{
#pragma omp declare reduction (| : long int : omp_out |= omp_in) /* { dg-error "predeclared arithmetic type" } */
#pragma omp declare reduction (+ : char : omp_out += omp_in) /* { dg-error "predeclared arithmetic type" } */
#pragma omp declare reduction (min : T : omp_out += omp_in) /* { dg-error "predeclared arithmetic type" } */
#pragma omp declare reduction (* : _Complex double : omp_out *= omp_in) /* { dg-error "predeclared arithmetic type" } */
}
#pragma omp declare reduction (| : __typeof (foo) : omp_out |= omp_in) /* { dg-error "function or array" } */
#pragma omp declare reduction (+ : char () : omp_out += omp_in) /* { dg-error "function or array" } */
#pragma omp declare reduction (min : T[2] : omp_out += omp_in) /* { dg-error "function or array" } */
void
bar (void)
{
#pragma omp declare reduction (| : __typeof (foo) : omp_out |= omp_in)/* { dg-error "function or array" } */
#pragma omp declare reduction (+ : char () : omp_out += omp_in) /* { dg-error "function or array" } */
#pragma omp declare reduction (min : T[2] : omp_out += omp_in) /* { dg-error "function or array" } */
}
struct A { int a; };
#pragma omp declare reduction (| : const struct A : omp_out.a |= omp_in.a) /* { dg-error "const, volatile or restrict" } */
#pragma omp declare reduction (+ : __const struct A : omp_out.a += omp_in.a) /* { dg-error "const, volatile or restrict" } */
typedef volatile struct A T2;
#pragma omp declare reduction (min : T2 : omp_out.a += omp_in.a) /* { dg-error "const, volatile or restrict" } */
#pragma omp declare reduction (* : struct A *__restrict : omp_out->a *= omp_in->a)/* { dg-error "const, volatile or restrict" } */
void
baz (void)
{
#pragma omp declare reduction (| : const struct A : omp_out.a |= omp_in.a) /* { dg-error "const, volatile or restrict" } */
#pragma omp declare reduction (+ : __const struct A : omp_out.a += omp_in.a) /* { dg-error "const, volatile or restrict" } */
typedef volatile struct A T3;
#pragma omp declare reduction (min : T3 : omp_out.a += omp_in.a) /* { dg-error "const, volatile or restrict" } */
#pragma omp declare reduction (* : struct A *__restrict : omp_out->a *= omp_in->a)/* { dg-error "const, volatile or restrict" } */
}

View file

@ -0,0 +1,42 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
struct W { int w; };
void init (struct W *, int, int *);
int v;
#pragma omp declare reduction (foo : long int : omp_out |= v) /* { dg-error "combiner refers to variable" } */
#pragma omp declare reduction (foo : char : omp_out = v) /* { dg-error "combiner refers to variable" } */
typedef short T;
#pragma omp declare reduction (foo : T : omp_out += v) /* { dg-error "combiner refers to variable" } */
#pragma omp declare reduction (foo : int : v *= omp_in) /* { dg-error "combiner refers to variable" } */
#pragma omp declare reduction (foo : struct W : omp_out.w *= omp_in.w + v) /* { dg-error "combiner refers to variable" } */
void
foo (int v)
{
#pragma omp declare reduction (foo : long int : omp_out |= v) /* { dg-error "combiner refers to variable" } */
#pragma omp declare reduction (foo : char : omp_out = v) /* { dg-error "combiner refers to variable" } */
#pragma omp declare reduction (foo : T : omp_out += v) /* { dg-error "combiner refers to variable" } */
#pragma omp declare reduction (foo : int : v *= omp_in) /* { dg-error "combiner refers to variable" } */
#pragma omp declare reduction (foo : struct W : omp_out.w *= omp_in.w + v) /* { dg-error "combiner refers to variable" } */
}
#pragma omp declare reduction (bar : long int : omp_out |= omp_in) initializer (omp_priv = v) /* { dg-error "initializer refers to variable" } */
#pragma omp declare reduction (bar : char : omp_out += omp_in) initializer (omp_priv = ((char) v)) /* { dg-error "initializer refers to variable" } */
#pragma omp declare reduction (bar : T : omp_out += omp_in) initializer (omp_priv = (short) v) /* { dg-error "initializer refers to variable" } */
#pragma omp declare reduction (bar : _Complex double : omp_out *= omp_in) initializer (omp_priv = (v)) /* { dg-error "initializer refers to variable" } */
#pragma omp declare reduction (bar : struct W : omp_out.w *= omp_in.w) initializer (omp_priv = { v } ) /* { dg-error "initializer refers to variable" } */
#pragma omp declare reduction (bar2 : struct W : omp_out.w *= omp_in.w) initializer (init (&omp_priv, v, (int *) 0)) /* { dg-error "initializer refers to variable" } */
#pragma omp declare reduction (bar3 : struct W : omp_out.w *= omp_in.w) initializer (init (&omp_priv, 0, &v)) /* { dg-error "initializer refers to variable" } */
void
bar (int v)
{
#pragma omp declare reduction (bar : long int : omp_out |= omp_in) initializer (omp_priv = v) /* { dg-error "initializer refers to variable" } */
#pragma omp declare reduction (bar : char : omp_out += omp_in) initializer (omp_priv = ((char) v)) /* { dg-error "initializer refers to variable" } */
#pragma omp declare reduction (bar : T : omp_out += omp_in) initializer (omp_priv = (short) v) /* { dg-error "initializer refers to variable" } */
#pragma omp declare reduction (bar : _Complex double : omp_out *= omp_in) initializer (omp_priv = (v)) /* { dg-error "initializer refers to variable" } */
#pragma omp declare reduction (bar : struct W : omp_out.w *= omp_in.w) initializer (omp_priv = { v }) /* { dg-error "initializer refers to variable" } */
#pragma omp declare reduction (bar2 : struct W : omp_out.w *= omp_in.w) initializer (init (&omp_priv, v, (int *) 0)) /* { dg-error "initializer refers to variable" } */
#pragma omp declare reduction (bar3 : struct W : omp_out.w *= omp_in.w) initializer (init (&omp_priv, 0, &v)) /* { dg-error "initializer refers to variable" } */
}

View file

@ -0,0 +1,77 @@
/* { dg-do compile } */
/* { dg-options "-fopenmp" } */
struct S { int s; };
struct T { int t; };
struct U { int u; };
#pragma omp declare reduction (+: struct S: omp_out.s += omp_in.s)
#pragma omp declare reduction (*: struct S: omp_out.s *= omp_in.s) \
initializer (omp_priv = {1})
#pragma omp declare reduction (foo: struct S: omp_out.s += omp_in.s)
void
f1 ()
{
struct S s, s2;
struct T t;
#pragma omp declare reduction (+: struct T: omp_out.t += omp_in.t)
#pragma omp parallel reduction (+: t) reduction (foo: s) reduction (*: s2)
s.s = 1, t.t = 1, s2.s = 2;
#pragma omp parallel reduction (+: s)
s.s = 1;
}
void bar (struct S *);
void
f2 ()
{
#pragma omp declare reduction (foo: struct S: omp_out.s += omp_in.s) initializer (bar (&omp_priv))
#pragma omp declare reduction (bar: struct S: omp_out.s += omp_in.s) initializer (bar (&omp_orig)) /* { dg-error "one of the initializer call arguments should be" } */
}
#pragma omp declare reduction (+: struct U: omp_out.u *= omp_in.u) /* { dg-error "previous" } */
#pragma omp declare reduction (+: struct U: omp_out.u += omp_in.u) /* { dg-error "redeclaration of" } */
void
f3 ()
{
#pragma omp declare reduction (f3: struct U: omp_out.u *= omp_in.u) /* { dg-error "previous" } */
#pragma omp declare reduction (f3: struct U: omp_out.u += omp_in.u) /* { dg-error "redeclaration of" } */
}
struct V
{
#pragma omp declare reduction (bar: struct S: omp_out.s *= omp_in.s) /* { dg-error "not at file or block scope" } */
#pragma omp declare reduction (bar: struct S: omp_out.s += omp_in.s) /* { dg-error "not at file or block scope" } */
};
#pragma omp declare reduction (n3: long: omp_out += omp_in) /* { dg-error "previous" } */
#pragma omp declare reduction (n3: long int: omp_out += omp_in) /* { dg-error "redeclaration of" } */
#pragma omp declare reduction (n3: short unsigned: omp_out += omp_in)
#pragma omp declare reduction (n3: short int: omp_out += omp_in)
void
f4 (void)
{
#pragma omp declare reduction (f4: long: omp_out += omp_in) /* { dg-error "previous" } */
#pragma omp declare reduction (f4: long int: omp_out += omp_in) /* { dg-error "redeclaration of" } */
#pragma omp declare reduction (f4: short unsigned: omp_out += omp_in)
#pragma omp declare reduction (f4: short int: omp_out += omp_in)
}
void
f5 (void)
{
#pragma omp declare reduction (+: struct S: omp_out.s += omp_in.s) initializer (omp_priv) /* { dg-error "expected" } */
#pragma omp declare reduction (+: struct T: omp_out.t += omp_in.t) initializer (omp_priv ()) /* { dg-error "expected" } */
}
void
f6 (a, b)
#pragma omp declare reduction (bar: struct S: omp_out.s *= omp_in.s) /* { dg-error "expected declaration specifiers before" } */
int a;
int b;
{
}

View file

@ -0,0 +1,6 @@
/* { dg-do compile } */
struct S;
#pragma omp declare reduction (+:struct S:omp_out.s += omp_in.s) /* { dg-error "invalid use of undefined type" } */
struct S { int s; };
#pragma omp declare reduction (*:struct S:omp_out.s *= omp_in.s)

View file

@ -6,7 +6,7 @@
!$OMP CRITICAL
CALL WORK(N,1)
! incorrect nesting of barrier region in a critical region
!$OMP BARRIER
!$OMP BARRIER ! { dg-error "region may not be closely nested inside of" }
CALL WORK(N,2)
!$OMP END CRITICAL
!$OMP END PARALLEL

View file

@ -611,7 +611,9 @@ make_edges (void)
case GIMPLE_OMP_TASK:
case GIMPLE_OMP_FOR:
case GIMPLE_OMP_SINGLE:
case GIMPLE_OMP_TEAMS:
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
case GIMPLE_OMP_SECTION:
@ -619,6 +621,13 @@ make_edges (void)
fallthru = true;
break;
case GIMPLE_OMP_TARGET:
cur_region = new_omp_region (bb, code, cur_region);
fallthru = true;
if (gimple_omp_target_kind (last) == GF_OMP_TARGET_KIND_UPDATE)
cur_region = cur_region->outer;
break;
case GIMPLE_OMP_SECTIONS:
cur_region = new_omp_region (bb, code, cur_region);
fallthru = true;

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