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;

Reply via email to