From patchwork Tue Oct 27 14:06:58 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kirill Yukhin X-Patchwork-Id: 536635 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E7EB2141319 for ; Wed, 28 Oct 2015 01:07:44 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=kloyutZy; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:content-transfer-encoding:in-reply-to; q=dns; s= default; b=oFDXXejgvVOU7pZHuWRTHKo66MFQywMoLuzAQqKJzJlwzo/ozOBmF gLO9ygL8rBeiyrr05cMPWgOLcMA5m0Od51OpREqBaJM9BpsP7cKAvmXMVRK7HCrK 9sfl2oyjPDMOJwmBO+5c4FfqbI7ZS7dA7rmwNa1jsPWea5ZSFHn/K4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:content-transfer-encoding:in-reply-to; s=default; bh=qXYr+aJmYNovzmvsjOam+kGE2jE=; b=kloyutZy7XNb7ndnOwkaGpUTFnGn j/tUB5OeNEZkXZyi5M+XhLCP4bBV6RvGCD7FGGJ1WNNL9SyE7ihOjWNXzB6q4CTf ZUBlfr3tJSZCf6fgS5pbUENjda7PceQdt7zKEQedCj6duMRO8L1tEDQZGu0gX2NN eSsnzJqkEWvJSxs= Received: (qmail 48313 invoked by alias); 27 Oct 2015 14:07:37 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 48288 invoked by uid 89); 27 Oct 2015 14:07:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-qg0-f44.google.com Received: from mail-qg0-f44.google.com (HELO mail-qg0-f44.google.com) (209.85.192.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 27 Oct 2015 14:07:26 +0000 Received: by qgem9 with SMTP id m9so145787420qge.1 for ; Tue, 27 Oct 2015 07:07:24 -0700 (PDT) X-Received: by 10.140.102.102 with SMTP id v93mr34486437qge.60.1445954843933; Tue, 27 Oct 2015 07:07:23 -0700 (PDT) Received: from msticlxl57.ims.intel.com (jfdmzpr01-ext.jf.intel.com. [134.134.139.70]) by smtp.gmail.com with ESMTPSA id z130sm4755746qkz.7.2015.10.27.07.07.19 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Oct 2015 07:07:23 -0700 (PDT) Date: Tue, 27 Oct 2015 17:06:58 +0300 From: Kirill Yukhin To: Joseph Myers Cc: Jakub Jelinek , Jeff Law , GCC Patches Subject: Re: [PATCH, VECTOR ABI] Add __attribute__((__simd__)) to GCC. Message-ID: <20151027140655.GC46998@msticlxl57.ims.intel.com> References: <561551B0.70507@redhat.com> <20151014123601.GA38813@msticlxl57.ims.intel.com> <20151015143328.GA2191@msticlxl57.ims.intel.com> <20151015143909.GF478@tucnak.redhat.com> <20151015144739.GB2191@msticlxl57.ims.intel.com> <20151022115151.GA58371@msticlxl57.ims.intel.com> <20151023141102.GA63293@msticlxl57.ims.intel.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes Hello Joseph, On 23 Oct 14:16, Joseph Myers wrote: > On Fri, 23 Oct 2015, Kirill Yukhin wrote: > > > > You need to update this patch to take account of Marek's fix for bug 67964 > > > (it was because I was suspicious of the "continue;" in this patch > > > accepting invalid syntax that I found that bug), retest and resubmit. > > I've rebased the patch on top of current trunk. > > This isn't taking proper account of Marek's fix. > > > @@ -3993,6 +4001,12 @@ c_parser_attributes (c_parser *parser) > > break; > > continue; > > } > > + if (is_attribute_p ("simd", attr_name)) > > + { > > + parser->simd_attr_present = 1; > > + c_parser_consume_token (parser); > > + continue; > > + } > > Any such continue needs first to break if the next token isn't a comma; > otherwise you accept bad syntax with no comma between successive > attributes. I've understood your point. Fixed both C/C++. I've additionally fixed Cilk case in C++ by analogy w/ Marek's fix. Boostrapped. Regtesting is in progress. Is it ok for trunk if pass? gcc/ * cp/parser.h (cp_parser): Add simd_attr_present. * cp/parser.c (cp_parser_late_return_type_opt): Handle simd_attr_present, require comman in __vector__ attribute. (cp_parser_gnu_attribute_list): Ditto. * c/c-parser.c (c_parser): Add simd_attr_present flag. (c_parser_declaration_or_fndef): Call c_parser_declaration_or_fndef if simd_attr_present is set. (c_finish_omp_declare_simd): Handle simd_attr_present. * doc/extend.texi (simd): Document new attribute. * omp-low.c (pass_omp_simd_clone::gate): If target allows - call without additional conditions. gcc/testsuite/ * c-c++-common/attr-simd.c: New test. * c-c++-common/attr-simd-2.c: Ditto. * c-c++-common/attr-simd-3.c: Ditto. --- Thanks, K index c8c6a2d..b026f72 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -224,6 +224,9 @@ struct GTY(()) c_parser { /* Buffer to hold all the tokens from parsing the vector attribute for the SIMD-enabled functions (formerly known as elemental functions). */ vec *cilk_simd_fn_tokens; + + /* Designates if "simd" attribute is specified in decl. */ + BOOL_BITFIELD simd_attr_present : 1; }; @@ -1701,7 +1704,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, if (declarator == NULL) { if (omp_declare_simd_clauses.exists () - || !vec_safe_is_empty (parser->cilk_simd_fn_tokens)) + || !vec_safe_is_empty (parser->cilk_simd_fn_tokens) + || parser->simd_attr_present) c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE, omp_declare_simd_clauses); c_parser_skip_to_end_of_block_or_statement (parser); @@ -1797,7 +1801,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, if (!d) d = error_mark_node; if (omp_declare_simd_clauses.exists () - || !vec_safe_is_empty (parser->cilk_simd_fn_tokens)) + || !vec_safe_is_empty (parser->cilk_simd_fn_tokens) + || parser->simd_attr_present) c_finish_omp_declare_simd (parser, d, NULL_TREE, omp_declare_simd_clauses); } @@ -1810,7 +1815,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, if (!d) d = error_mark_node; if (omp_declare_simd_clauses.exists () - || !vec_safe_is_empty (parser->cilk_simd_fn_tokens)) + || !vec_safe_is_empty (parser->cilk_simd_fn_tokens) + || parser->simd_attr_present) c_finish_omp_declare_simd (parser, d, NULL_TREE, omp_declare_simd_clauses); start_init (d, asm_name, global_bindings_p ()); @@ -1839,7 +1845,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, chainon (postfix_attrs, all_prefix_attrs)); if (omp_declare_simd_clauses.exists () - || !vec_safe_is_empty (parser->cilk_simd_fn_tokens)) + || !vec_safe_is_empty (parser->cilk_simd_fn_tokens) + || parser->simd_attr_present) { tree parms = NULL_TREE; if (d && TREE_CODE (d) == FUNCTION_DECL) @@ -1968,7 +1975,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, true, false, NULL, vNULL); store_parm_decls (); if (omp_declare_simd_clauses.exists () - || !vec_safe_is_empty (parser->cilk_simd_fn_tokens)) + || !vec_safe_is_empty (parser->cilk_simd_fn_tokens) + || parser->simd_attr_present) c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE, omp_declare_simd_clauses); DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus @@ -3993,6 +4001,15 @@ c_parser_attributes (c_parser *parser) break; continue; } + if (is_attribute_p ("simd", attr_name)) + { + parser->simd_attr_present = 1; + c_parser_consume_token (parser); + /* If the next token isn't a comma, we're done. */ + if (!c_parser_next_token_is (parser, CPP_COMMA)) + break; + continue; + } c_parser_consume_token (parser); if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) { @@ -15388,9 +15405,10 @@ c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms, vec clauses) { if (flag_cilkplus - && clauses.exists () && !vec_safe_is_empty (parser->cilk_simd_fn_tokens)) + && (clauses.exists () || parser->simd_attr_present) + && !vec_safe_is_empty (parser->cilk_simd_fn_tokens)) { - error ("%<#pragma omp declare simd%> cannot be used in the same " + error ("%<#pragma omp declare simd%> or __simd__ attribute cannot be used in the same " "function marked as a Cilk Plus SIMD-enabled function"); vec_free (parser->cilk_simd_fn_tokens); return; @@ -15423,7 +15441,7 @@ c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms, unsigned int tokens_avail = parser->tokens_avail; gcc_assert (parser->tokens == &parser->tokens_buf[0]); bool is_cilkplus_cilk_simd_fn = false; - + if (flag_cilkplus && !vec_safe_is_empty (parser->cilk_simd_fn_tokens)) { parser->tokens = parser->cilk_simd_fn_tokens->address (); @@ -15435,41 +15453,63 @@ c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms, parser->tokens = clauses.address (); parser->tokens_avail = clauses.length (); } - - /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */ - while (parser->tokens_avail > 3) + + if (parser->simd_attr_present + && is_cilkplus_cilk_simd_fn) { - c_token *token = c_parser_peek_token (parser); - if (!is_cilkplus_cilk_simd_fn) - gcc_assert (token->type == CPP_NAME - && strcmp (IDENTIFIER_POINTER (token->value), "simd") == 0); - else - gcc_assert (token->type == CPP_NAME - && is_cilkplus_vector_p (token->value)); - c_parser_consume_token (parser); - parser->in_pragma = true; + error ("SIMD-enabled function attributes" + "are allowed when attribute __simd__ is specified"); + clauses[0].type = CPP_EOF; + return; + } + /* Attach `omp declare simd’ attribute if __simd__ is specified AND no OpenMP clauses + present in decl. */ + if (parser->simd_attr_present + && parser->tokens_avail == 0) + { tree c = NULL_TREE; - if (is_cilkplus_cilk_simd_fn) - c = c_parser_omp_all_clauses (parser, CILK_SIMD_FN_CLAUSE_MASK, - "SIMD-enabled functions attribute"); - else - c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK, - "#pragma omp declare simd"); - c = c_omp_declare_simd_clauses_to_numbers (parms, c); - if (c != NULL_TREE) - c = tree_cons (NULL_TREE, c, NULL_TREE); - if (is_cilkplus_cilk_simd_fn) - { - tree k = build_tree_list (get_identifier ("cilk simd function"), - NULL_TREE); - TREE_CHAIN (k) = DECL_ATTRIBUTES (fndecl); - DECL_ATTRIBUTES (fndecl) = k; - } c = build_tree_list (get_identifier ("omp declare simd"), c); TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl); DECL_ATTRIBUTES (fndecl) = c; } + else + { + /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */ + while (parser->tokens_avail > 3) + { + c_token *token = c_parser_peek_token (parser); + if (!is_cilkplus_cilk_simd_fn) + gcc_assert (token->type == CPP_NAME + && strcmp (IDENTIFIER_POINTER (token->value), "simd") == 0); + else + gcc_assert (token->type == CPP_NAME + && is_cilkplus_vector_p (token->value)); + c_parser_consume_token (parser); + parser->in_pragma = true; + + tree c = NULL_TREE; + if (is_cilkplus_cilk_simd_fn) + c = c_parser_omp_all_clauses (parser, CILK_SIMD_FN_CLAUSE_MASK, + "SIMD-enabled functions attribute"); + else + c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK, + "#pragma omp declare simd"); + c = c_omp_declare_simd_clauses_to_numbers (parms, c); + if (c != NULL_TREE) + c = tree_cons (NULL_TREE, c, NULL_TREE); + if (is_cilkplus_cilk_simd_fn) + { + tree k = build_tree_list (get_identifier ("cilk simd function"), + NULL_TREE); + TREE_CHAIN (k) = DECL_ATTRIBUTES (fndecl); + DECL_ATTRIBUTES (fndecl) = k; + } + c = build_tree_list (get_identifier ("omp declare simd"), c); + TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl); + DECL_ATTRIBUTES (fndecl) = c; + } + } parser->tokens = &parser->tokens_buf[0]; parser->tokens_avail = tokens_avail; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7555bf3..69ffb61 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -19331,7 +19331,9 @@ cp_parser_late_return_type_opt (cp_parser* parser, cp_declarator *declarator, /* A late-specified return type is indicated by an initial '->'. */ if (token->type != CPP_DEREF && token->keyword != RID_REQUIRES - && !(declare_simd_p || cilk_simd_fn_vector_p)) + && !(declare_simd_p + || cilk_simd_fn_vector_p + || parser->simd_attr_present)) return NULL_TREE; tree save_ccp = current_class_ptr; @@ -19363,6 +19365,18 @@ cp_parser_late_return_type_opt (cp_parser* parser, cp_declarator *declarator, = cp_parser_late_parsing_omp_declare_simd (parser, declarator->std_attributes); + if (parser->simd_attr_present + && !declare_simd_p) + { + if (cilk_simd_fn_vector_p) + error ("__simd__ attribute cannot be used in the same function" + " marked as a Cilk Plus SIMD-enabled function"); + + tree c = build_tree_list (get_identifier ("omp declare simd"), NULL_TREE); + TREE_CHAIN (c) = declarator->std_attributes; + declarator->std_attributes = c; + } + if (quals >= 0) { current_class_ptr = save_ccp; @@ -23320,6 +23334,21 @@ cp_parser_gnu_attribute_list (cp_parser* parser) else if (is_cilkplus_vector_p (identifier)) { cp_parser_cilk_simd_fn_vector_attrs (parser, id_token); + /* Now, look for more attributes. If the next token isn't a + `,', we're done. */ + if (token->type != CPP_COMMA) + break; + + continue; + } else + if (is_attribute_p ("simd", identifier)) + { + parser->simd_attr_present = 1; + /* Now, look for more attributes. If the next token isn't a + `,', we're done. */ + if (token->type != CPP_COMMA) + break; + continue; } diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h index 760467c..f4e33e3 100644 --- a/gcc/cp/parser.h +++ b/gcc/cp/parser.h @@ -371,6 +371,8 @@ struct GTY(()) cp_parser { necessary. */ cp_omp_declare_simd_data * GTY((skip)) cilk_simd_fn_info; + bool simd_attr_present; + /* Nonzero if parsing a parameter list where 'auto' should trigger an implicit template parameter. */ bool auto_is_implicit_function_template_parm_p; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index fdb1547..32994a2 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3066,6 +3066,21 @@ This function attribute make a stack protection of the function if flags @option{fstack-protector} or @option{fstack-protector-strong} or @option{fstack-protector-explicit} are set. +@item simd +@cindex @code{simd} function attribute. +This attribute enables creation of one or more function versions that +can process multiple arguments using SIMD instructions from a +single invocation. Specifying this attribute allows compiler to +assume that such a versions are available at link time (provided +in the same or another translation unit). Generated versions are +target dependent and described in corresponding Vector ABI document. For +x86_64 target this document can be found +@w{@uref{https://sourceware.org/glibc/wiki/libmvec?action=AttachFile&do=view&target=VectorABI.txt,here}}. +It is prohibited to use the attribute along with Cilk Plus's @code{vector} +attribute. If the attribute is specified and @code{#pragma omp declare simd} +presented on a declaration and @code{-fopenmp} or @code{-fopenmp-simd} +switch is specified, then the attribute is ignored. + @item target (@var{options}) @cindex @code{target} function attribute Multiple target back ends implement the @code{target} attribute diff --git a/gcc/omp-low.c b/gcc/omp-low.c index ad7c017..232dc5c 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -17412,10 +17412,7 @@ public: bool pass_omp_simd_clone::gate (function *) { - return ((flag_openmp || flag_openmp_simd - || flag_cilkplus - || (in_lto_p && !flag_wpa)) - && (targetm.simd_clone.compute_vecsize_and_simdlen != NULL)); + return targetm.simd_clone.compute_vecsize_and_simdlen != NULL; } } // anon namespace diff --git a/gcc/testsuite/c-c++-common/attr-simd-2.c b/gcc/testsuite/c-c++-common/attr-simd-2.c new file mode 100644 index 0000000..e9afc11 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-simd-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-optimized -fopenmp-simd" } */ + +#pragma omp declare simd +__attribute__((__simd__)) +static int simd_attr (void) +{ + return 0; +} + +/* { dg-final { scan-tree-dump "omp declare simd" "optimized" } } */ diff --git a/gcc/testsuite/c-c++-common/attr-simd-3.c b/gcc/testsuite/c-c++-common/attr-simd-3.c new file mode 100644 index 0000000..2bbdf04 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-simd-3.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-fcilkplus" } */ +/* { dg-prune-output "undeclared here \\(not in a function\\)|\[^\n\r\]* was not declared in this scope" } */ + +void f () __attribute__((__simd__, __vector__)); /* { dg-error "in the same function marked as a Cilk Plus" } */ diff --git a/gcc/testsuite/c-c++-common/attr-simd.c b/gcc/testsuite/c-c++-common/attr-simd.c new file mode 100644 index 0000000..dabdd81 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-simd.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-optimized" } */ + +__attribute__((__simd__)) +static int simd_attr (void) +{ + return 0; +} + +/* { dg-final { scan-tree-dump "omp declare simd" "optimized" } } */