diff mbox

[Cilkplus] Array notations for Function Calls and Unary Expressions

Message ID BF230D13CA30DD48930C31D409933000011C95@FMSMSX102.amr.corp.intel.com
State New
Headers show

Commit Message

Iyer, Balaji V Jan. 17, 2012, 11:10 p.m. UTC
Hello Everyone,
    This patch is for the Cilkplus branch affecting the C++ Compiler. This patch will allow the use of array notations triplets as a function call parameter and for post and pre increment/decrement.

Thanking You,

Yours Sincerely,

Balaji V. Iyer.
diff mbox

Patch

diff --git a/gcc/cp/ChangeLog.cilk b/gcc/cp/ChangeLog.cilk
index 06ef1ec..072a6de 100644
--- a/gcc/cp/ChangeLog.cilk
+++ b/gcc/cp/ChangeLog.cilk
@@ -1,3 +1,29 @@ 
+2012-01-17  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+	* cp-array-notation.c (max): New function.
+	(fix_unary_array_notation_exprs): Likewise.
+	(build_x_array_notation_expr): Added a check to see if we get an
+	expression has a rank of 0.  Also added code to handle a case where
+	a function call with array notation as a parameter that results a
+	scalar value.  Also added a check if lhs_rank is zero.  Changed
+	modifycode to NOP_EXPR.  Replaced all lhs_rank in for-loop conditions
+	to max of lhs and rhs rank.  Added a check to see if array_expr_lhs is
+	null, if so then just use lhs.
+	(fix_conditional_array_notations): Renamed to fix_array_notation_exprs.
+	Also added a case for POSTINCREMENT_EXPR, POSTDECREMENT_EXPR,
+	PREDECREMENT_EXPR, PREINCREMENT_EXPR.
+	* cp-tree.h: Renamed fix_conditional_array_notations to
+	fix_array_notation_exprs.
+	* parser.c (cp_parser_assignment_expression): Modified to handle a
+	function-call that has array-notation as a parameter which will return
+	a single scalar value.
+	(cp_parser_compound_statement): Renamed fix_conditional array_notations
+	to fix_array_notation_exprs and make sure it is called only if
+	flag_enable_cilk is set.
+	* typeck.c (lvalue_or_else): Removed a error check for
+	ARRAY_NOTATION_REF, if flag_enable_cilk is defined.
+	(cp_build_addr_expr_1): Likewise.
+
 2012-01-12  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
 	* cp-array-notation.c (fix_conditional_array_notations): New function.
diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c
index dec87bb..a8667dd 100644
--- a/gcc/cp/cp-array-notation.c
+++ b/gcc/cp/cp-array-notation.c
@@ -48,6 +48,7 @@ 
 void replace_array_notations (tree *, tree *, tree *, int);
 void find_rank (tree array, int *rank);
 static tree fix_conditional_array_notations_1 (tree stmt);
+tree fix_unary_array_notation_exprs (tree stmt);
 
 /* This function is to find the rank of an array notation expression.
  * For example, an array notation of A[:][:] has a rank of 2.
@@ -198,6 +199,16 @@  replace_array_notations (tree *orig, tree *list, tree *array_operand,
   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;
+}
+
 /* this function is synonymous to the build_x_modify_expr. This function
  * will build the equivalent array notation expression
  */
@@ -228,13 +239,22 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
   find_rank (lhs, &lhs_rank);
   find_rank (rhs, &rhs_rank);
 
-  extract_array_notation_exprs (rhs, &rhs_list, &rhs_list_size);
+  /* If both are scalar, then no reason to do any of the components inside this
+   * function... a simple build_x_modify_expr would do.
+   */
+  if (lhs_rank == 0 && rhs_rank == 0)
+    return NULL_TREE;
   
