@@ -93,6 +93,8 @@ enum gimplify_omp_var_data
GOVD_MAP_0LEN_ARRAY = 32768,
+ GOVD_USE_DEVICE = 65536,
+
GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
| GOVD_LOCAL)
@@ -116,7 +118,9 @@ enum omp_region_type
ORT_COMBINED_TARGET = 33,
/* Dummy OpenMP region, used to disable expansion of
DECL_VALUE_EXPRs in taskloop pre body. */
- ORT_NONE = 64
+ ORT_NONE = 64,
+ /* An OpenACC host-data region. */
+ ORT_HOST_DATA = 128
};
/* Gimplify hashtable helper. */
@@ -6338,6 +6342,10 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
decl = TREE_OPERAND (decl, 0);
}
goto do_add_decl;
+ case OMP_CLAUSE_USE_DEVICE:
+ flags = GOVD_USE_DEVICE | GOVD_EXPLICIT;
+ check_non_private = "use_device";
+ 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)
@@ -7005,7 +7013,6 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
break;
case OMP_CLAUSE_DEVICE_RESIDENT:
- case OMP_CLAUSE_USE_DEVICE:
case OMP_CLAUSE_INDEPENDENT:
remove = true;
break;
@@ -7529,6 +7536,127 @@ gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
*expr_p = NULL_TREE;
}
+static tree
+gimplify_oacc_host_data_1 (tree *tp, int *walk_subtrees,
+ void *data ATTRIBUTE_UNUSED)
+{
+ splay_tree_node n = NULL;
+ location_t loc = EXPR_LOCATION (*tp);
+
+ switch (TREE_CODE (*tp))
+ {
+ case ADDR_EXPR:
+ {
+ tree decl = TREE_OPERAND (*tp, 0);
+
+ switch (TREE_CODE (decl))
+ {
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ case COMPONENT_REF:
+ case VIEW_CONVERT_EXPR:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ if (TREE_CODE (TREE_OPERAND (decl, 0)) == VAR_DECL)
+ n = splay_tree_lookup (gimplify_omp_ctxp->variables,
+ (splay_tree_key) TREE_OPERAND (decl, 0));
+ break;
+
+ case VAR_DECL:
+ n = splay_tree_lookup (gimplify_omp_ctxp->variables,
+ (splay_tree_key) decl);
+ break;
+
+ default:
+ ;
+ }
+
+ if (n != NULL && (n->value & GOVD_USE_DEVICE) != 0)
+ {
+ tree t = builtin_decl_explicit (BUILT_IN_GOACC_DEVICEPTR);
+ *tp = build_call_expr_loc (loc, t, 1, *tp);
+ }
+
+ *walk_subtrees = 0;
+ }
+ break;
+
+ case VAR_DECL:
+ {
+ tree decl = *tp;
+
+ n = splay_tree_lookup (gimplify_omp_ctxp->variables,
+ (splay_tree_key) decl);
+
+ if (n != NULL && (n->value & GOVD_USE_DEVICE) != 0)
+ {
+ if (!POINTER_TYPE_P (TREE_TYPE (decl)))
+ return decl;
+
+ tree t = builtin_decl_explicit (BUILT_IN_GOACC_DEVICEPTR);
+ *tp = build_call_expr_loc (loc, t, 1, *tp);
+ *walk_subtrees = 0;
+ }
+ }
+ break;
+
+ case OACC_PARALLEL:
+ case OACC_KERNELS:
+ case OACC_LOOP:
+ *walk_subtrees = 0;
+ break;
+
+ default:
+ ;
+ }
+
+ return NULL_TREE;
+}
+
+static enum gimplify_status
+gimplify_oacc_host_data (tree *expr_p, gimple_seq *pre_p)
+{
+ tree expr = *expr_p, orig_body;
+ gimple_seq body = NULL;
+
+ gimplify_scan_omp_clauses (&OACC_HOST_DATA_CLAUSES (expr), pre_p,
+ ORT_HOST_DATA, OACC_HOST_DATA);
+
+ orig_body = OACC_HOST_DATA_BODY (expr);
+
+ /* Perform a pre-pass over the host_data region's body, inserting calls to
+ GOACC_deviceptr where appropriate. */
+
+ tree ret = walk_tree_without_duplicates (&orig_body,
+ &gimplify_oacc_host_data_1, 0);
+
+ if (ret)
+ {
+ error_at (EXPR_LOCATION (expr),
+ "undefined use of variable %qE in host_data region",
+ DECL_NAME (ret));
+ gimplify_adjust_omp_clauses (pre_p, &OACC_HOST_DATA_CLAUSES (expr),
+ OACC_HOST_DATA);
+ return GS_ERROR;
+ }
+
+ push_gimplify_context ();
+
+ gimple *g = gimplify_and_return_first (orig_body, &body);
+
+ if (gimple_code (g) == GIMPLE_BIND)
+ pop_gimplify_context (g);
+ else
+ pop_gimplify_context (NULL);
+
+ gimplify_adjust_omp_clauses (pre_p, &OACC_HOST_DATA_CLAUSES (expr),
+ OACC_HOST_DATA);
+
+ gimplify_seq_add_stmt (pre_p, g);
+
+ return GS_ALL_DONE;
+}
+
/* Gimplify the contents of an OMP_PARALLEL statement. This involves
gimplification of the body, as well as scanning the body for used
variables. We need to do this scan now, because variable-sized
@@ -9595,6 +9723,9 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
break;
case OACC_HOST_DATA:
+ ret = gimplify_oacc_host_data (expr_p, pre_p);
+ break;
+
case OACC_DECLARE:
sorry ("directive not yet implemented");
ret = GS_ALL_DONE;
@@ -47,6 +47,8 @@ DEF_GOACC_BUILTIN (BUILT_IN_GOACC_UPDATE, "GOACC_update",
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_WAIT, "GOACC_wait",
BT_FN_VOID_INT_INT_VAR,
ATTR_NOTHROW_LIST)
+DEF_GOACC_BUILTIN (BUILT_IN_GOACC_DEVICEPTR, "GOACC_deviceptr",
+ BT_FN_PTR_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_GET_THREAD_NUM, "GOACC_get_thread_num",
BT_FN_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_GET_NUM_THREADS, "GOACC_get_num_threads",