@@ -1,3 +1,25 @@
+2012-01-25 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * c-array-notation.c (replace_array_notations): Added a new bool as
+ parameter and added support for it.
+ (find_rank): Likewise.
+ (extract_array_notation_exprs): Likewise.
+ (replace_array_notations): Likewise.
+ (max): New function.
+ (fix_builtin_array_notation_fn): Likewise.
+ (is_builtin_array_notation_fn): Likewise.
+ (contains_array_notation_expr): Likewise.
+ (build_array_notation_expr): Added support for builtin function.
+ Changed all for-loops that have comparison with lhs_rank, with
+ max (lhs_rank and rhs_rank). Also added a check if array_expr_lhs is
+ NULL, then we set that equal to lhs.
+ * c-parser.c (c_parser_expr_no_commas): Added support for array
+ notations inside function calls (i.e. function that takes array notation
+ as input and returns a scalar value).
+ * c-typeck.c (convert_arguments): If array notation is present inside
+ a function call, then we skip it for now since we will fix it up in a
+ later step.
+
2012-01-20 Balaji V. Iyer <balaji.v.iyer@intel.com>
* Makefile.in: Added array-notation-common.c file for compilation.
@@ -38,18 +38,25 @@
#include "gimple.h"
#include "c-family/c-objc.h"
-void replace_array_notations (tree *, tree *, tree *, int);
-void find_rank (tree, int *);
-void extract_array_notation_exprs (tree, tree **, int *);
+void replace_array_notations (tree *, bool, tree *, tree *, int);
+void find_rank (tree, bool, int *);
+void extract_array_notation_exprs (tree, bool, tree **, int *);
tree fix_conditional_array_notations (tree);
struct c_expr fix_array_notation_expr (location_t, enum tree_code,
struct c_expr);
+static bool is_builtin_array_notation_fn (tree func_name, an_reduce_type *type);
+static tree fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var);
+bool contains_array_notation_expr (tree expr);
+
+/* This function is to find the rank of an array notation expression.
+ * For example, an array notation of A[:][:] has a rank of 2.
+ */
void
-find_rank (tree array, int *rank)
+find_rank (tree array, bool ignore_builtin_fn, int *rank)
{
tree ii_tree;
int current_rank = 0, ii = 0;
-
+ an_reduce_type dummy_type = REDUCE_UNKNOWN;
if (!array)
return;
else if (TREE_CODE (array) == ARRAY_NOTATION_REF)
@@ -64,16 +71,30 @@ find_rank (tree array, int *rank)
else if (*rank == 0)
*rank = current_rank;
}
+ else if (TREE_CODE (array) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator ii_tsi;
+ for (ii_tsi = tsi_start (array); !tsi_end_p (ii_tsi);
+ tsi_next (&ii_tsi))
+ find_rank (*tsi_stmt_ptr (ii_tsi), ignore_builtin_fn, rank);
+ }
else
{
- if (TREE_CODE (array) == CALL_EXPR
- || TREE_CODE (array) == AGGR_INIT_EXPR)
+ if (TREE_CODE (array) == CALL_EXPR)
{
+ tree func_name = CALL_EXPR_FN (array);
+ if (TREE_CODE (func_name) == ADDR_EXPR)
+ if (ignore_builtin_fn)
+ if (is_builtin_array_notation_fn (func_name, &dummy_type))
+ /* If it is a builtin function, then we know it returns a
+ * scalar
+ */
+ return;
if (TREE_CODE (TREE_OPERAND (array, 0)) == INTEGER_CST)
{
int length = TREE_INT_CST_LOW (TREE_OPERAND (array, 0));
for (ii = 0; ii < length; ii++)
- find_rank (TREE_OPERAND (array, ii), rank);
+ find_rank (TREE_OPERAND (array, ii), ignore_builtin_fn, rank);
}
else
gcc_unreachable ();
@@ -81,17 +102,23 @@ find_rank (tree array, int *rank)
else
{
for (ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (array)); ii++)
- find_rank (TREE_OPERAND (array, ii), rank);
+ find_rank (TREE_OPERAND (array, ii), ignore_builtin_fn, rank);
}
}
return;
}
+/* this function will go through a tree and extract all the array notation
+ * expressions inside the subtrees
+ */
void
-extract_array_notation_exprs (tree node, tree **array_list, int *list_size)
+extract_array_notation_exprs (tree node, bool ignore_builtin_fn,
+ tree **array_list, int *list_size)
{
int ii = 0;
tree *new_array_list = NULL;
+ an_reduce_type dummy_type = REDUCE_UNKNOWN;
+
if (!node)
return;
else if (TREE_CODE (node) == ARRAY_NOTATION_REF)
@@ -110,18 +137,36 @@ extract_array_notation_exprs (tree node, tree **array_list, int *list_size)
{
tree_stmt_iterator ii_tsi;
for (ii_tsi = tsi_start (node); !tsi_end_p (ii_tsi); tsi_next (&ii_tsi))
- extract_array_notation_exprs (*tsi_stmt_ptr (ii_tsi), array_list,
- list_size);
+ extract_array_notation_exprs (*tsi_stmt_ptr (ii_tsi), ignore_builtin_fn,
+ array_list, list_size);
}
- else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == AGGR_INIT_EXPR)
+ else if (TREE_CODE (node) == CALL_EXPR)
{
+ if (is_builtin_array_notation_fn (CALL_EXPR_FN (node), &dummy_type))
+ {
+ if (ignore_builtin_fn)
+ return;
+ else
+ {
+ ii = *list_size;
+ new_array_list = (tree *) xrealloc (*array_list, (ii + 1) *
+ sizeof (tree));
+ gcc_assert (new_array_list);
+ new_array_list[ii] = node;
+ ii++;
+ *list_size = ii;
+ *array_list = new_array_list;
+ return;
+ }
+ }
if (TREE_CODE (TREE_OPERAND (node, 0)) == INTEGER_CST)
{
int length = TREE_INT_CST_LOW (TREE_OPERAND (node, 0));
for (ii = 0; ii < length; ii++)
- extract_array_notation_exprs (TREE_OPERAND (node, ii), array_list,
- list_size);
+ extract_array_notation_exprs
+ (TREE_OPERAND (node, ii), ignore_builtin_fn, array_list,
+ list_size);
}
else
gcc_unreachable (); /* should not get here */
@@ -130,17 +175,21 @@ extract_array_notation_exprs (tree node, tree **array_list, int *list_size)
else
{
for (ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (node)); ii++)
- extract_array_notation_exprs (TREE_OPERAND (node, ii), array_list,
- list_size);
+ extract_array_notation_exprs (TREE_OPERAND (node, ii),
+ ignore_builtin_fn, array_list, list_size);
}
return;
}
+/* this function will replace a subtree that has array notation with the
+ * appropriate scalar equivalent
+ */
void
-replace_array_notations (tree *orig, tree *list, tree *array_operand,
- int array_size)
+replace_array_notations (tree *orig, bool ignore_builtin_fn, tree *list,
+ tree *array_operand, int array_size)
{
int ii = 0;
+ an_reduce_type dummy_type = REDUCE_UNKNOWN;
if (array_size == 0 || *list == NULL || !*orig)
return;
@@ -157,18 +206,30 @@ replace_array_notations (tree *orig, tree *list, tree *array_operand,
{
tree_stmt_iterator ii_tsi;
for (ii_tsi = tsi_start (*orig); !tsi_end_p (ii_tsi); tsi_next (&ii_tsi))
- replace_array_notations (tsi_stmt_ptr (ii_tsi), list, array_operand,
- array_size);
+ replace_array_notations (tsi_stmt_ptr (ii_tsi), ignore_builtin_fn,
+ list, array_operand, array_size);
}
- else if (TREE_CODE (*orig) == CALL_EXPR
- || TREE_CODE (*orig) == AGGR_INIT_EXPR)
+ else if (TREE_CODE (*orig) == CALL_EXPR)
{
+ if (is_builtin_array_notation_fn (CALL_EXPR_FN (*orig), &dummy_type))
+ {
+ if (!ignore_builtin_fn)
+ {
+ for (ii = 0; ii < array_size; ii++)
+ {
+ if (*orig == list[ii])
+ *orig = array_operand[ii];
+ }
+ }
+ return;
+ }
if (TREE_CODE (TREE_OPERAND (*orig, 0)) == INTEGER_CST)
{
int length = TREE_INT_CST_LOW (TREE_OPERAND (*orig, 0));
for (ii = 0; ii < length; ii++)
- replace_array_notations (&TREE_OPERAND (*orig, ii), list,
- array_operand, array_size);
+ replace_array_notations
+ (&TREE_OPERAND (*orig, ii), ignore_builtin_fn, list,
+ array_operand, array_size);
}
else
gcc_unreachable (); /* should not get here! */
@@ -177,19 +238,30 @@ replace_array_notations (tree *orig, tree *list, tree *array_operand,
{
for (ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (*orig)); ii++)
{
- replace_array_notations (&TREE_OPERAND (*orig, ii), list,
- array_operand, array_size);
+ replace_array_notations
+ (&TREE_OPERAND (*orig, ii), ignore_builtin_fn, list,
+ array_operand, array_size);
}
}
return;
}
+/* this is a small function that will give the max of 2 integers */
+static int
+max (int x, int y)
+{
+ if (x > y)
+ return x;
+ else
+ return y;
+}
+
tree
build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
enum tree_code modifycode, location_t rhs_loc,
tree rhs, tree rhs_origtype)
{
- bool *lhs_vector = NULL, **rhs_vector = NULL;
+ bool *lhs_vector = NULL, **rhs_vector = NULL, found_builtin_fn = false;
tree *lhs_array = NULL, **rhs_array = NULL;
tree array_expr_lhs = NULL_TREE, array_expr_rhs = NULL_TREE;
tree array_expr = NULL_TREE;
@@ -205,14 +277,67 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
bool *lhs_count_down = NULL, **rhs_count_down = NULL;
tree *lhs_compare = NULL, *rhs_compare = NULL, *rhs_array_operand = NULL;
int lhs_rank = 0, rhs_rank = 0, ii = 0, jj = 0;
- tree ii_tree = NULL_TREE;
- tree *rhs_list = NULL;
+ tree ii_tree = NULL_TREE, new_modify_expr;
+ tree *rhs_list = NULL, new_var = NULL_TREE, builtin_loop = NULL_TREE;
int rhs_list_size = 0;
+
+ find_rank (rhs, false, &rhs_rank);
+
+ extract_array_notation_exprs (rhs, false, &rhs_list, &rhs_list_size);
+
+ loop = push_stmt_list ();
+
+ for (ii = 0; ii < rhs_list_size; ii++)
+ {
+ if (TREE_CODE (rhs_list[ii]) == CALL_EXPR)
+ {
+ builtin_loop = fix_builtin_array_notation_fn (rhs_list[ii], &new_var);
+ if (builtin_loop)
+ {
+ add_stmt (builtin_loop);
+ found_builtin_fn = true;
+ replace_array_notations (&rhs, false, &rhs_list[ii], &new_var, 1);
+ }
+ }
+ }
+
+ lhs_rank = 0;
+ rhs_rank = 0;
+ find_rank (lhs, true, &lhs_rank);
+ find_rank (rhs, true, &rhs_rank);
+
+ if (lhs_rank == 0 && rhs_rank == 0)
+ {
+ if (found_builtin_fn)
+ {
+ new_modify_expr = build_modify_expr (location, lhs, lhs_origtype,
+ modifycode, rhs_loc, rhs,
+ rhs_origtype);
+ add_stmt (new_modify_expr);
+ pop_stmt_list (loop);
+
+ return loop;
+ }
+ else
+ {
+ pop_stmt_list (loop);
+ return NULL_TREE;
+ }
+ }
+
- find_rank (lhs, &lhs_rank);
- find_rank (rhs, &rhs_rank);
- extract_array_notation_exprs (rhs, &rhs_list, &rhs_list_size);
+ /* if (TREE_CODE (rhs) == CALL_EXPR) */
+ /* { */
+ /* if (is_builtin_array_notation_fn (CALL_EXPR_FN (rhs), &type)) */
+ /* { */
+ /* loop = build_reduce_expr (location, lhs, lhs_origtype, modifycode, */
+ /* rhs_loc, rhs, rhs_origtype); */
+ /* return loop; */
+ /* } */
+ /* } */
+
+ extract_array_notation_exprs (rhs, true, &rhs_list, &rhs_list_size);
if (lhs_rank == 0 && rhs_rank != 0)
{
@@ -270,12 +395,12 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
*
* In both the scenarios, just checking the LHS_RANK is OK
*/
- body_label = (tree *) xmalloc (sizeof (tree) * lhs_rank);
- body_label_expr = (tree *) xmalloc (sizeof (tree) * lhs_rank);
- exit_label = (tree *) xmalloc (sizeof (tree) * lhs_rank);
- exit_label_expr = (tree *) xmalloc (sizeof (tree) * lhs_rank);
- cond_expr = (tree *) xmalloc (sizeof (tree) * lhs_rank);
- if_stmt_label = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+ body_label = (tree *) xmalloc (sizeof (tree) * max (lhs_rank, rhs_rank));
+ body_label_expr = (tree *) xmalloc (sizeof (tree) * max (lhs_rank, rhs_rank));
+ exit_label = (tree *) xmalloc (sizeof (tree) * max (lhs_rank, rhs_rank));
+ exit_label_expr = (tree *) xmalloc (sizeof (tree) * max (lhs_rank, rhs_rank));
+ cond_expr = (tree *) xmalloc (sizeof (tree) * max (lhs_rank, rhs_rank));
+ if_stmt_label = (tree *) xmalloc (sizeof (tree) * max (lhs_rank, rhs_rank));
lhs_expr_incr = (tree *) xmalloc (sizeof (tree) * lhs_rank);
rhs_expr_incr = (tree *) xmalloc (sizeof (tree) * rhs_rank);
@@ -354,8 +479,10 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
{
rhs_value[ii][jj] = ARRAY_NOTATION_ARRAY (rhs_array[ii][jj]);
rhs_start[ii][jj] = ARRAY_NOTATION_START (rhs_array[ii][jj]);
- rhs_length[ii][jj] = ARRAY_NOTATION_LENGTH (rhs_array[ii][jj]);
- rhs_stride[ii][jj] = ARRAY_NOTATION_STRIDE (rhs_array[ii][jj]);
+ rhs_length[ii][jj] =
+ ARRAY_NOTATION_LENGTH (rhs_array[ii][jj]);
+ rhs_stride[ii][jj] =
+ ARRAY_NOTATION_STRIDE (rhs_array[ii][jj]);
rhs_vector[ii][jj] = true;
/* If the stride value is variable (i.e. not constant) then
* assume that the length is positive
@@ -375,7 +502,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
}
}
- loop = push_stmt_list();
+
for (ii = 0; ii < lhs_rank; ii++)
{
@@ -385,7 +512,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
TREE_TYPE (lhs_start[ii]));
lhs_ind_init[ii] = build_modify_expr
(UNKNOWN_LOCATION, lhs_var[ii], TREE_TYPE (lhs_var[ii]),
- modifycode,
+ NOP_EXPR,
UNKNOWN_LOCATION, build_int_cst (TREE_TYPE (lhs_start[ii]), 0),
TREE_TYPE (lhs_start[ii]));
@@ -407,7 +534,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
}
- for (ii = 0; ii < lhs_rank ; ii++)
+ for (ii = 0; ii < max (lhs_rank, rhs_rank); ii++)
{
/* this will create the if statement label */
if_stmt_label[ii] = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
@@ -497,9 +624,9 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
}
}
}
- replace_array_notations (&rhs, rhs_list, rhs_array_operand,
- rhs_list_size);
- array_expr_rhs = rhs;
+ replace_array_notations (&rhs, true, rhs_list, rhs_array_operand,
+ rhs_list_size);
+ array_expr_rhs = rhs;
}
else
{
@@ -513,14 +640,16 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
(MODIFY_EXPR, void_type_node, rhs_var[ii],
build2 (PLUS_EXPR, TREE_TYPE (rhs_var[ii]), rhs_var[ii],
build_int_cst (TREE_TYPE (rhs_var[ii]), 1)));
- }
-
+ }
+
+ if (!array_expr_lhs)
+ array_expr_lhs = lhs;
array_expr = build_modify_expr (location, array_expr_lhs,
lhs_origtype, modifycode, rhs_loc,
array_expr_rhs, rhs_origtype);
- for (jj = 0; jj < lhs_rank; jj++)
+ for (jj = 0; jj < max (lhs_rank, rhs_rank); jj++)
{
if (rhs_rank && rhs_expr_incr[jj])
{
@@ -579,7 +708,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
*/
- for (ii = 0; ii < lhs_rank; ii++)
+ for (ii = 0; ii < max (lhs_rank, rhs_rank); ii++)
{
add_stmt (lhs_ind_init [ii]);
if (rhs_rank)
@@ -591,10 +720,11 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
add_stmt (body_label_expr[ii]);
}
-
- add_stmt (array_expr);
- for (ii = lhs_rank - 1; ii >= 0; ii--)
+ if (max (lhs_rank, rhs_rank))
+ add_stmt (array_expr);
+
+ for (ii = max (lhs_rank, rhs_rank) - 1; ii >= 0; ii--)
{
add_stmt (lhs_expr_incr[ii]);
if (rhs_rank && rhs_expr_incr[ii])
@@ -629,13 +759,14 @@ fix_conditional_array_notations_1 (tree stmt)
else if (TREE_CODE (stmt) == FOR_STMT || TREE_CODE (stmt) == CILK_FOR_STMT)
cond = FOR_COND (stmt);
else
+ /* otherwise dont even touch the statement */
return stmt;
- find_rank (cond, &rank);
+ find_rank (cond, true, &rank);
if (rank == 0)
return stmt;
- extract_array_notation_exprs (cond, &array_list, &list_size);
+ extract_array_notation_exprs (cond, true, &array_list, &list_size);
if (*array_list == NULL_TREE || list_size == 0)
return stmt;
@@ -802,7 +933,7 @@ fix_conditional_array_notations_1 (tree stmt)
}
}
}
- replace_array_notations (&stmt, array_list, array_operand, list_size);
+ replace_array_notations (&stmt, true, array_list, array_operand, list_size);
for (ii = 0; ii < rank; ii++)
{
@@ -915,13 +1046,15 @@ fix_array_notation_expr (location_t location, enum tree_code code,
tree *compare_expr, *if_stmt_label, *expr_incr, *ind_init;
bool **count_down, **array_vector;
- find_rank (arg.value, &rank);
+ find_rank (arg.value, false, &rank);
if (rank == 0)
- return arg;
-
- extract_array_notation_exprs (arg.value, &array_list, &list_size);
+ return arg;
- if (*array_list == NULL_TREE || list_size == 0)
+
+
+ extract_array_notation_exprs (arg.value, true, &array_list, &list_size);
+
+ if (list_size == 0 || *array_list == NULL_TREE)
return arg;
array_ops = (tree **) xmalloc (sizeof (tree *) * list_size);
@@ -1010,7 +1143,7 @@ fix_array_notation_expr (location_t location, enum tree_code code,
}
}
- loop = push_stmt_list();
+ loop = push_stmt_list ();
for (ii = 0; ii < rank; ii++)
{
@@ -1086,7 +1219,8 @@ fix_array_notation_expr (location_t location, enum tree_code code,
}
}
}
- replace_array_notations (&arg.value, array_list, array_operand, list_size);
+ replace_array_notations (&arg.value, true, array_list, array_operand,
+ list_size);
for (ii = 0; ii < rank; ii++)
{
@@ -1111,6 +1245,7 @@ fix_array_notation_expr (location_t location, enum tree_code code,
array_var[jj], array_length[0][jj]);
}
}
+
for (ii = 0; ii < rank; ii++)
{
@@ -1178,4 +1313,593 @@ fix_array_notation_expr (location_t location, enum tree_code code,
arg.value = loop;
return arg;
}
+
+
+static tree
+fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
+{
+ tree new_var_type = NULL_TREE, func_parm, new_expr, new_yes_expr, new_no_expr;
+ tree array_ind_value = NULL_TREE, new_no_ind, new_yes_ind, new_no_list;
+ tree new_yes_list, new_cond_expr, new_var_init;
+ an_reduce_type an_type = REDUCE_UNKNOWN;
+ tree *array_list = NULL;
+ int list_size = 0;
+ int rank = 0, ii = 0, jj = 0;
+ tree **array_ops, *array_var, *array_operand, jj_tree, loop;
+ tree **array_value, **array_stride, **array_length, **array_start;
+ tree *body_label, *body_label_expr, *exit_label, *exit_label_expr;
+ tree *compare_expr, *if_stmt_label, *expr_incr, *ind_init;
+ bool **count_down, **array_vector;
+
+ if (!is_builtin_array_notation_fn (CALL_EXPR_FN (an_builtin_fn), &an_type))
+ return NULL_TREE;
+
+ func_parm = CALL_EXPR_ARG (an_builtin_fn, 0);
+ while (TREE_CODE (func_parm) == CONVERT_EXPR
+ || TREE_CODE (func_parm) == NOP_EXPR)
+ func_parm = TREE_OPERAND (func_parm, 0);
+
+ find_rank (an_builtin_fn, false, &rank);
+ if (rank == 0)
+ return an_builtin_fn;
+ else if (rank > 1
+ && (an_type == REDUCE_MAX_INDEX || an_type == REDUCE_MIN_INDEX))
+ {
+ error ("__sec_reduce_min_ind or __sec_reduce_max_ind cannot have arrays"
+ " with dimension greater than 1.");
+ fnotice (stderr, "confused by earlier errors, bailing out\n");
+ exit (ICE_EXIT_CODE);
+ }
+
+ extract_array_notation_exprs (func_parm, true, &array_list, &list_size);
+
+ switch (an_type)
+ {
+ case REDUCE_ADD:
+ case REDUCE_MUL:
+ case REDUCE_MAX:
+ case REDUCE_MIN:
+ new_var_type = ARRAY_NOTATION_TYPE (array_list[0]);
+ break;
+ case REDUCE_ALL_ZEROS:
+ case REDUCE_ANY_ZEROS:
+ new_var_type = integer_type_node;
+ break;
+ case REDUCE_MAX_INDEX:
+ case REDUCE_MIN_INDEX:
+ new_var_type = integer_type_node;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+
+ array_ops = (tree **) xmalloc (sizeof (tree *) * list_size);
+ for (ii = 0; ii < list_size; ii++)
+ array_ops[ii] = (tree *) xmalloc (sizeof (tree) * rank);
+
+ array_vector = (bool **) xmalloc (sizeof (bool *) * list_size);
+ for (ii = 0; ii < list_size; ii++)
+ array_vector[ii] = (bool *) xmalloc (sizeof (bool) * rank);
+
+ array_value = (tree **) xmalloc (sizeof (tree *) * list_size);
+ array_stride = (tree **) xmalloc (sizeof (tree *) * list_size);
+ array_length = (tree **) xmalloc (sizeof (tree *) * list_size);
+ array_start = (tree **) xmalloc (sizeof (tree *) * list_size);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ array_value[ii] = (tree *) xmalloc (sizeof (tree) * rank);
+ array_stride[ii] = (tree *) xmalloc (sizeof (tree) * rank);
+ array_length[ii] = (tree *) xmalloc (sizeof (tree) * rank);
+ array_start[ii] = (tree *) xmalloc (sizeof (tree) * rank);
+ }
+
+ body_label = (tree *) xmalloc(sizeof (tree) * rank);
+ body_label_expr = (tree *) xmalloc (sizeof (tree) * rank);
+ exit_label = (tree *) xmalloc (sizeof (tree) * rank);
+ exit_label_expr = (tree *) xmalloc (sizeof (tree) * rank);
+ compare_expr = (tree *) xmalloc (sizeof (tree) * rank);
+ if_stmt_label = (tree *) xmalloc (sizeof (tree) * rank);
+
+ expr_incr = (tree *) xmalloc (sizeof (tree) * rank);
+ ind_init = (tree *) xmalloc (sizeof (tree) * rank);
+
+ count_down = (bool **) xmalloc (sizeof (bool *) * list_size);
+ for (ii = 0; ii < list_size; ii++)
+ count_down[ii] = (bool *) xmalloc (sizeof (bool) * rank);
+
+ array_operand = (tree *) xmalloc (sizeof (tree) * list_size);
+
+ array_var = (tree *) xmalloc (sizeof (tree) * rank);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ jj = 0;
+ for (jj_tree = array_list[ii];
+ jj_tree && TREE_CODE (jj_tree) == ARRAY_NOTATION_REF;
+ jj_tree = ARRAY_NOTATION_ARRAY (jj_tree))
+ {
+ array_ops[ii][jj] = jj_tree;
+ jj++;
+ }
+ }
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ if (TREE_CODE (array_list[ii]) == ARRAY_NOTATION_REF)
+ {
+ for (jj = 0; jj < rank; jj++)
+ {
+ if (TREE_CODE (array_ops[ii][jj]) == ARRAY_NOTATION_REF)
+ {
+ array_value[ii][jj] =
+ ARRAY_NOTATION_ARRAY (array_ops[ii][jj]);
+ array_start[ii][jj] =
+ ARRAY_NOTATION_START (array_ops[ii][jj]);
+ array_length[ii][jj] =
+ ARRAY_NOTATION_LENGTH (array_ops[ii][jj]);
+ array_stride[ii][jj] =
+ ARRAY_NOTATION_STRIDE (array_ops[ii][jj]);
+ array_vector[ii][jj] = true;
+
+ if (!TREE_CONSTANT (array_length[ii][jj]))
+ count_down[ii][jj] = false;
+ else if (tree_int_cst_lt
+ (array_length[ii][jj],
+ build_int_cst (TREE_TYPE (array_length[ii][jj]),
+ 0)))
+ count_down[ii][jj] = true;
+ else
+ count_down[ii][jj] = false;
+ }
+ else
+ array_vector[ii][jj] = false;
+ }
+ }
+ }
+
+ loop = alloc_stmt_list ();
+
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ array_var[ii] = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ ind_init[ii] =
+ build_modify_expr (UNKNOWN_LOCATION, array_var[ii],
+ TREE_TYPE (array_var[ii]), NOP_EXPR,
+ UNKNOWN_LOCATION,
+ build_int_cst (TREE_TYPE (array_var[ii]), 0),
+ TREE_TYPE (array_var[ii]));
+ }
+
+ for (ii = 0; ii < rank ; ii++)
+ {
+ /* this will create the if statement label */
+ if_stmt_label[ii] = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
+ void_type_node);
+ DECL_CONTEXT (if_stmt_label[ii]) = current_function_decl;
+ DECL_ARTIFICIAL (if_stmt_label[ii]) = 0;
+ DECL_IGNORED_P (if_stmt_label[ii]) = 1;
+
+ /* this label statment will point to the loop body */
+ body_label[ii] = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
+ void_type_node);
+ DECL_CONTEXT (body_label[ii]) = current_function_decl;
+ DECL_ARTIFICIAL (body_label[ii]) = 0;
+ DECL_IGNORED_P (body_label[ii]) = 1;
+ body_label_expr[ii] = build1 (LABEL_EXPR, void_type_node, body_label[ii]);
+
+ /* this will create the exit label..i.e. where the while loop will branch
+ out of
+ */
+ exit_label[ii] = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
+ void_type_node);
+ DECL_CONTEXT (exit_label[ii]) = current_function_decl;
+ DECL_ARTIFICIAL (exit_label[ii]) = 0;
+ DECL_IGNORED_P (exit_label[ii]) = 1;
+ exit_label_expr[ii] = build1 (LABEL_EXPR, void_type_node, exit_label[ii]);
+ }
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ if (array_vector[ii][0])
+ {
+ array_operand[ii] = array_value[ii][rank - 1];
+ gcc_assert (array_operand[ii]);
+
+ for (jj = rank - 1; jj >= 0; jj--)
+ {
+ if (count_down[ii][jj])
+ {
+ /* Array[start_index - (induction_var * stride)] */
+ array_operand[ii] = build_array_ref
+ (UNKNOWN_LOCATION, array_operand[ii],
+ build2 (MINUS_EXPR, TREE_TYPE (array_var[jj]),
+ array_start[ii][jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[jj]),
+ array_var[jj], array_stride[ii][jj])));
+ }
+ else
+ {
+ /* Array[start_index + (induction_var * stride)] */
+ array_operand[ii] = build_array_ref
+ (UNKNOWN_LOCATION, array_operand[ii],
+ build2 (PLUS_EXPR, TREE_TYPE (array_var[jj]),
+ array_start[ii][jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[jj]),
+ array_var[jj], array_stride[ii][jj])));
+ }
+ }
+ }
+ }
+ replace_array_notations (&func_parm, true, array_list, array_operand,
+ list_size);
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ expr_incr[ii] =
+ build2 (MODIFY_EXPR, void_type_node, array_var[ii],
+ build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii],
+ build_int_cst (TREE_TYPE (array_var[ii]), 1)));
+ }
+
+ for (jj = 0; jj < rank; jj++)
+ {
+ if (rank && expr_incr[jj])
+ {
+ if (count_down[0][jj])
+ compare_expr[jj] =
+ build2 (LT_EXPR, boolean_type_node, array_var[jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[jj]),
+ array_length[0][jj],
+ build_int_cst (TREE_TYPE (array_var[jj]), -1)));
+ else
+ compare_expr[jj] = build2 (LT_EXPR, boolean_type_node,
+ array_var[jj], array_length[0][jj]);
+ }
+ }
+
+ *new_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, new_var_type);
+ gcc_assert (*new_var);
+ if (an_type == REDUCE_MAX_INDEX || an_type == REDUCE_MIN_INDEX)
+ array_ind_value = build_decl
+ (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, TREE_TYPE (func_parm));
+
+ switch (an_type)
+ {
+ case REDUCE_ADD:
+ new_var_init = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, build_zero_cst (new_var_type), new_var_type);
+ new_expr = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), PLUS_EXPR,
+ UNKNOWN_LOCATION, func_parm, TREE_TYPE (func_parm));
+ break;
+ case REDUCE_MUL:
+ new_var_init = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, build_one_cst (new_var_type), new_var_type);
+ new_expr = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), MULT_EXPR,
+ UNKNOWN_LOCATION, func_parm, TREE_TYPE (func_parm));
+ break;
+ case REDUCE_ALL_ZEROS:
+ new_var_init = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, build_one_cst (new_var_type), new_var_type);
+ /* Initially you assume everything is zero, now if we find a case where
+ * it is NOT true, then we set the result to false. Otherwise
+ * we just keep the previous value
+ */
+ new_yes_expr = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, build_zero_cst (TREE_TYPE (*new_var)),
+ TREE_TYPE (*new_var));
+ new_no_expr = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var));
+ new_cond_expr = build2 (NE_EXPR, TREE_TYPE (func_parm), func_parm,
+ build_zero_cst (TREE_TYPE (func_parm)));
+ new_expr = build_conditional_expr
+ (UNKNOWN_LOCATION, new_cond_expr, false, new_yes_expr,
+ TREE_TYPE (new_yes_expr), new_no_expr, TREE_TYPE (new_no_expr));
+ break;
+ case REDUCE_ANY_ZEROS:
+ new_var_init = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, build_zero_cst (new_var_type), new_var_type);
+ /* Initially we assume there are NO zeros in the list. When we find
+ * a non-zero, we keep the previous value. If we find a zero, we
+ * set the value to true
+ */
+ new_no_expr = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, build_one_cst (new_var_type), new_var_type);
+ new_yes_expr = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var));
+ new_cond_expr = build2 (NE_EXPR, TREE_TYPE (func_parm), func_parm,
+ build_zero_cst (TREE_TYPE (func_parm)));
+ new_expr = build_conditional_expr
+ (UNKNOWN_LOCATION, new_cond_expr, false, new_yes_expr,
+ TREE_TYPE (new_yes_expr), new_no_expr, TREE_TYPE (new_no_expr));
+ break;
+ case REDUCE_MAX:
+ new_var_init = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, func_parm, new_var_type);
+ new_no_expr = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var));
+ new_yes_expr = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, func_parm, TREE_TYPE (*new_var));
+ new_expr = build_conditional_expr
+ (UNKNOWN_LOCATION,
+ build2 (LT_EXPR, TREE_TYPE (*new_var), *new_var, func_parm), false,
+ new_yes_expr, TREE_TYPE (*new_var), new_no_expr, TREE_TYPE (*new_var));
+ break;
+ case REDUCE_MIN:
+ new_var_init = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, func_parm, new_var_type);
+ new_no_expr = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var));
+ new_yes_expr = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, func_parm, TREE_TYPE (*new_var));
+ new_expr = build_conditional_expr
+ (UNKNOWN_LOCATION,
+ build2 (GT_EXPR, TREE_TYPE (*new_var), *new_var, func_parm), false,
+ new_yes_expr, TREE_TYPE (*new_var), new_no_expr, TREE_TYPE (*new_var));
+ break;
+ case REDUCE_MAX_INDEX:
+ new_var_init = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, build_zero_cst (new_var_type), new_var_type);
+ new_no_ind = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var));
+ new_no_expr = build_modify_expr
+ (UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR,
+ UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value));
+ if (list_size > 1)
+ {
+ new_yes_ind = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, array_var[0], TREE_TYPE (array_var[0]));
+ new_yes_expr = build_modify_expr
+ (UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR,
+ UNKNOWN_LOCATION, func_parm, TREE_TYPE (array_operand[0]));
+ }
+ else
+ {
+ new_yes_ind = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, TREE_OPERAND (array_operand[0], 1),
+ TREE_TYPE (TREE_OPERAND (array_operand[0], 1)));
+ new_yes_expr = build_modify_expr
+ (UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR,
+ UNKNOWN_LOCATION, func_parm, TREE_OPERAND (array_operand[0], 1));
+ }
+ new_yes_list = alloc_stmt_list ();
+ append_to_statement_list (new_yes_ind, &new_yes_list);
+ append_to_statement_list (new_yes_expr, &new_yes_list);
+
+ new_no_list = alloc_stmt_list ();
+ append_to_statement_list (new_no_ind, &new_no_list);
+ append_to_statement_list (new_no_expr, &new_no_list);
+
+ new_expr = build_conditional_expr
+ (UNKNOWN_LOCATION,
+ build2 (LT_EXPR, TREE_TYPE (array_ind_value), array_ind_value,
+ func_parm),
+ false,
+ new_yes_list, TREE_TYPE (*new_var), new_no_list, TREE_TYPE (*new_var));
+ break;
+ case REDUCE_MIN_INDEX:
+ new_var_init = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, build_zero_cst (new_var_type), new_var_type);
+ new_no_ind = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var));
+ new_no_expr = build_modify_expr
+ (UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR,
+ UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value));
+ if (list_size > 1)
+ {
+ new_yes_ind = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, array_var[0], TREE_TYPE (array_var[0]));
+ new_yes_expr = build_modify_expr
+ (UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR,
+ UNKNOWN_LOCATION, func_parm, TREE_TYPE (array_operand[0]));
+ }
+ else
+ {
+ new_yes_ind = build_modify_expr
+ (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
+ UNKNOWN_LOCATION, TREE_OPERAND (array_operand[0], 1),
+ TREE_TYPE (TREE_OPERAND (array_operand[0], 1)));
+ new_yes_expr = build_modify_expr
+ (UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value),
+ NOP_EXPR,
+ UNKNOWN_LOCATION, func_parm, TREE_OPERAND (array_operand[0], 1));
+ }
+ new_yes_list = alloc_stmt_list ();
+ append_to_statement_list (new_yes_ind, &new_yes_list);
+ append_to_statement_list (new_yes_expr, &new_yes_list);
+
+ new_no_list = alloc_stmt_list ();
+ append_to_statement_list (new_no_ind, &new_no_list);
+ append_to_statement_list (new_no_expr, &new_no_list);
+
+ new_expr = build_conditional_expr
+ (UNKNOWN_LOCATION,
+ build2 (GT_EXPR, TREE_TYPE (array_ind_value), array_ind_value,
+ func_parm),
+ false,
+ new_yes_list, TREE_TYPE (*new_var), new_no_list, TREE_TYPE (*new_var));
+ break;
+ default:
+ gcc_unreachable ();
+ break;
+ }
+
+ for (ii = 0; ii < rank; ii++)
+ append_to_statement_list (ind_init [ii], &loop);
+
+ append_to_statement_list (new_var_init, &loop);
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ /* append_to_statement_list (ind_init [ii], &loop); */
+
+ append_to_statement_list
+ (build1 (LABEL_EXPR, void_type_node, if_stmt_label[ii]), &loop);
+ append_to_statement_list
+ (build3 (COND_EXPR, void_type_node, compare_expr[ii],
+ build1 (GOTO_EXPR, void_type_node, body_label[ii]),
+ build1 (GOTO_EXPR, void_type_node, exit_label[ii])), &loop);
+ append_to_statement_list (body_label_expr[ii], &loop);
+ }
+
+ append_to_statement_list (new_expr, &loop);
+
+ for (ii = rank - 1; ii >= 0; ii--)
+ {
+ append_to_statement_list (expr_incr[ii], &loop);
+ append_to_statement_list
+ (build1 (GOTO_EXPR, void_type_node, if_stmt_label[ii]), &loop);
+ append_to_statement_list (exit_label_expr[ii], &loop);
+ }
+
+ free (body_label);
+ free (body_label_expr);
+ free (exit_label);
+ free (exit_label_expr);
+ free (compare_expr);
+ free (if_stmt_label);
+ free (expr_incr);
+ free (ind_init);
+ free (array_operand);
+ free (array_var);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ free (count_down[ii]);
+ free (array_value[ii]);
+ free (array_stride[ii]);
+ free (array_length[ii]);
+ free (array_start[ii]);
+ free (array_ops[ii]);
+ free (array_vector[ii]);
+ }
+
+ free (count_down);
+ free (array_value);
+ free (array_stride);
+ free (array_length);
+ free (array_start);
+ free (array_ops);
+ free (array_vector);
+
+
+ return loop;
+}
+
+static bool
+is_builtin_array_notation_fn (tree func_name, an_reduce_type *type)
+{
+ const char *function_name = NULL;
+
+ if (!func_name)
+ return false;
+
+ if (TREE_CODE (func_name) == IDENTIFIER_NODE)
+ function_name = IDENTIFIER_POINTER (func_name);
+ else if (TREE_CODE (func_name) == ADDR_EXPR)
+ {
+ func_name = TREE_OPERAND (func_name, 0);
+ if (TREE_CODE (func_name) == FUNCTION_DECL)
+ function_name = IDENTIFIER_POINTER (DECL_NAME (func_name));
+ }
+ if (!function_name)
+ return false;
+
+ if (!strcmp (function_name, "__sec_reduce_add"))
+ {
+ *type = REDUCE_ADD;
+ return true;
+ }
+ else if (!strcmp (function_name, "__sec_reduce_mul"))
+ {
+ *type = REDUCE_MUL;
+ return true;
+ }
+ else if (!strcmp (function_name, "__sec_reduce_all_zeros"))
+ {
+ *type = REDUCE_ALL_ZEROS;
+ return true;
+ }
+ else if (!strcmp (function_name, "__sec_reduce_any_zeros"))
+ {
+ *type = REDUCE_ANY_ZEROS;
+ return true;
+ }
+ else if (!strcmp (function_name, "__sec_reduce_max"))
+ {
+ *type = REDUCE_MAX;
+ return true;
+ }
+ else if (!strcmp (function_name, "__sec_reduce_min"))
+ {
+ *type = REDUCE_MIN;
+ return true;
+ }
+ else if (!strcmp (function_name, "__sec_reduce_min_ind"))
+ {
+ *type = REDUCE_MIN_INDEX;
+ return true;
+ }
+ else if (!strcmp (function_name, "__sec_reduce_max_ind"))
+ {
+ *type = REDUCE_MAX_INDEX;
+ return true;
+ }
+ else
+ {
+ *type = REDUCE_UNKNOWN;
+ return false;
+ }
+ return false;
+}
+
+bool
+contains_array_notation_expr (tree expr)
+{
+ tree *array_list = NULL;
+ int list_size = 0;
+ an_reduce_type type = REDUCE_UNKNOWN;
+
+ if (TREE_CODE (expr) == FUNCTION_DECL)
+ if (is_builtin_array_notation_fn (DECL_NAME (expr), &type))
+ return true;
+
+
+ extract_array_notation_exprs (expr, false, &array_list, &list_size);
+ if (array_list == NULL || list_size == 0)
+ return false;
+ else
+ return true;
+}
@@ -62,6 +62,7 @@ extern tree c_build_sync (tree *);
extern tree fix_conditional_array_notations (tree);
extern struct c_expr fix_array_notation_expr (location_t, enum tree_code,
struct c_expr);
+extern bool contains_array_notation_expr (tree);
struct pragma_simd_values local_simd_values;
@@ -5474,11 +5475,11 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
rhs = default_function_array_read_conversion (exp_location, rhs);
/* bviyer: The line below is where the parser has the form:
- * A = B
+ * A = B, where A&B could contain array notation expressions
* So this is where we must modify the Array Notation arrays */
- if (TREE_CODE (lhs.value) == ARRAY_NOTATION_REF
- || TREE_CODE (rhs.value) == ARRAY_NOTATION_REF)
+ if (flag_enable_cilk && (contains_array_notation_expr (lhs.value)
+ || contains_array_notation_expr (rhs.value)))
ret.value = build_array_notation_expr (op_location, lhs.value,
lhs.original_type, code,
exp_location, rhs.value,
@@ -110,6 +110,8 @@ static void readonly_warning (tree, enum lvalue_use);
static int lvalue_or_else (location_t, const_tree, enum lvalue_use);
static void record_maybe_used_decl (tree);
static int comptypes_internal (const_tree, const_tree, bool *, bool *);
+
+extern bool contains_array_notation_expr (tree);
/* Return true if EXP is a null pointer constant, false otherwise. */
@@ -3027,6 +3029,8 @@ convert_arguments (tree typelist, VEC(tree,gc) *values,
bool npc;
tree parmval;
+ if (flag_enable_cilk && contains_array_notation_expr (val))
+ continue;
if (type == void_type_node)
{
if (selector)
@@ -3268,11 +3272,16 @@ convert_arguments (tree typelist, VEC(tree,gc) *values,
if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
{
- error_at (input_location,
- "too few arguments to function %qE", function);
- if (fundecl && !DECL_BUILT_IN (fundecl))
- inform (DECL_SOURCE_LOCATION (fundecl), "declared here");
- return -1;
+ if (flag_enable_cilk && contains_array_notation_expr (function))
+ ;
+ else
+ {
+ error_at (input_location,
+ "too few arguments to function %qE", function);
+ if (fundecl && !DECL_BUILT_IN (fundecl))
+ inform (DECL_SOURCE_LOCATION (fundecl), "declared here");
+ return -1;
+ }
}
return error_args ? -1 : (int) parmnum;
@@ -5173,6 +5182,9 @@ convert_for_assignment (location_t location, tree type, tree rhs,
tree rname = NULL_TREE;
bool objc_ok = false;
+ if (flag_enable_cilk && contains_array_notation_expr (rhs))
+ return rhs;
+
if (errtype == ic_argpass)
{
tree selector;
@@ -5719,16 +5731,20 @@ convert_for_assignment (location_t location, tree type, tree rhs,
or one that results from arithmetic, even including
a cast to integer type. */
if (!null_pointer_constant)
- WARN_FOR_ASSIGNMENT (location, 0,
- G_("passing argument %d of %qE makes "
- "pointer from integer without a cast"),
- G_("assignment makes pointer from integer "
- "without a cast"),
- G_("initialization makes pointer from "
- "integer without a cast"),
- G_("return makes pointer from integer "
- "without a cast"));
-
+ {
+ if (flag_enable_cilk && contains_array_notation_expr (rhs))
+ ;
+ else
+ WARN_FOR_ASSIGNMENT (location, 0,
+ G_("passing argument %d of %qE makes "
+ "pointer from integer without a cast"),
+ G_("assignment makes pointer from integer "
+ "without a cast"),
+ G_("initialization makes pointer from "
+ "integer without a cast"),
+ G_("return makes pointer from integer "
+ "without a cast"));
+ }
return convert (type, rhs);
}
else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
@@ -1,3 +1,7 @@
+2012-01-25 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * gcc.dg/cilk-plus/array_notation_tests/builtin_func_double.c: New.
+
2012-01-21 Balaji V. Iyer <balaji.v.iyer@intel.com>
* g++.dg/cilk-plus/array_notation_tests/builtin_funcs.cc: New.
new file mode 100644
@@ -0,0 +1,73 @@
+#define HAVE_IO 1
+
+#if HAVE_IO
+#include <stdio.h>
+#endif
+#include <stdlib.h>
+
+/* char __sec_reduce_add (int *); */
+int main(int argc, char **argv)
+{
+ int ii,array[10], y = 0, y_int = 0, array2[10];
+ double x, yy, array3[10], array4[10];
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 1+ii;
+ array2[ii]= 2;
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ if (ii%2 && ii)
+ array3[ii] = (double)(1.0000/(double)ii);
+ else
+ array3[ii] = (double) ii + 0.10;
+ array4[ii] = (double) (1.00000/ (double)(ii+1));
+ }
+
+ /* array[:] = 5; */
+ x = __sec_reduce_max (array3[:] * array4[:]);
+ y = __sec_reduce_max_ind ( array3[:] * array4[:]);
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ printf("%5.3f ", array3[ii] * array4[ii]);
+ printf("\n");
+ printf("Max = %5.3f\t Max Index = %2d\n", x, y);
+#endif
+
+ x = __sec_reduce_min (array3[:] * array4[:]);
+ y = __sec_reduce_min_ind ( array3[:] * array4[:]);
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ printf("%5.3f ", array3[ii] * array4[ii]);
+ printf("\n");
+ printf("Min = %5.3f\t Min Index = %2d\n", x, y);
+#endif
+
+ x = __sec_reduce_add (array3[:] * array4[:]);
+ yy = __sec_reduce_mul ( array3[:] * array4[:]);
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ printf("%5.3f ", array3[ii] * array4[ii]);
+ printf("\n");
+ printf("Add = %5.3f\t Mul = %f\n", x, y);
+#endif
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ if (ii%2 && ii)
+ array3[ii] = (double)(1.0000/(double)ii);
+ else
+ array3[ii] = (double) ii + 0.00;
+ array4[ii] = (double) (1.00000/ (double)(ii+1));
+ }
+ y_int = __sec_reduce_any_zeros (array3[:] * array4[:]);
+ y = __sec_reduce_all_zeros ( array3[:] * array4[:]);
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ printf("%5.3f ", array3[ii] * array4[ii]);
+ printf("\n");
+ printf("Any Zeros = %d\t All Zeros = %d\n", y_int, y);
+#endif
+ return 0;
+}