+  extract_array_notation_exprs (rhs, &rhs_list, &rhs_list_size);
+
   if (lhs_rank == 0 && rhs_rank != 0)
     {
-      error ( "Left Hand-side rank cannot be scalar when "
-		"right-hand side is not");
-      return error_mark_node;
+      if (TREE_CODE (rhs) != CALL_EXPR)
+	{
+	  error ( "Left Hand-side rank cannot be scalar when "
+		  "right-hand side is not");
+	  return error_mark_node;
+	}
     }
   if (lhs_rank != 0 && rhs_rank != 0 && lhs_rank != rhs_rank)
     {
@@ -286,12 +306,12 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
    *
    * 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);
@@ -310,12 +330,17 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
   rhs_array_operand = (tree *) xmalloc (sizeof (tree) * rhs_list_size);
 
   ii = 0;
-  for (ii_tree = lhs; ii_tree && TREE_CODE (ii_tree) == ARRAY_NOTATION_REF;
-       ii_tree = ARRAY_NOTATION_ARRAY (ii_tree))
+  if (lhs_rank)
     {
-      lhs_array[ii] = ii_tree;
-      ii++;
+      for (ii_tree = lhs; ii_tree && TREE_CODE (ii_tree) == ARRAY_NOTATION_REF;
+	   ii_tree = ARRAY_NOTATION_ARRAY (ii_tree))
+	{
+	  lhs_array[ii] = ii_tree;
+	  ii++;
+	}
     }
+  else
+    lhs_array[0] = NULL_TREE;
 
   if (rhs_rank)
     {
@@ -370,8 +395,10 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 		{
 		  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
@@ -401,7 +428,7 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 				    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]));
 	  
@@ -417,13 +444,13 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 				integer_type_node);
       rhs_ind_init[ii] = build_modify_expr
 	(UNKNOWN_LOCATION, rhs_var[ii], TREE_TYPE (rhs_var[ii]),
-	 modifycode,
+	 NOP_EXPR,
 	 UNKNOWN_LOCATION, build_int_cst (TREE_TYPE (rhs_var[ii]), 0),
 	 TREE_TYPE (rhs_var[ii]));
     }
   
 
-  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,
@@ -530,12 +557,14 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	 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_x_modify_expr (array_expr_lhs, modifycode, array_expr_rhs,
 				    complain);
 
