From 21bf4b48a172ca20788d5cba0d686102600b8ed4 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Thu, 3 Feb 2022 11:37:17 -0800 Subject: [PATCH 2/2] OpenMP: Use OMP_ARRAY_SECTION instead of TREE_LIST in C++ FE This patch changes the representation of OMP array sections in the C++ front end to use the new OMP_ARRAY_SECTION tree code instead of a TREE_LIST. This is important for "declare mapper" support, because the array section representation may stick around longer (in "declare mapper" definitions), and special-case handling TREE_LIST becomes necessary in more places, which starts to become unwieldy. This patch has been rebased, but is largely unchanged from the last version posted. 2022-11-01 Julian Brown gcc/c-family/ * c-omp.cc (c_omp_split_clauses): Support OMP_ARRAY_SECTION. gcc/cp/ * parser.cc (cp_parser_omp_var_list_no_open): Use OMP_ARRAY_SECTION code instead of TREE_LIST to represent OpenMP array sections. * pt.cc (tsubst_copy, tsubst_omp_clause_decl, tsubst_copy_and_build): Add OMP_ARRAY_SECTION support. * semantics.cc (handle_omp_array_sections_1, handle_omp_array_sections, cp_oacc_check_attachments, finish_omp_clauses): Use OMP_ARRAY_SECTION instead of TREE_LIST where appropriate. * gimplify.cc (gimplify_expr): Ensure OMP_ARRAY_SECTION has been processed out before gimplification. --- gcc/c-family/c-omp.cc | 14 ++++++++++ gcc/cp/parser.cc | 15 ++++++++--- gcc/cp/pt.cc | 52 ++++++++++++++++++++++++++++++++++++ gcc/cp/semantics.cc | 62 ++++++++++++++++++++++--------------------- gcc/gimplify.cc | 3 +++ 5 files changed, 112 insertions(+), 34 deletions(-) diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc index 947014e8983..4a6c9c84f83 100644 --- a/gcc/c-family/c-omp.cc +++ b/gcc/c-family/c-omp.cc @@ -2679,6 +2679,9 @@ c_omp_split_clauses (location_t loc, enum tree_code code, } else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == TREE_LIST) { + /* TODO: This can go away once we transition all uses of + TREE_LIST for representing OMP array sections to + OMP_ARRAY_SECTION. */ tree t; for (t = OMP_CLAUSE_DECL (c); TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t)) @@ -2687,6 +2690,17 @@ c_omp_split_clauses (location_t loc, enum tree_code code, bitmap_clear_bit (&allocate_head, DECL_UID (t)); break; } + else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == OMP_ARRAY_SECTION) + { + tree t; + for (t = OMP_CLAUSE_DECL (c); + TREE_CODE (t) == OMP_ARRAY_SECTION; + t = TREE_OPERAND (t, 0)) + ; + if (DECL_P (t)) + bitmap_clear_bit (&allocate_head, DECL_UID (t)); + break; + } /* FALLTHRU */ case OMP_CLAUSE_PRIVATE: case OMP_CLAUSE_FIRSTPRIVATE: diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index cf619e88f46..4fe7454fe68 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -36927,11 +36927,14 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, decl = TREE_OPERAND (decl, 0); for (int i = dims.length () - 1; i >= 0; i--) - decl = tree_cons (dims[i].low_bound, dims[i].length, decl); + decl = build3_loc (input_location, OMP_ARRAY_SECTION, + TREE_TYPE (decl), decl, dims[i].low_bound, + dims[i].length); } else if (TREE_CODE (decl) == INDIRECT_REF) { bool ref_p = REFERENCE_REF_P (decl); + tree type = TREE_TYPE (decl); /* Turn *foo into foo[0:1]. */ decl = TREE_OPERAND (decl, 0); @@ -36943,7 +36946,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, - it's an indirection of a pointer, turn it into "foo[0:1]". */ if (!ref_p) - decl = tree_cons (integer_zero_node, integer_one_node, decl); + decl = build3_loc (input_location, OMP_ARRAY_SECTION, type, + decl, integer_zero_node, integer_one_node); } else if (TREE_CODE (decl) == ARRAY_REF) { @@ -36952,7 +36956,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, decl = TREE_OPERAND (decl, 0); STRIP_NOPS (decl); - decl = tree_cons (idx, integer_one_node, decl); + decl = build3_loc (input_location, OMP_ARRAY_SECTION, + TREE_TYPE (decl), decl, idx, integer_one_node); } else if (TREE_CODE (decl) == NON_LVALUE_EXPR || CONVERT_EXPR_P (decl)) @@ -37136,7 +37141,9 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, } else for (unsigned i = 0; i < dims.length (); i++) - decl = tree_cons (dims[i].low_bound, dims[i].length, decl); + decl = build3_loc (input_location, OMP_ARRAY_SECTION, + TREE_TYPE (decl), decl, dims[i].low_bound, + dims[i].length); break; default: diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 5eddad900ea..9129a8dd2de 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -16484,6 +16484,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case CALL_EXPR: case ARRAY_REF: case SCOPE_REF: + case OMP_ARRAY_SECTION: /* We should use one of the expression tsubsts for these codes. */ gcc_unreachable (); @@ -17517,6 +17518,17 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) return build_nt (ARRAY_REF, op0, op1, NULL_TREE, NULL_TREE); } + case OMP_ARRAY_SECTION: + { + tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl); + tree op1 = NULL_TREE, op2 = NULL_TREE; + if (TREE_OPERAND (t, 1)) + op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl); + if (TREE_OPERAND (t, 2)) + op2 = tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl); + return build_nt (OMP_ARRAY_SECTION, op0, op1, op2); + } + case CALL_EXPR: { int n = VL_EXP_OPERAND_LENGTH (t); @@ -17809,6 +17821,24 @@ tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain, = OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (decl); return ret; } + else if (TREE_CODE (decl) == OMP_ARRAY_SECTION) + { + tree low_bound + = tsubst_expr (TREE_OPERAND (decl, 1), args, complain, in_decl, + /*integral_constant_expression_p=*/false); + tree length = tsubst_expr (TREE_OPERAND (decl, 2), args, complain, + in_decl, + /*integral_constant_expression_p=*/false); + tree base = tsubst_omp_clause_decl (TREE_OPERAND (decl, 0), args, + complain, in_decl, NULL); + if (TREE_OPERAND (decl, 0) == base + && TREE_OPERAND (decl, 1) == low_bound + && TREE_OPERAND (decl, 2) == length) + return decl; + tree ret = build3 (OMP_ARRAY_SECTION, TREE_TYPE (base), base, low_bound, + length); + return ret; + } tree ret = tsubst_expr (decl, args, complain, in_decl, /*integral_constant_expression_p=*/false); /* Undo convert_from_reference tsubst_expr could have called. */ @@ -20596,6 +20626,28 @@ tsubst_copy_and_build (tree t, RECUR (TREE_OPERAND (t, 1)), complain|decltype_flag)); + case OMP_ARRAY_SECTION: + { + tree op0 = RECUR (TREE_OPERAND (t, 0)); + tree op1 = NULL_TREE, op2 = NULL_TREE; + if (op0 == error_mark_node) + RETURN (error_mark_node); + if (TREE_OPERAND (t, 1)) + { + op1 = RECUR (TREE_OPERAND (t, 1)); + if (op1 == error_mark_node) + RETURN (error_mark_node); + } + if (TREE_OPERAND (t, 2)) + { + op2 = RECUR (TREE_OPERAND (t, 2)); + if (op2 == error_mark_node) + RETURN (error_mark_node); + } + RETURN (build3_loc (EXPR_LOCATION (t), OMP_ARRAY_SECTION, + TREE_TYPE (op0), op0, op1, op2)); + } + case SIZEOF_EXPR: if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)) || ARGUMENT_PACK_P (TREE_OPERAND (t, 0))) diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 4c6495d1754..ac36ae6dc5d 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -5139,7 +5139,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec &types, enum c_omp_region_type ort) { tree ret, low_bound, length, type; - if (TREE_CODE (t) != TREE_LIST) + if (TREE_CODE (t) != OMP_ARRAY_SECTION) { if (error_operand_p (t)) return error_mark_node; @@ -5196,16 +5196,16 @@ handle_omp_array_sections_1 (tree c, tree t, vec &types, && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) - && TREE_CODE (TREE_CHAIN (t)) == FIELD_DECL) - TREE_CHAIN (t) = omp_privatize_field (TREE_CHAIN (t), false); - ret = handle_omp_array_sections_1 (c, TREE_CHAIN (t), types, + && TREE_CODE (TREE_OPERAND (t, 0)) == FIELD_DECL) + TREE_OPERAND (t, 0) = omp_privatize_field (TREE_OPERAND (t, 0), false); + ret = handle_omp_array_sections_1 (c, TREE_OPERAND (t, 0), types, maybe_zero_len, first_non_one, ort); if (ret == error_mark_node || ret == NULL_TREE) return ret; type = TREE_TYPE (ret); - low_bound = TREE_PURPOSE (t); - length = TREE_VALUE (t); + low_bound = TREE_OPERAND (t, 1); + length = TREE_OPERAND (t, 2); if ((low_bound && type_dependent_expression_p (low_bound)) || (length && type_dependent_expression_p (length))) return NULL_TREE; @@ -5411,7 +5411,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec &types, tree lb = cp_save_expr (low_bound); if (lb != low_bound) { - TREE_PURPOSE (t) = lb; + TREE_OPERAND (t, 1) = lb; low_bound = lb; } } @@ -5442,14 +5442,14 @@ handle_omp_array_sections_1 (tree c, tree t, vec &types, array-section-subscript, the array section could be non-contiguous. */ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND - && TREE_CODE (TREE_CHAIN (t)) == TREE_LIST) + && TREE_CODE (TREE_OPERAND (t, 0)) == OMP_ARRAY_SECTION) { /* If any prior dimension has a non-one length, then deem this array section as non-contiguous. */ - for (tree d = TREE_CHAIN (t); TREE_CODE (d) == TREE_LIST; - d = TREE_CHAIN (d)) + for (tree d = TREE_OPERAND (t, 0); TREE_CODE (d) == OMP_ARRAY_SECTION; + d = TREE_OPERAND (d, 0)) { - tree d_length = TREE_VALUE (d); + tree d_length = TREE_OPERAND (d, 2); if (d_length == NULL_TREE || !integer_onep (d_length)) { error_at (OMP_CLAUSE_LOCATION (c), @@ -5472,7 +5472,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec &types, tree lb = cp_save_expr (low_bound); if (lb != low_bound) { - TREE_PURPOSE (t) = lb; + TREE_OPERAND (t, 1) = lb; low_bound = lb; } /* Temporarily disable -fstrong-eval-order for array reductions. @@ -5550,10 +5550,12 @@ handle_omp_array_sections (tree &c, enum c_omp_region_type ort) return false; for (i = num, t = OMP_CLAUSE_DECL (c); i > 0; - t = TREE_CHAIN (t)) + t = TREE_OPERAND (t, 0)) { - tree low_bound = TREE_PURPOSE (t); - tree length = TREE_VALUE (t); + gcc_assert (TREE_CODE (t) == OMP_ARRAY_SECTION); + + tree low_bound = TREE_OPERAND (t, 1); + tree length = TREE_OPERAND (t, 2); i--; if (low_bound @@ -6665,8 +6667,8 @@ cp_oacc_check_attachments (tree c) tree t = OMP_CLAUSE_DECL (c); tree type; - while (TREE_CODE (t) == TREE_LIST) - t = TREE_CHAIN (t); + while (TREE_CODE (t) == OMP_ARRAY_SECTION) + t = TREE_OPERAND (t, 0); type = TREE_TYPE (t); @@ -6772,7 +6774,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) case OMP_CLAUSE_TASK_REDUCTION: field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP); t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) == TREE_LIST) + if (TREE_CODE (t) == OMP_ARRAY_SECTION) { if (handle_omp_array_sections (c, ort)) { @@ -6788,10 +6790,10 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; break; } - if (TREE_CODE (t) == TREE_LIST) + if (TREE_CODE (t) == OMP_ARRAY_SECTION) { - while (TREE_CODE (t) == TREE_LIST) - t = TREE_CHAIN (t); + while (TREE_CODE (t) == OMP_ARRAY_SECTION) + t = TREE_OPERAND (t, 0); } else { @@ -7812,7 +7814,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) else last_iterators = NULL_TREE; - if (TREE_CODE (t) == TREE_LIST) + if (TREE_CODE (t) == OMP_ARRAY_SECTION) { if (handle_omp_array_sections (c, ort)) remove = true; @@ -7972,7 +7974,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) auto_vec addr_tokens; t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) == TREE_LIST) + if (TREE_CODE (t) == OMP_ARRAY_SECTION) { grp_start_p = pc; grp_sentinel = OMP_CLAUSE_CHAIN (c); @@ -7982,7 +7984,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) else { t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) != TREE_LIST + if (TREE_CODE (t) != OMP_ARRAY_SECTION && !type_dependent_expression_p (t) && !omp_mappable_type (TREE_TYPE (t))) { @@ -8564,15 +8566,15 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) case OMP_CLAUSE_HAS_DEVICE_ADDR: t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) == TREE_LIST) + if (TREE_CODE (t) == OMP_ARRAY_SECTION) { if (handle_omp_array_sections (c, ort)) remove = true; else { t = OMP_CLAUSE_DECL (c); - while (TREE_CODE (t) == TREE_LIST) - t = TREE_CHAIN (t); + while (TREE_CODE (t) == OMP_ARRAY_SECTION) + t = TREE_OPERAND (t, 0); while (TREE_CODE (t) == INDIRECT_REF || TREE_CODE (t) == ARRAY_REF) t = TREE_OPERAND (t, 0); @@ -8943,10 +8945,10 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) if (DECL_P (t)) bitmap_clear_bit (&aligned_head, DECL_UID (t)); } - else if (TREE_CODE (t) == TREE_LIST) + else if (TREE_CODE (t) == OMP_ARRAY_SECTION) { - while (TREE_CODE (t) == TREE_LIST) - t = TREE_CHAIN (t); + while (TREE_CODE (t) == OMP_ARRAY_SECTION) + t = TREE_OPERAND (t, 0); if (DECL_P (t)) bitmap_clear_bit (&aligned_head, DECL_UID (t)); t = OMP_CLAUSE_DECL (c); diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 19b7046109e..058f66c8a75 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -17186,6 +17186,9 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, case TREE_LIST: gcc_unreachable (); + case OMP_ARRAY_SECTION: + gcc_unreachable (); + case COMPOUND_EXPR: ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none); break; -- 2.29.2