diff mbox

Replace dynamic arrays with vec_tree in Array Notation for C

Message ID BF230D13CA30DD48930C31D4099330003A43A852@FMSMSX101.amr.corp.intel.com
State New
Headers show

Commit Message

Iyer, Balaji V June 22, 2013, 12:50 a.m. UTC
Hello Richard et al.,
	As I mentioned in my previous email, I have changed all the dynamic array usage in the Array notation for C with vec_trees. I have also made them share the structures from Array Notation for C++. 
	In addition, I have replaced the cp_length_mismatch_in_expr_p from the C++ array notation with one in array-notation-common since the parameters will now match.

Is this OK for trunk? It is passing all the array notation tests in x86 and x86_64. It is also passing/failing all other tests as it is supposed to.

Here are the ChangeLog Entries:

gcc/c-family/ChangeLog
2013-06-21  Balaji V. Iyer  <balaji.v.iyer@intel.com>

        * array-notation-common.c (length_mismatch_in_expr): Changed the
        parameter type's from a dynamic array to a vec_tree.  Also removed
        the size parameters.
        * c-common.h (length_mismatch_in_expr_p): Fixed prototype's as per
        the change above.

gcc/cp/ChangeLog
2013-06-21  Balaji V. Iyer  <balaji.v.iyer@intel.com>

        * cp-array-notation.c (cp_length_mismatch_in_expr_p): Remove.
        (expand_an_in_modify_expr): Changed a function call from the above
        removed function to length_mismatch_in_expr_p.

gcc/c/ChangeLog
2013-06-21  Balaji V. Iyer  <balaji.v.iyer@intel.com>

        * c-array-notation.c (make_triplet_val_inv): New function.
        (create_cmp_incr): Likewise.
        (create_array_refs): Likewise.
        (fix_builtin_array_notation_fn): Replaced all mallocs with tree vec.
        Also modularized common parts between functions and called the function.
        (build_array_notation_expr): Likewise.
        (fix_conditional_array_notations_1): Likewise.
        (fix_array_notation_expr): Likewise.
        (fix_array_notation_call_expr): Likewise.


Thanks,

Balaji V. Iyer.

Comments

Richard Henderson June 25, 2013, 2:33 p.m. UTC | #1
On 06/21/2013 05:50 PM, Iyer, Balaji V wrote:
> Hello Richard et al.,
> 	As I mentioned in my previous email, I have changed all the dynamic array usage in the Array notation for C with vec_trees. I have also made them share the structures from Array Notation for C++. 
> 	In addition, I have replaced the cp_length_mismatch_in_expr_p from the C++ array notation with one in array-notation-common since the parameters will now match.
> 
> Is this OK for trunk? It is passing all the array notation tests in x86 and x86_64. It is also passing/failing all other tests as it is supposed to.
> 
> Here are the ChangeLog Entries:
> 
> gcc/c-family/ChangeLog
> 2013-06-21  Balaji V. Iyer  <balaji.v.iyer@intel.com>
> 
>         * array-notation-common.c (length_mismatch_in_expr): Changed the
>         parameter type's from a dynamic array to a vec_tree.  Also removed
>         the size parameters.
>         * c-common.h (length_mismatch_in_expr_p): Fixed prototype's as per
>         the change above.
> 
> gcc/cp/ChangeLog
> 2013-06-21  Balaji V. Iyer  <balaji.v.iyer@intel.com>
> 
>         * cp-array-notation.c (cp_length_mismatch_in_expr_p): Remove.
>         (expand_an_in_modify_expr): Changed a function call from the above
>         removed function to length_mismatch_in_expr_p.
> 
> gcc/c/ChangeLog
> 2013-06-21  Balaji V. Iyer  <balaji.v.iyer@intel.com>
> 
>         * c-array-notation.c (make_triplet_val_inv): New function.
>         (create_cmp_incr): Likewise.
>         (create_array_refs): Likewise.
>         (fix_builtin_array_notation_fn): Replaced all mallocs with tree vec.
>         Also modularized common parts between functions and called the function.
>         (build_array_notation_expr): Likewise.
>         (fix_conditional_array_notations_1): Likewise.
>         (fix_array_notation_expr): Likewise.
>         (fix_array_notation_call_expr): Likewise.
> 
> 
> Thanks,
> 
> Balaji V. Iyer. 
> 

Ok.


r~
diff mbox

Patch

diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 224e27b..788994f 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,11 @@ 
+2013-06-21  Balaji V. Iyer  <balaji.v.iyer@intel.com>  
+
+	* array-notation-common.c (length_mismatch_in_expr): Changed the
+	parameter type's from a dynamic array to a vec_tree.  Also removed
+	the size parameters.
+	* c-common.h (length_mismatch_in_expr_p): Fixed prototype's as per
+	the change above.
+
 2013-06-21  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
 	* c-common.h (struct cilkplus_an_parts): New structure.
diff --git a/gcc/c-family/array-notation-common.c b/gcc/c-family/array-notation-common.c
old mode 100644
new mode 100755
index 0e2a431..8eab89b
--- a/gcc/c-family/array-notation-common.c
+++ b/gcc/c-family/array-notation-common.c
@@ -75,35 +75,37 @@  extract_sec_implicit_index_arg (location_t location, tree fn)
   return return_int;
 }
 
-/* Returns true if there is length mismatch among expressions
-   on the same dimension and on the same side of the equal sign.  The
-   expressions (or ARRAY_NOTATION lengths) are passed in through 2-D array
-   **LIST where X and Y indicate first and second dimension sizes of LIST,
-   respectively.  */
+/* Returns true if there is a length mismatch among exprssions that are at the
+   same dimension and one the same side of the equal sign.  The Array notation
+   lengths (LIST->LENGTH) is passed in as a 2D vector of trees.  */
 
 bool
