Hello Everyone,
This patch is for the Cilkplus branch affecting only the C compiler. This
patch will implement the 1D array notation triplets. Array notations are
indented to allow users directly express high-level parallel vector operations
in the code. More information about array notations can be obtained from the
Cilk Plus Language reference manual: http://software.intel.com/file/40278.
Thanks,
Balaji V. Iyer.
diff --git a/gcc/ChangeLog.cilk b/gcc/ChangeLog.cilk
index d6e9cba..6d2b694 100644
--- a/gcc/ChangeLog.cilk
+++ b/gcc/ChangeLog.cilk
@@ -1,3 +1,23 @@
+2011-12-09 Balaji V. Iyer <balaji.v.i...@intel.com>
+
+ * c-typeck.c (build_array_notation_expr): New function.
+ * c-parser.c (c_parser_array_notation): Likewise.
+ (c_parser_array_notation): Likewise.
+ (c_parser_expr_no_commas): Added if statement to handle ARRAY_NOTATION.
+ (c_parser_postfix_expression_after_primary): Added a check to see
+ if ARRAY NOTATION was used, and if so then added appropriate code to
+ handle it.
+ * gimplify.c (gimplify_expr): Added a case for ARRAY_NOTATION_REF.
+ * tree.def (ARRAY_NOTATION_REF): New tree-type for array_notation.
+ * tree.h (ARRAY_NOTATION_CHECK): New define for ARRAY_NOTATION TREE
+ (ARRAY_NOTATION_ARRAY): Likewise.
+ (ARRAY_NOTATION_START): Likewise.
+ (ARRAY_NOTATION_END): Likewise.
+ (ARRAY_NOTATION_STRIDE): Likewise.
+ (ARRAY_NOTATION_TYPE): Likewise.
+ * tree-vectorizer.c (vectorize_loops): Added the function call
+ optimize_loop_nest_for_speed_p () into the if-loop.
+
2011-12-02 Balaji V. Iyer <balaji.v.i...@intel.com>
* cilk.c (create_metadata_label): Make notes instead of CODE_LABEL.
diff --git a/gcc/c-family/ChangeLog.cilk b/gcc/c-family/ChangeLog.cilk
index 720d552..5e57983 100644
--- a/gcc/c-family/ChangeLog.cilk
+++ b/gcc/c-family/ChangeLog.cilk
@@ -1,3 +1,7 @@
+2011-12-09 Balaji V. Iyer <balaji.v.i...@intel.com>
+
+ * c-common.h: Added build_array_notation_expr prototype.
+
2011-08-08 Balaji V. Iyer <balaji.v.i...@intel.com>
* c-common.c (c_common_reswords[]): Added "cilk_for", "cilk_spawn"
and "cilk_sync" keywords.]
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index d7fb0a7..ef687fe 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -549,6 +549,8 @@ extern tree pushdecl_top_level (tree);
extern tree pushdecl (tree);
extern tree build_modify_expr (location_t, tree, tree, enum tree_code,
location_t, tree, tree);
+extern tree build_array_notation_expr (location_t, tree, tree, enum tree_code,
+ location_t, tree, tree);
extern tree build_indirect_ref (location_t, tree, ref_operator);
extern int c_expand_decl (tree);
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 0ca816e..ec78eeb 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -1252,7 +1252,7 @@ void c_parser_simd_private(c_parser *);
void c_parser_simd_assert(c_parser *, bool);
void c_parser_simd_vectorlength (c_parser *);
void c_parser_simd_reduction (c_parser *);
-
+static tree c_parser_array_notation (c_parser *, tree, tree);
/* Parse a translation unit (C90 6.7, C99 6.9).
translation-unit:
@@ -5455,9 +5455,21 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr
*after)
exp_location = c_parser_peek_token (parser)->location;
rhs = c_parser_expr_no_commas (parser, NULL);
rhs = default_function_array_read_conversion (exp_location, rhs);
- ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
- code, exp_location, rhs.value,
- rhs.original_type);
+
+ /* bviyer: The line below is where the parser has the form:
+ * A = B
+ * 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)
+ ret.value = build_array_notation_expr (op_location, lhs.value,
+ lhs.original_type, code,
+ exp_location, rhs.value,
+ rhs.original_type);
+ else
+ ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
+ code, exp_location, rhs.value,
+ rhs.original_type);
if (code == NOP_EXPR)
ret.original_code = MODIFY_EXPR;
else
@@ -6941,10 +6953,44 @@ c_parser_postfix_expression_after_primary (c_parser
*parser,
case CPP_OPEN_SQUARE:
/* Array reference. */
c_parser_consume_token (parser);
- idx = c_parser_expression (parser).value;
- c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
- "expected %<]%>");
- expr.value = build_array_ref (op_loc, expr.value, idx);
+ if (c_parser_peek_token (parser)->type == CPP_COLON)
+ {
+ /* If we reach here, then we have something like this:
+ * Array [ : ]
+ */
+ if (flag_enable_cilk)
+ expr.value = c_parser_array_notation (parser, NULL_TREE,
+ expr.value);
+ }
+ else
+ {
+ /* Here we have 3 options.
+ * 1. ARRAY [ EXPR ] -- Normal array call.
+ * 2. ARRAY [ EXPR : EXPR ] -- Array notation without stride
+ * 3. ARRAY [ EXPR : EXPR : EXPR] -- Array notation with stride.
+
+ * For 1. we just handle it like any array expression.
+ * For 2, 3: WE handle the way we handle array notations.
+ */
+ tree initial_index = c_parser_expression (parser).value;
+ if (c_parser_peek_token (parser)->type == CPP_COLON)
+ {
+ if (flag_enable_cilk)
+ expr.value = c_parser_array_notation (parser, initial_index,
+ expr.value);
+ }
+ else
+ {
+ idx = initial_index;
+ /* bviyer: this is where they are going to find the values
+ of array index. So this is where we must modify to get
+ Array notation idx is the array index
+ */
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
+ "expected %<]%>");
+ expr.value = build_array_ref (op_loc, expr.value, idx);
+ }
+ }
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
break;
@@ -11688,6 +11734,97 @@ c_parser_cilk_for_statement (c_parser *parser, tree
grain)
to be created to make outlining happy. */
}
+static tree
+c_parser_array_notation (c_parser *parser, tree initial_index, tree
array_value)
+{
+ c_token *token = NULL;
+ tree start_index = NULL_TREE, end_index = NULL_TREE, stride = NULL_TREE;
+ tree value_tree = NULL_TREE, type = NULL_TREE, array_type = NULL_TREE;
+ tree array_type_domain = NULL_TREE;
+ double_int x;
+ array_type = TREE_TYPE (array_value);
+ gcc_assert (array_type);
+ type = TREE_TYPE (array_type);
+ token = c_parser_peek_token (parser);
+
+ if (token == NULL)
+ {
+ c_parser_error (parser, "expected %<:%> or numeral");
+ return value_tree;
+ }
+ else if (token->type == CPP_COLON)
+ {
+ if (!initial_index)
+ {
+ /* If we are here, then we have a case like this A[:] */
+ c_parser_consume_token (parser);
+ array_type_domain = TYPE_DOMAIN (array_type);
+ gcc_assert (array_type_domain);
+ start_index = TYPE_MINVAL (array_type_domain);
+ start_index = fold_build1 (CONVERT_EXPR, integer_type_node,
+ start_index);
+ x = TREE_INT_CST (TYPE_MAXVAL (array_type_domain));
+ x.low++;
+ end_index = double_int_to_tree (integer_type_node, x);
+
+ if (tree_int_cst_lt (build_int_cst (TREE_TYPE (end_index), 0),
+ end_index))
+ stride = build_int_cst (TREE_TYPE (start_index), 1);
+ else
+ stride = build_int_cst (TREE_TYPE (start_index), -1);
+ }
+ else if (initial_index != error_mark_node)
+ {
+ /* If we are here, then there should be 2 possibilities:
+ 1. Array [EXPR : EXPR]
+ 2. Array [EXPR : EXPR : EXPR]
+ */
+ start_index = initial_index;
+
+ c_parser_consume_token (parser); /* consume the ':' */
+ end_index = c_parser_expression (parser).value;
+ if (!end_index || end_index == error_mark_node)
+ {
+ c_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+ if (c_parser_peek_token (parser)->type == CPP_COLON)
+ {
+ c_parser_consume_token (parser);
+ stride = c_parser_expression (parser).value;
+ if (!stride || stride == error_mark_node)
+ {
+ c_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+ }
+ else
+ if (TREE_CONSTANT (start_index) && TREE_CONSTANT (end_index)
+ && tree_int_cst_lt (end_index, start_index))
+ stride = build_int_cst (TREE_TYPE (start_index), -1);
+ else
+ stride = build_int_cst (TREE_TYPE (start_index), 1);
+ }
+ else
+ c_parser_error (parser, "expected array notation expression");
+ }
+ else
+ c_parser_error (parser, "expected array notation expression");
+
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
+
+
+ value_tree = build5 (ARRAY_NOTATION_REF, NULL_TREE, NULL_TREE, NULL_TREE,
+ NULL_TREE, NULL_TREE, NULL_TREE);
+ ARRAY_NOTATION_ARRAY (value_tree) = array_value;
+ ARRAY_NOTATION_START (value_tree) = start_index;
+ ARRAY_NOTATION_LENGTH (value_tree) = end_index;
+ ARRAY_NOTATION_STRIDE (value_tree) = stride;
+ ARRAY_NOTATION_TYPE (value_tree) = type;
+
+ TREE_TYPE (value_tree) = type;
+ return value_tree;
+}
#include "gt-c-parser.h"
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 3052b1b..d9cf8e4 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -5043,6 +5043,239 @@ build_modify_expr (location_t location, tree lhs, tree
lhs_origtype,
protected_set_expr_location (result, location);
return result;
}
+
+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 = false, rhs_vector = false;
+ tree array_expr_lhs = NULL_TREE, array_expr_rhs = NULL_TREE, array_expr;
+ tree lhs_value = NULL_TREE, rhs_value = NULL_TREE;
+ tree lhs_stride = NULL_TREE, lhs_length = NULL_TREE, lhs_start = NULL_TREE;
+ tree rhs_stride = NULL_TREE, rhs_length = NULL_TREE, rhs_start = NULL_TREE;
+ tree loop, lhs_var = NULL_TREE, rhs_var = NULL_TREE;
+ tree body_label, body_label_expr;
+ tree exit_label, exit_label_expr, cond_expr, if_stmt_label;
+ tree temp = NULL_TREE;
+ tree lhs_expr_incr = NULL_TREE, rhs_expr_incr = NULL_TREE;
+ bool lhs_count_down = false, rhs_count_down = false;
+
+ if (TREE_CODE(lhs) == ARRAY_NOTATION_REF)
+ {
+ lhs_value = ARRAY_NOTATION_ARRAY (lhs);
+ lhs_start = ARRAY_NOTATION_START (lhs);
+ lhs_length = ARRAY_NOTATION_LENGTH (lhs);
+ lhs_stride = ARRAY_NOTATION_STRIDE (lhs);
+ lhs_vector = true;
+ /* if the stride value is variable (i.e. not constant) then assume the
+ programmer knows what he is doing and keep on going */
+ if (!TREE_CONSTANT (lhs_length))
+ lhs_count_down = false; /* assume we count up */
+ else if (tree_int_cst_lt (lhs_length,
+ build_int_cst (TREE_TYPE (lhs_length), 0)))
+ lhs_count_down = true;
+ }
+ else
+ {
+ if (TREE_CODE(rhs) == ARRAY_NOTATION_REF)
+ error ("Assignment of vector to a scalar is prohibited");
+ else
+ lhs_vector = false;
+ }
+
+ if (TREE_CODE (rhs) == ARRAY_NOTATION_REF)
+ {
+ rhs_value = ARRAY_NOTATION_ARRAY (rhs);
+ rhs_start = ARRAY_NOTATION_START (rhs);
+ rhs_length = ARRAY_NOTATION_LENGTH (rhs);
+ rhs_stride = ARRAY_NOTATION_STRIDE (rhs);
+ rhs_vector = true;
+
+ /* if the stride value is variable (i.e. not constant) then assume the
+ programmer knows what he is doing and keep on going */
+ if (!TREE_CONSTANT (rhs_length))
+ rhs_count_down = false; /* assume wwe count up */
+ else if (tree_int_cst_lt (rhs_length,
+ build_int_cst (TREE_TYPE (rhs_length), 0)))
+ rhs_count_down = true;
+ }
+ else
+ rhs_vector = false;
+
+ loop = push_stmt_list();
+
+ if (lhs_vector)
+ {
+ lhs_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE,
+ TREE_TYPE (lhs_start));
+ temp = build_modify_expr
+ (UNKNOWN_LOCATION, lhs_var, TREE_TYPE (lhs_var), modifycode,
+ UNKNOWN_LOCATION, build_int_cst (TREE_TYPE (lhs_start), 0),
+ TREE_TYPE (lhs_start));
+ add_stmt (temp);
+ }
+ if (rhs_vector)
+ {
+ rhs_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE,
+ TREE_TYPE (rhs_start));
+ add_stmt (build_modify_expr (UNKNOWN_LOCATION, rhs_var,
+ TREE_TYPE (rhs_var), modifycode,
+ UNKNOWN_LOCATION,
+ build_int_cst (TREE_TYPE(rhs_start), 0),
+ TREE_TYPE (rhs_start)));
+ }
+
+
+ /* this will create the if statement label */
+ if_stmt_label = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
+ void_type_node);
+ DECL_CONTEXT (if_stmt_label) = current_function_decl;
+ DECL_ARTIFICIAL (if_stmt_label) = 0;
+ DECL_IGNORED_P (if_stmt_label) = 1;
+
+ /* this label statment will point to the loop body */
+ body_label = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
+ void_type_node);
+ DECL_CONTEXT (body_label) = current_function_decl;
+ DECL_ARTIFICIAL (body_label) = 0;
+ DECL_IGNORED_P (body_label) = 1;
+ body_label_expr = build1 (LABEL_EXPR, void_type_node, body_label);
+
+ /* this will create the exit label..i.e. where the while loop will branch
+ out of
+ */
+ exit_label = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
+ void_type_node);
+ DECL_CONTEXT (exit_label) = current_function_decl;
+ DECL_ARTIFICIAL (exit_label) = 0;
+ DECL_IGNORED_P (exit_label) = 1;
+ exit_label_expr = build1 (LABEL_EXPR, void_type_node, exit_label);
+
+ if (lhs_vector)
+ {
+ /* Array[start_index + (induction_var * stride)] */
+ array_expr_lhs = build_array_ref
+ (location, lhs_value, build2 (PLUS_EXPR, TREE_TYPE (lhs_var), lhs_start,
+ build2 (MULT_EXPR, TREE_TYPE (lhs_var),
+ lhs_var, lhs_stride)));
+ if (lhs_count_down)
+ lhs_expr_incr = build2 (MODIFY_EXPR, void_type_node, lhs_var,
+ build2 (PLUS_EXPR, TREE_TYPE (lhs_var), lhs_var,
+ build_int_cst (TREE_TYPE (lhs_var),
+ -1)));
+ else
+ lhs_expr_incr = build2 (MODIFY_EXPR, void_type_node, lhs_var,
+ build2 (PLUS_EXPR, TREE_TYPE (lhs_var), lhs_var,
+ build_int_cst (TREE_TYPE (lhs_var),
+ 1)));
+ }
+ if (rhs_vector)
+ {
+
+ array_expr_rhs = build_array_ref
+ (location, rhs_value, build2 (PLUS_EXPR, TREE_TYPE (rhs_var), rhs_start,
+ build2 (MULT_EXPR, TREE_TYPE (rhs_var),
+ rhs_var, rhs_stride)));
+ if (rhs_count_down)
+ rhs_expr_incr = build2 (MODIFY_EXPR, void_type_node, rhs_var,
+ build2 (PLUS_EXPR, TREE_TYPE (rhs_var), rhs_var,
+ build_int_cst (TREE_TYPE (rhs_var),
+ -1)));
+ else
+ rhs_expr_incr = build2 (MODIFY_EXPR, void_type_node, rhs_var,
+ build2 (PLUS_EXPR, TREE_TYPE (rhs_var), rhs_var,
+ build_int_cst (TREE_TYPE (rhs_var),
+ 1)));
+ }
+ else
+ {
+ array_expr_rhs = rhs;
+ rhs_expr_incr = NULL_TREE;
+ }
+
+ array_expr = build_modify_expr (location, array_expr_lhs,
+ lhs_origtype, modifycode, rhs_loc,
+ array_expr_rhs, rhs_origtype);
+
+ if (rhs_expr_incr)
+ {
+ tree lhs_compare, rhs_compare;
+ if (lhs_count_down)
+ lhs_compare = build2 (GE_EXPR, boolean_type_node, lhs_var,
+ build2 (PLUS_EXPR, TREE_TYPE (lhs_length),
+ lhs_length,
+ build_int_cst (TREE_TYPE (lhs_length),
+ 1)));
+ else
+ lhs_compare = build2 (LE_EXPR, boolean_type_node, lhs_var,
+ build2 (MINUS_EXPR, TREE_TYPE (lhs_length),
+ lhs_length,
+ build_int_cst (TREE_TYPE (lhs_length),
+ 1)));
+
+ if (rhs_count_down)
+ rhs_compare = build2 (GE_EXPR, boolean_type_node, rhs_var,
+ build2 (PLUS_EXPR, TREE_TYPE (rhs_length),
+ rhs_length,
+ build_int_cst (TREE_TYPE (rhs_length),
+ 1)));
+ else
+ rhs_compare = build2 (LE_EXPR, boolean_type_node, rhs_var,
+ build2 (MINUS_EXPR, TREE_TYPE (rhs_length),
+ rhs_length,
+ build_int_cst (TREE_TYPE (rhs_length),
+ 1)));
+
+ cond_expr = build2 (TRUTH_ANDIF_EXPR, void_type_node, lhs_compare,
+ rhs_compare);
+ }
+ else
+ {
+ if (lhs_count_down)
+ cond_expr = build2 (GE_EXPR, boolean_type_node, lhs_var,
+ build2 (PLUS_EXPR, TREE_TYPE (lhs_length),
+ lhs_length,
+ build_int_cst (TREE_TYPE (lhs_length), 1)));
+ else
+ cond_expr = build2 (LE_EXPR, boolean_type_node, lhs_var,
+ fold_build2 (PLUS_EXPR, TREE_TYPE (lhs_length),
+ lhs_length,
+ build_int_cst (TREE_TYPE (lhs_length),
-1)));
+ }
+
+ /* The following statements will do the following:
+ * <if_stmt_label>:
+ * if (cond_expr) then go to body_label
+ * else go to exit_label
+ * <body_label>:
+ * array expression
+ * ii++ and jj++
+ * go to if_stmt_label
+ * <exit_label>:
+ * <REST OF CODE>
+ */
+
+ add_stmt (build1 (LABEL_EXPR, void_type_node, if_stmt_label));
+ add_stmt (build3 (COND_EXPR, void_type_node, cond_expr,
+ build1 (GOTO_EXPR, void_type_node, body_label),
+ build1 (GOTO_EXPR, void_type_node, exit_label)));
+
+ add_stmt (body_label_expr);
+ add_stmt (array_expr);
+ add_stmt (lhs_expr_incr);
+ if (rhs_expr_incr)
+ add_stmt (rhs_expr_incr);
+
+ add_stmt (build1 (GOTO_EXPR, void_type_node, if_stmt_label));
+ add_stmt (exit_label_expr);
+
+ pop_stmt_list (loop);
+
+ return loop;
+
+}
+
/* Return whether STRUCT_TYPE has an anonymous field with type TYPE.
This is used to implement -fplan9-extensions. */
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index be0b91d..a0016c3 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -7428,6 +7428,10 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p,
gimple_seq *post_p,
ret = gimplify_omp_atomic (expr_p, pre_p);
break;
+ case ARRAY_NOTATION_REF:
+ /* Nothing should happen here. Just return as OK */
+ ret = GS_ALL_DONE;
+ break;
case CILK_FOR_STMT:
{
gimplify_cilk_for (expr_p, pre_p, post_p);
diff --git a/gcc/testsuite/ChangeLog.cilk b/gcc/testsuite/ChangeLog.cilk
index 3796a85..6fef5a8 100644
--- a/gcc/testsuite/ChangeLog.cilk
+++ b/gcc/testsuite/ChangeLog.cilk
@@ -1,3 +1,10 @@
+2011-12-07 Balaji V. Iyer <balaji.v.i...@intel.com>
+
+ * gcc.dg/cilk-plus/array_notation_test/array_test1.c: New.
+ * gcc.dg/cilk-plus/array_notation_test/array_test2.c: Likewise.
+ * gcc.dg/cilk-plus/cilk-plus.exp: Added code to run array notation
+ tests.
+
2011-09-21 Balaji V. Iyer <balaji.v.i...@intel.com>
* g++.dg/cilk-plus/Clock.cpp: Changed extension from .cpp to .cc.
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation_tests/array_test1.c
b/gcc/testsuite/gcc.dg/cilk-plus/array_notation_tests/array_test1.c
new file mode 100644
index 0000000..0c5d742
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation_tests/array_test1.c
@@ -0,0 +1,74 @@
+#include <stdio.h>
+int main(int argc, char **argv)
+{
+ int array[10], ii = 0, x = 2, z= 0 , y = 0 ;
+
+ if (argc < 2)
+ {
+ fprintf(stderr,"Usage:%s <NUMBER>\n", argv[0]);
+ return -1;
+ }
+ for (ii = 0; ii < 10; ii++)
+ array[ii] = 10;
+
+ array[0:10:1] = 15;
+
+ printf("==============================================\n");
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %2d\n", ii, array[ii]);
+
+ array[0:10:2] = 20;
+
+ printf("==============================================\n");
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %2d\n", ii, array[ii]);
+
+
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ printf("==============================================\n");
+ printf("x = %2d\tz = %2d\n", x, z);
+ array[x:5:z] = 50;
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %2d\n", ii, array[ii]);
+
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ y = 10-atoi(argv[1]);
+ printf("==============================================\n");
+ printf("x = %2d\ty = %2d\tz = %2d\n", x, y, z);
+ array[x:y:z] = 505;
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %2d\n", ii, array[ii]);
+
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ y = 10-atoi(argv[1]);
+ printf("==============================================\n");
+ printf("x = %2d\ty = %2d\tz = %2d\n", x, y, z);
+ array[x:y:((10-atoi(argv[1]))/atoi(argv[1]))] = 25;
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %2d\n", ii, array[ii]);
+
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ y = 10-atoi(argv[1]);
+ printf("==============================================\n");
+ printf("x = %2d\ty = %2d\tz = %2d\n", x, y, z);
+ array[atoi(argv[1]):(10-atoi(argv[1])):((10-atoi(argv[1]))/atoi(argv[1]))] =
+ 1400;
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %2d\n", ii, array[ii]);
+
+ array[atoi("5"):5:1] = 5555;
+ printf("==============================================\n");
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %2d\n", ii, array[ii]);
+
+ array[atoi("5"):atoi("5"):atoi("1")] = 9999;
+ printf("==============================================\n");
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %2d\n", ii, array[ii]);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation_tests/array_test2.c
b/gcc/testsuite/gcc.dg/cilk-plus/array_notation_tests/array_test2.c
new file mode 100644
index 0000000..5fb3680
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation_tests/array_test2.c
@@ -0,0 +1,122 @@
+#include <stdio.h>
+int main(int argc, char **argv)
+{
+ int array[10], array2[10], ii = 0, x = 2, z= 0 , y = 0 ;
+ if (argc < 2)
+ {
+ fprintf(stderr,"Usage:%s <NUMBER>\n", argv[0]);
+ return -1;
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 10;
+ array2[ii] = 5000000;
+ }
+
+ array2[0:10:1] = array[0:10:1];
+
+ printf("==============================================\n");
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %7d\tarray2[%2d] = %7d\n", ii, array[ii],
+ ii, array2[ii]);
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 10;
+ array2[ii] = 5000000;
+ }
+ array2[0:10:2] = array[0:10:2];
+
+ printf("==============================================\n");
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %7d\tarray2[%2d] = %7d\n", ii, array[ii],
+ ii, array2[ii]);
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 10;
+ array2[ii] = 5000000;
+ }
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ printf("==============================================\n");
+ printf("x = %2d\tz = %2d\n", x, z);
+ array2[x:5:z] = array[x:5:z];
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %7d\tarray2[%2d] = %7d\n", ii, array[ii],
+ ii, array2[ii]);
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 500;
+ array2[ii] = 1000000;
+ }
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ y = 10-atoi(argv[1]);
+ printf("==============================================\n");
+ printf("x = %2d\ty = %2d\tz = %2d\n", x, y, z);
+ array2[x:y:z] = array[x:y:z];
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %7d\tarray2[%2d] = %7d\n", ii, array[ii],
+ ii, array2[ii]);
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 500;
+ array2[ii] = 1000000;
+ }
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ y = 10-atoi(argv[1]);
+ printf("==============================================\n");
+ printf("x = %2d\ty = %2d\tz = %2d\n", x, y, z);
+ array[x:y:((10-atoi(argv[1]))/atoi(argv[1]))] =
+ array2[x:y:((10-atoi(argv[1]))/atoi(argv[1]))];
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %7d\tarray2[%2d] = %7d\n", ii, array[ii],
+ ii, array2[ii]);
+
+ x = atoi(argv[1]);
+ z = (10-atoi(argv[1]))/atoi(argv[1]);
+ y = 10-atoi(argv[1]);
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 500;
+ array2[ii] = 1000000;
+ }
+ printf("==============================================\n");
+ printf("x = %2d\ty = %2d\tz = %2d\n", x, y, z);
+ array[atoi(argv[1]):(10-atoi(argv[1])):((10-atoi(argv[1]))/atoi(argv[1]))] =
+ array2[atoi(argv[1]):(10-atoi(argv[1])):((10-atoi(argv[1]))/atoi(argv[1]))];
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %7d\tarray2[%2d] = %7d\n", ii, array[ii],
+ ii, array2[ii]);
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 4;
+ array2[ii] = 2;
+ }
+
+ array[atoi("5"):5:1] = array2[atoi("5"):5:1];
+ printf("==============================================\n");
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %2d\tarray2[%2d] = %2d\n", ii, array[ii],
+ ii, array2[ii]);
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = 5;
+ array2[ii] = 1;
+ }
+ array[atoi("5"):atoi("5"):atoi("1")] =
+ array2[atoi("5"):atoi("5"):atoi("1")];
+ printf("==============================================\n");
+ for (ii = 0; ii<10; ii++)
+ printf("array[%2d] = %2d\tarray2[%2d] = %2d\n", ii, array[ii],
+ ii, array2[ii]);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/cilk_plus.exp
b/gcc/testsuite/gcc.dg/cilk-plus/cilk_plus.exp
index dcf096e..e11f555 100644
--- a/gcc/testsuite/gcc.dg/cilk-plus/cilk_plus.exp
+++ b/gcc/testsuite/gcc.dg/cilk-plus/cilk_plus.exp
@@ -19,5 +19,9 @@ load_lib gcc-dg.exp
dg-init
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] " -ldl
-lcilkrts -I $srcdir/../../libcilkrts/include -std=c99 " " "
+dg-finish
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/array_notation_tests/*.c]]
" -O3 -ftree-vectorize" " "
dg-finish
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index c594f8d..5069d22 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -193,7 +193,8 @@ vectorize_loops (void)
FOR_EACH_LOOP (li, loop, 0)
if (((!flag_enable_cilk) && (optimize_loop_nest_for_speed_p (loop)))
|| (flag_enable_cilk
- && (pragma_simd_vectorize_loop_p (loop->pragma_simd_index))))
+ && (optimize_loop_nest_for_speed_p (loop)
+ || pragma_simd_vectorize_loop_p (loop->pragma_simd_index))))
{
loop_vec_info loop_vinfo;
diff --git a/gcc/tree.c b/gcc/tree.c
index ba75681..25ab5db 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -6999,6 +6999,7 @@ iterative_hash_expr (const_tree t, hashval_t val)
}
return val;
}
+ return val;
}
/* Generate a hash value for a pair of expressions. This can be used
diff --git a/gcc/tree.def b/gcc/tree.def
index 22d0e59..7680cd0 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -423,6 +423,14 @@ DEFTREECODE (ARRAY_REF, "array_ref", tcc_reference, 4)
of the range is taken from the type of the expression. */
DEFTREECODE (ARRAY_RANGE_REF, "array_range_ref", tcc_reference, 4)
+/* Array Notation expression.
+ Operand 0 is the array; operand 1 is the starting array index
+ Operand 2 contains the ending array index.
+ Operand 3 is the stride.
+ Operand 4 is the element size measured in units of alignments of
+ element type. */
+DEFTREECODE (ARRAY_NOTATION_REF, "array_notation_ref", tcc_reference, 5)
+
/* C unary `*' or Pascal `^'. One operand, an expression for a pointer. */
DEFTREECODE (INDIRECT_REF, "indirect_ref", tcc_reference, 1)
diff --git a/gcc/tree.h b/gcc/tree.h
index b5c4515..c8cb13e 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -6299,4 +6299,13 @@ builtin_decl_implicit_p (enum built_in_function fncode)
&& builtin_info.implicit_p[uns_fncode]);
}
+#define ARRAY_NOTATION_CHECK(NODE) TREE_CHECK (NODE, ARRAY_NOTATION_REF)
+#define ARRAY_NOTATION_ARRAY(NODE) TREE_OPERAND (ARRAY_NOTATION_CHECK (NODE),
0)
+#define ARRAY_NOTATION_START(NODE) TREE_OPERAND (ARRAY_NOTATION_CHECK (NODE),
1)
+#define ARRAY_NOTATION_LENGTH(NODE) \
+ TREE_OPERAND (ARRAY_NOTATION_CHECK (NODE), 2)
+#define ARRAY_NOTATION_STRIDE(NODE) \
+ TREE_OPERAND (ARRAY_NOTATION_CHECK (NODE), 3)
+#define ARRAY_NOTATION_TYPE(NODE) TREE_OPERAND (ARRAY_NOTATION_CHECK (NODE), 4)
+
#endif /* GCC_TREE_H */