-  for (jj = 0; jj < lhs_rank; jj++)
+  for (jj = 0; jj < max (lhs_rank, rhs_rank); jj++)
     {
       if (rhs_rank && rhs_expr_incr[jj])
 	{
@@ -563,9 +592,12 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	  else
 	    rhs_compare[jj] = build2 (LT_EXPR, boolean_type_node, rhs_var[jj],
 				      rhs_length[0][jj]);
-      
-	  cond_expr[jj] = build2 (TRUTH_ANDIF_EXPR, void_type_node,
-				  lhs_compare[jj], rhs_compare[jj]);
+
+	  if (lhs_rank)
+	    cond_expr[jj] = build2 (TRUTH_ANDIF_EXPR, void_type_node,
+				    lhs_compare[jj], rhs_compare[jj]);
+	  else
+	    cond_expr[jj] = rhs_compare[jj];
 	}
       else
 	{
@@ -594,9 +626,10 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
    */
 
   
-  for (ii = 0; ii < lhs_rank; ii++)
+  for (ii = 0; ii < max (lhs_rank, rhs_rank); ii++)
     {
-      append_to_statement_list (lhs_ind_init [ii], &loop);
+      if (lhs_rank)
+	append_to_statement_list (lhs_ind_init [ii], &loop);
       if (rhs_rank)
 	append_to_statement_list (rhs_ind_init[ii], &loop);
       append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
@@ -608,12 +641,14 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 
       append_to_statement_list (body_label_expr[ii], &loop);
     }
-  
-  append_to_statement_list (array_expr, &loop);
 
-  for (ii = lhs_rank - 1; ii >= 0; ii--)
+  if (max (lhs_rank, rhs_rank))
+    append_to_statement_list (array_expr, &loop);
+  
+  for (ii = max (lhs_rank, rhs_rank) - 1; ii >= 0; ii--)
     {
-      append_to_statement_list (lhs_expr_incr[ii], &loop);
+      if (lhs_rank)
+	append_to_statement_list (lhs_expr_incr[ii], &loop);
       if (rhs_rank && rhs_expr_incr[ii])
 	append_to_statement_list (rhs_expr_incr[ii], &loop);
   
@@ -914,7 +949,7 @@  fix_conditional_array_notations_1 (tree stmt)
  * also walk through their subtrees.
  */
 tree
-fix_conditional_array_notations (tree t)
+fix_array_notation_exprs (tree t)
 {
   enum tree_code code;
   bool is_expr;
@@ -949,10 +984,6 @@  fix_conditional_array_notations (tree t)
     case NOP_EXPR:
     case INIT_EXPR:
     case MODIFY_EXPR:
-    case PREDECREMENT_EXPR:
-    case PREINCREMENT_EXPR:
-    case POSTDECREMENT_EXPR:
-    case POSTINCREMENT_EXPR:
     case ADDR_EXPR:
     case ARRAY_REF:
     case BIT_FIELD_REF:
@@ -965,7 +996,7 @@  fix_conditional_array_notations (tree t)
     case BIND_EXPR:
       {
 	BIND_EXPR_BODY (t) =
-	  fix_conditional_array_notations  (BIND_EXPR_BODY (t));
+	  fix_array_notation_exprs  (BIND_EXPR_BODY (t));
 	return t;
       }
 
@@ -974,7 +1005,7 @@  fix_conditional_array_notations (tree t)
 	tree_stmt_iterator i;
 	for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
 	  *tsi_stmt_ptr (i) =
-	    fix_conditional_array_notations (*tsi_stmt_ptr (i));
+	    fix_array_notation_exprs (*tsi_stmt_ptr (i));
 	return t;
       }
 
@@ -999,29 +1030,37 @@  fix_conditional_array_notations (tree t)
     case ARRAY_TYPE:
     case RECORD_TYPE:
     case METHOD_TYPE:
+      return t;
+ 
+    case PREDECREMENT_EXPR:
+    case PREINCREMENT_EXPR:
+    case POSTDECREMENT_EXPR:
+    case POSTINCREMENT_EXPR:
     case AGGR_INIT_EXPR:
     case CALL_EXPR:
+    case CLEANUP_POINT_EXPR:
+    case EXPR_STMT:
+      t = fix_unary_array_notation_exprs (t);
       return t;
-
     case COND_EXPR:
       t = fix_conditional_array_notations_1 (t);
       if (TREE_CODE (t) == COND_EXPR)
 	{
 	  COND_EXPR_THEN (t) =
-	    fix_conditional_array_notations (COND_EXPR_THEN (t));
+	    fix_array_notation_exprs (COND_EXPR_THEN (t));
 	  COND_EXPR_ELSE (t) =
-	    fix_conditional_array_notations (COND_EXPR_ELSE (t));
+	    fix_array_notation_exprs (COND_EXPR_ELSE (t));
 	}
       else
-	t = fix_conditional_array_notations (t);
+	t = fix_array_notation_exprs (t);
       return t;
 
     case SWITCH_EXPR:
       t = fix_conditional_array_notations_1 (t);
       if (TREE_CODE (t) == SWITCH_EXPR)
-	SWITCH_BODY (t) = fix_conditional_array_notations (SWITCH_BODY (t));
+	SWITCH_BODY (t) = fix_array_notation_exprs (SWITCH_BODY (t));
       else
-	t = fix_conditional_array_notations (t);
+	t = fix_array_notation_exprs (t);
       return t;
       
     case FOR_STMT:
@@ -1032,9 +1071,9 @@  fix_conditional_array_notations (tree t)
        * for statement, then we can't assume it is still FOR_STMT/CILK_FOR_STMT
        * so we have to check again */
       if (TREE_CODE (t) == CILK_FOR_STMT || TREE_CODE (t) == FOR_STMT)
-	FOR_BODY (t) = fix_conditional_array_notations (FOR_BODY (t));
+	FOR_BODY (t) = fix_array_notation_exprs (FOR_BODY (t));
       else
-	t = fix_conditional_array_notations (t);
+	t = fix_array_notation_exprs (t);
       return t;
 
     case IF_STMT:
@@ -1045,12 +1084,12 @@  fix_conditional_array_notations (tree t)
       if (TREE_CODE (t) == IF_STMT)
 	{
 	  if (THEN_CLAUSE (t))
-	    THEN_CLAUSE (t) = fix_conditional_array_notations (THEN_CLAUSE (t));
+	    THEN_CLAUSE (t) = fix_array_notation_exprs (THEN_CLAUSE (t));
 	  if (ELSE_CLAUSE (t))
-	    ELSE_CLAUSE (t) = fix_conditional_array_notations (ELSE_CLAUSE (t));
+	    ELSE_CLAUSE (t) = fix_array_notation_exprs (ELSE_CLAUSE (t));
 	}
       else
-	t = fix_conditional_array_notations (t);
+	t = fix_array_notation_exprs (t);
       return t;
 
     case SWITCH_STMT:
@@ -1062,10 +1101,10 @@  fix_conditional_array_notations (tree t)
 	{
 	  if (SWITCH_STMT_BODY (t))
 	    SWITCH_STMT_BODY (t) =
-	      fix_conditional_array_notations (SWITCH_STMT_BODY (t));
+	      fix_array_notation_exprs (SWITCH_STMT_BODY (t));
 	}
       else
-	t = fix_conditional_array_notations (t);
+	t = fix_array_notation_exprs (t);
       return t;
 
     case WHILE_STMT:
@@ -1076,10 +1115,10 @@  fix_conditional_array_notations (tree t)
       if (TREE_CODE (t) == WHILE_STMT)
 	{
 	  if (WHILE_BODY (t))
-	    WHILE_BODY (t) = fix_conditional_array_notations (WHILE_BODY (t));
+	    WHILE_BODY (t) = fix_array_notation_exprs (WHILE_BODY (t));
 	}
       else
-	t = fix_conditional_array_notations (t);
+	t = fix_array_notation_exprs (t);
       return t;
       
     case DO_STMT:
@@ -1090,10 +1129,10 @@  fix_conditional_array_notations (tree t)
       if (TREE_CODE (t) == DO_STMT)
 	{      
 	  if (DO_BODY (t))
-	    DO_BODY (t) = fix_conditional_array_notations (DO_BODY (t));
+	    DO_BODY (t) = fix_array_notation_exprs (DO_BODY (t));
 	}
       else
-	t = fix_conditional_array_notations (t);
+	t = fix_array_notation_exprs (t);
       return t;
       
     default:
@@ -1108,9 +1147,272 @@  fix_conditional_array_notations (tree t)
 	     that the scope of a FOR_EXPR is handled properly.  */
 	  for (i = 0; i < len; ++i)
 	    TREE_OPERAND (t, i) =
-	      fix_conditional_array_notations (TREE_OPERAND (t, i));
+	      fix_array_notation_exprs (TREE_OPERAND (t, i));
 	}
       return t;
     }
   return t;
 }