-length_mismatch_in_expr_p (location_t loc, tree **list, size_t x, size_t y)
+length_mismatch_in_expr_p (location_t loc, vec<vec<an_parts> >list)
 {
   size_t ii, jj;
-  tree start = NULL_TREE;
-  HOST_WIDE_INT l_start, l_node;
+  tree length = NULL_TREE;
+  HOST_WIDE_INT l_length, l_node;
+  
+  size_t x = list.length ();
+  size_t y = list[0].length ();
+  
   for (jj = 0; jj < y; jj++)
     {
-      start = NULL_TREE;
+      length = NULL_TREE;
       for (ii = 0; ii < x; ii++)
 	{
-	  if (!start)
-	    start = list[ii][jj];
-	  else if (TREE_CODE (start) == INTEGER_CST)
+	  if (!length)
+	    length = list[ii][jj].length;
+	  else if (TREE_CODE (length) == INTEGER_CST)
 	    {
-	      /* If start is a INTEGER, and list[ii][jj] is an integer then
+	      /* If length is a INTEGER, and list[ii][jj] is an integer then
 		 check if they are equal.  If they are not equal then return
 		 true.  */
-	      if (TREE_CODE (list[ii][jj]) == INTEGER_CST)
+	      if (TREE_CODE (list[ii][jj].length) == INTEGER_CST)
 		{
-		  l_node = int_cst_value (list[ii][jj]);
-		  l_start = int_cst_value (start);
-		  if (absu_hwi (l_start) != absu_hwi (l_node))
+		  l_node = int_cst_value (list[ii][jj].length);
+		  l_length = int_cst_value (length);
+		  if (absu_hwi (l_length) != absu_hwi (l_node))
 		    {
 		      error_at (loc, "length mismatch in expression");
 		      return true;
@@ -111,9 +113,9 @@  length_mismatch_in_expr_p (location_t loc, tree **list, size_t x, size_t y)
 		}
 	    }
 	  else
-	    /* We set the start node as the current node just in case it turns
+	    /* We set the length node as the current node just in case it turns
 	       out to be an integer.  */
-	    start = list[ii][jj];
+	    length = list[ii][jj].length;
 	}
     }
   return false;
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
old mode 100644
new mode 100755
index 95d3ccf..625c301
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1193,7 +1193,7 @@  extern bool contains_array_notation_expr (tree);
 extern tree expand_array_notation_exprs (tree);
 extern tree fix_conditional_array_notations (tree);
 extern tree find_correct_array_notation_type (tree);
-extern bool length_mismatch_in_expr_p (location_t, tree **, size_t, size_t);
+extern bool length_mismatch_in_expr_p (location_t, vec<vec<an_parts> >);
 extern enum built_in_function is_cilkplus_reduce_builtin (tree);
 extern bool find_rank (location_t, tree, tree, bool, size_t *);
 extern void extract_array_notation_exprs (tree, bool, vec<tree, va_gc> **);
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
old mode 100644
new mode 100755
index 05766ca..313fa7e
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,15 @@ 
+2013-06-21  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+	* c-array-notation.c (make_triplet_val_inv): New function.
+	(create_cmp_incr): Likewise.
+	(create_array_refs): Likewise.
+	(fix_builtin_array_notation_fn): Replaced all mallocs with tree vec.
+	Also modularized common parts between functions and called the function.
+	(build_array_notation_expr): Likewise.
+	(fix_conditional_array_notations_1): Likewise.
+	(fix_array_notation_expr): Likewise.
+	(fix_array_notation_call_expr): Likewise.
+
 2013-06-18  Marek Polacek  <polacek@redhat.com>
 
 	PR c/57630
diff --git a/gcc/c/c-array-notation.c b/gcc/c/c-array-notation.c
old mode 100644
new mode 100755
index 03b66b9..7788f7b
--- a/gcc/c/c-array-notation.c
+++ b/gcc/c/c-array-notation.c
@@ -74,6 +74,83 @@ 
 #include "opts.h"
 #include "c-family/c-common.h"
 
+/* If *VALUE is not of type INTEGER_CST, PARM_DECL or VAR_DECL, then map it
+   to a variable and then set *VALUE to the new variable.  */
+
+static inline void
+make_triplet_val_inv (location_t loc, tree *value)
+{
+  tree var, new_exp;
+  if (TREE_CODE (*value) != INTEGER_CST
+      && TREE_CODE (*value) != PARM_DECL
+      && TREE_CODE (*value) != VAR_DECL)
+    {
+      var = build_decl (loc, VAR_DECL, NULL_TREE, integer_type_node);
+      new_exp = build_modify_expr (loc, var, TREE_TYPE (var), NOP_EXPR, loc,
+				   *value, TREE_TYPE (*value));
+      add_stmt (new_exp);
+      *value = var;
+    }
+}
+
+/* Populates the INCR and CMP vectors with the increment (of type POSTINCREMENT
+   or POSTDECREMENT) and comparison (of TYPE GT_EXPR or LT_EXPR) expressions,
+   using data from LENGTH, COUNT_DOWN, and VAR.  INCR and CMP vectors are of
+   size RANK.  */
+
+static void
+create_cmp_incr (location_t loc, vec<an_loop_parts> *node, size_t rank,
+		 vec<vec<an_parts> > an_info)
+{
+  for (size_t ii = 0; ii < rank; ii++)
+    {
+      tree var = (*node)[ii].var;
+      tree length = an_info[0][ii].length;
+      (*node)[ii].incr = build_unary_op (loc, POSTINCREMENT_EXPR, var, 0);
+      (*node)[ii].cmp = build2 (LT_EXPR, boolean_type_node, var, length);
+    }
+}
+
+/* Returns a vector of size RANK that contains an array ref that is derived from
+   array notation triplet parameters stored in VALUE, START, STRIDE.  IS_VECTOR
+   is used to check if the data stored at its corresponding location is an
+   array notation. VAR is the induction variable passed in by the caller.
+
+   For example: For an array notation A[5:10:2], the vector start  will be
+   of size 1 holding '5', stride of same size as start but holding the value of
+   as 2, is_vector as true and count_down as false. Let's assume VAR is 'x'
+   This function returns a vector of size 1 with the following data:
+   A[5 + (x * 2)] .
+*/
+
+static vec<tree, va_gc> *
+create_array_refs (location_t loc, vec<vec<an_parts> > an_info,
+		   vec<an_loop_parts> an_loop_info, size_t size, size_t rank)
+{
+  tree ind_mult, ind_incr;
+  vec<tree, va_gc> *array_operand = NULL;
+  for (size_t ii = 0; ii < size; ii++)
+    if (an_info[ii][0].is_vector)
+      {
+	tree array_opr = an_info[ii][rank - 1].value;
+	for (int s_jj = rank - 1; s_jj >= 0; s_jj--)
+	  {
+	    tree var = an_loop_info[s_jj].var;
+	    tree stride = an_info[ii][s_jj].stride;
+	    tree start = an_info[ii][s_jj].start;
+	    ind_mult = build2 (MULT_EXPR, TREE_TYPE (var), var, stride);
+	    ind_incr = build2 (PLUS_EXPR, TREE_TYPE (var), start, ind_mult);
+	    array_opr = build_array_ref (loc, array_opr, ind_incr);
+	  }
+	vec_safe_push (array_operand, array_opr);
+      }
+    else
+      /* This is just a dummy node to make sure both the list sizes for both
+	 array list and array operand list are the same.  */
+      vec_safe_push (array_operand, integer_one_node);
+  return array_operand;
+}		     
+  
 /* Replaces all the scalar expressions in *NODE.  Returns a STATEMENT_LIST that
    holds the NODE along with variables that holds the results of the invariant
    expressions.  */
@@ -124,16 +201,13 @@  fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
   tree new_yes_list, new_cond_expr, new_var_init = NULL_TREE;
   tree new_exp_init = NULL_TREE;
   vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
-  size_t list_size = 0, rank = 0, ii = 0, jj = 0;
-  int s_jj = 0;
-  tree **array_ops, *array_var, jj_tree, loop_init, array_op0;
-  tree **array_value, **array_stride, **array_length, **array_start;
-  tree *compare_expr, *expr_incr, *ind_init;
+  size_t list_size = 0, rank = 0, ii = 0;
+  tree loop_init, array_op0;
   tree identity_value = NULL_TREE, call_fn = NULL_TREE, new_call_expr, body;
-  bool **count_down, **array_vector;
   location_t location = UNKNOWN_LOCATION;
   tree loop_with_init = alloc_stmt_list ();
-  
+  vec<vec<an_parts> > an_info = vNULL;
+  vec<an_loop_parts> an_loop_info = vNULL;
   enum built_in_function an_type =
     is_cilkplus_reduce_builtin (CALL_EXPR_FN (an_builtin_fn));
   if (an_type == BUILT_IN_NONE)
@@ -201,157 +275,27 @@  fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
     default:
       gcc_unreachable (); 
     }
-  
-  array_ops = XNEWVEC (tree *, list_size);
-  for (ii = 0; ii < list_size; ii++)
-    array_ops[ii] = XNEWVEC (tree, rank);
-  
-  array_vector = XNEWVEC (bool *, list_size);
-  for (ii = 0; ii < list_size; ii++)
-    array_vector[ii] = XNEWVEC (bool, rank);
-
-  array_value = XNEWVEC (tree *, list_size);
-  array_stride = XNEWVEC (tree *, list_size);
-  array_length = XNEWVEC (tree *, list_size);
-  array_start = XNEWVEC (tree *, list_size);
-
-  for (ii = 0; ii < list_size; ii++)
-    {
-      array_value[ii]  = XNEWVEC (tree, rank);
-      array_stride[ii] = XNEWVEC (tree, rank);
-      array_length[ii] = XNEWVEC (tree, rank);
-      array_start[ii]  = XNEWVEC (tree, rank);
-    }
-
-  compare_expr = XNEWVEC (tree, rank);
-  expr_incr = XNEWVEC (tree,  rank);
-  ind_init = XNEWVEC (tree, rank);
-  
-  count_down = XNEWVEC (bool *, list_size);
-  for (ii = 0; ii < list_size; ii++)
-    count_down[ii] = XNEWVEC (bool,  rank);
-  
-  array_var = XNEWVEC (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++)
-    {
-      tree array_node = (*array_list)[ii];
-      if (TREE_CODE (array_node) == 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] =
-		    fold_build1 (CONVERT_EXPR, integer_type_node,
-				 ARRAY_NOTATION_LENGTH (array_ops[ii][jj]));
-		  array_stride[ii][jj] =
-		    fold_build1 (CONVERT_EXPR, integer_type_node,
-				 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;
-	    }
-	}
-    }
 
+  an_loop_info.safe_grow_cleared (rank);
+  cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
   loop_init = alloc_stmt_list ();
 
   for (ii = 0; ii < rank; ii++)
     {
-      array_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
+      an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
 				  integer_type_node);
-      ind_init[ii] =
-	build_modify_expr (location, array_var[ii],
-			   TREE_TYPE (array_var[ii]), NOP_EXPR,
+      an_loop_info[ii].ind_init =
+	build_modify_expr (location, an_loop_info[ii].var,
+			   TREE_TYPE (an_loop_info[ii].var), NOP_EXPR,
 			   location,
-			   build_int_cst (TREE_TYPE (array_var[ii]), 0),
-			   TREE_TYPE (array_var[ii]));	
-    }
-  for (ii = 0; ii < list_size; ii++)
-    {
-      if (array_vector[ii][0])
-	{
-	  tree array_opr_node  = array_value[ii][rank - 1];
-	  for (s_jj = rank - 1; s_jj >= 0; s_jj--)
-	    {
-	      if (count_down[ii][s_jj])
-		{
-		  /* Array[start_index - (induction_var * stride)] */
-		  array_opr_node = build_array_ref
-		    (location, array_opr_node,
-		     build2 (MINUS_EXPR, TREE_TYPE (array_var[s_jj]),
-			     array_start[ii][s_jj],
-			     build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
-				     array_var[s_jj], array_stride[ii][s_jj])));
-		}
-	      else
-		{
-		  /* Array[start_index + (induction_var * stride)] */
-		  array_opr_node = build_array_ref
-		    (location, array_opr_node,
-		     build2 (PLUS_EXPR, TREE_TYPE (array_var[s_jj]),
-			     array_start[ii][s_jj],
-			     build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
-				     array_var[s_jj], array_stride[ii][s_jj])));
-		}
-	    }
-	  vec_safe_push (array_operand, array_opr_node);
-	}
-      else
-	/* This is just a dummy node to make sure the list sizes for both
-	   array list and array operand list are the same.  */
-	vec_safe_push (array_operand, integer_one_node);
+			   build_int_cst (TREE_TYPE (an_loop_info[ii].var), 0),
+			   TREE_TYPE (an_loop_info[ii].var));	
     }
+  array_operand = create_array_refs (location, an_info, an_loop_info,
+				     list_size, rank);
   replace_array_notations (&func_parm, true, array_list, array_operand);
-  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]);
-	}
-    }
 
+  create_cmp_incr (location, &an_loop_info, rank, an_info);
   if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
     {
       *new_var = build_decl (location, VAR_DECL, NULL_TREE, new_var_type);
@@ -519,7 +463,7 @@  fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
 	{
 	  new_yes_ind = build_modify_expr
 	    (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
-	     location, array_var[0], TREE_TYPE (array_var[0]));
+	     location, an_loop_info[0].var, TREE_TYPE (an_loop_info[0].var));
 	  new_yes_expr = build_modify_expr
 	    (location, array_ind_value, TREE_TYPE (array_ind_value),
 	     NOP_EXPR,
@@ -569,7 +513,7 @@  fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
 	{
 	  new_yes_ind = build_modify_expr
 	    (location, *new_var, TREE_TYPE (*new_var), NOP_EXPR,
-	     location, array_var[0], TREE_TYPE (array_var[0]));
+	     location, an_loop_info[0].var, TREE_TYPE (an_loop_info[0].var));
 	  new_yes_expr = build_modify_expr
 	    (location, array_ind_value, TREE_TYPE (array_ind_value),
 	     NOP_EXPR,
@@ -619,7 +563,7 @@  fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
     }
 
   for (ii = 0; ii < rank; ii++)
-    append_to_statement_list (ind_init [ii], &loop_init);
+    append_to_statement_list (an_loop_info[ii].ind_init, &loop_init);
 
   if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
       || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
@@ -632,33 +576,14 @@  fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
   for (ii = 0; ii < rank; ii++)
     {
       tree new_loop = push_stmt_list ();
-      c_finish_loop (location, compare_expr[ii], expr_incr[ii], body, NULL_TREE,
-		     NULL_TREE, true);
+      c_finish_loop (location, an_loop_info[ii].cmp, an_loop_info[ii].incr,
+		     body, NULL_TREE, NULL_TREE, true);
       body = pop_stmt_list (new_loop);
     }
   append_to_statement_list_force (body, &loop_with_init);
-  
-  XDELETEVEC (compare_expr);
-  XDELETEVEC (expr_incr);
-  XDELETEVEC (ind_init);
-  XDELETEVEC (array_var);  
-  for (ii = 0; ii < list_size; ii++)
-    {
-      XDELETEVEC (count_down[ii]);
-      XDELETEVEC (array_value[ii]);
-      XDELETEVEC (array_stride[ii]);
-      XDELETEVEC (array_length[ii]);
-      XDELETEVEC (array_start[ii]);
-      XDELETEVEC (array_ops[ii]);
-      XDELETEVEC (array_vector[ii]);
-    }
-  XDELETEVEC (count_down);
-  XDELETEVEC (array_value);
-  XDELETEVEC (array_stride);
-  XDELETEVEC (array_length);
-  XDELETEVEC (array_start);
-  XDELETEVEC (array_ops);
-  XDELETEVEC (array_vector);
+
+  an_info.release ();
+  an_loop_info.release ();
   
   return loop_with_init;
 }
@@ -674,31 +599,22 @@  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, found_builtin_fn = false;
-  tree **lhs_array = NULL, **rhs_array = NULL;
+  bool found_builtin_fn = false;
   tree array_expr_lhs = NULL_TREE, array_expr_rhs = NULL_TREE;
   tree array_expr = NULL_TREE;
-  tree **lhs_value = NULL, **rhs_value = NULL;
-  tree **lhs_stride = NULL, **lhs_length = NULL, **lhs_start = NULL;
-  tree **rhs_stride = NULL, **rhs_length = NULL, **rhs_start = NULL;
-  tree an_init = NULL_TREE, *lhs_var = NULL, *rhs_var = NULL;
-  tree *cond_expr = NULL;
+  tree an_init = NULL_TREE;
+  vec<tree> cond_expr = vNULL;
   tree body, loop_with_init = alloc_stmt_list();
   tree scalar_mods = NULL_TREE;
-  tree *lhs_expr_incr = NULL, *rhs_expr_incr = NULL;
-  tree *lhs_ind_init = NULL, *rhs_ind_init = NULL;
-  bool **lhs_count_down = NULL, **rhs_count_down = NULL;
-  tree *lhs_compare = NULL, *rhs_compare = NULL;
   vec<tree, va_gc> *rhs_array_operand = NULL, *lhs_array_operand = NULL;
   size_t lhs_rank = 0, rhs_rank = 0;
-  size_t ii = 0, jj = 0;
-  int s_jj = 0;
-  tree ii_tree = NULL_TREE, new_modify_expr;
+  size_t ii = 0;
   vec<tree, va_gc> *lhs_list = NULL, *rhs_list = NULL;
-  tree new_var = NULL_TREE, builtin_loop = NULL_TREE;
-  tree begin_var, lngth_var, strde_var;
-  size_t rhs_list_size = 0, lhs_list_size = 0;
-
+  tree new_modify_expr, new_var = NULL_TREE, builtin_loop = NULL_TREE;
+  size_t rhs_list_size = 0, lhs_list_size = 0; 
+  vec<vec<an_parts> > lhs_an_info = vNULL, rhs_an_info = vNULL;
+  vec<an_loop_parts> lhs_an_loop_info = vNULL, rhs_an_loop_info = vNULL;
+  
   /* If either of this is true, an error message must have been send out
      already.  Not necessary to send out multiple error messages.  */
   if (lhs == error_mark_node || rhs == error_mark_node)
@@ -810,296 +726,49 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
   /* Here we assign the array notation components to variable so that we can
      satisfy the exec once rule.  */
   for (ii = 0; ii < lhs_list_size; ii++)
-    {
+    { 
       tree array_node = (*lhs_list)[ii];
-      tree array_begin = ARRAY_NOTATION_START (array_node);
-      tree array_lngth = ARRAY_NOTATION_LENGTH (array_node);
-      tree array_strde = ARRAY_NOTATION_STRIDE (array_node);
-
-      if (TREE_CODE (array_begin) != INTEGER_CST)
-	{
-	  begin_var = build_decl (location, VAR_DECL, NULL_TREE,
-				  integer_type_node);
-	  add_stmt (build_modify_expr (location, begin_var,
-				       TREE_TYPE (begin_var),
-				       NOP_EXPR, location, array_begin,
-				       TREE_TYPE (array_begin)));      
-	  ARRAY_NOTATION_START (array_node) = begin_var;
-	}
-
-      if (TREE_CODE (array_lngth) != INTEGER_CST)
-	{
-	  lngth_var = build_decl (location, VAR_DECL, NULL_TREE,
-				  integer_type_node);
-	  add_stmt (build_modify_expr (location, lngth_var,
-				       TREE_TYPE (lngth_var),
-				       NOP_EXPR, location, array_lngth,
-				       TREE_TYPE (array_lngth)));
-	  ARRAY_NOTATION_LENGTH (array_node) = lngth_var;
-	}
-      if (TREE_CODE (array_strde) != INTEGER_CST)
-	{
-	  strde_var = build_decl (location, VAR_DECL, NULL_TREE,
-				  integer_type_node);
-
-	  add_stmt (build_modify_expr (location, strde_var,
-				       TREE_TYPE (strde_var),
-				       NOP_EXPR, location, array_strde,
-				       TREE_TYPE (array_strde)));
-	  ARRAY_NOTATION_STRIDE (array_node) = strde_var;
-	}
-    }
-  for (ii = 0; ii < rhs_list_size; ii++)
-    {
-      tree array_node = (*rhs_list)[ii];
-      if (array_node && TREE_CODE (array_node) == ARRAY_NOTATION_REF)
-	{
-	  tree array_begin = ARRAY_NOTATION_START (array_node);
-	  tree array_lngth = ARRAY_NOTATION_LENGTH (array_node);
-	  tree array_strde = ARRAY_NOTATION_STRIDE (array_node);
-
-	  if (TREE_CODE (array_begin) != INTEGER_CST)
-	    {
-	      begin_var = build_decl (location, VAR_DECL, NULL_TREE,
-				      integer_type_node);
-	      add_stmt (build_modify_expr (location, begin_var,
-					   TREE_TYPE (begin_var),
-					   NOP_EXPR, location, array_begin,
-					   TREE_TYPE (array_begin)));
-	      ARRAY_NOTATION_START (array_node) = begin_var;
-	    }
-	  if (TREE_CODE (array_lngth) != INTEGER_CST)
-	    {
-	      lngth_var = build_decl (location, VAR_DECL, NULL_TREE,
-				      integer_type_node);
-	      add_stmt (build_modify_expr (location, lngth_var,
-					   TREE_TYPE (lngth_var),
-					   NOP_EXPR, location, array_lngth,
-					   TREE_TYPE (array_lngth)));
-	      ARRAY_NOTATION_LENGTH (array_node) = lngth_var;
-	    }
-	  if (TREE_CODE (array_strde) != INTEGER_CST)
-	    {
-	      strde_var = build_decl (location, VAR_DECL, NULL_TREE,
-				      integer_type_node);
-
-	      add_stmt (build_modify_expr (location, strde_var,
-					   TREE_TYPE (strde_var),
-					   NOP_EXPR, location, array_strde,
-					   TREE_TYPE (array_strde)));
-	      ARRAY_NOTATION_STRIDE (array_node) = strde_var;
-	    }
-	}
+      make_triplet_val_inv (location, &ARRAY_NOTATION_START (array_node));
+      make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (array_node));
+      make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (array_node));
     }
-  
-  lhs_vector = XNEWVEC (bool *, lhs_list_size);
-  for (ii = 0; ii < lhs_list_size; ii++)
-    lhs_vector[ii] = XNEWVEC (bool, lhs_rank);
-  
-  rhs_vector = XNEWVEC (bool *, rhs_list_size);
-  for (ii = 0; ii < rhs_list_size; ii++)
-    rhs_vector[ii] = XNEWVEC (bool, rhs_rank);
-  
-  lhs_array = XNEWVEC (tree *, lhs_list_size);
-  for (ii = 0; ii < lhs_list_size; ii++)
-    lhs_array[ii] = XNEWVEC (tree, lhs_rank);
-  
-  rhs_array = XNEWVEC (tree *, rhs_list_size);
-  for (ii = 0; ii < rhs_list_size; ii++)
-    rhs_array[ii] = XNEWVEC (tree, rhs_rank);
-
-  lhs_value = XNEWVEC (tree *, lhs_list_size);
-  for (ii = 0; ii < lhs_list_size; ii++)
-    lhs_value[ii] = XNEWVEC (tree, lhs_rank);
-  
-  rhs_value = XNEWVEC (tree *, rhs_list_size);
-  for (ii = 0; ii < rhs_list_size; ii++)
-    rhs_value[ii] = XNEWVEC (tree, rhs_rank);
-
-  lhs_stride = XNEWVEC (tree *, lhs_list_size);
-  for (ii = 0; ii < lhs_list_size; ii++)
-    lhs_stride[ii] = XNEWVEC (tree, lhs_rank);
-  
-  rhs_stride = XNEWVEC (tree *, rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
-    rhs_stride[ii] = XNEWVEC (tree, rhs_rank);
-
-  lhs_length = XNEWVEC (tree *, lhs_list_size);
-  for (ii = 0; ii < lhs_list_size; ii++)
-    lhs_length[ii] = XNEWVEC (tree, lhs_rank);
-  
-  rhs_length = XNEWVEC (tree *, rhs_list_size);
-  for (ii = 0; ii < rhs_list_size; ii++)
-    rhs_length[ii] = XNEWVEC (tree, rhs_rank);
-  
-  lhs_start = XNEWVEC (tree *, lhs_list_size);
-  for (ii = 0; ii < lhs_list_size; ii++)
-    lhs_start[ii] = XNEWVEC (tree, lhs_rank);
-  
-  rhs_start = XNEWVEC (tree *, rhs_list_size);
-  for (ii = 0; ii < rhs_list_size; ii++)
-    rhs_start[ii] = XNEWVEC (tree, rhs_rank);
-
-  lhs_var = XNEWVEC (tree, lhs_rank);
-  rhs_var = XNEWVEC (tree, rhs_rank);
-  cond_expr = XNEWVEC (tree, MAX (lhs_rank, rhs_rank));
-
-  lhs_expr_incr = XNEWVEC (tree, lhs_rank);
-  rhs_expr_incr =XNEWVEC (tree, rhs_rank);
-
-  lhs_ind_init = XNEWVEC (tree, lhs_rank);
-  rhs_ind_init = XNEWVEC (tree, rhs_rank);
-
-  lhs_count_down = XNEWVEC (bool *, lhs_list_size);
-  for (ii = 0; ii < lhs_list_size; ii++)
-    lhs_count_down[ii] =  XNEWVEC (bool, lhs_rank);
+    if ((*rhs_list)[ii] && TREE_CODE ((*rhs_list)[ii]) == ARRAY_NOTATION_REF)
+      {  
+	tree array_node = (*rhs_list)[ii];
+	make_triplet_val_inv (location, &ARRAY_NOTATION_START (array_node));
+	make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (array_node));
+	make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (array_node));
+      }
   
-  rhs_count_down =  XNEWVEC (bool *, rhs_list_size);
-  for (ii = 0; ii < rhs_list_size; ii++)
-    rhs_count_down[ii] = XNEWVEC (bool, rhs_rank);
+  cond_expr.safe_grow_cleared (MAX (lhs_rank, rhs_rank));
 
-  lhs_compare =  XNEWVEC (tree, lhs_rank);
-  rhs_compare =  XNEWVEC (tree, rhs_rank);
-  
-  if (lhs_rank)
-    {
-      for (ii = 0; ii < lhs_list_size; ii++)
-	{
-	  jj = 0;
-	  ii_tree = (*lhs_list)[ii];
-	  while (ii_tree)
-	    {
-	      if (TREE_CODE (ii_tree) == ARRAY_NOTATION_REF)
-		{
-		  lhs_array[ii][jj] = ii_tree;
-		  jj++;
-		  ii_tree = ARRAY_NOTATION_ARRAY (ii_tree);
-		}
-	      else if (TREE_CODE (ii_tree) == ARRAY_REF)
-		ii_tree = TREE_OPERAND (ii_tree, 0);
-	      else if (TREE_CODE (ii_tree) == VAR_DECL
-		       || TREE_CODE (ii_tree) == PARM_DECL)
-		break;
-	    }
-	}
-    }
-  else
-    lhs_array[0][0] = NULL_TREE;
-  
+  lhs_an_loop_info.safe_grow_cleared (lhs_rank);
   if (rhs_rank)
-    {
-      for (ii = 0; ii < rhs_list_size; ii++)
-	{ 
-	  jj = 0; 
-	  ii_tree = (*rhs_list)[ii];
-	  while (ii_tree)
-	    {
-	      if (TREE_CODE (ii_tree) == ARRAY_NOTATION_REF)
-		{
-		  rhs_array[ii][jj] = ii_tree;
-		  jj++;
-		  ii_tree = ARRAY_NOTATION_ARRAY (ii_tree);
-		}
-	      else if (TREE_CODE (ii_tree) == ARRAY_REF)
-		ii_tree = TREE_OPERAND (ii_tree, 0);
-	      else if (TREE_CODE (ii_tree) == VAR_DECL
-		       || TREE_CODE (ii_tree) == PARM_DECL
-		       || TREE_CODE (ii_tree) == CALL_EXPR)
-		break;
-	    }
-	}
-    }
+    rhs_an_loop_info.safe_grow_cleared (rhs_rank);
 
-  for (ii = 0; ii < lhs_list_size; ii++)
-    {
-      tree lhs_node = (*lhs_list)[ii];
-      if (TREE_CODE (lhs_node) == ARRAY_NOTATION_REF)
-	{
-	  for (jj = 0; jj < lhs_rank; jj++)
-	    {
-	      if (TREE_CODE (lhs_array[ii][jj]) == ARRAY_NOTATION_REF)
-		{
-		  lhs_value[ii][jj] = ARRAY_NOTATION_ARRAY (lhs_array[ii][jj]);
-		  lhs_start[ii][jj] = ARRAY_NOTATION_START (lhs_array[ii][jj]);
-		  lhs_length[ii][jj] =
-		    fold_build1 (CONVERT_EXPR, integer_type_node,
-				 ARRAY_NOTATION_LENGTH (lhs_array[ii][jj]));
-		  lhs_stride[ii][jj] =
-		    fold_build1 (CONVERT_EXPR, integer_type_node,
-				 ARRAY_NOTATION_STRIDE (lhs_array[ii][jj]));
-		  lhs_vector[ii][jj] = true;
-		  /* IF the stride value is variable (i.e. not constant) then 
-		     assume that the length is positive.  */
-		  if (!TREE_CONSTANT (lhs_length[ii][jj]))
-		    lhs_count_down[ii][jj] = false;
-		  else if (tree_int_cst_lt
-			   (lhs_length[ii][jj],
-			    build_zero_cst (TREE_TYPE (lhs_length[ii][jj]))))
-		    lhs_count_down[ii][jj] = true;
-		  else
-		    lhs_count_down[ii][jj] = false;
-		}
-	      else
-		lhs_vector[ii][jj] = false;
-	    }
-	}
-    }
-  for (ii = 0; ii < rhs_list_size; ii++)
+  cilkplus_extract_an_triplets (lhs_list, lhs_list_size, lhs_rank,
+				&lhs_an_info);
+  if (rhs_rank)
     {
-      if (TREE_CODE ((*rhs_list)[ii]) == ARRAY_NOTATION_REF)
-	{
-	  for (jj = 0; jj < rhs_rank; jj++)
-	    {
-	      if (TREE_CODE (rhs_array[ii][jj]) == ARRAY_NOTATION_REF)
-		{
-		  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] =
-		    fold_build1 (CONVERT_EXPR, integer_type_node,
-				 ARRAY_NOTATION_LENGTH (rhs_array[ii][jj]));
-		  rhs_stride[ii][jj] =
-		    fold_build1 (CONVERT_EXPR, integer_type_node,
-				 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.  */
-		  if (!TREE_CONSTANT (rhs_length[ii][jj]))
-		    rhs_count_down[ii][jj] = false;
-		  else if (tree_int_cst_lt
-			   (rhs_length[ii][jj],
-			    build_int_cst (TREE_TYPE (rhs_length[ii][jj]), 0)))
-		    rhs_count_down[ii][jj] = true;
-		  else
-		    rhs_count_down[ii][jj] = false;	
-		}
-	      else
-		rhs_vector[ii][jj] = false;
-	    }
-	}
-      else
-	for (jj = 0; jj < rhs_rank; jj++)
-	  { 
-	    rhs_vector[ii][jj] = false;
-	    rhs_length[ii][jj] = NULL_TREE;
-	  }
+      rhs_an_loop_info.safe_grow_cleared (rhs_rank);
+      cilkplus_extract_an_triplets (rhs_list, rhs_list_size, rhs_rank,
+				    &rhs_an_info);
     }
-
-  if (length_mismatch_in_expr_p (EXPR_LOCATION (lhs), lhs_length,
-				 lhs_list_size, lhs_rank)
-      || length_mismatch_in_expr_p (EXPR_LOCATION (rhs), rhs_length,
-				    rhs_list_size, rhs_rank))
+  if (length_mismatch_in_expr_p (EXPR_LOCATION (lhs), lhs_an_info)
+      || (rhs_rank
+	  && length_mismatch_in_expr_p (EXPR_LOCATION (rhs), rhs_an_info)))
     {
       pop_stmt_list (an_init);
       return error_mark_node;
     }
-
   if (lhs_list_size > 0 && rhs_list_size > 0 && lhs_rank > 0 && rhs_rank > 0
-      && TREE_CODE (lhs_length[0][0]) == INTEGER_CST
-      && rhs_length[0][0]
-      && TREE_CODE (rhs_length[0][0]) == INTEGER_CST)
+      && TREE_CODE (lhs_an_info[0][0].length) == INTEGER_CST
+      && rhs_an_info[0][0].length
+      && TREE_CODE (rhs_an_info[0][0].length) == INTEGER_CST)
     {
-      HOST_WIDE_INT l_length = int_cst_value (lhs_length[0][0]);
-      HOST_WIDE_INT r_length = int_cst_value (rhs_length[0][0]);
+      HOST_WIDE_INT l_length = int_cst_value (lhs_an_info[0][0].length);
+      HOST_WIDE_INT r_length = int_cst_value (rhs_an_info[0][0].length);
       /* Length can be negative or positive.  As long as the magnitude is OK,
 	 then the array notation is valid.  */
       if (absu_hwi (l_length) != absu_hwi (r_length))
@@ -1110,256 +779,77 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
 	}
     }
   for (ii = 0; ii < lhs_rank; ii++)
-    {
-      if (lhs_vector[0][ii])
-	{
-	  lhs_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
-				    integer_type_node);
-	  lhs_ind_init[ii] = build_modify_expr
-	    (location, lhs_var[ii], TREE_TYPE (lhs_var[ii]),
-	     NOP_EXPR,
-	     location, build_zero_cst (TREE_TYPE (lhs_var[ii])),
-	     TREE_TYPE (lhs_var[ii]));
-	}
-    }
-
+    if (lhs_an_info[0][ii].is_vector)
+      {
+	lhs_an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
+					       integer_type_node);
+	lhs_an_loop_info[ii].ind_init = build_modify_expr
+	  (location, lhs_an_loop_info[ii].var,
+	   TREE_TYPE (lhs_an_loop_info[ii].var), NOP_EXPR,
+	   location, build_zero_cst (TREE_TYPE (lhs_an_loop_info[ii].var)),
+	   TREE_TYPE (lhs_an_loop_info[ii].var));
+      }
   for (ii = 0; ii < rhs_rank; ii++)
     {
       /* When we have a polynomial, we assume that the indices are of type 
 	 integer.  */
-      rhs_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
-				integer_type_node);
-      rhs_ind_init[ii] = build_modify_expr
-	(location, rhs_var[ii], TREE_TYPE (rhs_var[ii]),
-	 NOP_EXPR,
-	 location, build_int_cst (TREE_TYPE (rhs_var[ii]), 0),
-	 TREE_TYPE (rhs_var[ii]));
+      rhs_an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
+					     integer_type_node);
+      rhs_an_loop_info[ii].ind_init = build_modify_expr
+	(location, rhs_an_loop_info[ii].var,
+	 TREE_TYPE (rhs_an_loop_info[ii].var), NOP_EXPR,
+	 location, build_int_cst (TREE_TYPE (rhs_an_loop_info[ii].var), 0),
+	 TREE_TYPE (rhs_an_loop_info[ii].var));
     }
   if (lhs_rank)
     {
-      for (ii = 0; ii < lhs_list_size; ii++)
-	{
-	  if (lhs_vector[ii][0])
-	    { 
-	      /* The last ARRAY_NOTATION element's ARRAY component should be 
-		 the array's base value.  */
-	      tree lhs_array_opr = lhs_value[ii][lhs_rank - 1];
-	      for (s_jj = lhs_rank - 1; s_jj >= 0; s_jj--)
-		{
-		  if (lhs_count_down[ii][s_jj])
-	  	      /* Array[start_index + (induction_var * stride)].  */
-		      lhs_array_opr = build_array_ref
-			(location, lhs_array_opr,
-			 build2 (MINUS_EXPR, TREE_TYPE (lhs_var[s_jj]),
-				 lhs_start[ii][s_jj],
-				 build2 (MULT_EXPR, TREE_TYPE (lhs_var[s_jj]),
-					 lhs_var[s_jj],
-					 lhs_stride[ii][s_jj])));
-		  else
-		    lhs_array_opr = build_array_ref
-		      (location, lhs_array_opr,
-		       build2 (PLUS_EXPR, TREE_TYPE (lhs_var[s_jj]),
-			       lhs_start[ii][s_jj],
-			       build2 (MULT_EXPR, TREE_TYPE (lhs_var[s_jj]),
-				       lhs_var[s_jj],
-				       lhs_stride[ii][s_jj])));
-		}
-	      vec_safe_push (lhs_array_operand, lhs_array_opr);
-	    }
-	  else
-	    vec_safe_push (lhs_array_operand, integer_one_node);
-	}
+      lhs_array_operand = create_array_refs
+	(location, lhs_an_info, lhs_an_loop_info, lhs_list_size, lhs_rank);
       replace_array_notations (&lhs, true, lhs_list, lhs_array_operand);
       array_expr_lhs = lhs;
     }
-
+  if (rhs_array_operand)
+    vec_safe_truncate (rhs_array_operand, 0);
   if (rhs_rank)
     {
-      for (ii = 0; ii < rhs_list_size; ii++)
-	{
-	  if (rhs_vector[ii][0])
-	    {
-	      tree rhs_array_opr = rhs_value[ii][rhs_rank - 1];
-	      for (s_jj = rhs_rank - 1; s_jj >= 0; s_jj--)
-		{
-		  if (rhs_count_down[ii][s_jj])
-		    /* Array[start_index - (induction_var * stride)] */
-		    rhs_array_opr = build_array_ref
-		      (location, rhs_array_opr,
-		       build2 (MINUS_EXPR, TREE_TYPE (rhs_var[s_jj]),
-			       rhs_start[ii][s_jj],
-			       build2 (MULT_EXPR, TREE_TYPE (rhs_var[s_jj]),
-				       rhs_var[s_jj],
-				       rhs_stride[ii][s_jj])));
-		  else
-		    /* Array[start_index  + (induction_var * stride)] */
-		    rhs_array_opr = build_array_ref
-		      (location, rhs_array_opr,
-		       build2 (PLUS_EXPR, TREE_TYPE (rhs_var[s_jj]),
-			       rhs_start[ii][s_jj],
-			       build2 (MULT_EXPR, TREE_TYPE (rhs_var[s_jj]),
-				       rhs_var[s_jj],
-				       rhs_stride[ii][s_jj])));
-		}
-	      vec_safe_push (rhs_array_operand, rhs_array_opr);
-	    }
-	  else
-	  /* This is just a dummy node to make sure the list sizes for both
-	     array list and array operand list are the same.  */
-	  vec_safe_push (rhs_array_operand, integer_one_node);
-	}
-
-      for (ii = 0; ii < rhs_list_size; ii++)
-	{
-	  tree rhs_node = (*rhs_list)[ii];
-	  if (TREE_CODE (rhs_node) == CALL_EXPR)
-	    {
-	      int idx_value = 0;
-	      tree func_name = CALL_EXPR_FN (rhs_node);
-	      if (TREE_CODE (func_name) == ADDR_EXPR)
-		if (is_sec_implicit_index_fn (func_name))
-		  {
-		    idx_value = 
-		      extract_sec_implicit_index_arg (location, rhs_node);
-		    if (idx_value == -1) /* This means we have an error.  */
-		      return error_mark_node;
-		    else if (idx_value < (int) lhs_rank && idx_value >= 0)
-		      vec_safe_push (rhs_array_operand, lhs_var[idx_value]);
-		    else
-		      {
-			size_t ee = 0;
-			tree lhs_base = (*lhs_list)[ii];
-			for (ee = 0; ee < lhs_rank; ee++)
-			  lhs_base = ARRAY_NOTATION_ARRAY (lhs_base);
-			error_at (location, "__sec_implicit_index argument %d "
-				  "must be less than rank of %qD", idx_value,
-				  lhs_base);
-			return error_mark_node;
-		      }
-		  }  
-	    }
-	}
+      rhs_array_operand = create_array_refs
+	(location, rhs_an_info, rhs_an_loop_info, rhs_list_size, rhs_rank);
+      replace_array_notations (&rhs, true, rhs_list, rhs_array_operand);
+      vec_safe_truncate (rhs_array_operand, 0);
+      rhs_array_operand = fix_sec_implicit_args (location, rhs_list,
+						 rhs_an_loop_info, rhs_rank,
+						 rhs);
+      if (!rhs_array_operand)
+	return error_mark_node;
       replace_array_notations (&rhs, true, rhs_list, rhs_array_operand);
-      array_expr_rhs = rhs;
     }
-  else
+  else if (rhs_list_size > 0)
     {
-      for (ii = 0; ii < rhs_list_size; ii++)
-	{
-	  tree rhs_node = (*rhs_list)[ii];
-	  if (TREE_CODE (rhs_node) == CALL_EXPR)
-	    {
-	      int idx_value = 0;
-	      tree func_name = CALL_EXPR_FN (rhs_node);
-	      if (TREE_CODE (func_name) == ADDR_EXPR)
-		if (is_sec_implicit_index_fn (func_name))
-		  {
-		    idx_value = 
-		      extract_sec_implicit_index_arg (location, rhs_node);
-		    if (idx_value == -1) /* This means we have an error.  */
-		      return error_mark_node;
-		    else if (idx_value < (int) lhs_rank && idx_value >= 0)
-		      vec_safe_push (rhs_array_operand, lhs_var[idx_value]);
-		    else
-		      {
-			size_t ee = 0;
-			tree lhs_base = (*lhs_list)[ii];
-			for (ee = 0; ee < lhs_rank; ee++)
-			  lhs_base = ARRAY_NOTATION_ARRAY (lhs_base);
-			error_at (location, "__sec_implicit_index argument %d "
-				  "must be less than rank of %qD", idx_value,
-				  lhs_base);
-			return error_mark_node;
-		      }
-		  }  
-	    }
-	}
+      rhs_array_operand = fix_sec_implicit_args (location, rhs_list,
+						 lhs_an_loop_info, lhs_rank,
+						 lhs);
+      if (!rhs_array_operand)
+	return error_mark_node;
       replace_array_notations (&rhs, true, rhs_list, rhs_array_operand);
-      array_expr_rhs = rhs;
-      rhs_expr_incr[0] = NULL_TREE;
     }
-
-  for (ii = 0; ii < rhs_rank; ii++) 
-    rhs_expr_incr[ii] = build2 (MODIFY_EXPR, void_type_node, rhs_var[ii], 
-				build2 
-				(PLUS_EXPR, TREE_TYPE (rhs_var[ii]), 
-				 rhs_var[ii], 
-				 build_one_cst (TREE_TYPE (rhs_var[ii]))));
-
-  for (ii = 0; ii < lhs_rank; ii++) 
-    lhs_expr_incr[ii] = build2 
-      (MODIFY_EXPR, void_type_node, lhs_var[ii], 
-       build2 (PLUS_EXPR, TREE_TYPE (lhs_var[ii]), lhs_var[ii], 
-	       build_one_cst (TREE_TYPE (lhs_var[ii]))));
-  
-  /* If array_expr_lhs is NULL, then we have function that returns void or
-     its return value is ignored.  */
-  if (!array_expr_lhs)
-    array_expr_lhs = lhs;
-
+  array_expr_lhs = lhs;
+  array_expr_rhs = rhs;
   array_expr = build_modify_expr (location, array_expr_lhs, lhs_origtype, 
 				  modifycode, rhs_loc, array_expr_rhs, 
 				  rhs_origtype);
-
-  for (jj = 0; jj < MAX (lhs_rank, rhs_rank); jj++)
-    {
-      if (rhs_rank && rhs_expr_incr[jj])
-	{
-	  size_t iii = 0;
-	  if (lhs_rank == 0)
-	    lhs_compare[jj] = integer_one_node;
-	  else if (lhs_count_down[0][jj])
-	    lhs_compare[jj] = build2
-	      (GT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
-	  else
-	    lhs_compare[jj] = build2
-	      (LT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
-
-
-	  /* The reason why we have this here is for the following case:
-	         Array[:][:] = function_call(something) + Array2[:][:];
-
-	     So, we will skip the first operand of RHS and then go to the
-	     2nd to find whether we should count up or down.  */
-	 
-	  for (iii = 0; iii < rhs_list_size; iii++)
-	    if (rhs_vector[iii][jj])
-	      break;
-	      
-	  /* What we are doing here is this:
-	     We always count up, so:
-	       if (length is negative ==> which means we count down)
-	          we multiply length by -1 and count up => ii < -LENGTH
-	       else
-	          we just count up, so we compare for  ii < LENGTH
-	   */
-	  if (rhs_count_down[iii][jj])
-	    /* We use iii for rhs_length because that is the correct countdown
-	       we have to use.  */
-	      rhs_compare[jj] = build2
-		(LT_EXPR, boolean_type_node, rhs_var[jj],
-		 build2 (MULT_EXPR, TREE_TYPE (rhs_var[jj]),
-			 rhs_length[iii][jj],
-			 build_int_cst (TREE_TYPE (rhs_var[jj]), -1)));
-	  else
-	    rhs_compare[jj] = build2 (LT_EXPR, boolean_type_node, rhs_var[jj],
-				      rhs_length[iii][jj]);
-	  if (lhs_compare[ii] != integer_one_node)
-	    cond_expr[jj] = build2 (TRUTH_ANDIF_EXPR, void_type_node,
-				    lhs_compare[jj], rhs_compare[jj]);
-	  else
-	    cond_expr[jj] = rhs_compare[jj];
-	}
-      else
-	{
-	  if (lhs_count_down[0][jj])
-	    cond_expr[jj] = build2
-	      (GT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
-	  else
-	    cond_expr[jj] = build2
-	      (LT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
-	}
-    }
+  create_cmp_incr (location, &lhs_an_loop_info, lhs_rank, lhs_an_info);
+  if (rhs_rank)
+    create_cmp_incr (location, &rhs_an_loop_info, rhs_rank, rhs_an_info);
+  
+  for (ii = 0; ii < MAX (lhs_rank, rhs_rank); ii++)
+    if (ii < lhs_rank && ii < rhs_rank)
+      cond_expr[ii] = build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
+			      lhs_an_loop_info[ii].cmp,
+			      rhs_an_loop_info[ii].cmp);
+    else if (ii < lhs_rank && ii >= rhs_rank)
+      cond_expr[ii] = lhs_an_loop_info[ii].cmp;
+    else
+      gcc_unreachable ();
 
   an_init = pop_stmt_list (an_init);
   append_to_statement_list_force (an_init, &loop_with_init);
@@ -1369,18 +859,27 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
       tree incr_list = alloc_stmt_list ();
       tree new_loop = push_stmt_list ();
       if (lhs_rank)
-	add_stmt (lhs_ind_init[ii]);
+	add_stmt (lhs_an_loop_info[ii].ind_init);
       if (rhs_rank)
-	add_stmt (rhs_ind_init[ii]);
+	add_stmt (rhs_an_loop_info[ii].ind_init);
       if (lhs_rank)
-	append_to_statement_list_force (lhs_expr_incr[ii], &incr_list);
-      if (rhs_rank && rhs_expr_incr[ii])
-	append_to_statement_list_force (rhs_expr_incr[ii], &incr_list);
+	append_to_statement_list_force (lhs_an_loop_info[ii].incr, &incr_list);
+      if (rhs_rank && rhs_an_loop_info[ii].incr)
+	append_to_statement_list_force (rhs_an_loop_info[ii].incr, &incr_list);
       c_finish_loop (location, cond_expr[ii], incr_list, body, NULL_TREE,
 		     NULL_TREE, true);
       body = pop_stmt_list (new_loop);
     }
   append_to_statement_list_force (body, &loop_with_init);
+
+  lhs_an_info.release ();
+  lhs_an_loop_info.release ();
+  if (rhs_rank)
+    {
+      rhs_an_info.release ();
+      rhs_an_loop_info.release ();
+    }
+  cond_expr.release ();
   return loop_with_init;
 }
 
@@ -1396,15 +895,13 @@  fix_conditional_array_notations_1 (tree stmt)
   vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
   size_t list_size = 0;
   tree cond = NULL_TREE, builtin_loop = NULL_TREE, new_var = NULL_TREE;
-  size_t rank = 0, ii = 0, jj = 0;
-  int s_jj = 0;
-  tree **array_ops, *array_var, jj_tree, loop_init;
-  tree **array_value, **array_stride, **array_length, **array_start;
-  tree *compare_expr, *expr_incr, *ind_init;
-  bool **count_down, **array_vector;
-  tree begin_var, lngth_var, strde_var;
+  size_t rank = 0, ii = 0;
+  tree loop_init;
   location_t location = EXPR_LOCATION (stmt);
   tree body = NULL_TREE, loop_with_init = alloc_stmt_list ();
+  vec<vec<an_parts> > an_info = vNULL;
+  vec<an_loop_parts> an_loop_info = vNULL;
+ 
   if (TREE_CODE (stmt) == COND_EXPR)
     cond = COND_EXPR_COND (stmt);
   else if (TREE_CODE (stmt) == SWITCH_EXPR)
@@ -1440,7 +937,6 @@  fix_conditional_array_notations_1 (tree stmt)
 	    }
 	}
     }
-
   if (!find_rank (location, stmt, stmt, true, &rank))
     {
       pop_stmt_list (loop_init);
@@ -1458,194 +954,34 @@  fix_conditional_array_notations_1 (tree stmt)
     return stmt;
 
   list_size = vec_safe_length (array_list);
-
-  array_ops =  XNEWVEC (tree *, list_size);
-  for (ii = 0; ii < list_size; ii++)
-    array_ops[ii] =  XNEWVEC (tree, rank);
-
-  array_vector =  XNEWVEC (bool *, list_size);
-  for (ii = 0; ii < list_size; ii++)
-    array_vector[ii] =  XNEWVEC (bool, rank);
-
-  array_value = XNEWVEC (tree *, list_size);
-  array_stride = XNEWVEC (tree *, list_size);
-  array_length = XNEWVEC (tree *, list_size);
-  array_start =  XNEWVEC (tree *, list_size);
-
-  for (ii = 0; ii < list_size; ii++)
-    {
-      array_value[ii]  = XNEWVEC (tree, rank);
-      array_stride[ii] = XNEWVEC (tree, rank);
-      array_length[ii] = XNEWVEC (tree, rank);
-      array_start[ii]  = XNEWVEC (tree, rank);
-    }
-
-  compare_expr = XNEWVEC (tree, rank);
-  expr_incr = XNEWVEC (tree, rank);
-  ind_init = XNEWVEC (tree,  rank);
-
-  count_down = XNEWVEC (bool *, list_size);
-  for (ii = 0; ii < list_size; ii++)
-    count_down[ii] = XNEWVEC (bool, rank);
-
-  array_var = XNEWVEC (tree, rank);
-
-  for (ii = 0; ii < list_size; ii++)
-    {
-      tree array_node = (*array_list)[ii];
-      if (array_node && TREE_CODE (array_node) == ARRAY_NOTATION_REF)
-	{
-	  tree array_begin = ARRAY_NOTATION_START (array_node);
-	  tree array_lngth = ARRAY_NOTATION_LENGTH (array_node);
-	  tree array_strde = ARRAY_NOTATION_STRIDE (array_node);
-
-	  if (TREE_CODE (array_begin) != INTEGER_CST)
-	    {
-	      begin_var = build_decl (location, VAR_DECL, NULL_TREE,
-				      integer_type_node);
-	      add_stmt (build_modify_expr (location, begin_var,
-					   TREE_TYPE (begin_var),
-					   NOP_EXPR, location, array_begin,
-					   TREE_TYPE (array_begin)));
-	      ARRAY_NOTATION_START (array_node) = begin_var;
-	    }
-	  if (TREE_CODE (array_lngth) != INTEGER_CST)
-	    {
-	      lngth_var = build_decl (location, VAR_DECL, NULL_TREE,
-				      integer_type_node);
-	      add_stmt (build_modify_expr (location, lngth_var,
-					   TREE_TYPE (lngth_var),
-					   NOP_EXPR, location, array_lngth,
-					   TREE_TYPE (array_lngth)));
-	      ARRAY_NOTATION_LENGTH (array_node) = lngth_var;
-	    }
-	  if (TREE_CODE (array_strde) != INTEGER_CST)
-	    {
-	      strde_var = build_decl (location, VAR_DECL, NULL_TREE,
-				      integer_type_node);
-	      add_stmt (build_modify_expr (location, strde_var,
-					   TREE_TYPE (strde_var),
-					   NOP_EXPR, location, array_strde,
-					   TREE_TYPE (array_strde)));
-	      ARRAY_NOTATION_STRIDE (array_node) = strde_var;
-	    }
-	}
-    }  
-  for (ii = 0; ii < list_size; ii++)
-    {
-      tree array_node = (*array_list)[ii];
-      jj = 0;
-      for (jj_tree = array_node;
-	   jj_tree && TREE_CODE (jj_tree) == ARRAY_NOTATION_REF;
-	   jj_tree = ARRAY_NOTATION_ARRAY (jj_tree))
-	{
-	  array_ops[ii][jj] = jj_tree;
-	  jj++;
-	}
-    }
+  an_loop_info.safe_grow_cleared (rank);
+  
   for (ii = 0; ii < list_size; ii++)
-    {
-      tree array_node = (*array_list)[ii];
-      if (TREE_CODE (array_node) == 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] =
-		    fold_build1 (CONVERT_EXPR, integer_type_node,
-				 ARRAY_NOTATION_LENGTH (array_ops[ii][jj]));
-		  array_stride[ii][jj] =
-		    fold_build1 (CONVERT_EXPR, integer_type_node,
-				 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;
-	    }
-	}
-    }
-
+    if ((*array_list)[ii]
+	&& TREE_CODE ((*array_list)[ii]) == ARRAY_NOTATION_REF)
+      {
+	tree array_node = (*array_list)[ii];
+	make_triplet_val_inv (location, &ARRAY_NOTATION_START (array_node));
+	make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (array_node));
+	make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (array_node));
+      }
+  cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
   for (ii = 0; ii < rank; ii++)
     {
-      array_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
-				  integer_type_node);
-      ind_init[ii] =
-	build_modify_expr (location, array_var[ii],
-			   TREE_TYPE (array_var[ii]), NOP_EXPR,
+      an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
+					 integer_type_node);
+      an_loop_info[ii].ind_init =
+	build_modify_expr (location, an_loop_info[ii].var,
+			   TREE_TYPE (an_loop_info[ii].var), NOP_EXPR,
 			   location,
-			   build_int_cst (TREE_TYPE (array_var[ii]), 0),
-			   TREE_TYPE (array_var[ii]));
-    }
-  
-  for (ii = 0; ii < list_size; ii++)
-    {
-      if (array_vector[ii][0])
-	{
-	  tree array_opr = array_value[ii][rank - 1];
-	  for (s_jj = rank - 1; s_jj >= 0; s_jj--)
-	    {
-	      if (count_down[ii][s_jj])
-		/* Array[start_index - (induction_var * stride)] */
-		array_opr = build_array_ref
-		  (location, array_opr,
-		   build2 (MINUS_EXPR, TREE_TYPE (array_var[s_jj]),
-			   array_start[ii][s_jj],
-			   build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
-				   array_var[s_jj], array_stride[ii][s_jj])));
-	      else
-		/* Array[start_index + (induction_var * stride)] */
-		array_opr = build_array_ref
-		  (location, array_opr,
-		   build2 (PLUS_EXPR, TREE_TYPE (array_var[s_jj]),
-			   array_start[ii][s_jj],
-			   build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
-				   array_var[s_jj], array_stride[ii][s_jj])));
-	    }
-	  vec_safe_push (array_operand, array_opr);
-	}
-      else
-	/* This is just a dummy node to make sure the list sizes for both
-	   array list and array operand list are the same.  */
-	vec_safe_push (array_operand, integer_one_node);
+			   build_int_cst (TREE_TYPE (an_loop_info[ii].var), 0),
+			   TREE_TYPE (an_loop_info[ii].var));
     }
+  array_operand = create_array_refs (location, an_info, an_loop_info,
+				     list_size, rank);
   replace_array_notations (&stmt, true, array_list, array_operand);
-  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]);
-	}
-    }
-
+  create_cmp_incr (location, &an_loop_info, rank, an_info);
+  
   loop_init = pop_stmt_list (loop_init);
   body = stmt;
   append_to_statement_list_force (loop_init, &loop_with_init);
@@ -1653,33 +989,15 @@  fix_conditional_array_notations_1 (tree stmt)
   for (ii = 0; ii < rank; ii++)
     {
       tree new_loop = push_stmt_list ();
-      add_stmt (ind_init[ii]);
-      c_finish_loop (location, compare_expr[ii], expr_incr[ii], body, NULL_TREE,
-		     NULL_TREE, true);
+      add_stmt (an_loop_info[ii].ind_init);
+      c_finish_loop (location, an_loop_info[ii].cmp, an_loop_info[ii].incr,
+		     body, NULL_TREE, NULL_TREE, true);
       body = pop_stmt_list (new_loop);
     }
   append_to_statement_list_force (body, &loop_with_init);
-  XDELETEVEC (expr_incr);
-  XDELETEVEC (ind_init);
-  
-  for (ii = 0; ii < list_size; ii++)
-    {
-      XDELETEVEC (count_down[ii]);
-      XDELETEVEC (array_value[ii]);
-      XDELETEVEC (array_stride[ii]);
-      XDELETEVEC (array_length[ii]);
-      XDELETEVEC (array_start[ii]);
-      XDELETEVEC (array_ops[ii]);
-      XDELETEVEC (array_vector[ii]);
-    }
 
