@@ -1,3 +1,10 @@
+2011-12-16 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * c-typeck.c (find_rank): Modified to find rank of array notation
+ inside expressions such as PLUS_EXPR.
+ (build_array_notation_expr): Added support for N-Diamension array
+ notation.
+
2011-12-09 Balaji V. Iyer <balaji.v.iyer@intel.com>
* c-typeck.c (build_array_notation_expr): New function.
@@ -5044,231 +5044,399 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
return result;
}
+
+static int
+find_rank (tree array)
+{
+ int rank = 0;
+ tree ii_tree = NULL_TREE, jj_tree = NULL_TREE;
+ int highest_rank = 0, jj = 0;
+
+ if (TREE_CODE (array) != ARRAY_NOTATION_REF)
+ {
+ for (jj = 0; jj < TREE_CODE_LENGTH (TREE_CODE (array)); jj++)
+ {
+ rank = 0;
+ jj_tree = TREE_OPERAND (array, jj);
+ for (ii_tree = jj_tree;
+ ii_tree && TREE_CODE (ii_tree) == ARRAY_NOTATION_REF;
+ ii_tree = ARRAY_NOTATION_ARRAY (ii_tree))
+ rank++;
+
+ if (highest_rank != 0 && rank != 0 && highest_rank != rank)
+ error ("Rank Mismatch!");
+ else if (highest_rank < rank)
+ highest_rank = rank;
+ }
+ }
+ else
+ {
+ for (ii_tree = array;
+ ii_tree && TREE_CODE (ii_tree) == ARRAY_NOTATION_REF;
+ ii_tree = ARRAY_NOTATION_ARRAY (ii_tree))
+ rank++;
+ highest_rank = rank;
+ }
+
+ return highest_rank;
+}
+
tree
build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
enum tree_code modifycode, location_t rhs_loc,
tree rhs, tree rhs_origtype)
{
- bool lhs_vector = false, rhs_vector = false;
- tree array_expr_lhs = NULL_TREE, array_expr_rhs = NULL_TREE, array_expr;
- tree lhs_value = NULL_TREE, rhs_value = NULL_TREE;
- tree lhs_stride = NULL_TREE, lhs_length = NULL_TREE, lhs_start = NULL_TREE;
- tree rhs_stride = NULL_TREE, rhs_length = NULL_TREE, rhs_start = NULL_TREE;
- tree loop, lhs_var = NULL_TREE, rhs_var = NULL_TREE;
- tree body_label, body_label_expr;
- tree exit_label, exit_label_expr, cond_expr, if_stmt_label;
- tree temp = NULL_TREE;
- tree lhs_expr_incr = NULL_TREE, rhs_expr_incr = NULL_TREE;
- bool lhs_count_down = false, rhs_count_down = false;
+ bool *lhs_vector = NULL, *rhs_vector = NULL;
+ tree *lhs_array = NULL, *rhs_array = NULL;
+ 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 loop = NULL_TREE, *lhs_var = NULL, *rhs_var = NULL;
+ tree *body_label = NULL, *body_label_expr = NULL;
+ tree *exit_label = NULL, *exit_label_expr = NULL, *cond_expr = NULL;
+ tree *if_stmt_label = NULL;
+ 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;
+ int lhs_rank = 0, rhs_rank = 0, ii = 0;
+ tree ii_tree = NULL_TREE;
- if (TREE_CODE(lhs) == ARRAY_NOTATION_REF)
- {
- lhs_value = ARRAY_NOTATION_ARRAY (lhs);
- lhs_start = ARRAY_NOTATION_START (lhs);
- lhs_length = ARRAY_NOTATION_LENGTH (lhs);
- lhs_stride = ARRAY_NOTATION_STRIDE (lhs);
- lhs_vector = true;
- /* if the stride value is variable (i.e. not constant) then assume the
- programmer knows what he is doing and keep on going */
- if (!TREE_CONSTANT (lhs_length))
- lhs_count_down = false; /* assume we count up */
- else if (tree_int_cst_lt (lhs_length,
- build_int_cst (TREE_TYPE (lhs_length), 0)))
- lhs_count_down = true;
+ lhs_rank = find_rank (lhs);
+ rhs_rank = find_rank (rhs);
+
+ if (lhs_rank == 0 && rhs_rank != 0)
+ {
+ error_at (location, "Left Hand-side rank cannot be scalar when "
+ "right-hand side is not");
+ return error_mark_node;
}
- else
+ if (lhs_rank != 0 && rhs_rank != 0 && lhs_rank != rhs_rank)
{
- if (TREE_CODE(rhs) == ARRAY_NOTATION_REF)
- error ("Assignment of vector to a scalar is prohibited");
- else
- lhs_vector = false;
+ error_at (location, "Rank-mismatch");
+ return error_mark_node;
+ }
+
+ lhs_vector = (bool *) xmalloc (sizeof (bool) * lhs_rank);
+ rhs_vector = (bool *) xmalloc (sizeof (bool) * rhs_rank);
+
+ lhs_array = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+ rhs_array = (tree *) xmalloc (sizeof (tree) * rhs_rank);
+
+ lhs_value = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+ rhs_value = (tree *) xmalloc (sizeof (tree) * rhs_rank);
+
+ lhs_stride = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+ rhs_stride = (tree *) xmalloc (sizeof (tree) * rhs_rank);
+
+ lhs_length = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+ rhs_length = (tree *) xmalloc (sizeof (tree) * rhs_rank);
+
+ lhs_start = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+ rhs_start = (tree *) xmalloc (sizeof (tree) * rhs_rank);
+
+ lhs_var = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+ rhs_var = (tree *) xmalloc (sizeof (tree) * rhs_rank);
+
+ /* The reason why we are just using lhs_rank for this is because we have the
+ * following scenarios:
+ * LHS_RANK == RHS_RANK
+ * LHS_RANK != RHS_RANK && RHS_RANK = 0
+ *
+ * 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);
+
+ lhs_expr_incr = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+ rhs_expr_incr = (tree *) xmalloc (sizeof (tree) * rhs_rank);
+
+ lhs_ind_init = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+ rhs_ind_init = (tree *) xmalloc (sizeof (tree) * rhs_rank);
+
+ lhs_count_down = (bool *) xmalloc (sizeof (bool) * lhs_rank);
+ rhs_count_down = (bool *) xmalloc (sizeof (bool) * rhs_rank);
+
+ lhs_compare = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+ rhs_compare = (tree *) xmalloc (sizeof (tree) * rhs_rank);
+
+ ii = 0;
+ 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++;
+ }
+
+ if (rhs_rank)
+ {
+ ii = 0;
+ for (ii_tree = rhs; ii_tree && TREE_CODE (ii_tree) == ARRAY_NOTATION_REF;
+ ii_tree = ARRAY_NOTATION_ARRAY (ii_tree))
+ {
+ rhs_array[ii] = ii_tree;
+ ii++;
+ }
+ }
+
+ if (TREE_CODE (lhs) == ARRAY_NOTATION_REF)
+ {
+ for (ii = 0; ii < lhs_rank; ii++)
+ {
+ if (TREE_CODE (lhs_array[ii]) == ARRAY_NOTATION_REF)
+ {
+ lhs_value[ii] = ARRAY_NOTATION_ARRAY (lhs_array[ii]);
+ lhs_start[ii] = ARRAY_NOTATION_START (lhs_array[ii]);
+ lhs_length[ii] = ARRAY_NOTATION_LENGTH (lhs_array[ii]);
+ lhs_stride[ii] = ARRAY_NOTATION_STRIDE (lhs_array[ii]);
+ lhs_vector[ii] = true;
+ /* IF the stride value is variable (i.e. not constant) then
+ * assume that the length is positive
+ */
+ if (!TREE_CONSTANT (lhs_length[ii]))
+ lhs_count_down[ii] = false;
+ else if (tree_int_cst_lt
+ (lhs_length[ii],
+ build_int_cst (TREE_TYPE (lhs_length[ii]), 0)))
+ lhs_count_down[ii] = true;
+ else
+ lhs_count_down[ii] = false;
+ }
+ else
+ lhs_vector[ii] = false;
+ }
}
if (TREE_CODE (rhs) == ARRAY_NOTATION_REF)
{
- rhs_value = ARRAY_NOTATION_ARRAY (rhs);
- rhs_start = ARRAY_NOTATION_START (rhs);
- rhs_length = ARRAY_NOTATION_LENGTH (rhs);
- rhs_stride = ARRAY_NOTATION_STRIDE (rhs);
- rhs_vector = true;
-
- /* if the stride value is variable (i.e. not constant) then assume the
- programmer knows what he is doing and keep on going */
- if (!TREE_CONSTANT (rhs_length))
- rhs_count_down = false; /* assume wwe count up */
- else if (tree_int_cst_lt (rhs_length,
- build_int_cst (TREE_TYPE (rhs_length), 0)))
- rhs_count_down = true;
+ for (ii = 0; ii < rhs_rank; ii++)
+ {
+ if (TREE_CODE (rhs_array[ii]) == ARRAY_NOTATION_REF)
+ {
+ rhs_value[ii] = ARRAY_NOTATION_ARRAY (rhs_array[ii]);
+ rhs_start[ii] = ARRAY_NOTATION_START (rhs_array[ii]);
+ rhs_length[ii] = ARRAY_NOTATION_LENGTH (rhs_array[ii]);
+ rhs_stride[ii] = ARRAY_NOTATION_STRIDE (rhs_array[ii]);
+ rhs_vector[ii] = true;
+ /* If the stride value is variable (i.e. not constant) then
+ * assume that the length is positive
+ */
+ if (!TREE_CONSTANT (rhs_length[ii]))
+ rhs_count_down[ii] = false;
+ else if (tree_int_cst_lt
+ (rhs_length[ii],
+ build_int_cst (TREE_TYPE (rhs_length[ii]), 0)))
+ rhs_count_down[ii] = true;
+ else
+ rhs_count_down[ii] = false;
+ }
+ else
+ rhs_vector[ii] = false;
+ }
}
- else
- rhs_vector = false;
loop = push_stmt_list();
- if (lhs_vector)
+ for (ii = 0; ii < lhs_rank; ii++)
{
- lhs_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE,
- TREE_TYPE (lhs_start));
- temp = build_modify_expr
- (UNKNOWN_LOCATION, lhs_var, TREE_TYPE (lhs_var), modifycode,
- UNKNOWN_LOCATION, build_int_cst (TREE_TYPE (lhs_start), 0),
- TREE_TYPE (lhs_start));
- add_stmt (temp);
+ if (lhs_vector[ii])
+ {
+ lhs_var[ii] = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE,
+ TREE_TYPE (lhs_start[ii]));
+ lhs_ind_init[ii] = build_modify_expr
+ (UNKNOWN_LOCATION, lhs_var[ii], TREE_TYPE (lhs_var[ii]),
+ modifycode,
+ UNKNOWN_LOCATION, build_int_cst (TREE_TYPE (lhs_start[ii]), 0),
+ TREE_TYPE (lhs_start[ii]));
+
+ }
}
- if (rhs_vector)
+ for (ii = 0; ii < rhs_rank; ii++)
{
- rhs_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE,
- TREE_TYPE (rhs_start));
- add_stmt (build_modify_expr (UNKNOWN_LOCATION, rhs_var,
- TREE_TYPE (rhs_var), modifycode,
- UNKNOWN_LOCATION,
- build_int_cst (TREE_TYPE(rhs_start), 0),
- TREE_TYPE (rhs_start)));
+ if (rhs_vector[ii])
+ {
+ rhs_var[ii] = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE,
+ TREE_TYPE (rhs_start[ii]));
+ rhs_ind_init[ii] = build_modify_expr
+ (UNKNOWN_LOCATION, rhs_var[ii], TREE_TYPE (rhs_var[ii]),
+ modifycode,
+ UNKNOWN_LOCATION, build_int_cst (TREE_TYPE(rhs_start[ii]), 0),
+ TREE_TYPE (rhs_start[ii]));
+
+ }
}
-
- /* this will create the if statement label */
- if_stmt_label = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
- void_type_node);
- DECL_CONTEXT (if_stmt_label) = current_function_decl;
- DECL_ARTIFICIAL (if_stmt_label) = 0;
- DECL_IGNORED_P (if_stmt_label) = 1;
+ for (ii = 0; ii < lhs_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 = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
- void_type_node);
- DECL_CONTEXT (body_label) = current_function_decl;
- DECL_ARTIFICIAL (body_label) = 0;
- DECL_IGNORED_P (body_label) = 1;
- body_label_expr = build1 (LABEL_EXPR, void_type_node, body_label);
-
- /* this will create the exit label..i.e. where the while loop will branch
- out of
- */
- exit_label = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
- void_type_node);
- DECL_CONTEXT (exit_label) = current_function_decl;
- DECL_ARTIFICIAL (exit_label) = 0;
- DECL_IGNORED_P (exit_label) = 1;
- exit_label_expr = build1 (LABEL_EXPR, void_type_node, exit_label);
-
- if (lhs_vector)
- {
- /* Array[start_index + (induction_var * stride)] */
- array_expr_lhs = build_array_ref
- (location, lhs_value, build2 (PLUS_EXPR, TREE_TYPE (lhs_var), lhs_start,
- build2 (MULT_EXPR, TREE_TYPE (lhs_var),
- lhs_var, lhs_stride)));
- if (lhs_count_down)
- lhs_expr_incr = build2 (MODIFY_EXPR, void_type_node, lhs_var,
- build2 (PLUS_EXPR, TREE_TYPE (lhs_var), lhs_var,
- build_int_cst (TREE_TYPE (lhs_var),
- -1)));
- else
- lhs_expr_incr = build2 (MODIFY_EXPR, void_type_node, lhs_var,
- build2 (PLUS_EXPR, TREE_TYPE (lhs_var), lhs_var,
- build_int_cst (TREE_TYPE (lhs_var),
- 1)));
- }
- if (rhs_vector)
+ /* 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]);
+ }
+
+ if (lhs_rank)
+ {
+ /* The last ARRAY_NOTATION element's ARRAY component should be the array's
+ * base value
+ */
+ array_expr_lhs = lhs_value[lhs_rank - 1];
+ for (ii = lhs_rank - 1; ii >= 0; ii--)
+ {
+ /* Array[start_index + (induction_var * stride)] */
+ array_expr_lhs = build_array_ref
+ (location, array_expr_lhs,
+ build2 (PLUS_EXPR, TREE_TYPE (lhs_var[ii]), lhs_start[ii],
+ build2 (MULT_EXPR, TREE_TYPE (lhs_var[ii]), lhs_var[ii],
+ lhs_stride[ii])));
+ if (lhs_count_down[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_int_cst (TREE_TYPE (lhs_var[ii]), -1)));
+ else
+ 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_int_cst (TREE_TYPE (lhs_var[ii]), 1)));
+ }
+ }
+
+ if (rhs_rank)
{
-
- array_expr_rhs = build_array_ref
- (location, rhs_value, build2 (PLUS_EXPR, TREE_TYPE (rhs_var), rhs_start,
- build2 (MULT_EXPR, TREE_TYPE (rhs_var),
- rhs_var, rhs_stride)));
- if (rhs_count_down)
- rhs_expr_incr = build2 (MODIFY_EXPR, void_type_node, rhs_var,
- build2 (PLUS_EXPR, TREE_TYPE (rhs_var), rhs_var,
- build_int_cst (TREE_TYPE (rhs_var),
- -1)));
- else
- rhs_expr_incr = build2 (MODIFY_EXPR, void_type_node, rhs_var,
- build2 (PLUS_EXPR, TREE_TYPE (rhs_var), rhs_var,
- build_int_cst (TREE_TYPE (rhs_var),
- 1)));
+ /* The last ARRAY NOTATION element's ARRAY component should be the
+ * array's base value
+ */
+ array_expr_rhs = rhs_value[rhs_rank - 1];
+ for (ii = rhs_rank - 1; ii >= 0; ii--)
+ {
+ /* Array[start_index + (induction_var * stride)] */
+ array_expr_rhs = build_array_ref
+ (location, array_expr_rhs,
+ build2 (PLUS_EXPR, TREE_TYPE (rhs_var[ii]), rhs_start[ii],
+ build2 (MULT_EXPR, TREE_TYPE (rhs_var[ii]), rhs_var[ii],
+ rhs_stride[ii])));
+
+ if (rhs_count_down[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_int_cst (TREE_TYPE (rhs_var[ii]), -1)));
+ else
+ 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_int_cst (TREE_TYPE (rhs_var[ii]), 1)));
+ }
}
else
{
array_expr_rhs = rhs;
- rhs_expr_incr = NULL_TREE;
+ rhs_expr_incr[0] = NULL_TREE;
}
array_expr = build_modify_expr (location, array_expr_lhs,
lhs_origtype, modifycode, rhs_loc,
array_expr_rhs, rhs_origtype);
- if (rhs_expr_incr)
+ for (ii = 0; ii < lhs_rank; ii++)
{
- tree lhs_compare, rhs_compare;
- if (lhs_count_down)
- lhs_compare = build2 (GE_EXPR, boolean_type_node, lhs_var,
- build2 (PLUS_EXPR, TREE_TYPE (lhs_length),
- lhs_length,
- build_int_cst (TREE_TYPE (lhs_length),
- 1)));
- else
- lhs_compare = build2 (LE_EXPR, boolean_type_node, lhs_var,
- build2 (MINUS_EXPR, TREE_TYPE (lhs_length),
- lhs_length,
- build_int_cst (TREE_TYPE (lhs_length),
- 1)));
-
- if (rhs_count_down)
- rhs_compare = build2 (GE_EXPR, boolean_type_node, rhs_var,
- build2 (PLUS_EXPR, TREE_TYPE (rhs_length),
- rhs_length,
- build_int_cst (TREE_TYPE (rhs_length),
- 1)));
- else
- rhs_compare = build2 (LE_EXPR, boolean_type_node, rhs_var,
- build2 (MINUS_EXPR, TREE_TYPE (rhs_length),
- rhs_length,
- build_int_cst (TREE_TYPE (rhs_length),
- 1)));
+ if (rhs_rank && rhs_expr_incr[ii])
+ {
+ if (lhs_count_down[ii])
+ lhs_compare[ii] = build2
+ (GT_EXPR, boolean_type_node, lhs_var[ii], lhs_length[ii]);
+
+ else
+ lhs_compare[ii] = build2
+ (LT_EXPR, boolean_type_node, lhs_var[ii], lhs_length[ii]);
+
+ if (rhs_count_down[ii])
+ rhs_compare[ii] = build2
+ (GT_EXPR, boolean_type_node, rhs_var[ii], rhs_length[ii]);
+ else
+ rhs_compare[ii] = build2
+ (LT_EXPR, boolean_type_node, rhs_var[ii], rhs_length[ii]);
- cond_expr = build2 (TRUTH_ANDIF_EXPR, void_type_node, lhs_compare,
- rhs_compare);
- }
- else
- {
- if (lhs_count_down)
- cond_expr = build2 (GE_EXPR, boolean_type_node, lhs_var,
- build2 (PLUS_EXPR, TREE_TYPE (lhs_length),
- lhs_length,
- build_int_cst (TREE_TYPE (lhs_length), 1)));
+ cond_expr[ii] = build2 (TRUTH_ANDIF_EXPR, void_type_node,
+ lhs_compare[ii], rhs_compare[ii]);
+ }
else
- cond_expr = build2 (LE_EXPR, boolean_type_node, lhs_var,
- fold_build2 (PLUS_EXPR, TREE_TYPE (lhs_length),
- lhs_length,
- build_int_cst (TREE_TYPE (lhs_length), -1)));
+ {
+ if (lhs_count_down[ii])
+ cond_expr[ii] = build2
+ (GT_EXPR, boolean_type_node, lhs_var[ii], lhs_length[ii]);
+ else
+ cond_expr[ii] = build2
+ (LT_EXPR, boolean_type_node, lhs_var[ii], lhs_length[ii]);
+ }
}
/* The following statements will do the following:
- * <if_stmt_label>:
+ * <if_stmt_label>: (in order from outermost to innermost)
* if (cond_expr) then go to body_label
* else go to exit_label
* <body_label>:
* array expression
+ *
+ * (the increment, goto and exit_label goes from innermost to
+ * outermost).
* ii++ and jj++
* go to if_stmt_label
* <exit_label>:
* <REST OF CODE>
*/
+
- add_stmt (build1 (LABEL_EXPR, void_type_node, if_stmt_label));
- add_stmt (build3 (COND_EXPR, void_type_node, cond_expr,
- build1 (GOTO_EXPR, void_type_node, body_label),
- build1 (GOTO_EXPR, void_type_node, exit_label)));
+ for (ii = 0; ii < lhs_rank; ii++)
+ {
+ add_stmt (lhs_ind_init [ii]);
+ if (rhs_rank)
+ add_stmt (rhs_ind_init[ii]);
+ add_stmt (build1 (LABEL_EXPR, void_type_node, if_stmt_label[ii]));
+ add_stmt (build3 (COND_EXPR, void_type_node, cond_expr[ii],
+ build1 (GOTO_EXPR, void_type_node, body_label[ii]),
+ build1 (GOTO_EXPR, void_type_node, exit_label[ii])));
- add_stmt (body_label_expr);
+ add_stmt (body_label_expr[ii]);
+ }
+
add_stmt (array_expr);
- add_stmt (lhs_expr_incr);
- if (rhs_expr_incr)
- add_stmt (rhs_expr_incr);
+
+ for (ii = lhs_rank - 1; ii >= 0; ii--)
+ {
+ add_stmt (lhs_expr_incr[ii]);
+ if (rhs_rank && rhs_expr_incr[ii])
+ add_stmt (rhs_expr_incr[ii]);
- add_stmt (build1 (GOTO_EXPR, void_type_node, if_stmt_label));
- add_stmt (exit_label_expr);
+ add_stmt (build1 (GOTO_EXPR, void_type_node, if_stmt_label[ii]));
+ add_stmt (exit_label_expr[ii]);
+ }
pop_stmt_list (loop);