diff options
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 125 |
1 files changed, 108 insertions, 17 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 326476f..0a55bf7 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "tree-cfg.h" #include "tree-ssa.h" +#include "tree-hash-traits.h" #include "omp-general.h" #include "omp-low.h" #include "gimple-low.h" @@ -8921,7 +8922,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, { struct gimplify_omp_ctx *ctx, *outer_ctx; tree c; - hash_map<tree, tree> *struct_map_to_clause = NULL; + hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL; hash_set<tree> *struct_deref_set = NULL; tree *prev_list_p = NULL, *orig_list_p = list_p; int handled_depend_iterators = -1; @@ -9365,7 +9366,14 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, GOVD_FIRSTPRIVATE | GOVD_SEEN); } - if (!DECL_P (decl)) + if (TREE_CODE (decl) == TARGET_EXPR) + { + if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL, + is_gimple_lvalue, fb_lvalue) + == GS_ERROR) + remove = true; + } + else if (!DECL_P (decl)) { tree d = decl, *pd; if (TREE_CODE (d) == ARRAY_REF) @@ -9381,12 +9389,15 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, && TREE_CODE (decl) == INDIRECT_REF && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0))) - == REFERENCE_TYPE)) + == REFERENCE_TYPE) + && (OMP_CLAUSE_MAP_KIND (c) + != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)) { pd = &TREE_OPERAND (decl, 0); decl = TREE_OPERAND (decl, 0); } bool indir_p = false; + bool component_ref_p = false; tree orig_decl = decl; tree decl_ref = NULL_TREE; if ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA)) != 0 @@ -9397,6 +9408,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, while (TREE_CODE (decl) == COMPONENT_REF) { decl = TREE_OPERAND (decl, 0); + component_ref_p = true; if (((TREE_CODE (decl) == MEM_REF && integer_zerop (TREE_OPERAND (decl, 1))) || INDIRECT_REF_P (decl)) @@ -9405,6 +9417,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, { indir_p = true; decl = TREE_OPERAND (decl, 0); + STRIP_NOPS (decl); } if (TREE_CODE (decl) == INDIRECT_REF && DECL_P (TREE_OPERAND (decl, 0)) @@ -9416,8 +9429,11 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, } } } - else if (TREE_CODE (decl) == COMPONENT_REF) + else if (TREE_CODE (decl) == COMPONENT_REF + && (OMP_CLAUSE_MAP_KIND (c) + != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)) { + component_ref_p = true; while (TREE_CODE (decl) == COMPONENT_REF) decl = TREE_OPERAND (decl, 0); if (TREE_CODE (decl) == INDIRECT_REF @@ -9487,7 +9503,10 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, if (code == OACC_UPDATE && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH) OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER); - if (DECL_P (decl) + if ((DECL_P (decl) + || (component_ref_p + && (INDIRECT_REF_P (decl) + || TREE_CODE (decl) == MEM_REF))) && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH @@ -9544,7 +9563,10 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, gcc_assert (base == decl); splay_tree_node n - = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); + = (DECL_P (decl) + ? splay_tree_lookup (ctx->variables, + (splay_tree_key) decl) + : NULL); bool ptr = (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER); bool attach_detach = (OMP_CLAUSE_MAP_KIND (c) @@ -9570,7 +9592,11 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, OMP_CLAUSE_SET_MAP_KIND (c, k); has_attachments = true; } - if (n == NULL || (n->value & GOVD_MAP) == 0) + if ((DECL_P (decl) + && (n == NULL || (n->value & GOVD_MAP) == 0)) + || (!DECL_P (decl) + && (!struct_map_to_clause + || struct_map_to_clause->get (decl) == NULL))) { tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP); @@ -9581,7 +9607,18 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, if (base_ref) OMP_CLAUSE_DECL (l) = unshare_expr (base_ref); else - OMP_CLAUSE_DECL (l) = decl; + { + OMP_CLAUSE_DECL (l) = unshare_expr (decl); + if (!DECL_P (OMP_CLAUSE_DECL (l)) + && (gimplify_expr (&OMP_CLAUSE_DECL (l), + pre_p, NULL, is_gimple_lvalue, + fb_lvalue) + == GS_ERROR)) + { + remove = true; + break; + } + } OMP_CLAUSE_SIZE (l) = (!attach ? size_int (1) @@ -9589,7 +9626,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l)) : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l)))); if (struct_map_to_clause == NULL) - struct_map_to_clause = new hash_map<tree, tree>; + struct_map_to_clause + = new hash_map<tree_operand_hash, tree>; struct_map_to_clause->put (decl, l); if (ptr || attach_detach) { @@ -9623,15 +9661,41 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, flags |= GOVD_SEEN; if (has_attachments) flags |= GOVD_MAP_HAS_ATTACHMENTS; - goto do_add_decl; + + /* If this is a *pointer-to-struct expression, make sure a + firstprivate map of the base-pointer exists. */ + if (component_ref_p + && ((TREE_CODE (decl) == MEM_REF + && integer_zerop (TREE_OPERAND (decl, 1))) + || INDIRECT_REF_P (decl)) + && DECL_P (TREE_OPERAND (decl, 0)) + && !splay_tree_lookup (ctx->variables, + ((splay_tree_key) + TREE_OPERAND (decl, 0)))) + { + decl = TREE_OPERAND (decl, 0); + tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), + OMP_CLAUSE_MAP); + enum gomp_map_kind mkind + = GOMP_MAP_FIRSTPRIVATE_POINTER; + OMP_CLAUSE_SET_MAP_KIND (c2, mkind); + OMP_CLAUSE_DECL (c2) = decl; + OMP_CLAUSE_SIZE (c2) = size_zero_node; + OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c); + OMP_CLAUSE_CHAIN (c) = c2; + } + + if (DECL_P (decl)) + goto do_add_decl; } else if (struct_map_to_clause) { tree *osc = struct_map_to_clause->get (decl); tree *sc = NULL, *scp = NULL; - if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) - || ptr - || attach_detach) + if (n != NULL + && (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) + || ptr + || attach_detach)) n->value |= GOVD_SEEN; sc = &OMP_CLAUSE_CHAIN (*osc); if (*sc != c @@ -9732,6 +9796,13 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, } else if (*sc != c) { + if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, + fb_lvalue) + == GS_ERROR) + { + remove = true; + break; + } *list_p = OMP_CLAUSE_CHAIN (c); OMP_CLAUSE_CHAIN (c) = *sc; *sc = c; @@ -9867,6 +9938,24 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, break; } + /* If this was of the form map(*pointer_to_struct), then the + 'pointer_to_struct' DECL should be considered deref'ed. */ + if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALLOC + || GOMP_MAP_COPY_TO_P (OMP_CLAUSE_MAP_KIND (c)) + || GOMP_MAP_COPY_FROM_P (OMP_CLAUSE_MAP_KIND (c))) + && INDIRECT_REF_P (orig_decl) + && DECL_P (TREE_OPERAND (orig_decl, 0)) + && TREE_CODE (TREE_TYPE (orig_decl)) == RECORD_TYPE) + { + tree ptr = TREE_OPERAND (orig_decl, 0); + if (!struct_deref_set || !struct_deref_set->contains (ptr)) + { + if (!struct_deref_set) + struct_deref_set = new hash_set<tree> (); + struct_deref_set->add (ptr); + } + } + if (!remove && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH @@ -11216,6 +11305,12 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, } } } + if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT + && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)) + { + remove = true; + break; + } if (!DECL_P (decl)) { if ((ctx->region_type & ORT_TARGET) != 0 @@ -11262,10 +11357,6 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c)); } } - else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT - && (code == OMP_TARGET_EXIT_DATA - || code == OACC_EXIT_DATA)) - remove = true; else if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER |