From: Jakub Jelinek Date: Thu, 16 Jun 2016 19:03:05 +0000 (+0200) Subject: gimplify.c (gimplify_scan_omp_clauses): Handle COMPONENT_REFs with base of reference... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=283635f9bd93d373b93efc1f6ffdd215f93be5fe;p=gcc.git gimplify.c (gimplify_scan_omp_clauses): Handle COMPONENT_REFs with base of reference to struct. * gimplify.c (gimplify_scan_omp_clauses): Handle COMPONENT_REFs with base of reference to struct. * parser.c (cp_parser_omp_var_list_no_open): Call convert_from_reference before cp_parser_postfix_dot_deref_expression. * semantics.c (finish_omp_clauses): Don't ICE when processing_template_decl when checking for bitfields and unions. Look through REFERENCE_REF_P as base of COMPONENT_REF. * testsuite/libgomp.c++/target-20.C: New test. From-SVN: r237538 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a8e22ed32fe..20e4ecdb4e0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2016-06-16 Jakub Jelinek + + * gimplify.c (gimplify_scan_omp_clauses): Handle COMPONENT_REFs + with base of reference to struct. + 2016-06-16 Uros Bizjak * doc/invoke.texi (x86 Options): Document -m80387 and -mhard-float. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d62ab39d438..5ad3354d69c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2016-06-16 Jakub Jelinek + + * parser.c (cp_parser_omp_var_list_no_open): Call + convert_from_reference before cp_parser_postfix_dot_deref_expression. + * semantics.c (finish_omp_clauses): Don't ICE when + processing_template_decl when checking for bitfields and unions. + Look through REFERENCE_REF_P as base of COMPONENT_REF. + 2016-06-15 Paolo Carlini * decl.c (wrapup_globals_for_namespace): Use DECL_SOURCE_LOCATION and diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a9c636b7f41..0846f0c04ea 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -30001,6 +30001,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, = cp_lexer_peek_token (parser->lexer)->location; cp_id_kind idk = CP_ID_KIND_NONE; cp_lexer_consume_token (parser->lexer); + decl = convert_from_reference (decl); decl = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT, decl, false, diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 9b0cff8c310..4cc5d2316fb 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -6664,7 +6664,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) { if (type_dependent_expression_p (t)) break; - if (DECL_BIT_FIELD (TREE_OPERAND (t, 1))) + if (TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL + && DECL_BIT_FIELD (TREE_OPERAND (t, 1))) { error_at (OMP_CLAUSE_LOCATION (c), "bit-field %qE in %qs clause", @@ -6680,8 +6681,9 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) } while (TREE_CODE (t) == COMPONENT_REF) { - if (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) - == UNION_TYPE) + if (TREE_TYPE (TREE_OPERAND (t, 0)) + && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) + == UNION_TYPE)) { error_at (OMP_CLAUSE_LOCATION (c), "%qE is a member of a union", t); @@ -6692,6 +6694,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) } if (remove) break; + if (REFERENCE_REF_P (t)) + t = TREE_OPERAND (t, 0); if (VAR_P (t) || TREE_CODE (t) == PARM_DECL) { if (bitmap_bit_p (&map_field_head, DECL_UID (t))) diff --git a/gcc/gimplify.c b/gcc/gimplify.c index ae8b4fcce3c..47c4d253e41 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -6983,6 +6983,11 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, { while (TREE_CODE (decl) == COMPONENT_REF) decl = TREE_OPERAND (decl, 0); + if (TREE_CODE (decl) == INDIRECT_REF + && DECL_P (TREE_OPERAND (decl, 0)) + && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0))) + == REFERENCE_TYPE)) + decl = TREE_OPERAND (decl, 0); } if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue) == GS_ERROR) @@ -6998,9 +7003,11 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, break; } - if (TYPE_SIZE_UNIT (TREE_TYPE (decl)) == NULL - || (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (decl))) - != INTEGER_CST)) + tree stype = TREE_TYPE (decl); + if (TREE_CODE (stype) == REFERENCE_TYPE) + stype = TREE_TYPE (stype); + if (TYPE_SIZE_UNIT (stype) == NULL + || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST) { error_at (OMP_CLAUSE_LOCATION (c), "mapping field %qE of variable length " @@ -7040,6 +7047,14 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode, &unsignedp, &reversep, &volatilep, false); + tree orig_base = base; + if ((TREE_CODE (base) == INDIRECT_REF + || (TREE_CODE (base) == MEM_REF + && integer_zerop (TREE_OPERAND (base, 1)))) + && DECL_P (TREE_OPERAND (base, 0)) + && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) + == REFERENCE_TYPE)) + base = TREE_OPERAND (base, 0); gcc_assert (base == decl && (offset == NULL_TREE || TREE_CODE (offset) == INTEGER_CST)); @@ -7053,7 +7068,10 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP); OMP_CLAUSE_SET_MAP_KIND (l, GOMP_MAP_STRUCT); - OMP_CLAUSE_DECL (l) = decl; + if (orig_base != base) + OMP_CLAUSE_DECL (l) = unshare_expr (orig_base); + else + OMP_CLAUSE_DECL (l) = decl; OMP_CLAUSE_SIZE (l) = size_int (1); if (struct_map_to_clause == NULL) struct_map_to_clause = new hash_map; @@ -7095,6 +7113,18 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, *list_p = l; list_p = &OMP_CLAUSE_CHAIN (l); } + if (orig_base != base && code == OMP_TARGET) + { + tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), + OMP_CLAUSE_MAP); + enum gomp_map_kind mkind + = GOMP_MAP_FIRSTPRIVATE_REFERENCE; + 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 (l); + OMP_CLAUSE_CHAIN (l) = c2; + } flags = GOVD_MAP | GOVD_EXPLICIT; if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr) flags |= GOVD_SEEN; @@ -7113,8 +7143,12 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, o1 = 0; if (bitpos) o1 = o1 + bitpos / BITS_PER_UNIT; - for (sc = &OMP_CLAUSE_CHAIN (*osc); - *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc)) + sc = &OMP_CLAUSE_CHAIN (*osc); + if (*sc != c + && (OMP_CLAUSE_MAP_KIND (*sc) + == GOMP_MAP_FIRSTPRIVATE_REFERENCE)) + sc = &OMP_CLAUSE_CHAIN (*sc); + for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc)) if (ptr && sc == prev_list_p) break; else if (TREE_CODE (OMP_CLAUSE_DECL (*sc)) @@ -7150,6 +7184,15 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, &mode, &unsignedp, &reversep, &volatilep, false); + if ((TREE_CODE (base) == INDIRECT_REF + || (TREE_CODE (base) == MEM_REF + && integer_zerop (TREE_OPERAND (base, + 1)))) + && DECL_P (TREE_OPERAND (base, 0)) + && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, + 0))) + == REFERENCE_TYPE)) + base = TREE_OPERAND (base, 0); if (base != decl) break; if (scp) diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index cf551f49384..586657bb130 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,7 @@ +2016-06-16 Jakub Jelinek + + * testsuite/libgomp.c++/target-20.C: New test. + 2016-06-10 Thomas Schwinge Cesar Philippidis diff --git a/libgomp/testsuite/libgomp.c++/target-20.C b/libgomp/testsuite/libgomp.c++/target-20.C new file mode 100644 index 00000000000..a722ec00c59 --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/target-20.C @@ -0,0 +1,80 @@ +extern "C" void abort (); +struct S { int a, b, c, d; }; + +void +foo (S &s) +{ + int err; + #pragma omp target map (s.b, s.d) map (from: err) + { + err = s.b != 21 || s.d != 24; + s.b++; s.d++; + } + if (err || s.b != 22 || s.d != 25) + abort (); + #pragma omp target data map (s.b, s.d) + { + #pragma omp target map (alloc: s.b, s.d) map (from: err) + { + err = s.b != 22 || s.d != 25; + s.b++; s.d++; + } + } + if (err || s.b != 23 || s.d != 26) + abort (); + #pragma omp target data map (s) + { + #pragma omp target map (alloc: s.b, s.d) map (from: err) + { + err = s.b != 23 || s.d != 26; + s.b++; s.d++; + } + } + if (err || s.b != 24 || s.d != 27) + abort (); +} + +template +void +bar (S &s, T &t, U u) +{ + int err; + #pragma omp target map (s.b, s.d, t.b, t.d, u.b, u.d) map (from: err) + { + err = s.b != 21 || s.d != 24 || t.b != 73 || t.d != 82 || u.b != 31 || u.d != 37; + s.b++; s.d++; t.b++; t.d++; u.b++; u.d++; + } + if (err || s.b != 22 || s.d != 25 || t.b != 74 || t.d != 83 || u.b != 32 || u.d != 38) + abort (); + #pragma omp target data map (s.b, s.d, t.b, t.d, u.b, u.d) + { + #pragma omp target map (alloc: s.b, s.d, t.b, t.d, u.b, u.d) map (from: err) + { + err = s.b != 22 || s.d != 25 || t.b != 74 || t.d != 83 || u.b != 32 || u.d != 38; + s.b++; s.d++; t.b++; t.d++; u.b++; u.d++; + } + } + if (err || s.b != 23 || s.d != 26 || t.b != 75 || t.d != 84 || u.b != 33 || u.d != 39) + abort (); + #pragma omp target data map (s, t, u) + { + #pragma omp target map (alloc: s.b, s.d, t.b, t.d, u.b, u.d) map (from: err) + { + err = s.b != 23 || s.d != 26 || t.b != 75 || t.d != 84 || u.b != 33 || u.d != 39; + s.b++; s.d++; t.b++; t.d++; u.b++; u.d++; + } + } + if (err || s.b != 24 || s.d != 27 || t.b != 76 || t.d != 85 || u.b != 34 || u.d != 40) + abort (); +} + +int +main () +{ + S s = { 1, 21, 2, 24 }; + foo (s); + S s2 = { 3, 21, 4, 24 }; + S t = { 5, 73, 6, 82 }; + S u = { 7, 31, 8, 37 }; + bar (s2, t, u); +}