Hello Everyone,
This patch is for the Cilkplus branch affecting mainly the C compiler. This
patch will start the implementation of elemental functions in the branch. This
patch will parse the elemental function attributes in the C compiler
Thanking You,
Yours Sincerely,
Balaji V. Iyer.
diff --git a/gcc/ChangeLog.cilk b/gcc/ChangeLog.cilk
index ebabff6..1398870 100644
--- a/gcc/ChangeLog.cilk
+++ b/gcc/ChangeLog.cilk
@@ -1,3 +1,15 @@
+2012-03-09 Balaji V. Iyer <balaji.v.i...@intel.com>
+
+ * attribs.c (decl_attributes): Added a check for elemental function
+ attribute.
+ (is_elem_fn_attribute_p): New function.
+ * c-parser.c (c_parser_attributes): Added a check for vector attribute.
+ (c_parser_elem_fn_processor_clause): New function.
+ (c_parser_elem_fn_uniform_clause): Likewise.
+ (c_parser_elem_fn_linear_clause): Likewise.
+ (c_parser_elem_fn_vlength_clause): Likewise.
+ (c_parser_elem_fn_expr_list): Likewise.
+
2012-02-15 Balaji V. Iyer <balaji.v.i...@intel.com>
* cilk.c (cilk_fix_stack_reg): New function.
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 0e94fd2..2ececc4 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -228,6 +228,18 @@ lookup_attribute_spec (const_tree name)
substring_hash (attr.str, attr.length));
}
+
+static bool
+is_elem_fn_attribute_p (tree name)
+{
+ return is_attribute_p ("mask", name)
+ || is_attribute_p ("unmask", name)
+ || is_attribute_p ("vectorlength", name)
+ || is_attribute_p ("vector", name)
+ || is_attribute_p ("linear", name)
+ || is_attribute_p ("uniform", name);
+}
+
/* Process the attributes listed in ATTRIBUTES and install them in *NODE,
which is either a DECL (including a TYPE_DECL) or a TYPE. If a DECL,
it should be modified in place; if a TYPE, a copy should be created
@@ -312,8 +324,9 @@ decl_attributes (tree *node, tree attributes, int flags)
if (spec == NULL)
{
- warning (OPT_Wattributes, "%qE attribute directive ignored",
- name);
+ if (!is_elem_fn_attribute_p (name))
+ warning (OPT_Wattributes, "%qE attribute directive ignored",
+ name);
continue;
}
else if (list_length (args) < spec->min_length
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index c67ea97..4f940e1 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -65,6 +65,7 @@ extern struct c_expr fix_array_notation_expr (location_t,
enum tree_code,
extern bool contains_array_notation_expr (tree);
struct pragma_simd_values local_simd_values;
+
/* Initialization routine for this file. */
@@ -242,6 +243,8 @@ typedef struct GTY(()) c_parser {
static GTY (()) c_parser *the_parser;
+static VEC(tree,gc) *c_parser_elem_fn_expr_list (c_parser *parser);
+
/* Read in and lex a single token, storing it in *TOKEN. */
static void
@@ -3635,7 +3638,12 @@ c_parser_attributes (c_parser *parser)
attr_args = NULL_TREE;
else
{
- expr_list = c_parser_expr_list (parser, false, true, NULL);
+ if (TREE_CODE (attr_name) == IDENTIFIER_NODE
+ && simple_cst_equal (attr_name,
+ get_identifier ("vector")) == 1)
+ expr_list = c_parser_elem_fn_expr_list (parser);
+ else
+ expr_list = c_parser_expr_list (parser, false, true, NULL);
attr_args = build_tree_list_vec (expr_list);
release_tree_vector (expr_list);
}
@@ -11870,4 +11878,421 @@ c_parser_array_notation (c_parser *parser, tree
initial_index, tree array_value)
return value_tree;
}
+static tree
+c_parser_elem_fn_processor_clause (c_parser *parser)
+{
+ c_token *token;
+ tree proc_tree_list = NULL_TREE;
+ VEC(tree,gc) *proc_vec_list = NULL;
+
+ token = c_parser_peek_token (parser);
+ if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+ {
+ c_parser_error (parser, "expected %<)%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ else
+ c_parser_consume_token (parser);
+
+ proc_vec_list = make_tree_vector ();
+
+ if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ {
+ token = c_parser_peek_token (parser);
+ if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+ && simple_cst_equal (token->value, get_identifier ("pentium_4")) == 1)
+ {
+ c_parser_consume_token (parser);
+ VEC_safe_push (tree, gc, proc_vec_list,
+ build_string (strlen ("pentium_4"), "pentium_4"));
+ }
+ else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+ && simple_cst_equal (token->value,
+ get_identifier ("pentium4_sse3")) == 1)
+ {
+ c_parser_consume_token (parser);
+ VEC_safe_push (tree, gc, proc_vec_list,
+ build_string (strlen ("pentium4_sse3"),
+ "pentium4_sse3"));
+ }
+ else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+ && simple_cst_equal (token->value,
+ get_identifier ("core2_duo_ssse3")) == 1)
+ {
+ c_parser_consume_token (parser);
+ VEC_safe_push (tree, gc, proc_vec_list,
+ build_string (strlen ("core2_duo_ssse3"),
+ "core2_duo_ssse3"));
+ }
+ else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+ && simple_cst_equal (token->value,
+ get_identifier ("core2_duo_sse_4_1")) == 1)
+ {
+ c_parser_consume_token (parser);
+ VEC_safe_push (tree, gc, proc_vec_list,
+ build_string (strlen ("core2_duo_sse_4_1"),
+ "core2_duo_sse_4_1"));
+ }
+ else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+ && simple_cst_equal (token->value,
+ get_identifier ("core_i7_sse4_2")) == 1)
+ {
+ c_parser_consume_token (parser);
+ 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 (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ c_parser_consume_token (parser);
+ else
+ c_parser_error (parser, "expected %>)%>");
+ }
+ else
+ c_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;
+}
+
+static tree
+c_parser_elem_fn_uniform_clause (c_parser *parser)
+{
+ c_token *token;
+ tree uniform_tree;
+ tree str_token = NULL_TREE;
+ VEC(tree,gc) *uniform_vec = NULL;
+
+ if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+ {
+ c_parser_error (parser, "expected %<)%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ else
+ c_parser_consume_token (parser);
+
+ uniform_vec = make_tree_vector ();
+ while (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ {
+ token = c_parser_peek_token (parser);
+ if (token->value && token->type == CPP_NAME)
+ {
+ /* convert the variable to a string */
+ str_token = build_string (strlen (IDENTIFIER_POINTER (token->value)),
+ IDENTIFIER_POINTER (token->value));
+ VEC_safe_push (tree, gc, uniform_vec, str_token);
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ {
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is_not (parser, CPP_NAME))
+ {
+ c_parser_error (parser, "expected identifier after %<,%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ }
+ else if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
+ {
+ c_parser_error (parser,
+ "expected %<,%> or %<)%> after identifier");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ }
+ else
+ {
+ c_parser_error (parser, "expected number or comma");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ }
+ c_parser_consume_token (parser);
+ 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;
+}
+
+static tree
+c_parser_elem_fn_linear_clause (c_parser *parser)
+{
+ c_token *token;
+ VEC(tree,gc) *linear_vec = NULL;
+ tree linear_tree = NULL_TREE;
+ tree var_str, step_size;
+
+ if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+ {
+ c_parser_error (parser, "expected %<)%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ else
+ c_parser_consume_token (parser);
+ linear_vec = make_tree_vector ();
+ // VEC_safe_push (tree, gc, linear_vec, get_identifier ("linear"));
+
+ while (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ {
+ token = c_parser_peek_token (parser);
+ if (token->value && token->type == CPP_NAME)
+ {
+ var_str = build_string (strlen (IDENTIFIER_POINTER (token->value)),
+ IDENTIFIER_POINTER (token->value));
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is (parser, CPP_COLON))
+ {
+ c_parser_consume_token (parser);
+ token = c_parser_peek_token (parser);
+ if (token->value && token->type == CPP_NUMBER)
+ step_size = token->value;
+ else
+ {
+ c_parser_error (parser, "expected step-size");
+ return NULL_TREE;
+ }
+ c_parser_consume_token (parser);
+ }
+ 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 (c_parser_next_token_is (parser, CPP_COMMA))
+ {
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is_not (parser, CPP_NAME))
+ {
+ c_parser_error (parser,
+ "expected variable after %<,%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ }
+ else if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
+ {
+ c_parser_error (parser,
+ "expected %<,%> or %<)%> after variable/step");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ }
+ else
+ {
+ c_parser_error (parser, "expected variable name or comma");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ }
+ c_parser_consume_token (parser); /* 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;
+}
+
+static tree
+c_parser_elem_fn_vlength_clause (c_parser *parser)
+{
+ c_token *token;
+ VEC(tree,gc) *vlength_vec = NULL;
+ tree vlength_tree = NULL_TREE;
+
+ if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+ {
+ c_parser_error (parser, "expected %<)%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ else
+ c_parser_consume_token (parser);
+
+ vlength_vec = make_tree_vector ();
+ // VEC_safe_push (tree, gc, vlength_vec, get_identifier ("vectorlength"));
+ while (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ {
+ token = c_parser_peek_token (parser);
+ if (token->value && token->type == CPP_NUMBER)
+ {
+ VEC_safe_push (tree, gc, vlength_vec, token->value);
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ {
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is_not (parser, CPP_NUMBER))
+ {
+ c_parser_error (parser, "expected vectorlength after %<,%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ }
+ else if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
+ {
+ c_parser_error (parser,
+ "expected %<,%> or %<)%> after vectorlength");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ }
+ else
+ {
+ c_parser_error (parser, "expected number or comma");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
+ }
+ c_parser_consume_token (parser);
+ 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;
+}
+
+static VEC(tree,gc) *
+c_parser_elem_fn_expr_list (c_parser *parser)
+{
+ c_token *token;
+ VEC(tree,gc) *expr_list = NULL;
+ tree proc_list = NULL_TREE, mask_list = NULL_TREE, uniform_list = NULL_TREE;
+ tree vlength_list = NULL_TREE, linear_list = NULL_TREE;
+
+ expr_list = make_tree_vector ();
+
+ while (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ {
+ token = c_parser_peek_token (parser);
+ if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+ && simple_cst_equal (token->value,
+ get_identifier ("processor")) == 1)
+ {
+ c_parser_consume_token (parser);
+ gcc_assert (proc_list == NULL_TREE);
+ proc_list = c_parser_elem_fn_processor_clause (parser);
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ {
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ {
+ c_parser_error (parser, "expected identifier after %<,%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return expr_list;
+ }
+ }
+ }
+ else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+ && simple_cst_equal (token->value,
+ get_identifier ("mask")) == 1)
+ {
+ gcc_assert (mask_list == NULL_TREE);
+ mask_list = get_identifier ("mask");
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ {
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ {
+ c_parser_error (parser, "expected identifier after %<,%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return expr_list;
+ }
+ }
+ }
+ else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+ && simple_cst_equal (token->value,
+ get_identifier ("unmask")) == 1)
+ {
+ c_parser_consume_token (parser);
+ gcc_assert (mask_list == NULL_TREE);
+ mask_list = get_identifier ("unmask");
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ {
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ {
+ c_parser_error (parser, "expected identifier after %<,%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return expr_list;
+ }
+ }
+ }
+ else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+ && simple_cst_equal (token->value,
+ get_identifier ("vectorlength")) == 1)
+ {
+ c_parser_consume_token (parser);
+ gcc_assert (vlength_list == NULL_TREE);
+ vlength_list = c_parser_elem_fn_vlength_clause (parser);
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ {
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ {
+ c_parser_error (parser, "expected identifier after %<,%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return expr_list;
+ }
+ }
+ }
+ else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+ && simple_cst_equal (token->value,
+ get_identifier ("uniform")) == 1)
+ {
+ c_parser_consume_token (parser);
+ gcc_assert (uniform_list == NULL_TREE);
+ uniform_list = c_parser_elem_fn_uniform_clause (parser);
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ {
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ {
+ c_parser_error (parser, "expected identifier after %<,%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return expr_list;
+ }
+ }
+ }
+ else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+ && simple_cst_equal (token->value,
+ get_identifier ("linear")) == 1)
+ {
+ c_parser_consume_token (parser);
+ gcc_assert (linear_list == NULL_TREE);
+ linear_list = c_parser_elem_fn_linear_clause (parser);
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ {
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ {
+ c_parser_error (parser, "expected identifier after %<,%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return expr_list;
+ }
+ }
+ }
+ }
+
+ 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-c-parser.h"