-  XDELETEVEC (count_down);
-  XDELETEVEC (array_value);
-  XDELETEVEC (array_stride);
-  XDELETEVEC (array_length);
-  XDELETEVEC (array_start);
-  XDELETEVEC (array_ops);
-  XDELETEVEC (array_vector);
+  an_loop_info.release ();
+  an_info.release ();
 
   return loop_with_init;
 }
@@ -1716,13 +1034,11 @@  fix_array_notation_expr (location_t location, enum tree_code code,
 {
 
   vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
-  size_t list_size = 0, rank = 0, ii = 0, jj = 0;
-  int s_jj = 0;
-  tree **array_ops, *array_var, jj_tree, loop_init;
-  tree **array_value, **array_stride, **array_length, **array_start;
-  tree *compare_expr, *expr_incr, *ind_init;
+  size_t list_size = 0, rank = 0, ii = 0;
+  tree loop_init;
   tree body, loop_with_init = alloc_stmt_list ();
-  bool **count_down, **array_vector;
+  vec<vec<an_parts> > an_info = vNULL;
+  vec<an_loop_parts> an_loop_info = vNULL;
   
   if (!find_rank (location, arg.value, arg.value, false, &rank))
     {
@@ -1742,165 +1058,33 @@  fix_array_notation_expr (location_t location, enum tree_code code,
     return arg;
 
   list_size = vec_safe_length (array_list);
-  
-  array_ops = XNEWVEC (tree *, list_size);
-  for (ii = 0; ii < list_size; ii++)
-    array_ops[ii] = XNEWVEC (tree,  rank);
-  
-  array_vector =  XNEWVEC (bool *, list_size);
-  for (ii = 0; ii < list_size; ii++)
-    array_vector[ii] = XNEWVEC (bool, rank);
-
-  array_value = XNEWVEC (tree *, list_size);
-  array_stride = XNEWVEC (tree *, list_size);
-  array_length = XNEWVEC (tree *, list_size);
-  array_start = XNEWVEC (tree *, list_size);
-
-  for (ii = 0; ii < list_size; ii++)
-    {
-      array_value[ii]  = XNEWVEC (tree, rank);
-      array_stride[ii] = XNEWVEC (tree, rank);
-      array_length[ii] = XNEWVEC (tree, rank);
-      array_start[ii]  = XNEWVEC (tree, rank);
-    }
 
-  compare_expr = XNEWVEC (tree, rank);
-  expr_incr = XNEWVEC (tree, rank);
-  ind_init = XNEWVEC (tree, rank);
-  
-  count_down = XNEWVEC (bool *, list_size);
-  for (ii = 0; ii < list_size; ii++)
-    count_down[ii] = XNEWVEC (bool, rank);
-  array_var = XNEWVEC (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++;
-	}
-    }
+  an_loop_info.safe_grow_cleared (rank);
+  cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
   
   loop_init = push_stmt_list ();
-
-  for (ii = 0; ii < list_size; ii++)
-    {
-      tree array_node = (*array_list)[ii];
-      if (TREE_CODE (array_node) == 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] =
-		    fold_build1 (CONVERT_EXPR, integer_type_node,
-				 ARRAY_NOTATION_LENGTH (array_ops[ii][jj]));
-		  array_stride[ii][jj] =
-		    fold_build1 (CONVERT_EXPR, integer_type_node,
-				 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;
-	    }
-	}
-    }
-
   for (ii = 0; ii < rank; ii++)
     {
-      array_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
-				  integer_type_node);
-      ind_init[ii] =
-	build_modify_expr (location, array_var[ii],
-			   TREE_TYPE (array_var[ii]), NOP_EXPR,
+      an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
+					 integer_type_node);
+      an_loop_info[ii].ind_init =
+	build_modify_expr (location, an_loop_info[ii].var,
+			   TREE_TYPE (an_loop_info[ii].var), NOP_EXPR,
 			   location,
-			   build_int_cst (TREE_TYPE (array_var[ii]), 0),
-			   TREE_TYPE (array_var[ii]));
+			   build_int_cst (TREE_TYPE (an_loop_info[ii].var), 0),
+			   TREE_TYPE (an_loop_info[ii].var));;
 	
     }
-  for (ii = 0; ii < list_size; ii++)
-    {
-      if (array_vector[ii][0])
-	{
-	  tree array_opr = array_value[ii][rank - 1];
-	  for (s_jj = rank - 1; s_jj >= 0; s_jj--)
-	    {
-	      if (count_down[ii][s_jj])
-		/* Array[start_index - (induction_var * stride)] */
-		array_opr = build_array_ref
-		  (location, array_opr,
-		   build2 (MINUS_EXPR, TREE_TYPE (array_var[s_jj]),
-			   array_start[ii][s_jj],
-			   build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
-				   array_var[s_jj], array_stride[ii][s_jj])));
-	      else
-		/* Array[start_index + (induction_var * stride)] */
-		array_opr = build_array_ref
-		  (location, array_opr,
-		   build2 (PLUS_EXPR, TREE_TYPE (array_var[s_jj]),
-			   array_start[ii][s_jj],
-			   build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
-				   array_var[s_jj], array_stride[ii][s_jj])));
-	    }
-	  vec_safe_push (array_operand, array_opr);
-	}
-      else
-      	/* This is just a dummy node to make sure the list sizes for both
-	   array list and array operand list are the same.  */
-	vec_safe_push (array_operand, integer_one_node);
-    }
+  array_operand = create_array_refs (location, an_info, an_loop_info,
+				     list_size, rank);
   replace_array_notations (&arg.value, true, array_list, array_operand);
+  create_cmp_incr (location, &an_loop_info, rank, an_info);
 
-  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]);
-	}
-    }
-  
+  arg = default_function_array_read_conversion (location, arg);
   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
-    {
-      arg = default_function_array_read_conversion (location, arg);
-      arg.value = build_unary_op (location, code, arg.value, 0);
-    }
+    arg.value = build_unary_op (location, code, arg.value, 0);
   else if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
-    {
-      arg = default_function_array_read_conversion (location, arg);
-      arg = parser_build_unary_op (location, code, arg);
-    }
+    arg = parser_build_unary_op (location, code, arg);
 
   loop_init = pop_stmt_list (loop_init);
   append_to_statement_list_force (loop_init, &loop_with_init);
@@ -1909,36 +1093,16 @@  fix_array_notation_expr (location_t location, enum tree_code code,
   for (ii = 0; ii < rank; ii++)
     {
       tree new_loop = push_stmt_list ();
-      add_stmt (ind_init[ii]);
-      c_finish_loop (location, compare_expr[ii], expr_incr[ii], body, NULL_TREE,
+      add_stmt (an_loop_info[ii].ind_init);
+      c_finish_loop (location, an_loop_info[ii].cmp,
+		     an_loop_info[ii].incr, body, NULL_TREE,
 		     NULL_TREE, true);
       body = pop_stmt_list (new_loop);
     }
   append_to_statement_list_force (body, &loop_with_init);
-   XDELETEVEC (expr_incr);
-  XDELETEVEC (ind_init);
-  XDELETEVEC (array_var);
-  
-  for (ii = 0; ii < list_size; ii++)
-    {
-      XDELETEVEC (count_down[ii]);
-      XDELETEVEC (array_value[ii]);
-      XDELETEVEC (array_stride[ii]);
-      XDELETEVEC (array_length[ii]);
-      XDELETEVEC (array_start[ii]);
-      XDELETEVEC (array_ops[ii]);
-      XDELETEVEC (array_vector[ii]);
-    }
-
-  XDELETEVEC (count_down);
-  XDELETEVEC (array_value);
-  XDELETEVEC (array_stride);
-  XDELETEVEC (array_length);
-  XDELETEVEC (array_start);
-  XDELETEVEC (array_ops);
-  XDELETEVEC (array_vector);
-
   arg.value = loop_with_init;
+  an_info.release ();
+  an_loop_info.release ();
   return arg;
 }
 
@@ -1950,15 +1114,12 @@  fix_array_notation_call_expr (tree arg)
 {
   vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
   tree new_var = NULL_TREE;
-  size_t list_size = 0, rank = 0, ii = 0, jj = 0;
-  int s_jj = 0;
-  tree **array_ops, *array_var, jj_tree, loop_init;
-  tree **array_value, **array_stride, **array_length, **array_start;
+  size_t list_size = 0, rank = 0, ii = 0;
+  tree loop_init;
   tree body, loop_with_init = alloc_stmt_list ();
-  tree *compare_expr, *expr_incr, *ind_init;
-  bool **count_down, **array_vector;
-  tree begin_var, lngth_var, strde_var;
   location_t location = UNKNOWN_LOCATION;
+  vec<vec<an_parts> > an_info = vNULL;
+  vec<an_loop_parts> an_loop_info = vNULL;
 
   if (TREE_CODE (arg) == CALL_EXPR
       && is_cilkplus_reduce_builtin (CALL_EXPR_FN (arg)))
@@ -1967,8 +1128,7 @@  fix_array_notation_call_expr (tree arg)
       /* We are ignoring the new var because either the user does not want to
 	 capture it OR he is using sec_reduce_mutating function.  */
       return loop_init;
-    }
-  
+    }  
   if (!find_rank (location, arg, arg, false, &rank))
     return error_mark_node;
   
@@ -1981,237 +1141,53 @@  fix_array_notation_call_expr (tree arg)
   
   list_size = vec_safe_length (array_list);
   location = EXPR_LOCATION (arg);
-
-  array_ops = XNEWVEC (tree *, list_size);
-  for (ii = 0; ii < list_size; ii++)
-    array_ops[ii] = XNEWVEC (tree, rank);
-  
-  array_vector = XNEWVEC (bool *, list_size);
-  for (ii = 0; ii < list_size; ii++)
-    array_vector[ii] = (bool *) XNEWVEC (bool, rank);
-
-  array_value = XNEWVEC (tree *, list_size);
-  array_stride = XNEWVEC (tree *, list_size);
-  array_length = XNEWVEC (tree *, list_size);
-  array_start = XNEWVEC (tree *, list_size);
-
-  for (ii = 0; ii < list_size; ii++)
-    {
-      array_value[ii]  = XNEWVEC (tree, rank);
-      array_stride[ii] = XNEWVEC (tree, rank);
-      array_length[ii] = XNEWVEC (tree, rank);
-      array_start[ii]  = XNEWVEC (tree, rank);
-    }
-
-  compare_expr = XNEWVEC (tree, rank);
-  expr_incr = XNEWVEC (tree, rank);
-  ind_init = XNEWVEC (tree, rank);
-  
-  count_down =  XNEWVEC (bool *, list_size);
-  for (ii = 0; ii < list_size; ii++)
-    count_down[ii] = XNEWVEC (bool, rank);
-  
-  array_var = XNEWVEC (tree, rank);
+  an_loop_info.safe_grow_cleared (rank);
   
   loop_init = push_stmt_list ();
   for (ii = 0; ii < list_size; ii++)
