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 <balaji.v.i...@intel.com>
+
+ * c-parser.c (c_parser_elem_fn_expr_list): Fixed a bug and consumed
+ one token.
+
2012-04-05 Balaji V. Iyer <balaji.v.i...@intel.com>
* 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 <balaji.v.i...@intel.com>
+
+ * 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 <balaji.v.i...@intel.com>
* 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 <balaji.v.i...@intel.com>
* 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"