+
+tree
+fix_unary_array_notation_exprs (tree stmt)
+{
+
+  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 (stmt, &rank);
+  if (rank == 0)
+    return stmt;  
+  
+  extract_array_notation_exprs (stmt, &array_list, &list_size);
+  
+  if (*array_list == NULL_TREE || list_size == 0)
+    return stmt;
+
+  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 (&stmt, 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++)
+    {
+      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 (stmt, &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);
+
+  stmt = loop;
+  return stmt;
+}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index eae4550..4f3778d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6026,7 +6026,7 @@  extern void gimplify_cilk_spawn                (tree *, gimple_seq *,
 /* In cp/cp-array-notations.c */
 extern tree build_x_array_notation_expr        (tree, enum tree_code, tree,
 						tsubst_flags_t);
-extern tree fix_conditional_array_notations    (tree);
+extern tree fix_array_notation_exprs           (tree);
 /* -- end of C++ */
 
 #endif /* ! GCC_CP_TREE_H */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7f96acd..fd35211 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -41,6 +41,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "tree-pretty-print.h"
 #include "parser.h"
 
+extern void extract_array_notation_exprs (tree, tree **, int *);
+extern tree fix_unary_array_notation_exprs (tree);
 struct pragma_simd_values local_simd_values;
 
 /* The lexer.  */
@@ -7636,6 +7638,7 @@  cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
 				 cp_id_kind * pidk)
 {
   tree expr;
+  tree new_expr;
 
   /* If the next token is the `throw' keyword, then we're looking at
      a throw-expression.  */
@@ -7679,16 +7682,15 @@  cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
 	      /* Check if expression is of type ARRAY_NOTATION_REF, if so then
 	       * break up an array notation expression correctly 
 	       */
-	      if (TREE_CODE (expr) == ARRAY_NOTATION_REF
-		  || TREE_CODE (rhs) == ARRAY_NOTATION_REF)
-		expr = build_x_array_notation_expr (expr, assignment_operator,
-						    rhs, tf_warning_or_error);
-	      else
-		/* Build the assignment expression.  */
+	      new_expr = build_x_array_notation_expr (expr, assignment_operator,
+						      rhs, tf_warning_or_error);
+	      if (!new_expr)
 		expr = build_x_modify_expr (expr,
 					    assignment_operator,
 					    rhs,
 					    tf_warning_or_error);
+	      else
+		expr = new_expr;
 	    }
 	}
     }