-    {
-      tree array_node = (*array_list)[ii];
-      if (array_node && TREE_CODE (array_node) == ARRAY_NOTATION_REF)
-	{
-	  tree array_begin = ARRAY_NOTATION_START (array_node);
-	  tree array_lngth = ARRAY_NOTATION_LENGTH (array_node);
-	  tree array_strde = ARRAY_NOTATION_STRIDE (array_node);
-
-	  if (TREE_CODE (array_begin) != INTEGER_CST)
-	    {
-	      begin_var = build_decl (location, VAR_DECL, NULL_TREE,
-				      integer_type_node);
-	      add_stmt (build_modify_expr (location, begin_var,
-					   TREE_TYPE (begin_var),
-					   NOP_EXPR, location, array_begin,
-					   TREE_TYPE (array_begin)));
-	      ARRAY_NOTATION_START (array_node) = begin_var;
-	    }
-	  if (TREE_CODE (array_lngth) != INTEGER_CST)
-	    {
-	      lngth_var = build_decl (location, VAR_DECL, NULL_TREE,
-				      integer_type_node);
-	      add_stmt (build_modify_expr (location, lngth_var,
-					   TREE_TYPE (lngth_var),
-					   NOP_EXPR, location, array_lngth,
-					   TREE_TYPE (array_lngth)));
-	      ARRAY_NOTATION_LENGTH (array_node) = lngth_var;
-	    }
-	  if (TREE_CODE (array_strde) != INTEGER_CST)
-	    {
-	      strde_var = build_decl (location, VAR_DECL, NULL_TREE,
-				      integer_type_node);
-	      add_stmt (build_modify_expr (location, strde_var,
-					   TREE_TYPE (strde_var),
-					   NOP_EXPR, location, array_strde,
-					   TREE_TYPE (array_strde)));
-	      ARRAY_NOTATION_STRIDE (array_node) = strde_var;
-	    }
-	}
-    }
-  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))
+    if ((*array_list)[ii]
+	&& TREE_CODE ((*array_list)[ii]) == ARRAY_NOTATION_REF)
 	{
-	  array_ops[ii][jj] = jj_tree;
-	  jj++;
+	  tree array_node = (*array_list)[ii];
+	  make_triplet_val_inv (location, &ARRAY_NOTATION_START (array_node));
+	  make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (array_node));
+	  make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (array_node));
 	}
-    }
-
-  for (ii = 0; ii < list_size; ii++)
-    {
-      tree array_node = (*array_list)[ii];
-      if (TREE_CODE (array_node) == 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] =
-		    fold_build1 (CONVERT_EXPR, integer_type_node,
-				 ARRAY_NOTATION_LENGTH (array_ops[ii][jj]));
-		  array_stride[ii][jj] =
-		    fold_build1 (CONVERT_EXPR, integer_type_node,
-				 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;
-	    }
-	}
-    }
-
-  if (length_mismatch_in_expr_p (location, array_length, list_size, rank))
+  cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
+  if (length_mismatch_in_expr_p (location, an_info))
     {
       pop_stmt_list (loop_init);
       return error_mark_node;
     }
-  
   for (ii = 0; ii < rank; ii++)
     {
-      array_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
-				  integer_type_node);
-      ind_init[ii] =
-	build_modify_expr (location, array_var[ii],
-			   TREE_TYPE (array_var[ii]), NOP_EXPR,
-			   location,
-			   build_int_cst (TREE_TYPE (array_var[ii]), 0),
-			   TREE_TYPE (array_var[ii]));
+      an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
+					 integer_type_node);
+      an_loop_info[ii].ind_init =
+	build_modify_expr (location, an_loop_info[ii].var,
+			   TREE_TYPE (an_loop_info[ii].var), NOP_EXPR, location,
+			   build_int_cst (TREE_TYPE (an_loop_info[ii].var), 0),
+			   TREE_TYPE (an_loop_info[ii].var));
 	
     }
-  for (ii = 0; ii < list_size; ii++)
-    {
-      if (array_vector[ii][0])
-	{
-	  tree array_opr_node = array_value[ii][rank - 1];
-	  for (s_jj = rank - 1; s_jj >= 0; s_jj--)
-	    {
-	      if (count_down[ii][s_jj])
-		/* Array[start_index - (induction_var * stride)] */
-		array_opr_node = build_array_ref
-		  (location, array_opr_node,
-		   build2 (MINUS_EXPR, TREE_TYPE (array_var[s_jj]),
-			   array_start[ii][s_jj],
-			   build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
-				   array_var[s_jj], array_stride[ii][s_jj])));
-	      else
-		/* Array[start_index + (induction_var * stride)] */
-		array_opr_node = build_array_ref
-		  (location, array_opr_node,
-		   build2 (PLUS_EXPR, TREE_TYPE (array_var[s_jj]),
-			   array_start[ii][s_jj],
-			   build2 (MULT_EXPR, TREE_TYPE (array_var[s_jj]),
-				   array_var[s_jj], array_stride[ii][s_jj])));
-	    }
-	  vec_safe_push (array_operand, array_opr_node);
-	}
-      else
-	/* This is just a dummy node to make sure the list sizes for both
-	   array list and array operand list are the same.  */
-	vec_safe_push (array_operand, integer_one_node);
-    }
+  array_operand = create_array_refs (location, an_info, an_loop_info,
+				     list_size, rank);
   replace_array_notations (&arg, true, array_list, array_operand);
-  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]);
-	}
-    }
-
+  create_cmp_incr (location, &an_loop_info, rank, an_info);
   loop_init = pop_stmt_list (loop_init);
   append_to_statement_list_force (loop_init, &loop_with_init);
   body = arg;
   for (ii = 0; ii < rank; ii++)
     {
       tree new_loop = push_stmt_list ();
-      add_stmt (ind_init[ii]);
-      c_finish_loop (location, compare_expr[ii], expr_incr[ii], body, NULL_TREE,
-		     NULL_TREE, true);
+      add_stmt (an_loop_info[ii].ind_init);
+      c_finish_loop (location, an_loop_info[ii].cmp, an_loop_info[ii].incr,
+		     body, NULL_TREE, NULL_TREE, true);
       body = pop_stmt_list (new_loop);
     }
   append_to_statement_list_force (body, &loop_with_init);
-  XDELETEVEC (compare_expr);
-  XDELETEVEC (expr_incr);
-  XDELETEVEC (ind_init);
-  XDELETEVEC (array_var);
-  
-  for (ii = 0; ii < list_size; ii++)
-    {
-      XDELETEVEC (count_down[ii]);
-      XDELETEVEC (array_value[ii]);
-      XDELETEVEC (array_stride[ii]);
-      XDELETEVEC (array_length[ii]);
-      XDELETEVEC (array_start[ii]);
-      XDELETEVEC (array_ops[ii]);
-      XDELETEVEC (array_vector[ii]);
-    }
-
-  XDELETEVEC (count_down);
-  XDELETEVEC (array_value);
-  XDELETEVEC (array_stride);
-  XDELETEVEC (array_length);
-  XDELETEVEC (array_start);
-  XDELETEVEC (array_ops);
-  XDELETEVEC (array_vector);
-  
+  an_loop_info.release ();
+  an_info.release ();
   return loop_with_init;
 }
 
@@ -2390,4 +1366,3 @@  build_array_notation_ref (location_t loc, tree array, tree start_index,
   
   return array_ntn_tree;
 }
-
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b4f36b0..2a8e59c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@ 
+2013-06-21  Balaji V. Iyer  <balaji.v.iyer@intel.com> 
+
+	* cp-array-notation.c (cp_length_mismatch_in_expr_p): Remove.
+	(expand_an_in_modify_expr): Changed a function call from the above
+	removed function to length_mismatch_in_expr_p.
+
 2013-06-21  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
 	* call.c (convert_like_real): Added a check if array notation is present
diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c
old mode 100644
new mode 100755
index 92272b3..491da0f
--- a/gcc/cp/cp-array-notation.c
+++ b/gcc/cp/cp-array-notation.c
@@ -78,52 +78,6 @@  create_an_loop (tree init, tree cond, tree incr, tree body)
   finish_for_stmt (for_stmt);
 }
 
-/* Returns true if there is a length mismatch among exprssions that are at the
-   same dimension and one the same side of the equal sign.  The Array notation
-   lengths (LIST->LENGTH) is passed in as a 2D vector of trees.  */
-
-static bool
-cp_length_mismatch_in_expr_p (location_t loc, vec<vec<an_parts> >list)
-{
-  size_t ii, jj;
-  tree length = NULL_TREE;
-  HOST_WIDE_INT l_length, l_node;
-  
-  size_t x = list.length ();
-  size_t y = list[0].length ();
-  
-  for (jj = 0; jj < y; jj++)
-    {
-      length = NULL_TREE;
-      for (ii = 0; ii < x; ii++)
-	{
-	  if (!length)
-	    length = list[ii][jj].length;
-	  else if (TREE_CODE (length) == INTEGER_CST)
-	    {
-	      /* If length is a INTEGER, and list[ii][jj] is an integer then
-		 check if they are equal.  If they are not equal then return
-		 true.  */
-	      if (TREE_CODE (list[ii][jj].length) == INTEGER_CST)
-		{
-		  l_node = int_cst_value (list[ii][jj].length);
-		  l_length = int_cst_value (length);
-		  if (absu_hwi (l_length) != absu_hwi (l_node))
-		    {
-		      error_at (loc, "length mismatch in expression");
-		      return true;
-		    }
-		}
-	    }
-	  else
-	    /* We set the length node as the current node just in case it turns
-	       out to be an integer.  */
-	    length = list[ii][jj].length;
-	}
-    }
-  return false;
-}
-
 /* If *VALUE is not a constant integer, then this function replaces it with
    a variable to make it loop invariant for array notations.  */
 
@@ -744,9 +698,9 @@  expand_an_in_modify_expr (location_t location, tree lhs,
   if (rhs_list)
     cilkplus_extract_an_triplets (rhs_list, rhs_list_size, rhs_rank,
 				  &rhs_an_info);
-  if (cp_length_mismatch_in_expr_p (EXPR_LOCATION (lhs), lhs_an_info)
-      || (rhs_list && cp_length_mismatch_in_expr_p (EXPR_LOCATION (rhs),
-						    rhs_an_info)))
+  if (length_mismatch_in_expr_p (EXPR_LOCATION (lhs), lhs_an_info)
+      || (rhs_list && length_mismatch_in_expr_p (EXPR_LOCATION (rhs),
+						 rhs_an_info)))
     {
       pop_stmt_list (an_init);
       return error_mark_node;