From patchwork Mon Sep 11 11:44:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tobias Burnus X-Patchwork-Id: 137887 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:ab0a:0:b0:3f2:4152:657d with SMTP id m10csp2023002vqo; Mon, 11 Sep 2023 04:44:59 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGZnDTvSltMsJj8TB245ncwzYCG4vbQRPrEpcpDuhgIpJOBtb8yljJ5U8rrQz71Tx6WE+lP X-Received: by 2002:a19:2d02:0:b0:4fe:711:2931 with SMTP id k2-20020a192d02000000b004fe07112931mr6975263lfj.22.1694432698792; Mon, 11 Sep 2023 04:44:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694432698; cv=none; d=google.com; s=arc-20160816; b=fO1qn1MXDaBac++tK6xl9GP/ZOinL34PsFaZitEdYWwK/SLCBSBcIEUX7awv1Kk/HX 5iLO3nLimNhVwg1wacDGRfAuNA0Gf/OQOgMIxAw+O/tmOgPtsjpWN8So6ublCNCd4sL9 TpeaWzZ7zgr0MQxLNhXHN8WtM57XDank6hTcWA+DxT8LDBufCl2Wvxs3O199xTY0+8Hv uDcOhWt2otBRHUnBzQ5i8EMlFs9Gv6rf1XXk7TY2gVrN2TRO+BL7mOwlTX+gFhez9zXm SyROqkaQdpKi6DqaaF2+GKEOQL8Oj7q1Ematql+AmRHdds/8tVlBzQSHS+RaScPCC9yN vxUw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:in-reply-to:references:to:from :content-language:subject:user-agent:mime-version:date:message-id :ironport-sdr:dmarc-filter:delivered-to; bh=yWfd0+xAVR/Argg1JHRTQjv74og7cvRNR+EW7UGWMU8=; fh=Ukq+Py8AahY2f+tGx20TuBbjrWgiELkxMEiSsvbP5zk=; b=tkeFDSkg7/mm6FAfeliscMMhm+VQp7wzrGTHGydiSqgjY4MrDaomy5XnvZkZeAlJkk Exk4cnfEb1MfEEFbmCQOHVwl0sSHfQensWeayopX8xFJbqLXx3IASCbfCYJ8ulZBiJwx Mm+6dUNfnsX8N9D97NJz55PRbW38kj+seFFuBW/HK57AhWSiTKYbbWWmimQZxvjK3tF9 v9uZDRELt3D9Ml77MSjL/soUYhDV5MuYc7Zq6m9LGNObYlET2Lblxo9K145jD0xWQliS Rj/dFYmsmOcWy3fhcHn6oa5zOV0bax99DL7xGM6nl4i8rqWtU3GLCRJoQPgcPjSVa5Sf F3Kw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id d4-20020aa7d5c4000000b005257c5f7d9esi6566995eds.412.2023.09.11.04.44.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Sep 2023 04:44:58 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0F2033858C30 for ; Mon, 11 Sep 2023 11:44:43 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa2.mentor.iphmx.com (esa2.mentor.iphmx.com [68.232.141.98]) by sourceware.org (Postfix) with ESMTPS id 81B1C385840F for ; Mon, 11 Sep 2023 11:44:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 81B1C385840F Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com X-CSE-ConnectionGUID: SIn8DdPHQNG9ji80Jy1oqQ== X-CSE-MsgGUID: WzdFMoz0TgemHnpQkoO6qA== X-IronPort-AV: E=Sophos;i="6.02,244,1688457600"; d="diff'?scan'208";a="18578425" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa2.mentor.iphmx.com with ESMTP; 11 Sep 2023 03:44:12 -0800 IronPort-SDR: RcWaQ979luwylt+xBG5hEShSg8NCPm6lSsj7Ny5mpC3zhjJfdaTREtAwl9CKkwGFA+Meo7r4Vy aQxPAtiGizAlevLWc9puv9PtTy1/ccNMVcuoo7/A2y6NDq2ZTCVi1WRvJxhS1jAQ1vtZw40mnq J6jmmnWD9ajfAKlTutWzLbvlJK+StCw4tGqepUe2Ai5muAXUYSHGcRDjWAEmSJJGE3WfjAwvBJ R6oIOorpzDGmmEE+uxlobSdbxScL6A3KMO2AGLvEMv/EYrG66vT04Wdaqmq5VW9vkzpFC7Dn44 UH0= Message-ID: Date: Mon, 11 Sep 2023 13:44:07 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.15.0 Subject: [Patch] OpenMP (C only): omp allocate - extend parsing support, improve diagnostic (was: [Patch] OpenMP (C only): omp allocate - handle stack vars, improve diagnostic) Content-Language: en-US From: Tobias Burnus To: Jakub Jelinek , gcc-patches References: <2b31f97f-22a4-3b47-c0d8-4fb01dea7c1c@codesourcery.com> In-Reply-To: <2b31f97f-22a4-3b47-c0d8-4fb01dea7c1c@codesourcery.com> X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-14.mgc.mentorg.com (139.181.222.14) To svr-ies-mbx-12.mgc.mentorg.com (139.181.222.12) X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1776741461533916416 X-GMAIL-MSGID: 1776741461533916416 The patch adds more check and fixes some minor FE bits, but it now has a 'sorry' for automatic/stack variables in the middle end. I think it is useful by itself as it completes the C FE part and adds diagnostic, even if the actual code generation is disabled. Comments, remarks, suggestions? The actual code generation works fine (see previous patch) but it fails with OpenMP privatization and mapping; I have locally an incomplete WIP patch to fix this. But until it works, the 'sorry' makes more sense. Besides solving that issue, C++ needs to be updated to be on par with C and my (not yet posted) Fortran patch also needs some changes for the C and ME changes. Tobias ----------------- Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955 OpenMP (C only): omp allocate - extend parsing support, improve diagnostic The 'allocate' directive can be used for both stack and static variables. While the parser in C and C++ was pre-existing, it missed several diagnostics, which this commit adds - for now only for C. While the "sorry, unimplemented" for static variables is still issues during parsing, the sorry for stack variables is now issued in the middle end, preparing for the actual implementation. (Again: only for C.) gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_construct): Move call to c_parser_omp_allocate to ... (c_parser_pragma): ... here. (c_parser_omp_allocate): Avoid ICE is allocator could not be parsed; set 'omp allocate' attribute for stack/automatic variables and only reject static variables; add several additional restriction checks. * c-tree.h (c_mark_decl_jump_unsafe_in_current_scope): New prototype. * c-decl.cc (decl_jump_unsafe): Return true for omp-allocated decls. (c_mark_decl_jump_unsafe_in_current_scope): New. (warn_about_goto, c_check_switch_jump_warnings): Add error for omp-allocated decls. gcc/ChangeLog: * gimplify.cc (gimplify_bind_expr): Check for insertion after variable cleanup. Convert 'omp allocate' var-decl attribute to GOMP_alloc/GOMP_free calls. gcc/testsuite/ChangeLog: * c-c++-common/gomp/allocate-5.c: Fix testcase; make some dg-messages for 'sorry' as c++, only. * c-c++-common/gomp/directive-1.c: Make a 'sorry' c++ only. * c-c++-common/gomp/allocate-9.c: New test. * c-c++-common/gomp/allocate-11.c: New test. * c-c++-common/gomp/allocate-12.c: New test. * c-c++-common/gomp/allocate-14.c: New test. * c-c++-common/gomp/allocate-15.c: New test. gcc/c/c-decl.cc | 23 ++++++ gcc/c/c-parser.cc | 112 +++++++++++++++++++++++--- gcc/c/c-tree.h | 1 + gcc/gimplify.cc | 40 +++++++++ gcc/testsuite/c-c++-common/gomp/allocate-11.c | 40 +++++++++ gcc/testsuite/c-c++-common/gomp/allocate-12.c | 46 +++++++++++ gcc/testsuite/c-c++-common/gomp/allocate-14.c | 26 ++++++ gcc/testsuite/c-c++-common/gomp/allocate-15.c | 28 +++++++ gcc/testsuite/c-c++-common/gomp/allocate-5.c | 60 +++++++------- gcc/testsuite/c-c++-common/gomp/allocate-9.c | 96 ++++++++++++++++++++++ gcc/testsuite/c-c++-common/gomp/directive-1.c | 2 +- 11 files changed, 432 insertions(+), 42 deletions(-) diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 649c5ae66c2..05fdb9240ae 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -681,6 +681,11 @@ decl_jump_unsafe (tree decl) if (VAR_P (decl) && C_DECL_COMPOUND_LITERAL_P (decl)) return false; + if (flag_openmp + && VAR_P (decl) + && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl))) + return true; + /* Always warn about crossing variably modified types. */ if ((VAR_P (decl) || TREE_CODE (decl) == TYPE_DECL) && c_type_variably_modified_p (TREE_TYPE (decl))) @@ -724,6 +729,12 @@ c_print_identifier (FILE *file, tree node, int indent) c_binding_oracle = save; } +void +c_mark_decl_jump_unsafe_in_current_scope () +{ + current_scope->has_jump_unsafe_decl = 1; +} + /* Establish a binding between NAME, an IDENTIFIER_NODE, and DECL, which may be any of several kinds of DECL or TYPE or error_mark_node, in the scope SCOPE. */ @@ -3974,6 +3985,9 @@ warn_about_goto (location_t goto_loc, tree label, tree decl) if (c_type_variably_modified_p (TREE_TYPE (decl))) error_at (goto_loc, "jump into scope of identifier with variably modified type"); + else if (flag_openmp + && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl))) + error_at (goto_loc, "jump skips OpenMP % allocation"); else if (!warning_at (goto_loc, OPT_Wjump_misses_init, "jump skips variable initialization")) @@ -4253,6 +4267,15 @@ c_check_switch_jump_warnings (struct c_spot_bindings *switch_bindings, "variably modified type")); emitted = true; } + else if (flag_openmp + && lookup_attribute ("omp allocate", + DECL_ATTRIBUTES (b->decl))) + { + saw_error = true; + error_at (case_loc, + "switch jumps over OpenMP % allocation"); + emitted = true; + } else emitted = warning_at (case_loc, OPT_Wjump_misses_init, diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index c04962d67a4..fb4e69fffb7 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -1681,6 +1681,7 @@ static bool c_parser_omp_declare (c_parser *, enum pragma_context); static void c_parser_omp_requires (c_parser *); static bool c_parser_omp_error (c_parser *, enum pragma_context); static void c_parser_omp_assumption_clauses (c_parser *, bool); +static void c_parser_omp_allocate (c_parser *); static void c_parser_omp_assumes (c_parser *); static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *); static void c_parser_oacc_routine (c_parser *, enum pragma_context); @@ -13649,6 +13650,10 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p) c_parser_omp_requires (parser); return false; + case PRAGMA_OMP_ALLOCATE: + c_parser_omp_allocate (parser); + return false; + case PRAGMA_OMP_ASSUMES: if (context != pragma_external) { @@ -19348,10 +19353,13 @@ c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name) align (constant-expression)] */ static void -c_parser_omp_allocate (location_t loc, c_parser *parser) +c_parser_omp_allocate (c_parser *parser) { tree alignment = NULL_TREE; tree allocator = NULL_TREE; + c_parser_consume_pragma (parser); + location_t loc = c_parser_peek_token (parser)->location; + location_t allocator_loc = UNKNOWN_LOCATION; tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE); do { @@ -19376,7 +19384,9 @@ c_parser_omp_allocate (location_t loc, c_parser *parser) c_expr expr = c_parser_expr_no_commas (parser, NULL); expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); expr_loc = c_parser_peek_token (parser)->location; - if (p[2] == 'i' && alignment) + if (expr.value == error_mark_node) + ; + else if (p[2] == 'i' && alignment) { error_at (expr_loc, "too many %qs clauses", "align"); break; @@ -19403,6 +19413,7 @@ c_parser_omp_allocate (location_t loc, c_parser *parser) else { allocator = c_fully_fold (expr.value, false, NULL); + allocator_loc = expr_loc; tree orig_type = expr.original_type ? expr.original_type : TREE_TYPE (allocator); orig_type = TYPE_MAIN_VARIANT (orig_type); @@ -19422,14 +19433,92 @@ c_parser_omp_allocate (location_t loc, c_parser *parser) } while (true); c_parser_skip_to_pragma_eol (parser); - if (allocator || alignment) - for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c)) - { - OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator; - OMP_CLAUSE_ALLOCATE_ALIGN (c) = alignment; - } - - sorry_at (loc, "%<#pragma omp allocate%> not yet supported"); + c_mark_decl_jump_unsafe_in_current_scope (); + for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c)) + { + tree var = OMP_CLAUSE_DECL (c); + if (TREE_CODE (var) == PARM_DECL) + { + error_at (OMP_CLAUSE_LOCATION (nl), + "function parameter %qD may not appear as list item in an " + "% directive", var); + continue; + } + if (!c_check_in_current_scope (var)) + { + error_at (OMP_CLAUSE_LOCATION (nl), + "% directive must be in the same scope as %qD", + var); + inform (DECL_SOURCE_LOCATION (var), "declared here"); + continue; + } + if (lookup_attribute ("omp allocate", DECL_ATTRIBUTES (var))) + { + error_at (OMP_CLAUSE_LOCATION (nl), + "%qD already appeared as list item in an " + "% directive", var); + continue; + } + if (TREE_STATIC (var)) + { + if (allocator == NULL_TREE && allocator_loc == UNKNOWN_LOCATION) + error_at (loc, "% clause required for " + "static variable %qD", var); + else if (allocator + && (tree_int_cst_sgn (allocator) != 1 + || tree_to_shwi (allocator) > 8)) + /* 8 = largest predefined memory allocator. */ + error_at (allocator_loc, + "% clause requires a predefined allocator as " + "%qD is static", var); + else + sorry_at (OMP_CLAUSE_LOCATION (nl), + "%<#pragma omp allocate%> for static variables like " + "%qD not yet supported", var); + continue; + } + if (allocator + && TREE_CODE (allocator) == VAR_DECL + && c_check_in_current_scope (var)) + { + if (DECL_SOURCE_LOCATION (allocator) > DECL_SOURCE_LOCATION (var)) + { + error_at (OMP_CLAUSE_LOCATION (nl), + "allocator variable %qD must be declared before %qD", + allocator, var); + inform (DECL_SOURCE_LOCATION (allocator), "declared here"); + inform (DECL_SOURCE_LOCATION (var), "declared here"); + } + else + { + gcc_assert (cur_stmt_list + && TREE_CODE (cur_stmt_list) == STATEMENT_LIST); + tree_stmt_iterator l = tsi_last (cur_stmt_list); + while (!tsi_end_p (l)) + { + if (EXPR_LOCATION (*l) < DECL_SOURCE_LOCATION (var)) + break; + if (TREE_CODE (*l) == MODIFY_EXPR + && TREE_OPERAND (*l, 0) == allocator) + { + error_at (EXPR_LOCATION (*l), + "allocator variable %qD, used in the " + "% directive for %qD, must not be " + "modified between declaration of %qD and its " + "% directive", + allocator, var, var); + inform (DECL_SOURCE_LOCATION (var), "declared here"); + inform (OMP_CLAUSE_LOCATION (nl), "used here"); + break; + } + --l; + } + } + } + DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("omp allocate"), + build_tree_list (allocator, alignment), + DECL_ATTRIBUTES (var)); + } } /* OpenMP 2.5: @@ -24926,9 +25015,6 @@ c_parser_omp_construct (c_parser *parser, bool *if_p) strcpy (p_name, "#pragma wait"); stmt = c_parser_oacc_wait (loc, parser, p_name); break; - case PRAGMA_OMP_ALLOCATE: - c_parser_omp_allocate (loc, parser); - return; case PRAGMA_OMP_ATOMIC: c_parser_omp_atomic (loc, parser, false); return; diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index f928137c8d4..2664354337b 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -626,6 +626,7 @@ extern unsigned int start_underspecified_init (location_t, tree); extern void finish_underspecified_init (tree, unsigned int); extern void push_scope (void); extern tree pop_scope (void); +extern void c_mark_decl_jump_unsafe_in_current_scope (); extern void c_bindings_start_stmt_expr (struct c_spot_bindings *); extern void c_bindings_end_stmt_expr (struct c_spot_bindings *); diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index a49b50bc857..a0e8cc2199d 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -1363,6 +1363,46 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) if (VAR_P (t)) { struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; + tree attr; + + if (flag_openmp + && !is_global_var (t) + && DECL_CONTEXT (t) == current_function_decl + && TREE_USED (t) + && (attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t))) + != NULL_TREE) + { + tree alloc = TREE_PURPOSE (TREE_VALUE (attr)); + tree align = TREE_VALUE (TREE_VALUE (attr)); + /* Allocate directives that appear in a target region must specify + an allocator clause unless a requires directive with the + dynamic_allocators clause is present in the same compilation + unit. */ + bool missing_dyn_alloc = false; + if (alloc == NULL_TREE + && ((omp_requires_mask & OMP_REQUIRES_DYNAMIC_ALLOCATORS) + == 0)) + { + /* This comes too early for omp_discover_declare_target..., + but should at least catch the most common cases. */ + missing_dyn_alloc + = cgraph_node::get (current_function_decl)->offloadable; + for (struct gimplify_omp_ctx *ctx2 = ctx; + ctx2 && !missing_dyn_alloc; ctx2 = ctx2->outer_context) + if (ctx2->code == OMP_TARGET) + missing_dyn_alloc = true; + } + if (missing_dyn_alloc) + error_at (DECL_SOURCE_LOCATION (t), + "% directive for %qD inside a target " + "region must specify an % clause", t); + else if (align != NULL_TREE + || alloc == NULL_TREE + || !integer_onep (alloc)) + sorry_at (DECL_SOURCE_LOCATION (t), + "OpenMP % directive, used for %qD, not " + "yet supported", t); + } /* Mark variable as local. */ if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t)) diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-11.c b/gcc/testsuite/c-c++-common/gomp/allocate-11.c new file mode 100644 index 00000000000..f9ad50abb7f --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/allocate-11.c @@ -0,0 +1,40 @@ +/* TODO: enable for C++ once implemented. */ +/* { dg-do compile { target c } } */ + +void bar(); +void use (int*); + +void +f (int i) +{ + switch (i) /* { dg-note "switch starts here" } */ + { + int j; /* { dg-note "'j' declared here" } */ + /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target *-*-* } .-1 } */ + #pragma omp allocate(j) + case 42: /* { dg-error "switch jumps over OpenMP 'allocate' allocation" } */ + bar (); + /* { dg-warning "statement will never be executed \\\[-Wswitch-unreachable\\\]" "" { target *-*-* } .-1 } */ + break; + case 51: /* { dg-error "switch jumps over OpenMP 'allocate' allocation" } */ + use (&j); + break; + } +} + +int +h (int i2) +{ + if (i2 == 5) + goto label; /* { dg-error "jump skips OpenMP 'allocate' allocation" } */ + return 5; + + int k2; /* { dg-note "'k2' declared here" } */ + /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target *-*-* } .-1 } */ + int j2 = 4; /* { dg-note "'j2' declared here" } */ + /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target *-*-* } .-1 } */ + #pragma omp allocate(k2, j2) +label: /* { dg-note "label 'label' defined here" } */ + k2 = 4; + return j2 + k2; +} diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-12.c b/gcc/testsuite/c-c++-common/gomp/allocate-12.c new file mode 100644 index 00000000000..aeb38547ba5 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/allocate-12.c @@ -0,0 +1,46 @@ +/* TODO: enable for C++ once implemented. */ +/* { dg-do compile { target c } } */ + +typedef enum omp_allocator_handle_t +{ + omp_default_mem_alloc = 1, + omp_low_lat_mem_alloc = 5, + __omp_allocator_handle_t_max__ = __UINTPTR_MAX__ +} omp_allocator_handle_t; + +int +f () +{ + omp_allocator_handle_t my_allocator; + int n = 5; /* { dg-note "declared here" } */ + my_allocator = omp_default_mem_alloc; /* { dg-error "allocator variable 'my_allocator', used in the 'allocate' directive for 'n', must not be modified between declaration of 'n' and its 'allocate' directive" } */ + /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target *-*-* } .-2 } */ + #pragma omp allocate(n) allocator(my_allocator) /* { dg-note "used here" } */ + n = 7; + return n; +} + + +int +g () +{ + int n = 5; /* { dg-note "declared here" } */ + /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target *-*-* } .-1 } */ + omp_allocator_handle_t my_allocator = omp_low_lat_mem_alloc; /* { dg-note "declared here" } */ + #pragma omp allocate(n) allocator(my_allocator) /* { dg-error "allocator variable 'my_allocator' must be declared before 'n'" } */ + n = 7; + return n; +} + +int +h () +{ + /* my_allocator uninitialized - but only diagnosed in the ME with -Wuninitialized; + see gomp/allocate-10.c. */ + omp_allocator_handle_t my_allocator; + int n = 5; + /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target *-*-* } .-1 } */ + #pragma omp allocate(n) allocator(my_allocator) + n = 7; + return n; +} diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-14.c b/gcc/testsuite/c-c++-common/gomp/allocate-14.c new file mode 100644 index 00000000000..b25da5497c5 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/allocate-14.c @@ -0,0 +1,26 @@ +/* TODO: enable for C++ once implemented. */ +/* { dg-do compile { target c } } */ + +#pragma omp begin declare target +void +f () +{ + + int var; /* { dg-error "'allocate' directive for 'var' inside a target region must specify an 'allocator' clause" } */ + #pragma omp allocate(var) + var = 5; +} +#pragma omp end declare target + +void +h () +{ + #pragma omp target + #pragma omp parallel + #pragma omp serial + { + int var2[5]; /* { dg-error "'allocate' directive for 'var2' inside a target region must specify an 'allocator' clause" } */ + #pragma omp allocate(var2) + var2[0] = 7; + } +} diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-15.c b/gcc/testsuite/c-c++-common/gomp/allocate-15.c new file mode 100644 index 00000000000..d9600f96c46 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/allocate-15.c @@ -0,0 +1,28 @@ +/* TODO: enable for C++ once implemented. */ +/* { dg-do compile { target c } } */ + +#pragma omp requires dynamic_allocators + +#pragma omp begin declare target +void +f () +{ + + int var; /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive, used for 'var', not yet supported" } */ + #pragma omp allocate(var) + var = 5; +} +#pragma omp end declare target + +void +h () +{ + #pragma omp target + #pragma omp parallel + #pragma omp serial + { + int var2[5]; /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive, used for 'var2', not yet supported" } */ + #pragma omp allocate(var2) + var2[0] = 7; + } +} diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-5.c b/gcc/testsuite/c-c++-common/gomp/allocate-5.c index 8a9181205f7..2ca4786264f 100644 --- a/gcc/testsuite/c-c++-common/gomp/allocate-5.c +++ b/gcc/testsuite/c-c++-common/gomp/allocate-5.c @@ -18,60 +18,64 @@ typedef enum omp_allocator_handle_t void foo () { + omp_allocator_handle_t my_allocator = omp_default_mem_alloc; int a, b; - omp_allocator_handle_t my_allocator; -#pragma omp allocate (a) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" } */ -#pragma omp allocate (b) allocator(my_allocator) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" } */ + static int c; +#pragma omp allocate (a) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } } */ +#pragma omp allocate (b) allocator(my_allocator) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } } */ +#pragma omp allocate(c) align(32) + /* { dg-message "'allocator' clause required for static variable 'c'" "" { target c } .-1 } */ + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */ } void bar () { - int a, b; + int a, a2, b; omp_allocator_handle_t my_allocator; #pragma omp allocate /* { dg-error "expected '\\(' before end of line" } */ - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */ + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ #pragma omp allocate allocator(my_allocator) /* { dg-error "expected '\\(' before 'allocator'" } */ - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */ + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ #pragma omp allocate(a) foo(my_allocator) /* { dg-error "expected 'allocator'" } */ /* { dg-error "expected end of line before '\\(' token" "" { target *-*-* } .-1 } */ - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-2 } */ -#pragma omp allocate(a) allocator(b) /* { dg-error "'allocator' clause allocator expression has type 'int' rather than 'omp_allocator_handle_t'" "todo: cp/semantics.c" { xfail c++ } } */ - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */ + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */ +#pragma omp allocate(a2) allocator(b) /* { dg-error "'allocator' clause allocator expression has type 'int' rather than 'omp_allocator_handle_t'" "todo: cp/semantics.c" { xfail c++ } } */ + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ } void align_test () { - int i; - #pragma omp allocate(i) allocator(omp_default_mem_alloc), align(32) - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */ - #pragma omp allocate(i) align ( 32 ),allocator(omp_default_mem_alloc) - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */ - #pragma omp allocate(i),allocator(omp_default_mem_alloc) align(32) - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */ - #pragma omp allocate(i) align ( 32 ) allocator(omp_default_mem_alloc) - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */ + int i1,i2,i3,i4,i5,i6; + #pragma omp allocate(i1) allocator(omp_default_mem_alloc), align(32) + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ + #pragma omp allocate(i2) align ( 32 ),allocator(omp_default_mem_alloc) + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ + #pragma omp allocate(i3),allocator(omp_default_mem_alloc) align(32) + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ + #pragma omp allocate(i4) align ( 32 ) allocator(omp_default_mem_alloc) + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ - #pragma omp allocate(i) allocator ( omp_high_bw_mem_alloc ), align ( 32 ) allocator(omp_default_mem_alloc) + #pragma omp allocate(i5) allocator ( omp_high_bw_mem_alloc ), align ( 32 ) allocator(omp_default_mem_alloc) /* { dg-error "too many 'allocator' clauses" "" { target *-*-* } .-1 } */ /* { dg-error "expected end of line before '\\)' token" "" { target *-*-* } .-2 } */ - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-3 } */ - #pragma omp allocate(i) align ( 32 ), align(32) allocator(omp_default_mem_alloc) + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-3 } */ + #pragma omp allocate(i6) align ( 32 ), align(32) allocator(omp_default_mem_alloc) /* { dg-error "too many 'align' clauses" "" { target *-*-* } .-1 } */ /* { dg-error "expected end of line before '\\)' token" "" { target *-*-* } .-2 } */ - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-3 } */ + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-3 } */ } void align_test2 () { - int i; + int i, i2,i3; #pragma omp allocate(i) align (32.0) /* { dg-error "'align' clause argument needs to be positive constant power of two integer expression" } */ - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */ - #pragma omp allocate(i) align ( 31 ) /* { dg-error "'align' clause argument needs to be positive constant power of two integer expression" } */ - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */ - #pragma omp allocate(i) align ( -32 ) /* { dg-error "'align' clause argument needs to be positive constant power of two integer expression" } */ - /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */ + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ + #pragma omp allocate(i2) align ( 31 ) /* { dg-error "'align' clause argument needs to be positive constant power of two integer expression" } */ + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ + #pragma omp allocate(i3) align ( -32 ) /* { dg-error "'align' clause argument needs to be positive constant power of two integer expression" } */ + /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ } diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-9.c b/gcc/testsuite/c-c++-common/gomp/allocate-9.c new file mode 100644 index 00000000000..6b2b9bfb6b5 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/allocate-9.c @@ -0,0 +1,96 @@ +typedef enum omp_allocator_handle_t +{ + omp_null_allocator = 0, + omp_default_mem_alloc = 1, + omp_large_cap_mem_alloc = 2, + omp_const_mem_alloc = 3, + omp_high_bw_mem_alloc = 4, + omp_low_lat_mem_alloc = 5, + omp_cgroup_mem_alloc = 6, + omp_pteam_mem_alloc = 7, + omp_thread_mem_alloc = 8, + __ompx_last_mem_alloc = omp_thread_mem_alloc, + __omp_allocator_handle_t_max__ = __UINTPTR_MAX__ +} omp_allocator_handle_t; + + +static int A[5] = {1,2,3,4,5}; +int B, C, D; + +/* If the following fails bacause of added predefined allocators, please update + - c/c-parser.c's c_parser_omp_allocate + - fortran/openmp.cc's is_predefined_allocator + - libgomp/env.c's parse_allocator + - libgomp/libgomp.texi (document the new values - multiple locations) + + ensure that the memory-spaces are also up to date. */ + +#pragma omp allocate(A) align(32) allocator((omp_allocator_handle_t) 9) /* { dg-error "'allocator' clause requires a predefined allocator as 'A' is static" "" { xfail c++ } } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ + + +// typo in allocator name: +#pragma omp allocate(A) allocator(omp_low_latency_mem_alloc) +/* { dg-error "'omp_low_latency_mem_alloc' undeclared here \\(not in a function\\); did you mean 'omp_low_lat_mem_alloc'\\?" "" { target c } .-1 } */ +/* { dg-error "'omp_low_latency_mem_alloc' was not declared in this scope; did you mean 'omp_low_lat_mem_alloc'\\?" "" { target c++ } .-2 } */ +/* { dg-error "'allocator' clause required for static variable 'A'" "" { target c } .-3 } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-4 } */ + +/* align be const multiple of 2 */ +#pragma omp allocate(A) align(31) allocator(omp_default_mem_alloc) /* { dg-error "'align' clause argument needs to be positive constant power of two integer expression" } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' for static variables like 'A' not yet supported" "" { target c } .-1 } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */ + +/* allocator missing (required as A is static) */ +#pragma omp allocate(A) align(32) /* { dg-error "'allocator' clause required for static variable 'A'" "" { xfail c++ } } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ + +/* "expression in the clause must be a constant expression that evaluates to one of the + predefined memory allocator values -> omp_low_lat_mem_alloc" */ +#pragma omp allocate(B) allocator((omp_allocator_handle_t) (omp_high_bw_mem_alloc+1)) align(32) /* OK: omp_low_lat_mem_alloc */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' for static variables like 'B' not yet supported" "" { target c } .-1 } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */ + +#pragma omp allocate(C) allocator((omp_allocator_handle_t) 2) /* OK: omp_large_cap_mem_alloc */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' for static variables like 'C' not yet supported" "" { target c } .-1 } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */ + +#pragma omp allocate(A) align(32) allocator(omp_null_allocator) /* { dg-error "'allocator' clause requires a predefined allocator as 'A' is static" "" { xfail c++ } } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ + +#pragma omp allocate(C) align(32) allocator(omp_large_cap_mem_alloc) /* { dg-error "'C' already appeared as list item in an 'allocate' directive" "" { xfail *-*-* } } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' for static variables like 'C' not yet supported" "" { target c } .-1 } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */ + +// allocate directive in same TU +int f() +{ + #pragma omp allocate(D) align(32) allocator(omp_large_cap_mem_alloc) /* { dg-error "'allocate' directive must be in the same scope as 'D'" "" { xfail c++ } } */ +/* { dg-note "declared here" "" { target c } 18 } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */ + return A[0]; +} + +int g() +{ + int a2=1, b2=2; + #pragma omp allocate(a2) +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ + #pragma omp allocate(a2) /* { dg-error "'a2' already appeared as list item in an 'allocate' directive" "" { xfail c++ } } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ + { + int c2=3; + #pragma omp allocate(c2, b2) /* { dg-error "'allocate' directive must be in the same scope as 'b2'" "" { xfail c++ } } */ +/* { dg-note "declared here" "" { target c } .-8 } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */ + return c2+a2+b2; + /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target c } .-5 } */ + /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target c } .-12 } */ + } +} + +int h(int q) +{ + #pragma omp allocate(q) /* { dg-error "function parameter 'q' may not appear as list item in an 'allocate' directive" "" { xfail c++ } } */ +/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ + return q; +} diff --git a/gcc/testsuite/c-c++-common/gomp/directive-1.c b/gcc/testsuite/c-c++-common/gomp/directive-1.c index fc441538778..21ca319b9f9 100644 --- a/gcc/testsuite/c-c++-common/gomp/directive-1.c +++ b/gcc/testsuite/c-c++-common/gomp/directive-1.c @@ -19,7 +19,7 @@ foo (void) int i, k = 0, l = 0; #pragma omp allocate, (i) /* { dg-error "expected '\\\(' before ',' token" } */ /* { dg-error "expected end of line before ',' token" "" { target c++ } .-1 } */ - /* { dg-message "not yet supported" "" { target *-*-* } .-2 } */ + /* { dg-message "not yet supported" "" { target c++ } .-2 } */ #pragma omp critical, (bar) /* { dg-error "expected an OpenMP clause before '\\\(' token" } */ ; #pragma omp flush, (k, l) /* { dg-error "expected '\\\(' or end of line before ',' token" "" { target c } } */