aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimplify.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gimplify.cc')
-rw-r--r--gcc/gimplify.cc108
1 files changed, 86 insertions, 22 deletions
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index a0e8cc2..9f4722f 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "tree-pretty-print.h"
#include "diagnostic-core.h"
+#include "diagnostic.h" /* For errorcount. */
#include "alias.h"
#include "fold-const.h"
#include "calls.h"
@@ -1372,6 +1373,7 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
&& (attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t)))
!= NULL_TREE)
{
+ gcc_assert (!DECL_HAS_VALUE_EXPR_P (t));
tree alloc = TREE_PURPOSE (TREE_VALUE (attr));
tree align = TREE_VALUE (TREE_VALUE (attr));
/* Allocate directives that appear in a target region must specify
@@ -1396,12 +1398,56 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
error_at (DECL_SOURCE_LOCATION (t),
"%<allocate%> directive for %qD inside a target "
"region must specify an %<allocator%> clause", t);
- else if (align != NULL_TREE
- || alloc == NULL_TREE
- || !integer_onep (alloc))
- sorry_at (DECL_SOURCE_LOCATION (t),
- "OpenMP %<allocate%> directive, used for %qD, not "
- "yet supported", t);
+ /* Skip for omp_default_mem_alloc (= 1),
+ unless align is present. */
+ else if (!errorcount
+ && (align != NULL_TREE
+ || alloc == NULL_TREE
+ || !integer_onep (alloc)))
+ {
+ tree tmp = build_pointer_type (TREE_TYPE (t));
+ tree v = create_tmp_var (tmp, get_name (t));
+ DECL_IGNORED_P (v) = 0;
+ tmp = remove_attribute ("omp allocate", DECL_ATTRIBUTES (t));
+ DECL_ATTRIBUTES (v)
+ = tree_cons (get_identifier ("omp allocate var"),
+ build_tree_list (NULL_TREE, t), tmp);
+ tmp = build_fold_indirect_ref (v);
+ TREE_THIS_NOTRAP (tmp) = 1;
+ SET_DECL_VALUE_EXPR (t, tmp);
+ DECL_HAS_VALUE_EXPR_P (t) = 1;
+ tree sz = TYPE_SIZE_UNIT (TREE_TYPE (t));
+ if (alloc == NULL_TREE)
+ alloc = build_zero_cst (ptr_type_node);
+ if (align == NULL_TREE)
+ align = build_int_cst (size_type_node, DECL_ALIGN_UNIT (t));
+ else
+ align = build_int_cst (size_type_node,
+ MAX (tree_to_uhwi (align),
+ DECL_ALIGN_UNIT (t)));
+ tmp = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
+ tmp = build_call_expr_loc (DECL_SOURCE_LOCATION (t), tmp,
+ 3, align, sz, alloc);
+ tmp = fold_build2_loc (DECL_SOURCE_LOCATION (t), MODIFY_EXPR,
+ TREE_TYPE (v), v,
+ fold_convert (TREE_TYPE (v), tmp));
+ gcc_assert (BIND_EXPR_BODY (bind_expr) != NULL_TREE
+ && (TREE_CODE (BIND_EXPR_BODY (bind_expr))
+ == STATEMENT_LIST));
+ tree_stmt_iterator e = tsi_start (BIND_EXPR_BODY (bind_expr));
+ while (!tsi_end_p (e))
+ {
+ if ((TREE_CODE (*e) == DECL_EXPR
+ && TREE_OPERAND (*e, 0) == t)
+ || (TREE_CODE (*e) == CLEANUP_POINT_EXPR
+ && TREE_CODE (TREE_OPERAND (*e, 0)) == DECL_EXPR
+ && TREE_OPERAND (TREE_OPERAND (*e, 0), 0) == t))
+ break;
+ ++e;
+ }
+ gcc_assert (!tsi_end_p (e));
+ tsi_link_before (&e, tmp, TSI_SAME_STMT);
+ }
}
/* Mark variable as local. */
@@ -1486,22 +1532,6 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
cleanup = NULL;
stack_save = NULL;
- /* If the code both contains VLAs and calls alloca, then we cannot reclaim
- the stack space allocated to the VLAs. */
- if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
- {
- gcall *stack_restore;
-
- /* Save stack on entry and restore it on exit. Add a try_finally
- block to achieve this. */
- build_stack_save_restore (&stack_save, &stack_restore);
-
- gimple_set_location (stack_save, start_locus);
- gimple_set_location (stack_restore, end_locus);
-
- gimplify_seq_add_stmt (&cleanup, stack_restore);
- }
-
/* Add clobbers for all variables that go out of scope. */
for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
{
@@ -1509,6 +1539,17 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
&& !is_global_var (t)
&& DECL_CONTEXT (t) == current_function_decl)
{
+ if (flag_openmp
+ && DECL_HAS_VALUE_EXPR_P (t)
+ && TREE_USED (t)
+ && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t)))
+ {
+ tree tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
+ tmp = build_call_expr_loc (end_locus, tmp, 2,
+ TREE_OPERAND (DECL_VALUE_EXPR (t), 0),
+ build_zero_cst (ptr_type_node));
+ gimplify_and_add (tmp, &cleanup);
+ }
if (!DECL_HARD_REGISTER (t)
&& !TREE_THIS_VOLATILE (t)
&& !DECL_HAS_VALUE_EXPR_P (t)
@@ -1565,6 +1606,22 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
gimplify_ctxp->live_switch_vars->remove (t);
}
+ /* If the code both contains VLAs and calls alloca, then we cannot reclaim
+ the stack space allocated to the VLAs. */
+ if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
+ {
+ gcall *stack_restore;
+
+ /* Save stack on entry and restore it on exit. Add a try_finally
+ block to achieve this. */
+ build_stack_save_restore (&stack_save, &stack_restore);
+
+ gimple_set_location (stack_save, start_locus);
+ gimple_set_location (stack_restore, end_locus);
+
+ gimplify_seq_add_stmt (&cleanup, stack_restore);
+ }
+
if (ret_clauses)
{
gomp_target *stmt;
@@ -7894,6 +7951,13 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
if (error_operand_p (decl))
return false;
+ if (DECL_ARTIFICIAL (decl))
+ {
+ tree attr = lookup_attribute ("omp allocate var", DECL_ATTRIBUTES (decl));
+ if (attr)
+ decl = TREE_VALUE (TREE_VALUE (attr));
+ }
+
if (ctx->region_type == ORT_NONE)
return lang_hooks.decls.omp_disregard_value_expr (decl, false);