location_t loc = gimple_location (stmt);
bool offloaded, data_region;
unsigned int map_cnt = 0;
- bool has_depend = false;
offloaded = is_gimple_omp_offloaded (stmt);
switch (gimple_omp_target_kind (stmt))
dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
lower_depend_clauses (gimple_omp_target_clauses_ptr (stmt),
&dep_ilist, &dep_olist);
- has_depend = true;
}
tgt_bind = NULL;
type = TREE_TYPE (ovar);
if (is_reference (ovar))
type = TREE_TYPE (type);
- bool use_firstprivate_int, force_addr;
- use_firstprivate_int = false;
- force_addr = false;
if ((INTEGRAL_TYPE_P (type)
&& TYPE_PRECISION (type) <= POINTER_SIZE)
|| TREE_CODE (type) == POINTER_TYPE)
- use_firstprivate_int = true;
- if (has_depend)
- {
- if (is_reference (var))
- use_firstprivate_int = false;
- else if (is_gimple_reg (var))
- {
- if (DECL_HAS_VALUE_EXPR_P (var))
- {
- tree v = get_base_address (var);
- if (DECL_P (v) && TREE_ADDRESSABLE (v))
- {
- use_firstprivate_int = false;
- force_addr = true;
- }
- else
- switch (TREE_CODE (v))
- {
- case INDIRECT_REF:
- case MEM_REF:
- use_firstprivate_int = false;
- force_addr = true;
- break;
- default:
- break;
- }
- }
- }
- else
- use_firstprivate_int = false;
- }
- if (use_firstprivate_int)
{
tkind = GOMP_MAP_FIRSTPRIVATE_INT;
tree t = var;
}
else if (is_reference (var))
gimplify_assign (x, var, &ilist);
- else if (!force_addr && is_gimple_reg (var))
+ else if (is_gimple_reg (var))
{
tree avar = create_tmp_var (TREE_TYPE (var));
mark_addressable (avar);
type = TREE_TYPE (var);
if (is_reference (var))
type = TREE_TYPE (type);
- bool use_firstprivate_int;
- use_firstprivate_int = false;
if ((INTEGRAL_TYPE_P (type)
&& TYPE_PRECISION (type) <= POINTER_SIZE)
|| TREE_CODE (type) == POINTER_TYPE)
- use_firstprivate_int = true;
- if (has_depend)
- {
- tree v = lookup_decl_in_outer_ctx (var, ctx);
- if (is_reference (v))
- use_firstprivate_int = false;
- else if (is_gimple_reg (v))
- {
- if (DECL_HAS_VALUE_EXPR_P (v))
- {
- v = get_base_address (v);
- if (DECL_P (v) && TREE_ADDRESSABLE (v))
- use_firstprivate_int = false;
- else
- switch (TREE_CODE (v))
- {
- case INDIRECT_REF:
- case MEM_REF:
- use_firstprivate_int = false;
- break;
- default:
- break;
- }
- }
- }
- else
- use_firstprivate_int = false;
- }
- if (use_firstprivate_int)
{
x = build_receiver_ref (var, false, ctx);
if (TREE_CODE (type) != POINTER_TYPE)
}
}
-/* Host fallback with firstprivate map-type handling. */
-
-static void
-gomp_target_fallback_firstprivate (void (*fn) (void *), size_t mapnum,
- void **hostaddrs, size_t *sizes,
- unsigned short *kinds)
-{
- size_t tgt_align = 0, tgt_size = 0;
- calculate_firstprivate_requirements (mapnum, sizes, kinds, &tgt_align,
- &tgt_size);
- if (tgt_align)
- {
- char *tgt = gomp_alloca (tgt_size + tgt_align - 1);
- copy_firstprivate_data (tgt, mapnum, hostaddrs, sizes, kinds, tgt_align,
- tgt_size);
- }
- gomp_target_fallback (fn, hostaddrs);
-}
-
-/* Handle firstprivate map-type for shared memory devices and the host
- fallback. Return the pointer of firstprivate copies which has to be freed
- after use. */
-
-static void *
-gomp_target_unshare_firstprivate (size_t mapnum, void **hostaddrs,
- size_t *sizes, unsigned short *kinds)
-{
- size_t tgt_align = 0, tgt_size = 0;
- char *tgt = NULL;
-
- calculate_firstprivate_requirements (mapnum, sizes, kinds, &tgt_align,
- &tgt_size);
- if (tgt_align)
- {
- tgt = gomp_malloc (tgt_size + tgt_align - 1);
- copy_firstprivate_data (tgt, mapnum, hostaddrs, sizes, kinds, tgt_align,
- tgt_size);
- }
- return tgt;
-}
-
/* Helper function of GOMP_target{,_ext} routines. */
static void *
unsigned int flags, void **depend, void **args)
{
struct gomp_device_descr *devicep = resolve_device (device);
+ size_t tgt_align = 0, tgt_size = 0;
+ bool fpc_done = false;
if (flags & GOMP_TARGET_FLAG_NOWAIT)
{
{
struct gomp_thread *thr = gomp_thread ();
if (thr->task && thr->task->depend_hash)
- gomp_task_maybe_wait_for_dependencies (depend);
+ {
+ /* If we might need to wait, copy firstprivate now. */
+ calculate_firstprivate_requirements (mapnum, sizes, kinds,
+ &tgt_align, &tgt_size);
+ if (tgt_align)
+ {
+ char *tgt = gomp_alloca (tgt_size + tgt_align - 1);
+ copy_firstprivate_data (tgt, mapnum, hostaddrs, sizes, kinds,
+ tgt_align, tgt_size);
+ }
+ fpc_done = true;
+ gomp_task_maybe_wait_for_dependencies (depend);
+ }
}
void *fn_addr;
|| !(fn_addr = gomp_get_target_fn_addr (devicep, fn))
|| (devicep->can_run_func && !devicep->can_run_func (fn_addr)))
{
- gomp_target_fallback_firstprivate (fn, mapnum, hostaddrs, sizes, kinds);
+ if (!fpc_done)
+ {
+ calculate_firstprivate_requirements (mapnum, sizes, kinds,
+ &tgt_align, &tgt_size);
+ if (tgt_align)
+ {
+ char *tgt = gomp_alloca (tgt_size + tgt_align - 1);
+ copy_firstprivate_data (tgt, mapnum, hostaddrs, sizes, kinds,
+ tgt_align, tgt_size);
+ }
+ }
+ gomp_target_fallback (fn, hostaddrs);
return;
}
struct target_mem_desc *tgt_vars;
- void *fpc = NULL;
if (devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
{
- fpc = gomp_target_unshare_firstprivate (mapnum, hostaddrs, sizes, kinds);
+ if (!fpc_done)
+ {
+ calculate_firstprivate_requirements (mapnum, sizes, kinds,
+ &tgt_align, &tgt_size);
+ if (tgt_align)
+ {
+ char *tgt = gomp_alloca (tgt_size + tgt_align - 1);
+ copy_firstprivate_data (tgt, mapnum, hostaddrs, sizes, kinds,
+ tgt_align, tgt_size);
+ }
+ }
tgt_vars = NULL;
}
else
args);
if (tgt_vars)
gomp_unmap_vars (tgt_vars, true);
- else
- free (fpc);
}
/* Host fallback for GOMP_target_data{,_ext} routines. */
|| (devicep->can_run_func && !devicep->can_run_func (fn_addr)))
{
ttask->state = GOMP_TARGET_TASK_FALLBACK;
- gomp_target_fallback_firstprivate (ttask->fn, ttask->mapnum,
- ttask->hostaddrs, ttask->sizes,
- ttask->kinds);
+ gomp_target_fallback (ttask->fn, ttask->hostaddrs);
return false;
}
if (devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
{
ttask->tgt = NULL;
- ttask->firstprivate_copies
- = gomp_target_unshare_firstprivate (ttask->mapnum, ttask->hostaddrs,
- ttask->sizes, ttask->kinds);
actual_arguments = ttask->hostaddrs;
}
else