Hello Everyone,
This patch is for the C-Compiler in the Cilkplus branch. This patch is an
extension to the patches in the following email:
http://gcc.gnu.org/ml/gcc-patches/2011-12/msg01581.html. This patch will add
increment and decrement-operations support on array notations.
Thanking You,
Yours Sincerely,
Balaji V. Iyer.
diff --git a/gcc/ChangeLog.cilk b/gcc/ChangeLog.cilk
index d53e09e..76decf6 100644
--- a/gcc/ChangeLog.cilk
+++ b/gcc/ChangeLog.cilk
@@ -1,3 +1,12 @@
+2011-12-24 Balaji V. Iyer <balaji.v.i...@intel.com>
+
+ * c-array-notations.c (fix_array_notation_expr): New function.
+ (fix_conditional_array_notations_1): Fixed a bug, by changing greater
+ than to less-than.
+ * c-parser.c (c_parser_unary_expression): Added support to handle
+ array notations in unary operations.
+ (c_parser_postfix_expression_after_primary): Likewise.
+
2011-12-23 Balaji V. Iyer <balaji.v.i...@intel.com>
* c-array-notations.c (fix_conditional_array_notations): New function.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 1721a42..5d3af92 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1130,12 +1130,12 @@ C_COMMON_OBJS = c-family/c-common.o
c-family/c-cppbuiltin.o c-family/c-dump.o \
c-family/c-format.o c-family/c-gimplify.o c-family/c-lex.o \
c-family/c-omp.o c-family/c-opts.o c-family/c-pch.o \
c-family/c-ppoutput.o c-family/c-pragma.o c-family/c-pretty-print.o \
- c-family/c-semantics.o c-family/c-ada-spec.o cilk-spawn.o c-array-notation.o
+ c-family/c-semantics.o c-family/c-ada-spec.o cilk-spawn.o
# Language-specific object files for C and Objective C.
C_AND_OBJC_OBJS = attribs.o c-errors.o c-decl.o c-typeck.o \
- c-convert.o c-aux-info.o c-objc-common.o c-parser.o tree-mudflap.o \
- $(C_COMMON_OBJS) $(C_TARGET_OBJS)
+ c-convert.o c-aux-info.o c-objc-common.o c-parser.o c-array-notation.o \
+ tree-mudflap.o $(C_COMMON_OBJS) $(C_TARGET_OBJS)
# Language-specific object files for C.
C_OBJS = c-lang.o c-family/stub-objc.o $(C_AND_OBJC_OBJS)
diff --git a/gcc/c-array-notation.c b/gcc/c-array-notation.c
index 0884263..ca8bfbb 100644
--- a/gcc/c-array-notation.c
+++ b/gcc/c-array-notation.c
@@ -19,7 +19,8 @@ void replace_array_notations (tree *, tree *, tree *, int);
void find_rank (tree, int *);
void extract_array_notation_exprs (tree, tree **, int *);
tree fix_conditional_array_notations (tree);
-
+struct c_expr fix_array_notation_expr (location_t, enum tree_code,
+ struct c_expr);
void
find_rank (tree array, int *rank)
{
@@ -752,7 +753,7 @@ fix_conditional_array_notations_1 (tree stmt)
{
if (count_down[0][jj])
compare_expr[jj] =
- build2 (GT_EXPR, boolean_type_node, array_var[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)));
@@ -834,3 +835,276 @@ fix_conditional_array_notations (tree stmt)
else
return fix_conditional_array_notations_1 (stmt);
}
+
+struct c_expr
+fix_array_notation_expr (location_t location, enum tree_code code,
+ struct c_expr arg)
+{
+
+ 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;
+
+ find_rank (arg.value, &rank);
+ if (rank == 0)
+ return arg;
+
+ extract_array_notation_exprs (arg.value, &array_list, &list_size);
+
+ if (*array_list == NULL_TREE || list_size == 0)
+ return arg;
+
+ 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 = push_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 (&arg.value, 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]);
+ }
+ }
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ add_stmt (ind_init [ii]);
+
+ add_stmt (build1 (LABEL_EXPR, void_type_node, if_stmt_label[ii]));
+ add_stmt (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])));
+ add_stmt (body_label_expr[ii]);
+ }
+
+ arg = default_function_array_read_conversion (location, arg);
+ if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
+ arg.value = build_unary_op (location, code, arg.value, 0);
+ else if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
+ arg = parser_build_unary_op (location, code, arg);
+ add_stmt (arg.value);
+
+ for (ii = rank - 1; ii >= 0; ii--)
+ {
+ add_stmt (expr_incr[ii]);
+ add_stmt (build1 (GOTO_EXPR, void_type_node, if_stmt_label[ii]));
+ add_stmt (exit_label_expr[ii]);
+ }
+
+ pop_stmt_list (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);
+
+ arg.value = loop;
+ return arg;
+}
+
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 457abee..f8d5b25 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -60,6 +60,8 @@ along with GCC; see the file COPYING3. If not see
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);
struct pragma_simd_values local_simd_values;
@@ -5962,14 +5964,26 @@ c_parser_unary_expression (c_parser *parser)
c_parser_consume_token (parser);
exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_read_conversion (exp_loc, op);
- return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
+ if (TREE_CODE (op.value) == ARRAY_NOTATION_REF)
+ op = fix_array_notation_expr (exp_loc, PREINCREMENT_EXPR, op);
+ else
+ {
+ op = default_function_array_read_conversion (exp_loc, op);
+ op = parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
+ }
+ return op;
case CPP_MINUS_MINUS:
c_parser_consume_token (parser);
exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_read_conversion (exp_loc, op);
- return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
+ if (TREE_CODE (op.value) == ARRAY_NOTATION_REF)
+ op = fix_array_notation_expr (exp_loc, PREDECREMENT_EXPR, op);
+ else
+ {
+ op = default_function_array_read_conversion (exp_loc, op);
+ op = parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
+ }
+ return op;
case CPP_AND:
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
@@ -7100,18 +7114,29 @@ c_parser_postfix_expression_after_primary (c_parser
*parser,
case CPP_PLUS_PLUS:
/* Postincrement. */
c_parser_consume_token (parser);
- expr = default_function_array_read_conversion (expr_loc, expr);
- expr.value = build_unary_op (op_loc,
- POSTINCREMENT_EXPR, expr.value, 0);
+ if (TREE_CODE (expr.value) == ARRAY_NOTATION_REF)
+ expr = fix_array_notation_expr (expr_loc, POSTINCREMENT_EXPR, expr);
+ else
+ {
+ expr = default_function_array_read_conversion (expr_loc, expr);
+ expr.value = build_unary_op (op_loc,
+ POSTINCREMENT_EXPR, expr.value, 0);
+ }
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
break;
case CPP_MINUS_MINUS:
/* Postdecrement. */
c_parser_consume_token (parser);
- expr = default_function_array_read_conversion (expr_loc, expr);
- expr.value = build_unary_op (op_loc,
- POSTDECREMENT_EXPR, expr.value, 0);
+ if (TREE_CODE (expr.value) == ARRAY_NOTATION_REF)
+ expr = fix_array_notation_expr (expr_loc, POSTDECREMENT_EXPR, expr);
+ else
+ {
+
+ expr = default_function_array_read_conversion (expr_loc, expr);
+ expr.value = build_unary_op (op_loc,
+ POSTDECREMENT_EXPR, expr.value, 0);
+ }
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
break;