From patchwork Sun Apr 8 05:02:00 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Iyer, Balaji V" X-Patchwork-Id: 151336 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]) by ozlabs.org (Postfix) with SMTP id 87654B7039 for ; Sun, 8 Apr 2012 15:02:24 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1334466145; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:From:To:Subject:Date:Message-ID:Content-Type: MIME-Version:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=pZF6qN3 lMPNcqiT2u7qRUYLZpV0=; b=mrs/dUrVW9wjS1JfZiMDTGB0kUAMjUReU0wEQKp 9ib74y3wyf6TpYcmERI7E/tiQFWxj94Cxj9apP2gsoLYlkWt87HQByQJTz5iBqgW dJ1NBLQOTf36CA2VOFZEh9M4qPgJNesGTK4974JtPCJsG+G7Wki06E/NcM11Gc5Q jh8I= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:X-ExtLoop1:Received:Received:Received:From:To:Subject:Date:Message-ID:Content-Type:MIME-Version:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=c8sfdZrxNeZA+X9h1TJAuK716ECMcRh5GiO/A6aw6A3uUP2KotnpllveB4Zue6 cNOWHUA8F4iwmEJsnnjbKuoxGgQwSB6YX9CB7i+GYjYljWK1UDkOu50obuhFEwHg wqUkcmbzaRuhHFwDaJdl8lu/2Gvh/3YDX/Xh1Cg0KVHe8=; Received: (qmail 12060 invoked by alias); 8 Apr 2012 05:02:20 -0000 Received: (qmail 12051 invoked by uid 22791); 8 Apr 2012 05:02:17 -0000 X-SWARE-Spam-Status: No, hits=-4.5 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mga14.intel.com (HELO mga14.intel.com) (143.182.124.37) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 08 Apr 2012 05:02:03 +0000 Received: from azsmga002.ch.intel.com ([10.2.17.35]) by azsmga102.ch.intel.com with ESMTP; 07 Apr 2012 22:02:01 -0700 X-ExtLoop1: 1 Received: from azsmsx601.amr.corp.intel.com ([10.2.121.193]) by AZSMGA002.ch.intel.com with ESMTP; 07 Apr 2012 22:02:01 -0700 Received: from fmsmsx108.amr.corp.intel.com (10.19.9.228) by azsmsx601.amr.corp.intel.com (10.2.121.193) with Microsoft SMTP Server (TLS) id 8.2.255.0; Sat, 7 Apr 2012 22:02:00 -0700 Received: from fmsmsx102.amr.corp.intel.com ([169.254.2.56]) by FMSMSX108.amr.corp.intel.com ([169.254.10.72]) with mapi id 14.01.0355.002; Sat, 7 Apr 2012 22:02:00 -0700 From: "Iyer, Balaji V" To: "gcc-patches@gcc.gnu.org" Subject: [PATCH][Cilkplus] Parsing support for Elemental function for C++ Date: Sun, 8 Apr 2012 05:02:00 +0000 Message-ID: MIME-Version: 1.0 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 Hello Everyone, This patch is for the Cilkplus branch affecting mainly the C++ compiler. It provides parsing support for elemental function attributes. Thanks, Balaji V. Iyer. diff --git a/gcc/ChangeLog.cilk b/gcc/ChangeLog.cilk index 6b7c176..dc96718 100644 --- a/gcc/ChangeLog.cilk +++ b/gcc/ChangeLog.cilk @@ -1,3 +1,8 @@ +2012-04-06 Balaji V. Iyer + + * c-parser.c (c_parser_elem_fn_expr_list): Fixed a bug and consumed + one token. + 2012-04-05 Balaji V. Iyer * config/i386/i386.c (type_natural_mode): Added a flag_enable_cilk diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 4aa4c2d..00a5064 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -12203,6 +12203,7 @@ c_parser_elem_fn_expr_list (c_parser *parser) && simple_cst_equal (token->value, get_identifier ("mask")) == 1) { + c_parser_consume_token (parser); gcc_assert (mask_list == NULL_TREE); mask_list = get_identifier ("mask"); if (c_parser_next_token_is (parser, CPP_COMMA)) diff --git a/gcc/cp/ChangeLog.cilk b/gcc/cp/ChangeLog.cilk index 0970089..65880f9 100644 --- a/gcc/cp/ChangeLog.cilk +++ b/gcc/cp/ChangeLog.cilk @@ -1,3 +1,13 @@ +2012-04-06 Balaji V. Iyer + + * parser.c (cp_parser_attribute_list): Added code to catch vector + attribute. + (cp_parser_elem_fn_processor_clause): New function. + (cp_parser_elem_fn_uniform_clause): Likewise. + (cp_parser_elem_fn_vlength_clause): Likewise. + (cp_parser_elem_fn_linear_clause): Likewise. + (cp_parser_elem_fn_expression_list): Likewise. + 2012-03-16 Balaji V. Iyer * decl.c (finish_function_body): called DECL_HAS_SPAWN_P and set it to @@ -5,7 +15,7 @@ * pt.c (tsubst_copy): Carried the spawn call information from one call expression to another. (tsubst_copy_and_build): Likewise. - + 2012-02-14 Balaji V. Iyer * parser.c (cp_parser_compound_stmt): Added a check to see if the diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index f6408ae..9cc8794 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -241,7 +241,8 @@ static tree cp_literal_operator_id static tree cp_parser_array_notation (cp_parser *, tree, tree); - +static VEC(tree,gc) *cp_parser_elem_fn_expression_list + (cp_parser *); /* Manifest constants. */ #define CP_LEXER_BUFFER_SIZE ((256 * 1024) / sizeof (cp_token)) @@ -20760,10 +20761,17 @@ cp_parser_attribute_list (cp_parser* parser) VEC(tree,gc) *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 we do find a vector attribute, we call the + * cp_parser_elem_fn_expression_list */ + if (TREE_CODE (identifier) == IDENTIFIER_NODE + && simple_cst_equal (identifier, + get_identifier ("vector")) == 1) + vec = cp_parser_elem_fn_expression_list (parser); + 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 @@ -29206,4 +29214,402 @@ cp_parser_array_notation (cp_parser *parser, tree init_index, tree array_value) return value_tree; } +/* this function handles the processor clause in elemental func. attribute */ +static tree +cp_parser_elem_fn_processor_clause (cp_parser *parser) +{ + VEC (tree,gc) *proc_vec_list = NULL; + tree proc_tree_list = NULL_TREE; + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)) + { + cp_parser_error (parser, "expected %<)%>"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL_TREE; + } + else + cp_lexer_consume_token (parser->lexer); + + proc_vec_list = make_tree_vector (); + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_token *token = cp_lexer_consume_token (parser->lexer); + if (token->u.value + && TREE_CODE (token->u.value) == IDENTIFIER_NODE + && simple_cst_equal (token->u.value, + get_identifier ("pentium_4")) == 1) + VEC_safe_push (tree, gc, proc_vec_list, + build_string (strlen ("pentium_4"), "pentium_4")); + else if (token->u.value + && TREE_CODE (token->u.value) == IDENTIFIER_NODE + && simple_cst_equal (token->u.value, + get_identifier ("pentium4_sse3")) == 1) + VEC_safe_push (tree, gc, proc_vec_list, + build_string (strlen ("pentium4_sse3"), + "pentium4_sse3")); + else if (token->u.value + && TREE_CODE (token->u.value) == IDENTIFIER_NODE + && simple_cst_equal (token->u.value, + get_identifier ("core2_duo_ssse3")) == 1) + VEC_safe_push (tree, gc, proc_vec_list, + build_string (strlen ("core2_duo_ssse3"), + "core2_duo_ssse3")); + else if (token->u.value + && TREE_CODE (token->u.value) == IDENTIFIER_NODE + && simple_cst_equal (token->u.value, + get_identifier ("core2_duo_sse_4_1")) == 1) + VEC_safe_push (tree, gc, proc_vec_list, + build_string (strlen ("core2_duo_sse_4_1"), + "core2_duo_sse_4_1")); + else if (token->u.value + && TREE_CODE (token->u.value) == IDENTIFIER_NODE + && simple_cst_equal (token->u.value, + get_identifier ("core_i7_sse4_2")) == 1) + VEC_safe_push (tree, gc, proc_vec_list, + build_string (strlen ("core_i7_sse4_2"), + "core_i7_sse4_2")); + else + sorry ("processor type not supported."); + + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + cp_lexer_consume_token (parser->lexer); + else + cp_parser_error (parser, "expected %>)%>"); + } + else + cp_parser_error (parser, "expected %>(%> and CPUID"); + + proc_tree_list = build_tree_list_vec (proc_vec_list); + release_tree_vector (proc_vec_list); + proc_tree_list = build_tree_list (get_identifier ("processor"), + proc_tree_list); + return proc_tree_list; +} + +/* this function handles the uniform clause in elemental func. attribute */ +static tree +cp_parser_elem_fn_uniform_clause (cp_parser *parser) +{ + VEC(tree,gc) *uniform_vec = NULL; + tree uniform_tree, str_token = NULL_TREE; + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)) + { + cp_parser_error (parser, "expected %<)%>"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL_TREE; + } + else + cp_lexer_consume_token (parser->lexer); + + uniform_vec = make_tree_vector (); + while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_token *token = cp_lexer_consume_token (parser->lexer); + if (token->u.value && token->type == CPP_NAME) + { + /* convert the variable to a string */ + str_token = + build_string (strlen (IDENTIFIER_POINTER (token->u.value)), + IDENTIFIER_POINTER (token->u.value)); + VEC_safe_push (tree, gc, uniform_vec, str_token); + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + { + cp_lexer_consume_token (parser->lexer); + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) + { + cp_parser_error (parser, "expected identifier after %<,%>"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL_TREE; + } + } + else if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_parser_error (parser, + "expected %<,%> or %<)%> after identifier"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL_TREE; + } + } + else + { + cp_parser_error (parser, "expected variable"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL_TREE; + } + } + cp_lexer_consume_token (parser->lexer); + + uniform_tree = build_tree_list_vec (uniform_vec); + release_tree_vector (uniform_vec); + uniform_tree = build_tree_list (get_identifier ("uniform"), uniform_tree); + return uniform_tree; +} + +/* this function handles the vectorlength clause in elemental func. attribute */ +static tree +cp_parser_elem_fn_vlength_clause (cp_parser *parser) +{ + VEC(tree,gc) *vlength_vec = NULL; + tree vlength_tree = NULL_TREE; + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)) + { + cp_parser_error (parser, "expected %<)%>"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL_TREE; + } + else + cp_lexer_consume_token (parser->lexer); + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_token *token = cp_lexer_consume_token (parser->lexer); + if (token->u.value && token->type == CPP_NUMBER) + VEC_safe_push (tree, gc, vlength_vec, token->u.value); + if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_parser_error (parser, "Cannot have multiple vector lengths for " + "elemental functions"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL_TREE; + } + else + cp_lexer_consume_token (parser->lexer); + } + else + { + cp_parser_error (parser, "expected integer"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL_TREE; + } + + vlength_tree = build_tree_list_vec (vlength_vec); + release_tree_vector (vlength_vec); + vlength_tree = build_tree_list (get_identifier ("vectorlength"), + vlength_tree); + return vlength_tree; +} + +/* this function handles the linear clause in elemental func. attribute */ +static tree +cp_parser_elem_fn_linear_clause (cp_parser *parser) +{ + VEC(tree,gc) *linear_vec = NULL; + tree linear_tree = NULL_TREE, var_str, step_size; + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)) + { + cp_parser_error (parser, "expected %<(%>"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL_TREE; + } + else + cp_lexer_consume_token (parser->lexer); + + linear_vec = make_tree_vector (); + + while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_token *token = cp_lexer_consume_token (parser->lexer); + if (token->u.value && token->type == CPP_NAME) + { + var_str = build_string (strlen (IDENTIFIER_POINTER (token->u.value)), + IDENTIFIER_POINTER (token->u.value)); + if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) + { + cp_lexer_consume_token (parser->lexer); + token = cp_lexer_consume_token (parser->lexer); + if (token->u.value && token->type == CPP_NUMBER) + step_size = token->u.value; + else + { + cp_parser_error (parser, "expected step-size"); + return NULL_TREE; + } + } + else + step_size = integer_one_node; + + VEC_safe_push (tree, gc, linear_vec, var_str); + VEC_safe_push (tree, gc, linear_vec, step_size); + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + { + cp_lexer_consume_token (parser->lexer); + if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) + { + cp_parser_error (parser, + "expected variable after %<,%>"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL_TREE; + } + } + else if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_parser_error (parser, + "expected %<,%> or %<)%> after variable/step"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL_TREE; + } + } + else + { + cp_parser_error (parser, "expected variable name"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL_TREE; + } + } + cp_lexer_consume_token (parser->lexer); /* consume the ')' */ + linear_tree = build_tree_list_vec (linear_vec); + release_tree_vector (linear_vec); + linear_tree = build_tree_list (get_identifier ("linear"), linear_tree); + return linear_tree; +} + +/* this function handles all the clauses in elemental func. attribute */ +static VEC(tree,gc) * +cp_parser_elem_fn_expression_list (cp_parser *parser ATTRIBUTE_UNUSED) +{ + VEC(tree,gc) *expr_list = make_tree_vector (); + tree proc_list = NULL_TREE, vlength_list = NULL_TREE, mask_list = NULL_TREE; + tree uniform_list = NULL_TREE, linear_list = NULL_TREE; + + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) + cp_lexer_consume_token (parser->lexer); + else + { + cp_parser_error (parser, "expected %<(%>"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL; + } + + while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_token *token = cp_lexer_consume_token (parser->lexer); + + if (token->u.value + && TREE_CODE (token->u.value) == IDENTIFIER_NODE + && simple_cst_equal (token->u.value, + get_identifier ("processor")) == 1) + { + if (proc_list) + { + cp_parser_error + (parser, "Cannot have multiple processor clauses"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL; + } + gcc_assert (NULL_TREE == proc_list); + proc_list = cp_parser_elem_fn_processor_clause (parser); + + } + else if (token->u.value + && TREE_CODE (token->u.value) == IDENTIFIER_NODE + && simple_cst_equal (token->u.value, + get_identifier ("mask")) == 1) + { + if (mask_list) + { + cp_parser_error (parser, "Cannot have multiple mask clause"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL; + } + gcc_assert (mask_list == NULL_TREE); + mask_list = get_identifier ("mask"); + } + else if (token->u.value + && TREE_CODE (token->u.value) == IDENTIFIER_NODE + && simple_cst_equal (token->u.value, + get_identifier ("nomask")) == 1) + { + if (mask_list) + { + cp_parser_error (parser, "Cannot have multiple [no]mask clause"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL; + } + gcc_assert (mask_list == NULL_TREE); + mask_list = get_identifier ("nomask"); + } + else if (token->u.value + && TREE_CODE (token->u.value) == IDENTIFIER_NODE + && simple_cst_equal (token->u.value, + get_identifier ("vectorlength")) == 1) + { + if (vlength_list) + { + cp_parser_error (parser, "Cannot have multiple vectorlength " + "clause"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL; + } + gcc_assert (NULL_TREE == vlength_list); + vlength_list = cp_parser_elem_fn_vlength_clause (parser); + } + else if (token->u.value + && TREE_CODE (token->u.value) == IDENTIFIER_NODE + && simple_cst_equal (token->u.value, + get_identifier ("uniform")) == 1) + { + if (uniform_list) + { + cp_parser_error (parser, + "Cannot have multiple uniform clauses"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL; + } + gcc_assert (NULL_TREE == uniform_list); + uniform_list = cp_parser_elem_fn_uniform_clause (parser); + } + else if (token->u.value + && TREE_CODE (token->u.value) == IDENTIFIER_NODE + && simple_cst_equal (token->u.value, + get_identifier ("linear")) == 1) + { + if (linear_list) + { + cp_parser_error (parser, + "Cannot have multiple linear clauses"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return NULL; + } + gcc_assert (NULL_TREE == linear_list); + linear_list = cp_parser_elem_fn_linear_clause (parser); + } + else + { + cp_parser_error (parser, "unknown clause"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return expr_list; + } + + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + { + cp_lexer_consume_token (parser->lexer); + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_parser_error (parser, "expected identifier after %<,%>"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return expr_list; + } + } + } + cp_lexer_consume_token (parser->lexer); /* consume the ')' */ + + if (proc_list) + VEC_safe_push (tree, gc, expr_list, proc_list); + if (vlength_list) + VEC_safe_push (tree, gc, expr_list, vlength_list); + if (uniform_list) + VEC_safe_push (tree, gc, expr_list, uniform_list); + if (mask_list) + VEC_safe_push (tree, gc, expr_list, mask_list); + if (linear_list) + VEC_safe_push (tree, gc, expr_list, linear_list); + + return expr_list; +} + #include "gt-cp-parser.h"