From 713b46fafe2e7079c1820254468c20e999ef85a5 Mon Sep 17 00:00:00 2001 From: "Balaji V. Iyer" Date: Tue, 25 Jun 2013 20:41:21 +0000 Subject: [PATCH] Replaced Dynamic arrays with vec trees in Array Notation for C. gcc/c-family/ChangeLog 2013-06-21 Balaji V. Iyer * 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 * 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 * 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. From-SVN: r200405 --- gcc/c-family/ChangeLog | 8 + gcc/c-family/array-notation-common.c | 40 +- gcc/c-family/c-common.h | 2 +- gcc/c/ChangeLog | 12 + gcc/c/c-array-notation.c | 1599 +++++--------------------- gcc/cp/ChangeLog | 6 + gcc/cp/cp-array-notation.c | 52 +- 7 files changed, 338 insertions(+), 1381 deletions(-) diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 03269e906c3..bc73a809a55 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -4,6 +4,14 @@ * c-cppbuiltin.c (c_cpp_builtins): Likewise. * c-opts.c (c_common_post_options): Likewise. +2013-06-21 Balaji V. Iyer + + * 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 * 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 index 0e2a43132f5..8eab89ba6fb 100644 --- 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 >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 index 95d3ccfd845..625c3011460 100644 --- 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 >); 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 **); diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 05766caa8ff..313fa7e96bc 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,15 @@ +2013-06-21 Balaji V. Iyer + + * 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 PR c/57630 diff --git a/gcc/c/c-array-notation.c b/gcc/c/c-array-notation.c index 03b66b9cf79..7788f7bf145 100644 --- 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 *node, size_t rank, + vec > 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 * +create_array_refs (location_t loc, vec > an_info, + vec an_loop_info, size_t size, size_t rank) +{ + tree ind_mult, ind_incr; + vec *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 *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 > an_info = vNULL; + vec 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 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 *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 *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 > lhs_an_info = vNULL, rhs_an_info = vNULL; + vec 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 *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 > an_info = vNULL; + vec 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 *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 > an_info = vNULL; + vec 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 *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 > an_info = vNULL; + vec 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 55ed6a5659f..97d7fad089c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -40,6 +40,12 @@ * typeck.c (build_x_conditional_expr): Likewise. * typeck2.c (check_narrowing): Likewise. +2013-06-21 Balaji V. Iyer + + * 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 * 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 index 92272b332d1..491da0fecc4 100644 --- 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 >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; -- 2.30.2