From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27348 invoked by alias); 23 Oct 2015 14:11:39 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 27337 invoked by uid 89); 23 Oct 2015 14:11:38 -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-wi0-f181.google.com Received: from mail-wi0-f181.google.com (HELO mail-wi0-f181.google.com) (209.85.212.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 23 Oct 2015 14:11:36 +0000 Received: by wicfx6 with SMTP id fx6so33161728wic.1 for ; Fri, 23 Oct 2015 07:11:33 -0700 (PDT) X-Received: by 10.180.102.233 with SMTP id fr9mr400742wib.59.1445609493339; Fri, 23 Oct 2015 07:11:33 -0700 (PDT) Received: from msticlxl57.ims.intel.com (jfdmzpr02-ext.jf.intel.com. [134.134.137.71]) by smtp.gmail.com with ESMTPSA id ew2sm3120344wic.20.2015.10.23.07.11.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 23 Oct 2015 07:11:31 -0700 (PDT) Date: Fri, 23 Oct 2015 14:16:00 -0000 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: <20151023141102.GA63293@msticlxl57.ims.intel.com> References: <20151005130733.GB62312@msticlxl57.ims.intel.com> <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> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes X-SW-Source: 2015-10/txt/msg02455.txt.bz2 Hello Joseph, On 22 Oct 12:48, Joseph Myers wrote: > On Thu, 22 Oct 2015, Kirill Yukhin wrote: > > > Ping? > > 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. Additionally I've discovered that despite of the tests being in c-c++-common, attribute was added to C only. I've added it to C++ as well. Updated ChangeLog: gcc/ * cp/parser.h (cp_parser): Add simd_attr_present. * cp/parser.c (cp_parser_late_return_type_opt): Handle simd_attr_present. (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. Bootstrapped. Regtests showed 2 flakys (IMHO) + all new tests PASS: $ 26110-vector-attr-2-ref/src/gcc/contrib/compare_tests *ref *exp # Comparing directories ## Dir1=26110-vector-attr-2-ref: 4 sum files ## Dir2=26121-vector-attr-2-exp: 4 sum files # Comparing 4 common sum files ## /bin/sh 26110-vector-attr-2-ref/src/gcc/contrib/compare_tests /tmp/gxx-sum1.11112 /tmp/gxx-sum2.11112 Tests that now fail, but worked before: gcc.dg/cpp/_Pragma3.c (test for excess errors) gcc.dg/pragma-diag-5.c missing (test for warnings, line 2) unix/-m32: gcc.dg/cpp/_Pragma3.c (test for excess errors) unix/-m32: gcc.dg/pragma-diag-5.c missing (test for warnings, line 2) Is it ok for trunk? -- Thanks, K > -- > Joseph S. Myers > joseph@codesourcery.com diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index c8c6a2d..ae6122a 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,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; + } c_parser_consume_token (parser); if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) { @@ -15388,9 +15402,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 +15438,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 +15450,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..8970cf5 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; @@ -23321,6 +23335,11 @@ cp_parser_gnu_attribute_list (cp_parser* parser) { cp_parser_cilk_simd_fn_vector_attrs (parser, id_token); continue; + } else + if (is_attribute_p ("simd", identifier)) + { + parser->simd_attr_present = 1; + continue; } if (arguments != error_mark_node) 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" } } */