From patchwork Thu Dec 5 16:36:39 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Iyer, Balaji V" X-Patchwork-Id: 297197 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 517112C00A2 for ; Fri, 6 Dec 2013 03:37:05 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:references:in-reply-to :content-type:mime-version; q=dns; s=default; b=RaqY98daxnn9aosF k2yQoD0NhFjQXkRps26wCsYknRszpaLr/eXEg7Z2N8RJt9WV0FV7QoFW9YGxhdj6 4lhaQAzk1+Fm0B7cjvwkicY4DRWDjDiubrKhSIKbsBspC8mhdgjl2whiSgEzYsOX BQN53QXP5sdfRM7AMEE/fk1K0zY= 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:from :to:cc:subject:date:message-id:references:in-reply-to :content-type:mime-version; s=default; bh=crJMufAy+K7X/bxenKuxK0 GXBco=; b=rRwVl86BSLKa3RkQ0LYYvV+5wNyqdtlnNkMTe8T+MKGkHcKxYr+Ms+ ZY6m4KXpGA/VNlWoB48ZM42BZm7u3HqP7GN8u7o/NSXoxrldw2btYIfC9qccJvKF NHZgdAp3+jEm6NAOsG5r/B3Bf5xV2BNfowE0vz6wwGXxNXOcQFtK4= Received: (qmail 6935 invoked by alias); 5 Dec 2013 16:36:53 -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 6834 invoked by uid 89); 5 Dec 2013 16:36:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.4 required=5.0 tests=AWL, BAYES_50, LIKELY_SPAM_SUBJECT, SPF_PASS autolearn=no version=3.3.2 X-HELO: mga09.intel.com Received: from Unknown (HELO mga09.intel.com) (134.134.136.24) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 05 Dec 2013 16:36:49 +0000 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 05 Dec 2013 08:32:59 -0800 X-ExtLoop1: 1 Received: from fmsmsx104.amr.corp.intel.com ([10.19.9.35]) by orsmga001.jf.intel.com with ESMTP; 05 Dec 2013 08:36:39 -0800 Received: from fmsmsx154.amr.corp.intel.com (10.18.116.70) by FMSMSX104.amr.corp.intel.com (10.19.9.35) with Microsoft SMTP Server (TLS) id 14.3.123.3; Thu, 5 Dec 2013 08:36:39 -0800 Received: from fmsmsx101.amr.corp.intel.com ([169.254.1.227]) by FMSMSX154.amr.corp.intel.com ([169.254.6.112]) with mapi id 14.03.0123.003; Thu, 5 Dec 2013 08:36:39 -0800 From: "Iyer, Balaji V" To: Jakub Jelinek CC: "Aldy Hernandez (aldyh@redhat.com)" , "gcc-patches@gcc.gnu.org" Subject: FW: [GOMP4][PATCH] SIMD-enabled functions (formerly Elemental functions) for C++ Date: Thu, 5 Dec 2013 16:36:39 +0000 Message-ID: References: In-Reply-To: MIME-Version: 1.0 X-IsSubscribed: yes PING! -Balaji V. Iyer. > -----Original Message----- > From: Iyer, Balaji V > Sent: Saturday, November 30, 2013 11:53 PM > To: 'Jakub Jelinek' > Cc: Aldy Hernandez (aldyh@redhat.com); 'Jeff Law'; 'gcc- > patches@gcc.gnu.org' > Subject: RE: [GOMP4][PATCH] SIMD-enabled functions (formerly Elemental > functions) for C++ > > Hello Everyone, > The changes mentioned in http://gcc.gnu.org/ml/gcc-patches/2013- > 11/msg03506.html is also applicable to my C++ patch. With this email, I am > attaching a fixed patch. > > Here are the ChangeLog entries: > > gcc/cp/ChangeLog > 2013-11-30 Balaji V. Iyer > > * decl2.c (is_late_template_attribute): Added a check for SIMD-enabled > functions attribute. If found, return true. > * parser.c (cp_parser_direct_declarator): When Cilk Plus is enabled > see if there is an attribute after function decl. If so, then > parse them now. > (cp_parser_late_return_type_opt): Handle parsing of Cilk Plus SIMD > enabled function late parsing. > (cp_parser_gnu_attribute_list): Parse all the tokens for the vector > attribute for a SIMD-enabled function. > (cp_parser_omp_all_clauses): Skip parsing to the end of pragma when > the function is used by SIMD-enabled function (indicated by NULL > pragma token). > (cp_parser_elem_fn_vectorlength): New function. > (cp_parser_elem_fn_expr_list): Likewise. > (cp_parser_late_parsing_elem_fn_info): Likewise. > * parser.h (cp_parser::elem_fn_info): New field. > * decl.c (grokfndecl): Added a check if Cilk Plus is enabled and > if so, adjust the Cilk Plus SIMD-enabled function attributes. > > > gcc/testsuite/ChangeLog > 2013-11-30 Balaji V. Iyer > > * g++.dg/cilk-plus/cilk-plus.exp: Called the C/C++ common tests for > SIMD enabled function. > * g++.dg/cilk-plus/ef_test.C: New test. > > Is this OK for branch? > > Thanks, > > Balaji V. Iyer. > > > -----Original Message----- > > From: Iyer, Balaji V > > Sent: Wednesday, November 20, 2013 6:19 PM > > To: Jakub Jelinek > > Cc: Aldy Hernandez (aldyh@redhat.com); Jeff Law; > > gcc-patches@gcc.gnu.org > > Subject: [GOMP4][PATCH] SIMD-enabled functions (formerly Elemental > > functions) for C++ > > > > Hello Everyone, > > Attached, please find a patch that will implement SIMD-enabled > > functions for C++ targeting the gomp-4_0-branch. Here are the > > Changelog entries. Is this OK to install? > > > > gcc/cp/ChangeLog > > 2013-11-20 Balaji V. Iyer > > > > * parser.c (cp_parser_direct_declarator): When Cilk Plus is enabled > > see if there is an attribute after function decl. If so, then > > parse them now. > > (cp_parser_late_return_type_opt): Handle parsing of Cilk Plus SIMD > > enabled function late parsing. > > (cp_parser_gnu_attribute_list): Parse all the tokens for the vector > > attribute for a SIMD-enabled function. > > (cp_parser_omp_all_clauses): Skip parsing to the end of pragma when > > the function is used by SIMD-enabled function (indicated by NULL > > pragma token). > > (cp_parser_elem_fn_vectorlength): New function. > > (cp_parser_elem_fn_expr_list): Likewise. > > (cp_parser_late_parsing_elem_fn_info): Likewise. > > * parser.h (cp_parser::elem_fn_info): New field. > > > > gcc/testsuite/ChangeLog > > 2013-11-20 Balaji V. Iyer > > > > * g++.dg/cilk-plus/cilk-plus.exp: Called the C/C++ common tests for > > SIMD enabled function. > > * g++.dg/cilk-plus/ef_test.C: New test. > > > > > > Thanking You, > > > > Yours Sincerely, > > > > Balaji V. Iyer. Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 205562) +++ gcc/cp/decl.c (working copy) @@ -7669,6 +7669,34 @@ } } + if (flag_enable_cilkplus) + { + /* Adjust "cilk plus elemental attribute" attributes. */ + tree ods = lookup_attribute ("cilk plus elemental", *attrlist); + if (ods) + { + tree attr; + for (attr = ods; attr; + attr = lookup_attribute ("cilk plus elemental", + TREE_CHAIN (attr))) + { + if (TREE_CODE (type) == METHOD_TYPE) + walk_tree (&TREE_VALUE (attr), declare_simd_adjust_this, + DECL_ARGUMENTS (decl), NULL); + if (TREE_VALUE (attr) != NULL_TREE) + { + tree cl = TREE_VALUE (TREE_VALUE (attr)); + cl = c_omp_declare_simd_clauses_to_numbers + (DECL_ARGUMENTS (decl), cl); + if (cl) + TREE_VALUE (TREE_VALUE (attr)) = cl; + else + TREE_VALUE (attr) = NULL_TREE; + } + } + } + } + /* Caller will do the rest of this. */ if (check < 0) return decl; Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 205562) +++ gcc/cp/pt.c (working copy) @@ -8603,9 +8603,12 @@ { *p = TREE_CHAIN (t); TREE_CHAIN (t) = NULL_TREE; - if (flag_openmp - && is_attribute_p ("omp declare simd", - get_attribute_name (t)) + if (((flag_openmp + && is_attribute_p ("omp declare simd", + get_attribute_name (t))) + || (flag_enable_cilkplus + && is_attribute_p ("cilk plus elemental", + get_attribute_name (t)))) && TREE_VALUE (t)) { tree clauses = TREE_VALUE (TREE_VALUE (t)); Index: gcc/cp/decl2.c =================================================================== --- gcc/cp/decl2.c (revision 205562) +++ gcc/cp/decl2.c (working copy) @@ -1124,6 +1124,10 @@ && is_attribute_p ("omp declare simd", name)) return true; + /* Ditto as above for Cilk Plus SIMD-enabled function attributes. */ + if (flag_enable_cilkplus && is_attribute_p ("cilk plus elemental", name)) + return true; + /* If any of the arguments are dependent expressions, we can't evaluate the attribute until instantiation time. */ for (arg = args; arg; arg = TREE_CHAIN (arg)) Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 205562) +++ gcc/cp/parser.c (working copy) @@ -2115,6 +2115,9 @@ static tree cp_parser_late_parsing_omp_declare_simd (cp_parser *, tree); +static tree cp_parser_late_parsing_elem_fn_info + (cp_parser *, tree); + static tree synthesize_implicit_template_parm (cp_parser *); static tree finish_fully_implicit_template @@ -17035,6 +17038,14 @@ attrs = cp_parser_std_attribute_spec_seq (parser); + /* In here, we handle cases where attribute is used after + the function declaration. For example: + void func (int x) __attribute__((vector(..))); */ + if (flag_enable_cilkplus + && cp_lexer_next_token_is_keyword (parser->lexer, + RID_ATTRIBUTE)) + attrs = chainon (cp_parser_gnu_attributes_opt (parser), + attrs); late_return = (cp_parser_late_return_type_opt (parser, declarator, memfn ? cv_quals : -1)); @@ -17743,7 +17754,7 @@ Returns the type indicated by the type-id. In addition to this this parses any queued up omp declare simd - clauses. + clauses and Cilk Plus SIMD-enabled function's vector attributes. QUALS is either a bitmask of cv_qualifiers or -1 for a non-member function. */ @@ -17758,10 +17769,14 @@ && declarator && declarator->kind == cdk_id); + bool elem_fn_vector_p = (parser->elem_fn_info + && declarator + && declarator->kind == cdk_id); + /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); /* A late-specified return type is indicated by an initial '->'. */ - if (token->type != CPP_DEREF && !declare_simd_p) + if (token->type != CPP_DEREF && !(declare_simd_p || elem_fn_vector_p)) return NULL_TREE; tree save_ccp = current_class_ptr; @@ -17780,6 +17795,10 @@ type = cp_parser_trailing_type_id (parser); } + if (elem_fn_vector_p) + declarator->std_attributes + = cp_parser_late_parsing_elem_fn_info (parser, + declarator->std_attributes); if (declare_simd_p) declarator->std_attributes = cp_parser_late_parsing_omp_declare_simd (parser, @@ -21310,6 +21329,121 @@ return cp_parser_std_attribute_spec_seq (parser); } +/* Parses the vectorlength clause in Cilk Plus SIMD-enabled function + (formerly called elemental functions). Syntax: + vectorlength ( ) */ + +static void +cp_parser_elem_fn_vectorlength (cp_parser *parser, + cp_omp_declare_simd_data *info) +{ + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + { + info->error_seen = true; + return; + } + + cp_token *token = cp_lexer_peek_token (parser->lexer); + location_t loc = token->location; + if (!token->u.value) + { + error_at (loc, "expected vectorlength value"); + info->error_seen = true; + cp_parser_skip_to_closing_parenthesis (parser, true, false, true); + return; + } + if (TREE_CODE (token->u.value) != INTEGER_CST) + { + error_at (loc, "vectorlength must be a constant integer"); + info->error_seen = true; + cp_parser_skip_to_closing_parenthesis (parser, true, false, true); + return; + } + if (!integer_pow2p (token->u.value)) + { + error_at (loc, "vectorlength must be a power of 2"); + info->error_seen = true; + cp_parser_skip_to_closing_parenthesis (parser, true, false, true); + return; + } + /* Consume the vectorlength value. */ + cp_lexer_consume_token (parser->lexer); + + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) + info->error_seen = true; +} + +cp_omp_declare_simd_data info; + +/* Parses the Cilk Plus SIMD-enabled function's attribute. Syntax: + vector [()] */ + +static void +cp_parser_elem_fn_expr_list (cp_parser *parser, cp_token *v_token) +{ + bool first_p = parser->elem_fn_info == NULL; + cp_token *token = v_token; + if (first_p) + { + info.error_seen = false; + info.fndecl_seen = false; + info.tokens = vNULL; + parser->elem_fn_info = &info; + } + int paren_scope = 0; + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) + { + cp_lexer_consume_token (parser->lexer); + v_token = cp_lexer_peek_token (parser->lexer); + paren_scope++; + } + while (paren_scope > 0) + { + token = cp_lexer_peek_token (parser->lexer); + if (token->type == CPP_OPEN_PAREN) + paren_scope++; + else if (token->type == CPP_CLOSE_PAREN) + paren_scope--; + else if (token->type == CPP_NAME + && TREE_CODE (token->u.value) == IDENTIFIER_NODE) + { + tree val = token->u.value; + if (simple_cst_equal (val, get_identifier ("mask")) == 1) + token->u.value = get_identifier ("inbranch"); + else if (simple_cst_equal (val, get_identifier ("nomask")) == 1) + token->u.value = get_identifier ("notinbranch"); + else if (simple_cst_equal (val, + get_identifier ("vectorlength")) == 1) + { + token->u.value = get_identifier ("simdlen"); + parser->lexer->next_token->u.value = token->u.value; + cp_lexer_consume_token (parser->lexer); + cp_parser_elem_fn_vectorlength (parser, &info); + /* The above function should parse till the end of + vectorlength's last parenthesis. */ + continue; + } + /* linear and uniform are the same between SIMD-enabled functions + and #pragma omp declare simd. */ + + /* We sometimes modify the next token, so reset the next token. */ + parser->lexer->next_token->u.value = token->u.value; + } + + /* Do not push the last ')' */ + if (!(token->type == CPP_CLOSE_PAREN && paren_scope == 0)) + cp_lexer_consume_token (parser->lexer); + } + + token->type = CPP_PRAGMA_EOL; + parser->lexer->next_token = token; + cp_lexer_consume_token (parser->lexer); + + struct cp_token_cache *cp = + cp_token_cache_new (v_token, cp_lexer_peek_token (parser->lexer)); + parser->elem_fn_info->tokens.safe_push (cp); +} + /* Parse an (optional) series of attributes. attributes: @@ -21406,8 +21540,9 @@ { tree arguments = NULL_TREE; - /* Consume the token. */ - token = cp_lexer_consume_token (parser->lexer); + /* Consume the token, but save it since we need it for the + SIMD enabled function parsing. */ + cp_token *id_token = cp_lexer_consume_token (parser->lexer); /* Save away the identifier that indicates which attribute this is. */ @@ -21415,7 +21550,7 @@ /* For keywords, use the canonical spelling, not the parsed identifier. */ ? ridpointers[(int) token->keyword] - : token->u.value; + : id_token->u.value; attribute = build_tree_list (identifier, NULL_TREE); @@ -21427,10 +21562,17 @@ vec *vec; int attr_flag = (attribute_takes_identifier_p (identifier) ? id_attr : normal_attr); - vec = cp_parser_parenthesized_expression_list - (parser, attr_flag, /*cast_p=*/false, - /*allow_expansion_p=*/false, - /*non_constant_p=*/NULL); + if (simple_cst_equal (identifier, + get_identifier ("vector")) == 1) + { + cp_parser_elem_fn_expr_list (parser, id_token); + continue; + } + else + vec = cp_parser_parenthesized_expression_list + (parser, attr_flag, /*cast_p=*/false, + /*allow_expansion_p=*/false, + /*non_constant_p=*/NULL); if (vec == NULL) arguments = error_mark_node; else @@ -21441,6 +21583,12 @@ /* Save the arguments away. */ TREE_VALUE (attribute) = arguments; } + else if (simple_cst_equal (identifier, + get_identifier ("vector")) == 1) + { + cp_parser_elem_fn_expr_list (parser, id_token); + continue; + } if (arguments != error_mark_node) { @@ -28080,7 +28228,10 @@ } } saw_error: - cp_parser_skip_to_pragma_eol (parser, pragma_tok); + /* In Cilk Plus SIMD enabled functions, there is no pragma_token, so + no reason to skip to the end. */ + if (!(flag_enable_cilkplus && pragma_tok == NULL)) + cp_parser_skip_to_pragma_eol (parser, pragma_tok); if (finish_p) return finish_omp_clauses (clauses); return clauses; @@ -30078,6 +30229,61 @@ } } +/* Handles the delayed parsing of the Cilk Plus SIMD-enabled function. + This function is modelled similar to the late parsing of omp declare + simd. */ + +static tree +cp_parser_late_parsing_elem_fn_info (cp_parser *parser, tree attrs) +{ + struct cp_token_cache *ce; + cp_omp_declare_simd_data *info = parser->elem_fn_info; + int ii = 0; + + if (parser->omp_declare_simd != NULL) + { + error ("%<#pragma omp declare simd%> cannot be used in the same function" + " marked as a SIMD-enabled function"); + parser->elem_fn_info = NULL; + return attrs; + } + if (!info->error_seen && info->fndecl_seen) + { + error ("vector attribute not immediately followed by a single function" + " declaration or definition"); + info->error_seen = true; + } + if (info->error_seen) + return attrs; + + /* Vector attributes are converted to #pragma omp declare simd values and + so we need them enabled. */ + flag_openmp = 1; + + FOR_EACH_VEC_ELT (info->tokens, ii, ce) + { + tree c, cl; + + cp_parser_push_lexer_for_tokens (parser, ce); + parser->lexer->in_pragma = true; + cl = cp_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK, + "SIMD-enabled functions attribute", + NULL); + cp_parser_pop_lexer (parser); + if (cl) + cl = tree_cons (NULL_TREE, cl, NULL_TREE); + //c = build_tree_list (get_identifier ("omp declare simd"), cl); + c = build_tree_list (get_identifier ("cilk plus elemental"), cl); + TREE_CHAIN (c) = attrs; + if (processing_template_decl) + ATTR_IS_DEPENDENT (c) = 1; + attrs = c; + } + info->fndecl_seen = true; + parser->elem_fn_info = NULL; + return attrs; +} + /* Finalize #pragma omp declare simd clauses after direct declarator has been parsed, and put that into "omp declare simd" attribute. */ Index: gcc/cp/parser.h =================================================================== --- gcc/cp/parser.h (revision 205562) +++ gcc/cp/parser.h (working copy) @@ -361,6 +361,13 @@ data structure with everything needed for parsing the clauses. */ cp_omp_declare_simd_data * GTY((skip)) omp_declare_simd; + /* When parsing the vector attribute in Cilk Plus SIMD-enabled function, + this is a pointer to data structure with everything needed for parsing + the clauses. The cp_omp_declare_simd_data struct will hold all the + necessary information, so creating another struct for this is not + necessary. */ + cp_omp_declare_simd_data * GTY((skip)) elem_fn_info; + /* Nonzero if parsing a parameter list where 'auto' should trigger an implicit template parameter. */ bool auto_is_implicit_function_template_parm_p; Index: gcc/testsuite/g++.dg/cilk-plus/ef_test.C =================================================================== --- gcc/testsuite/g++.dg/cilk-plus/ef_test.C (revision 0) +++ gcc/testsuite/g++.dg/cilk-plus/ef_test.C (revision 0) @@ -0,0 +1,38 @@ +/* { dg-do run } */ +/* { dg-options "-fcilkplus" } */ + + +__attribute__((vector (nomask), vector(mask), vector(mask,linear(x:1)))) +int func (int x) +{ + return x+5; +} + + +__attribute__((vector(mask,uniform (y), linear(x:1)))) +__attribute__((vector (nomask, uniform (x), linear(y:1)))) +int func2 (int x, int y) +{ + return x+y; +} + +int func4 (int x, int y) __attribute__((vector, vector (nomask), vector (uniform(y), linear(x:1)))); + + +template +__attribute__((vector, vector(mask,uniform (y), linear(x:1)))) +T func3 (T x, R y) +{ + return x+(T)y; +} + + + +int main (void) +{ + if ((func3 (5, 4) + func2 (5, 4) + func (5) + (int) func3 (5, 4)) != + (5 + 4) + (5 + 4) + (5 + 5) + (int) ((long)5 +(int)4)) + __builtin_abort (); + return 0; +} + Index: gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp =================================================================== --- gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp (revision 205562) +++ gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp (working copy) @@ -60,6 +60,12 @@ dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -g -O2 -ftree-vectorize -fcilkplus" " " dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -g -O3 -fcilkplus" " " dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -O3 -ftree-vectorize -fcilkplus -g" " " + +dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/EF/*.c]] " -g" " " +dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/EF/*.c]] " -O1" " " +dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/EF/*.c]] " -O2 -std=c++11" " " +dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/EF/*.c]] " -O2 -ftree-vectorize" " " +dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/EF/*.c]] " -O3 -g" " " dg-finish unset TEST_EXTRA_LIBS