@@ -9121,7 +9123,8 @@  cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
   /* Consume the `}'.  */
   cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
 
-  compound_stmt = fix_conditional_array_notations (compound_stmt);
+  if (flag_enable_cilk)
+    compound_stmt = fix_array_notation_exprs (compound_stmt);
   return compound_stmt;
 }
 
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 9de4d67..a0f0e92 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4863,9 +4863,17 @@  cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
       cp_lvalue_kind kind = lvalue_kind (arg);
       if (kind == clk_none)
 	{
-	  if (complain & tf_error)
-	    lvalue_error (input_location, lv_addressof);
-	  return error_mark_node;
+	  /* If we are using array notation, we will fix it up at the end,
+	   * so right now, we just ignore this error
+	   */
+	  if (flag_enable_cilk && TREE_CODE (arg) == ARRAY_NOTATION_REF)
+	    ;
+	  else
+	    {
+	      if (complain & tf_error)
+		lvalue_error (input_location, lv_addressof);
+	      return error_mark_node;
+	    }
 	}
       if (strict_lvalue && (kind & (clk_rvalueref|clk_class)))
 	{
@@ -8423,7 +8431,12 @@  lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
 {
   cp_lvalue_kind kind = lvalue_kind (ref);
 
-  if (kind == clk_none)
+  if (flag_enable_cilk && TREE_CODE (ref) == ARRAY_NOTATION_REF)
+    /* IF we are using array notations then we will fix up later and not
+     * worry about it now
+     */
+    return 1;
+  else if (kind == clk_none)
     {
       if (complain & tf_error)
 	lvalue_error (input_location, use);
diff --git a/gcc/testsuite/ChangeLog.cilk b/gcc/testsuite/ChangeLog.cilk
index 80a004a..1071752 100644
--- a/gcc/testsuite/ChangeLog.cilk
+++ b/gcc/testsuite/ChangeLog.cilk
@@ -1,3 +1,13 @@ 
+2012-01-17  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+	* g++.dg/cilk-plus/array_notation_tests/predecr_test.cc: New.
+	* g++.dg/cilk-plus/array_notation_tests/preincr_test.cc: Likewise.
+	* g++.dg/cilk-plus/array_notation_tests/postdecr_test.cc: Likewise.
+	* g++.dg/cilk-plus/array_notation_tests/postincr_test.cc: Likewise.
+	* g++.dg/cilk-plus/array_notation_tests/func.cc: Likewise.
+	* g++.dg/cilk-plus/array_notation_tests/func_call.cc: Likewise.
+	* g++.dg/cilk-plus/cilk-plus.exp: Added HAVE_IO flag for compilation.
+
 2012-01-12  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
 	* g++.dg/cilk-plus/array_notation_tests/switch_test.cc: New
diff --git a/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/postdecr_test.cc b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/postdecr_test.cc
new file mode 100644
index 0000000..fc0955f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/postdecr_test.cc
@@ -0,0 +1,47 @@ 
+#if HAVE_IO
+#include <iostream>
+#include <cstdlib>
+#endif
+using namespace std;
+int main(int argc, char **argv)
+{
+  int array[10];
+
+  for (int ii = 0; ii < 10; ii++)
+    array[ii] = 0;
+
+  array[:] = 19383;
+
+  array[:]--;
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+  cout << endl;
+#endif
+
+  for (int ii = 0; ii < 10; ii++)
+    array[:]--;
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+  cout << endl;
+#endif
+
+  if (argc == 2)
+    array[0:10:1]--; 
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+  cout << endl;
+#endif
+  array[0:10/argc:argc]--; 
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+#endif
+  return 1;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/postincr_test.cc b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/postincr_test.cc
new file mode 100644
index 0000000..f6f0804
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/postincr_test.cc
@@ -0,0 +1,47 @@ 
+#if HAVE_IO
+#include <iostream>
+#include <cstdlib>
+#endif
+using namespace std;
+int main(int argc, char **argv)
+{
+  int array[10];
+
+  for (int ii = 0; ii < 10; ii++)
+    array[ii] = 0;
+
+  array[:] = 19383;
+
+  array[:]++;
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+  cout << endl;
+#endif
+
+  for (int ii = 0; ii < 10; ii++)
+    array[:]++;
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+  cout << endl;
+#endif
+
+  if (argc == 2)
+    array[0:10:1]++; 
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+  cout << endl;
+#endif
+  array[0:10/argc:argc]++; 
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+#endif
+  return 1;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/predecr_test.cc b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/predecr_test.cc
new file mode 100644
index 0000000..47696c7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/predecr_test.cc
@@ -0,0 +1,47 @@ 
+#if HAVE_IO
+#include <iostream>
+#include <cstdlib>
+#endif
+using namespace std;
+int main(int argc, char **argv)
+{
+  int array[10];
+
+  for (int ii = 0; ii < 10; ii++)
+    array[ii] = 0;
+
+  array[:] = 19383;
+
+  --array[:];
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+  cout << endl;
+#endif
+
+  for (int ii = 0; ii < 10; ii++)
+    --array[:];
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+  cout << endl;
+#endif
+
+  if (argc == 2)
+    --array[0:10:1]; 
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+  cout << endl;
+#endif
+  --array[0:10/argc:argc]; 
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+#endif
+  return 1;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/preincr_test.cc b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/preincr_test.cc
new file mode 100644
index 0000000..9a0b1fd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/preincr_test.cc
@@ -0,0 +1,47 @@ 
+#if HAVE_IO
+#include <iostream>
+#include <cstdlib>
+#endif
+using namespace std;
+int main(int argc, char **argv)
+{
+  int array[10];
+
+  for (int ii = 0; ii < 10; ii++)
+    array[ii] = 0;
+
+  array[:] = 19383;
+
+  ++array[:];
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+  cout << endl;
+#endif
+
+  for (int ii = 0; ii < 10; ii++)
+    ++array[:];
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+  cout << endl;
+#endif
+
+  if (argc == 2)
+    ++array[0:10:1];
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+  cout << endl;
+#endif
+  ++array[0:10/argc:argc]; 
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    cout << array[ii] << endl;
+#endif
+  return 1;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/cilk_plus.exp b/gcc/testsuite/g++.dg/cilk-plus/cilk_plus.exp
index 1fa67ce..33f10ae 100644
--- a/gcc/testsuite/g++.dg/cilk-plus/cilk_plus.exp
+++ b/gcc/testsuite/g++.dg/cilk-plus/cilk_plus.exp
@@ -23,6 +23,6 @@  dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] " -w -lcilkrts -ldl -
 dg-finish
 
 dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/array_notation_tests/*.cc]] " -O3 -ftree-vectorize" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/array_notation_tests/*.cc]] " -DHAVE_IO=1 -O3 -ftree-vectorize" " "
 
 dg-finish
diff --git a/gcc/testsuite/g++.dg/cilk-plus/func.cc b/gcc/testsuite/g++.dg/cilk-plus/func.cc
new file mode 100644
index 0000000..97511e3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/func.cc
@@ -0,0 +1,9 @@ 
+int funct (int x)
+{
+  x++;
+  return x;
+}
+int funct2 (int x, int y)
+{
+  return (x+y);
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/func_call.cc b/gcc/testsuite/g++.dg/cilk-plus/func_call.cc
new file mode 100644
index 0000000..5a67f5c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/func_call.cc
@@ -0,0 +1,100 @@ 
+#if HAVE_IO
+#include <iostream> 
+#endif
+
+extern int funct(int x);
+extern int funct2(int x, int y);
+extern void func_ptr (int *x);
+int main(int argc, char **argv)
+{
+  int array[10], array2[10], x = 0, y;
+  for (int ii = 0; ii < 10; ii++)
+    array[ii] = 0;
+
+  array[:]++;
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    array[0:10:1]++;
+#endif
+
+#if HAVE_IO
+  std::cout << "Before Function Call" << std::endl;
+  for (int ii = 0; ii < 10; ii++)
+    std::cout << array[ii] << std::endl;
+#endif
+
+  array2[:] = funct(array[:]);
+  
+#if HAVE_IO
+  std::cout << std::endl;
+  std::cout << "After Function Call" << std::endl;
+  for (int ii = 0; ii < 10; ii++)
+    std::cout << array2[ii] << std::endl;
+#endif
+
+  x += funct (array[:]);
+#if HAVE_IO
+  std::cout << "x (Just sum of all in After Function Call) = " << x 
+    << std::endl;
+#endif
+
+  x = 0;
+  x += funct (array[0:10:1]);
+#if HAVE_IO
+  std::cout << "x (Just sum of all in After Function Call) = " << x 
+    << std::endl;
+#endif
+
+  x = 0;
+  x += funct (array[0:10/argc:argc]);
+#if HAVE_IO
+  std::cout << "x (Just sum of all in After Function Call, if Argc == 1) = " 
+    << x << std::endl;
+#endif
+
+  x = 0;
+#if HAVE_IO
+  x = funct (funct(array[:]));
+  std::cout << "x (Just array[9]+1+1) = " << x << std::endl;
+#endif
+  array2[:] = funct (funct (funct (array[:])));
+
+#if HAVE_IO
+  std::cout << "After Function Call (must be array[x]+1+1+1" << std::endl;
+  for (int ii = 0; ii < 10; ii++)
+    std::cout << array2[ii] << std::endl;
+#endif
+  x = 0;
+  for (int ii = 0; ii < 10; ii++) 
+    x += funct (funct (funct (array[:])));
+
+#if HAVE_IO
+  std::cout << "x  (After 3 function calls in for loop 14 * 100) =  " << x <<
+    std::endl;
+#endif
+  x = 0;
+  for (int ii = 0; ii < 10; ii++)
+    x += funct (funct (funct (funct2 (array[:], array2[:]))));
+
+#if HAVE_IO
+  std::cout << 
+    "x  (After 4 different function calls in for loop ((11+14)+3) * 100) =  " << x <<
+    std::endl;
+#endif
+
+#if HAVE_IO
+  std::cout << std::endl;
+  std::cout << "Before adding every element by 1" << std::endl;
+  for (int ii = 0; ii < 10; ii++)
+    std::cout << array[ii] << std::endl;
+#endif
+
+  func_ptr (&array[:]);
+#if HAVE_IO
+  std::cout << std::endl;
+  std::cout << "After adding every element by 1" << std::endl;
+  for (int ii = 0; ii < 10; ii++)
+    std::cout << array[ii] << std::endl;
+#endif
+  return x;
+}