aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/cp-array-notation.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/cp-array-notation.c')
-rw-r--r--gcc/cp/cp-array-notation.c582
1 files changed, 255 insertions, 327 deletions
diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c
index 491da0f..d279ddd 100644
--- a/gcc/cp/cp-array-notation.c
+++ b/gcc/cp/cp-array-notation.c
@@ -59,7 +59,6 @@
#include "diagnostic.h"
#include "tree-iterator.h"
#include "vec.h"
-#include "gimple.h"
/* Creates a FOR_STMT with INIT, COND, INCR and BODY as the initializer,
condition, increment expression and the loop-body, respectively. */
@@ -82,17 +81,12 @@ create_an_loop (tree init, tree cond, tree incr, tree body)
a variable to make it loop invariant for array notations. */
static inline void
-make_triplet_val_inv (location_t loc, tree *value, tsubst_flags_t cry)
+make_triplet_val_inv (tree *value)
{
- tree var;
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);
- finish_expr_stmt (build_x_modify_expr (loc, var, NOP_EXPR, *value, cry));
- *value = var;
- }
+ *value = get_temp_regvar (ptrdiff_type_node, *value);
}
/* Returns a vector of size RANK that contains an ARRAY_REF. This vector is
@@ -112,47 +106,22 @@ create_array_refs (location_t loc, vec<vec<an_parts> > an_info,
{
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 str = NULL_TREE, v = NULL_TREE, st = NULL_TREE;
- tree start = an_info[ii][s_jj].start;
- tree stride = an_info[ii][s_jj].stride;
- tree var = an_loop_info[s_jj].var;
-
- /* If stride and start are of same type and the induction var
- is not, convert induction variable to stride's type. */
- if (TREE_TYPE (start) == TREE_TYPE (stride)
- && TREE_TYPE (stride) != TREE_TYPE (var))
- {
- st = start;
- str = stride;
- v = build_c_cast (loc, TREE_TYPE (str), var);
- }
- else if (TREE_TYPE (start) != TREE_TYPE (stride))
- {
- /* If we reach here, then the stride and start are of
- different types, and so it doesn't really matter what
- the induction variable type is, convert everything to
- integer. The reason why we pick an integer
- instead of something like size_t is because the stride
- and length can be + or -. */
- st = build_c_cast (loc, integer_type_node, start);
- str = build_c_cast (loc, integer_type_node, stride);
- v = build_c_cast (loc, integer_type_node, var);
- }
- else
- {
- st = start;
- str = stride;
- v = var;
- }
-
- ind_mult = build2 (MULT_EXPR, TREE_TYPE (v), v, str);
- ind_incr = build2 (PLUS_EXPR, TREE_TYPE (v), st, ind_mult);
+ tree start = cp_fold_convert (ptrdiff_type_node,
+ an_info[ii][s_jj].start);
+ tree stride = cp_fold_convert (ptrdiff_type_node,
+ an_info[ii][s_jj].stride);
+ tree var = cp_fold_convert (ptrdiff_type_node,
+ an_loop_info[s_jj].var);
+
+ ind_mult = build2 (MULT_EXPR, TREE_TYPE (var), var, stride);
+ ind_incr = build2 (PLUS_EXPR, TREE_TYPE (var), start, ind_mult);
/* Array [ start_index + (induction_var * stride)] */
array_opr = grok_array_decl (loc, array_opr, ind_incr, false);
}
@@ -192,7 +161,7 @@ replace_invariant_exprs (tree *node)
{
size_t ix = 0;
tree node_list = NULL_TREE;
- tree t = NULL_TREE, new_var = NULL_TREE, new_node;
+ tree t = NULL_TREE, new_var = NULL_TREE;
struct inv_list data;
data.list_values = NULL;
@@ -204,17 +173,18 @@ replace_invariant_exprs (tree *node)
{
node_list = push_stmt_list ();
for (ix = 0; vec_safe_iterate (data.list_values, ix, &t); ix++)
- {
- if (processing_template_decl || !TREE_TYPE (t))
- new_var = build_min_nt_loc (EXPR_LOCATION (t), VAR_DECL, NULL_TREE,
- NULL_TREE);
- else
- new_var = build_decl (EXPR_LOCATION (t), VAR_DECL, NULL_TREE,
- TREE_TYPE (t));
- gcc_assert (new_var != NULL_TREE && new_var != error_mark_node);
- new_node = build_x_modify_expr (EXPR_LOCATION (t), new_var, NOP_EXPR,
- t, tf_warning_or_error);
- finish_expr_stmt (new_node);
+ {
+ /* Sometimes, when comma_expr has a function call in it, it will
+ typecast it to void. Find_inv_trees finds those nodes and so
+ if it void type, then don't bother creating a new var to hold
+ the return value. */
+ if (VOID_TYPE_P (TREE_TYPE (t)))
+ {
+ finish_expr_stmt (t);
+ new_var = void_zero_node;
+ }
+ else
+ new_var = get_temp_regvar (TREE_TYPE (t), t);
vec_safe_push (data.replacement, new_var);
}
cp_walk_tree (node, replace_inv_trees, (void *) &data, NULL);
@@ -235,7 +205,6 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
tree new_var_type = NULL_TREE, func_parm, new_yes_expr, new_no_expr;
tree array_ind_value = NULL_TREE, new_no_ind, new_yes_ind, new_no_list;
tree new_yes_list, new_cond_expr, new_expr = NULL_TREE;
- tree new_var_init = NULL_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;
tree body, an_init, loop_with_init = alloc_stmt_list ();
@@ -305,7 +274,7 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
- new_var_type = integer_type_node;
+ new_var_type = boolean_type_node;
break;
case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
@@ -334,24 +303,30 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
if (TREE_CODE ((*array_list)[ii]) == ARRAY_NOTATION_REF)
{
tree anode = (*array_list)[ii];
- make_triplet_val_inv (location, &ARRAY_NOTATION_START (anode),
- tf_warning_or_error);
- make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (anode),
- tf_warning_or_error);
- make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (anode),
- tf_warning_or_error);
+ make_triplet_val_inv (&ARRAY_NOTATION_START (anode));
+ make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode));
+ make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode));
}
cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
for (ii = 0; ii < rank; ii++)
{
- an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
- TREE_TYPE (an_info[0][ii].start));
- an_loop_info[ii].ind_init = build_x_modify_expr
- (location, an_loop_info[ii].var, NOP_EXPR,
- build_zero_cst (TREE_TYPE (an_loop_info[ii].var)),
- tf_warning_or_error);
+ tree typ = ptrdiff_type_node;
+
+ /* In this place, we are using get_temp_regvar instead of
+ create_temporary_var if an_type is SEC_REDUCE_MAX/MIN_IND because
+ the array_ind_value depends on this value being initalized to 0. */
+ if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
+ || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
+ an_loop_info[ii].var = get_temp_regvar (typ, build_zero_cst (typ));
+ else
+ {
+ an_loop_info[ii].var = create_temporary_var (typ);
+ add_decl_expr (an_loop_info[ii].var);
+ }
+ an_loop_info[ii].ind_init =
+ build_x_modify_expr (location, an_loop_info[ii].var, INIT_EXPR,
+ build_zero_cst (typ), tf_warning_or_error);
}
-
array_operand = create_array_refs (location, an_info, an_loop_info,
list_size, rank);
replace_array_notations (&func_parm, true, array_list, array_operand);
@@ -360,26 +335,9 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
TREE_TYPE (func_parm) = TREE_TYPE ((*array_list)[0]);
create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error);
- if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
- {
- if (processing_template_decl)
- *new_var = build_decl (location, VAR_DECL, NULL_TREE, new_var_type);
- else
- *new_var = create_tmp_var (new_var_type, NULL);
- }
- else
- /* We do not require a new variable for mutating. The "identity value"
- itself is the variable. */
- *new_var = NULL_TREE;
-
if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
- || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
- {
- array_ind_value = create_tmp_var (TREE_TYPE (func_parm), NULL);
- gcc_assert (array_ind_value && (array_ind_value != error_mark_node));
- DECL_INITIAL (array_ind_value) = NULL_TREE;
- pushdecl (array_ind_value);
- }
+ || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
+ array_ind_value = get_temp_regvar (TREE_TYPE (func_parm), func_parm);
array_op0 = (*array_operand)[0];
switch (an_type)
@@ -394,35 +352,36 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
break;
case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
- code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO) ? EQ_EXPR
- : NE_EXPR;
+ code = ((an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO) ? EQ_EXPR
+ : NE_EXPR);
init = build_zero_cst (new_var_type);
cond_init = build_one_cst (new_var_type);
comp_node = build_zero_cst (TREE_TYPE (func_parm));
break;
case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO:
case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
- code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO) ? NE_EXPR
- : EQ_EXPR;
+ code = ((an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO) ? NE_EXPR
+ : EQ_EXPR);
init = build_one_cst (new_var_type);
cond_init = build_zero_cst (new_var_type);
comp_node = build_zero_cst (TREE_TYPE (func_parm));
break;
case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX:
code = MAX_EXPR;
- init = TYPE_MIN_VALUE (new_var_type) ? TYPE_MIN_VALUE (new_var_type)
- : func_parm;
+ init = (TYPE_MIN_VALUE (new_var_type) ? TYPE_MIN_VALUE (new_var_type)
+ : func_parm);
break;
case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN:
code = MIN_EXPR;
- init = TYPE_MAX_VALUE (new_var_type) ? TYPE_MAX_VALUE (new_var_type)
- : func_parm;
+ init = (TYPE_MAX_VALUE (new_var_type) ? TYPE_MAX_VALUE (new_var_type)
+ : func_parm);
break;
case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
- code = an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND ? LE_EXPR
- : GE_EXPR;
+ code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND ? LE_EXPR
+ : GE_EXPR);
init = an_loop_info[0].var;
+ break;
case BUILT_IN_CILKPLUS_SEC_REDUCE:
init = identity_value;
break;
@@ -433,9 +392,11 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
gcc_unreachable ();
}
- if (init)
- new_var_init = build_x_modify_expr (location, *new_var, NOP_EXPR, init,
- tf_warning_or_error);
+ if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
+ *new_var = get_temp_regvar (new_var_type, init);
+ else
+ *new_var = NULL_TREE;
+
switch (an_type)
{
case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD:
@@ -470,8 +431,6 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
break;
case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
- new_exp_init = build_x_modify_expr (location, array_ind_value, NOP_EXPR,
- func_parm, tf_warning_or_error);
new_yes_expr = build_x_modify_expr (location, array_ind_value, NOP_EXPR,
func_parm, tf_warning_or_error);
new_no_expr = build_x_modify_expr (location, array_ind_value, NOP_EXPR,
@@ -521,21 +480,8 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
default:
gcc_unreachable ();
}
-
- /* The reason we are putting initial variable twice is because the
- new exp init below depends on this value being initialized. */
- for (ii = 0; ii < rank; ii++)
- finish_expr_stmt (an_loop_info[ii].ind_init);
-
- if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
- finish_expr_stmt (new_var_init);
-
- if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
- || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
- finish_expr_stmt (new_exp_init);
-
an_init = pop_stmt_list (an_init);
- append_to_statement_list_force (an_init, &loop_with_init);
+ append_to_statement_list (an_init, &loop_with_init);
body = new_expr;
for (ii = 0; ii < rank; ii++)
@@ -545,7 +491,7 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
an_loop_info[ii].incr, body);
body = pop_stmt_list (new_loop);
}
- append_to_statement_list_force (body, &loop_with_init);
+ append_to_statement_list (body, &loop_with_init);
an_info.release ();
an_loop_info.release ();
@@ -634,10 +580,7 @@ expand_an_in_modify_expr (location_t location, tree lhs,
return an_init;
}
else
- {
- pop_stmt_list (an_init);
- return NULL_TREE;
- }
+ gcc_unreachable ();
}
/* If for some reason location is not set, then find if LHS or RHS has
@@ -659,8 +602,6 @@ expand_an_in_modify_expr (location_t location, tree lhs,
if (lhs_rank == 0 && rhs_rank != 0)
{
- if (location == UNKNOWN_LOCATION && EXPR_HAS_LOCATION (rhs))
- location = EXPR_LOCATION (rhs);
error_at (location, "%qD cannot be scalar when %qD is not", lhs, rhs);
return error_mark_node;
}
@@ -675,17 +616,17 @@ expand_an_in_modify_expr (location_t location, tree lhs,
for (ii = 0; ii < lhs_list_size; ii++)
{
tree anode = (*lhs_list)[ii];
- make_triplet_val_inv (location, &ARRAY_NOTATION_START (anode), complain);
- make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (anode), complain);
- make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (anode), complain);
+ make_triplet_val_inv (&ARRAY_NOTATION_START (anode));
+ make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode));
+ make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode));
}
for (ii = 0; ii < rhs_list_size; ii++)
if ((*rhs_list)[ii] && TREE_CODE ((*rhs_list)[ii]) == ARRAY_NOTATION_REF)
{
tree aa = (*rhs_list)[ii];
- make_triplet_val_inv (location, &ARRAY_NOTATION_START (aa), complain);
- make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (aa), complain);
- make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (aa), complain);
+ make_triplet_val_inv (&ARRAY_NOTATION_START (aa));
+ make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (aa));
+ make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (aa));
}
lhs_an_loop_info.safe_grow_cleared (lhs_rank);
@@ -705,31 +646,29 @@ expand_an_in_modify_expr (location_t location, tree lhs,
pop_stmt_list (an_init);
return error_mark_node;
}
- tree rhs_len = (rhs_list_size > 0 && rhs_rank > 0) ?
- rhs_an_info[0][0].length : NULL_TREE;
- tree lhs_len = (lhs_list_size > 0 && lhs_rank > 0) ?
- lhs_an_info[0][0].length : NULL_TREE;
+ tree rhs_len = ((rhs_list_size > 0 && rhs_rank > 0) ?
+ rhs_an_info[0][0].length : NULL_TREE);
+ tree lhs_len = ((lhs_list_size > 0 && lhs_rank > 0) ?
+ lhs_an_info[0][0].length : NULL_TREE);
if (lhs_list_size > 0 && rhs_list_size > 0 && lhs_rank > 0 && rhs_rank > 0
&& TREE_CODE (lhs_len) == INTEGER_CST && rhs_len
- && TREE_CODE (rhs_len) == INTEGER_CST)
- {
- HOST_WIDE_INT l_length = int_cst_value (lhs_len);
- HOST_WIDE_INT r_length = int_cst_value (rhs_len);
- if (absu_hwi (l_length) != absu_hwi (r_length))
- {
- error_at (location, "length mismatch between LHS and RHS");
- pop_stmt_list (an_init);
- return error_mark_node;
- }
+ && TREE_CODE (rhs_len) == INTEGER_CST
+ && !tree_int_cst_equal (rhs_len, lhs_len))
+ {
+ error_at (location, "length mismatch between LHS and RHS");
+ pop_stmt_list (an_init);
+ return error_mark_node;
}
- for (ii = 0; ii < lhs_rank; ii++)
- if (lhs_an_info[0][ii].start && TREE_TYPE (lhs_an_info[0][ii].start))
- lhs_an_loop_info[ii].var =
- build_decl (location, VAR_DECL, NULL_TREE,
- TREE_TYPE (lhs_an_info[0][ii].start));
- else
- lhs_an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
- integer_type_node);
+ for (ii = 0; ii < lhs_rank; ii++)
+ {
+ tree typ = ptrdiff_type_node;
+ lhs_an_loop_info[ii].var = create_temporary_var (typ);
+ add_decl_expr (lhs_an_loop_info[ii].var);
+ lhs_an_loop_info[ii].ind_init = build_x_modify_expr
+ (location, lhs_an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ),
+ complain);
+ }
+
if (rhs_list_size > 0)
{
rhs_array_operand = fix_sec_implicit_args (location, rhs_list,
@@ -743,24 +682,15 @@ expand_an_in_modify_expr (location_t location, tree lhs,
rhs_list = NULL;
extract_array_notation_exprs (rhs, true, &rhs_list);
rhs_list_size = vec_safe_length (rhs_list);
-
- for (ii = 0; ii < lhs_rank; ii++)
- if (lhs_an_info[0][ii].is_vector)
- {
- lhs_an_loop_info[ii].ind_init = build_x_modify_expr
- (location, lhs_an_loop_info[ii].var, NOP_EXPR,
- build_zero_cst (TREE_TYPE (lhs_an_loop_info[ii].var)), complain);
- }
+
for (ii = 0; ii < rhs_rank; ii++)
{
- /* When we have a polynomial, we assume that the indices are of type
- integer. */
- rhs_an_loop_info[ii].var =
- build_decl (location, VAR_DECL, NULL_TREE,
- TREE_TYPE (rhs_an_info[0][ii].start));
+ tree typ = ptrdiff_type_node;
+ rhs_an_loop_info[ii].var = create_temporary_var (typ);
+ add_decl_expr (rhs_an_loop_info[ii].var);
rhs_an_loop_info[ii].ind_init = build_x_modify_expr
- (location, rhs_an_loop_info[ii].var, NOP_EXPR,
- build_zero_cst (TREE_TYPE (rhs_an_loop_info[ii].var)), complain);
+ (location, rhs_an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ),
+ complain);
}
if (lhs_rank)
@@ -809,12 +739,12 @@ expand_an_in_modify_expr (location_t location, tree lhs,
else if (ii < lhs_rank && ii >= rhs_rank)
cond_expr[ii] = lhs_an_loop_info[ii].cmp;
else
- /* No need to compare ii < rhs_rank && ii >= lhs_rank because valid Array
- notation expression cannot RHS's rank cannot be greater than LHS. */
+ /* No need to compare ii < rhs_rank && ii >= lhs_rank because in a valid
+ Array notation expression, rank of RHS cannot be greater than LHS. */
gcc_unreachable ();
an_init = pop_stmt_list (an_init);
- append_to_statement_list_force (an_init, &loop_with_init);
+ append_to_statement_list (an_init, &loop_with_init);
body = array_expr;
for (ii = 0; ii < MAX (lhs_rank, rhs_rank); ii++)
{
@@ -824,17 +754,13 @@ expand_an_in_modify_expr (location_t location, tree lhs,
if (lhs_rank)
{
- append_to_statement_list_force (lhs_an_loop_info[ii].ind_init,
- &init_list);
- append_to_statement_list_force (lhs_an_loop_info[ii].incr,
- &incr_list);
+ append_to_statement_list (lhs_an_loop_info[ii].ind_init, &init_list);
+ append_to_statement_list (lhs_an_loop_info[ii].incr, &incr_list);
}
if (rhs_rank)
{
- append_to_statement_list_force (rhs_an_loop_info[ii].ind_init,
- &init_list);
- append_to_statement_list_force (rhs_an_loop_info[ii].incr,
- &incr_list);
+ append_to_statement_list (rhs_an_loop_info[ii].ind_init, &init_list);
+ append_to_statement_list (rhs_an_loop_info[ii].incr, &incr_list);
}
create_an_loop (init_list, cond_expr[ii], incr_list, body);
body = pop_stmt_list (new_loop);
@@ -867,7 +793,6 @@ cp_expand_cond_array_notations (tree orig_stmt)
tree an_init, body, stmt = NULL_TREE;
tree builtin_loop, new_var = NULL_TREE;
tree loop_with_init = alloc_stmt_list ();
- tsubst_flags_t complain = tf_warning_or_error;
location_t location = UNKNOWN_LOCATION;
vec<vec<an_parts> > an_info = vNULL;
vec<an_loop_parts> an_loop_info = vNULL;
@@ -884,13 +809,17 @@ cp_expand_cond_array_notations (tree orig_stmt)
|| find_rank (EXPR_LOCATION (no_expr), no_expr, no_expr, true,
&no_rank))
return error_mark_node;
- if (cond_rank != 0 && cond_rank != yes_rank && yes_rank != 0)
+ /* If the condition has a zero rank, then handle array notations in body
+ seperately. */
+ if (cond_rank == 0)
+ return orig_stmt;
+ if (cond_rank != yes_rank && yes_rank != 0)
{
error_at (EXPR_LOCATION (yes_expr), "rank mismatch with controlling"
" expression of parent if-statement");
return error_mark_node;
}
- else if (cond_rank != 0 && cond_rank != no_rank && no_rank != 0)
+ else if (cond_rank != no_rank && no_rank != 0)
{
error_at (EXPR_LOCATION (no_expr), "rank mismatch with controlling "
"expression of parent if-statement");
@@ -911,13 +840,17 @@ cp_expand_cond_array_notations (tree orig_stmt)
&& !find_rank (EXPR_LOCATION (no_expr), no_expr, no_expr, true,
&no_rank)))
return error_mark_node;
- if (cond_rank != 0 && cond_rank != yes_rank && yes_rank != 0)
+
+ /* Same reasoning as for COND_EXPR. */
+ if (cond_rank == 0)
+ return orig_stmt;
+ else if (cond_rank != yes_rank && yes_rank != 0)
{
error_at (EXPR_LOCATION (yes_expr), "rank mismatch with controlling"
" expression of parent if-statement");
return error_mark_node;
}
- else if (cond_rank != 0 && cond_rank != no_rank && no_rank != 0)
+ else if (cond_rank != no_rank && no_rank != 0)
{
error_at (EXPR_LOCATION (no_expr), "rank mismatch with controlling "
"expression of parent if-statement");
@@ -949,11 +882,11 @@ cp_expand_cond_array_notations (tree orig_stmt)
vec_safe_push (new_var_list, new_var);
replace_array_notations (&orig_stmt, false, sub_list,
new_var_list);
- append_to_statement_list_force (builtin_loop, &stmt);
+ append_to_statement_list (builtin_loop, &stmt);
}
}
}
- append_to_statement_list_force (orig_stmt, &stmt);
+ append_to_statement_list (orig_stmt, &stmt);
rank = 0;
array_list = NULL;
if (!find_rank (EXPR_LOCATION (stmt), stmt, stmt, true, &rank))
@@ -977,37 +910,28 @@ cp_expand_cond_array_notations (tree orig_stmt)
for (ii = 0; ii < list_size; ii++)
{
tree anode = (*array_list)[ii];
- make_triplet_val_inv (location, &ARRAY_NOTATION_START (anode), complain);
- make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (anode), complain);
- make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (anode), complain);
+ make_triplet_val_inv (&ARRAY_NOTATION_START (anode));
+ make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode));
+ make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode));
}
cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
- for (ii = 0; ii < rank; ii++)
- if (TREE_TYPE (an_info[0][ii].start)
- && TREE_CODE (TREE_TYPE (an_info[0][ii].start)) != TEMPLATE_TYPE_PARM)
- {
- an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
- TREE_TYPE (an_info[0][ii].start));
- an_loop_info[ii].ind_init = build_x_modify_expr
- (location, an_loop_info[ii].var, NOP_EXPR,
- build_zero_cst (TREE_TYPE (an_loop_info[ii].var)),
- tf_warning_or_error);
- }
- else
- {
- an_loop_info[ii].var = build_min_nt_loc (location, VAR_DECL,
- NULL_TREE, NULL_TREE);
- an_loop_info[ii].ind_init =
- build_x_modify_expr (location, an_loop_info[ii].var, NOP_EXPR,
- integer_zero_node, tf_warning_or_error);
- }
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ tree typ = ptrdiff_type_node;
+ an_loop_info[ii].var = create_temporary_var (typ);
+ add_decl_expr (an_loop_info[ii].var);
+ an_loop_info[ii].ind_init =
+ build_x_modify_expr (location, an_loop_info[ii].var, INIT_EXPR,
+ build_zero_cst (typ), tf_warning_or_error);
+ }
array_operand = create_array_refs (location, an_info, an_loop_info,
list_size, rank);
replace_array_notations (&stmt, true, array_list, array_operand);
create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error);
an_init = pop_stmt_list (an_init);
- append_to_statement_list_force (an_init, &loop_with_init);
+ append_to_statement_list (an_init, &loop_with_init);
body = stmt;
for (ii = 0; ii < rank; ii++)
@@ -1017,7 +941,7 @@ cp_expand_cond_array_notations (tree orig_stmt)
an_loop_info[ii].incr, body);
body = pop_stmt_list (new_loop);
}
- append_to_statement_list_force (body, &loop_with_init);
+ append_to_statement_list (body, &loop_with_init);
an_info.release ();
an_loop_info.release ();
@@ -1062,14 +986,14 @@ expand_unary_array_notation_exprs (tree orig_stmt)
{
vec<tree, va_gc> *sub_list = NULL, *new_var_list = NULL;
stmt = alloc_stmt_list ();
- append_to_statement_list_force (builtin_loop, &stmt);
+ append_to_statement_list (builtin_loop, &stmt);
vec_safe_push (sub_list, list_node);
vec_safe_push (new_var_list, new_var);
replace_array_notations (&orig_stmt, false, sub_list, new_var_list);
}
}
if (stmt != NULL_TREE)
- append_to_statement_list_force (finish_expr_stmt (orig_stmt), &stmt);
+ append_to_statement_list (finish_expr_stmt (orig_stmt), &stmt);
else
stmt = orig_stmt;
rank = 0;
@@ -1089,22 +1013,19 @@ expand_unary_array_notation_exprs (tree orig_stmt)
for (ii = 0; ii < list_size; ii++)
{
tree array_node = (*array_list)[ii];
- make_triplet_val_inv (location, &ARRAY_NOTATION_START (array_node),
- tf_warning_or_error);
- make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (array_node),
- tf_warning_or_error);
- make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (array_node),
- tf_warning_or_error);
+ make_triplet_val_inv (&ARRAY_NOTATION_START (array_node));
+ make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (array_node));
+ make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (array_node));
}
cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
for (ii = 0; ii < rank; ii++)
{
- an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
- TREE_TYPE (an_info[0][ii].start));
+ tree typ = ptrdiff_type_node;
+ an_loop_info[ii].var = create_temporary_var (typ);
+ add_decl_expr (an_loop_info[ii].var);
an_loop_info[ii].ind_init = build_x_modify_expr
- (location, an_loop_info[ii].var, NOP_EXPR,
- build_zero_cst (TREE_TYPE (an_loop_info[ii].var)),
+ (location, an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ),
tf_warning_or_error);
}
array_operand = create_array_refs (location, an_info, an_loop_info,
@@ -1113,7 +1034,7 @@ expand_unary_array_notation_exprs (tree orig_stmt)
create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error);
an_init = pop_stmt_list (an_init);
- append_to_statement_list_force (an_init, &loop_with_init);
+ append_to_statement_list (an_init, &loop_with_init);
body = stmt;
for (ii = 0; ii < rank; ii++)
@@ -1123,7 +1044,7 @@ expand_unary_array_notation_exprs (tree orig_stmt)
an_loop_info[ii].incr, body);
body = pop_stmt_list (new_loop);
}
- append_to_statement_list_force (body, &loop_with_init);
+ append_to_statement_list (body, &loop_with_init);
an_info.release ();
an_loop_info.release ();
@@ -1139,21 +1060,35 @@ static tree
expand_return_expr (tree expr)
{
tree new_mod_list, new_var, new_mod, retval_expr;
-
+ size_t rank = 0;
+ location_t loc = EXPR_LOCATION (expr);
if (TREE_CODE (expr) != RETURN_EXPR)
return expr;
+
+ if (!find_rank (loc, expr, expr, false, &rank))
+ return error_mark_node;
- location_t loc = EXPR_LOCATION (expr);
- new_mod_list = alloc_stmt_list ();
+ /* If the return expression contains array notations, then flag it as
+ error. */
+ if (rank >= 1)
+ {
+ error_at (loc, "array notation expression cannot be used as a return "
+ "value");
+ return error_mark_node;
+ }
+
+ new_mod_list = push_stmt_list ();
retval_expr = TREE_OPERAND (expr, 0);
- new_var = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE (retval_expr));
+ new_var = create_temporary_var (TREE_TYPE (retval_expr));
+ add_decl_expr (new_var);
new_mod = expand_an_in_modify_expr (loc, new_var, NOP_EXPR,
- TREE_OPERAND (retval_expr, 1),
- tf_warning_or_error);
+ TREE_OPERAND (retval_expr, 1),
+ tf_warning_or_error);
TREE_OPERAND (retval_expr, 1) = new_var;
TREE_OPERAND (expr, 0) = retval_expr;
- append_to_statement_list_force (new_mod, &new_mod_list);
- append_to_statement_list_force (expr, &new_mod_list);
+ add_stmt (new_mod);
+ add_stmt (expr);
+ new_mod_list = pop_stmt_list (new_mod_list);
return new_mod_list;
}
@@ -1290,19 +1225,21 @@ expand_array_notation_exprs (tree t)
else
t = expand_array_notation_exprs (t);
return t;
-
- case SWITCH_EXPR:
- t = cp_expand_cond_array_notations (t);
- if (TREE_CODE (t) == SWITCH_EXPR)
- SWITCH_BODY (t) = expand_array_notation_exprs (SWITCH_BODY (t));
- else
- t = expand_array_notation_exprs (t);
- return t;
- case FOR_STMT:
+ case FOR_STMT:
+ if (contains_array_notation_expr (FOR_COND (t)))
+ {
+ error_at (EXPR_LOCATION (FOR_COND (t)),
+ "array notation cannot be used in a condition for "
+ "a for-loop");
+ return error_mark_node;
+ }
/* FIXME: Add a check for CILK_FOR_STMT here when we add Cilk tasking
keywords. */
if (TREE_CODE (t) == FOR_STMT)
- FOR_BODY (t) = expand_array_notation_exprs (FOR_BODY (t));
+ {
+ FOR_BODY (t) = expand_array_notation_exprs (FOR_BODY (t));
+ FOR_EXPR (t) = expand_array_notation_exprs (FOR_EXPR (t));
+ }
else
t = expand_array_notation_exprs (t);
return t;
@@ -1322,44 +1259,39 @@ expand_array_notation_exprs (tree t)
t = expand_array_notation_exprs (t);
return t;
case SWITCH_STMT:
- t = cp_expand_cond_array_notations (t);
- /* If the above function added some extra instructions above the original
- switch statement, then we can't assume it is still SWITCH_STMT so we
- have to check again. */
- if (TREE_CODE (t) == SWITCH_STMT)
+ if (contains_array_notation_expr (SWITCH_STMT_COND (t)))
{
- if (SWITCH_STMT_BODY (t))
- SWITCH_STMT_BODY (t) =
- expand_array_notation_exprs (SWITCH_STMT_BODY (t));
+ error_at (EXPR_LOCATION (SWITCH_STMT_COND (t)),
+ "array notation cannot be used as a condition for "
+ "switch statement");
+ return error_mark_node;
}
- else
- t = expand_array_notation_exprs (t);
+ if (SWITCH_STMT_BODY (t))
+ SWITCH_STMT_BODY (t) =
+ expand_array_notation_exprs (SWITCH_STMT_BODY (t));
return t;
case WHILE_STMT:
- t = cp_expand_cond_array_notations (t);
- /* If the above function added some extra instructions above the original
- while statement, then we can't assume it is still WHILE_STMTso we
- have to check again. */
- if (TREE_CODE (t) == WHILE_STMT)
+ if (contains_array_notation_expr (WHILE_COND (t)))
{
- if (WHILE_BODY (t))
- WHILE_BODY (t) = expand_array_notation_exprs (WHILE_BODY (t));
+ if (EXPR_LOCATION (WHILE_COND (t)) != UNKNOWN_LOCATION)
+ loc = EXPR_LOCATION (WHILE_COND (t));
+ error_at (loc, "array notation cannot be used as a condition for "
+ "while statement");
+ return error_mark_node;
}
- else
- t = expand_array_notation_exprs (t);
+ if (WHILE_BODY (t))
+ WHILE_BODY (t) = expand_array_notation_exprs (WHILE_BODY (t));
return t;
case DO_STMT:
- t = cp_expand_cond_array_notations (t);
- /* If the above function added some extra instructions above the original
- do-while statement, then we can't assume it is still DO_STMT so we
- have to check again. */
- if (TREE_CODE (t) == DO_STMT)
- {
- if (DO_BODY (t))
- DO_BODY (t) = expand_array_notation_exprs (DO_BODY (t));
+ if (contains_array_notation_expr (DO_COND (t)))
+ {
+ error_at (EXPR_LOCATION (DO_COND (t)),
+ "array notation cannot be used as a condition for a "
+ "do-while statement");
+ return error_mark_node;
}
- else
- t = expand_array_notation_exprs (t);
+ if (DO_BODY (t))
+ DO_BODY (t) = expand_array_notation_exprs (DO_BODY (t));
return t;
default:
if (is_expr)
@@ -1380,59 +1312,66 @@ expand_array_notation_exprs (tree t)
return t;
}
-/* Given the base of an array (ARRAY), the START_INDEX, the number of elements
- to be accessed (LENGTH) and the STRIDE, construct an ARRAY_NOTATION_REF tree
- of type TYPE and return it. Restrictions on START_INDEX, LENGTH and STRIDE
- are the same as that of index field passed into ARRAY_REF. The only
- additional restriction is that, unlike index in ARRAY_REF, stride, length
- and start_index cannot contain array notations. */
+/* Given the base of an array (ARRAY), the START (start_index), the number of
+ elements to be accessed (LENGTH) and the STRIDE, construct an
+ ARRAY_NOTATION_REF tree of type TYPE and return it. Restrictions on START,
+ LENGTH and STRIDE are the same as that of index field passed into ARRAY_REF.
+ The only additional restriction is that, unlike index in ARRAY_REF, stride,
+ length and start_index cannot contain array notations. */
tree
-build_array_notation_ref (location_t loc, tree array, tree start_index,
- tree length, tree stride, tree type)
+build_array_notation_ref (location_t loc, tree array, tree start, tree length,
+ tree stride, tree type)
{
tree array_ntn_expr = NULL_TREE;
-
- /* When dealing with templates, do the type checking at a later time. */
- if (processing_template_decl || !type)
+
+ /* If we enter the then-case of the if-statement below, we have hit a case
+ like this: ARRAY [:]. */
+ if (!start && !length)
{
- if (!type && TREE_TYPE (array))
- type = TREE_TYPE (array);
- array_ntn_expr = build_min_nt_loc (loc, ARRAY_NOTATION_REF, array,
- start_index, length, stride, type,
- NULL_TREE);
- TREE_TYPE (array_ntn_expr) = type;
+ if (TREE_CODE (type) != ARRAY_TYPE)
+ {
+ error_at (loc, "start-index and length fields necessary for "
+ "using array notation in pointers or records");
+ return error_mark_node;
+ }
+ tree domain = TYPE_DOMAIN (type);
+ if (!domain)
+ {
+ error_at (loc, "start-index and length fields necessary for "
+ "using array notation with array of unknown bound");
+ return error_mark_node;
+ }
+ start = cp_fold_convert (ptrdiff_type_node, TYPE_MINVAL (domain));
+ length = size_binop (PLUS_EXPR, TYPE_MAXVAL (domain), size_one_node);
+ length = cp_fold_convert (ptrdiff_type_node, length);
}
- if (!stride)
- {
- if (TREE_CONSTANT (start_index) && TREE_CONSTANT (length)
- && TREE_CODE (start_index) != VAR_DECL
- && TREE_CODE (length) != VAR_DECL
- && tree_int_cst_lt (length, start_index))
- stride = build_int_cst (TREE_TYPE (start_index), -1);
- else
- stride = build_int_cst (TREE_TYPE (start_index), 1);
+
+ if (!stride)
+ stride = build_one_cst (ptrdiff_type_node);
+
+ /* When dealing with templates, triplet type-checking will be done in pt.c
+ after type substitution. */
+ if (processing_template_decl
+ && (type_dependent_expression_p (array)
+ || type_dependent_expression_p (length)
+ || type_dependent_expression_p (start)
+ || type_dependent_expression_p (stride)))
+ array_ntn_expr = build_min_nt_loc (loc, ARRAY_NOTATION_REF, array, start,
+ length, stride, NULL_TREE);
+ else
+ {
+ if (!cilkplus_an_triplet_types_ok_p (loc, start, length, stride, type))
+ return error_mark_node;
+ array_ntn_expr = build4 (ARRAY_NOTATION_REF, NULL_TREE, array, start,
+ length, stride);
}
+ if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == POINTER_TYPE)
+ TREE_TYPE (array_ntn_expr) = TREE_TYPE (type);
+ else
+ gcc_unreachable ();
- if (!cilkplus_an_triplet_types_ok_p (loc, start_index, length, stride, type))
- return error_mark_node;
-
- if (!processing_template_decl)
- {
- array_ntn_expr = build4 (ARRAY_NOTATION_REF, NULL_TREE, NULL_TREE,
- NULL_TREE, NULL_TREE, NULL_TREE);
- ARRAY_NOTATION_ARRAY (array_ntn_expr) = array;
- ARRAY_NOTATION_START (array_ntn_expr) = start_index;
- ARRAY_NOTATION_LENGTH (array_ntn_expr) = length;
- ARRAY_NOTATION_STRIDE (array_ntn_expr) = stride;
- if (type && (TREE_CODE (type) == ARRAY_TYPE
- || TREE_CODE (type) == POINTER_TYPE))
- TREE_TYPE (array_ntn_expr) = TREE_TYPE (type);
- else
- TREE_TYPE (array_ntn_expr) = type;
- }
SET_EXPR_LOCATION (array_ntn_expr, loc);
-
return array_ntn_expr;
}
@@ -1462,20 +1401,9 @@ cilkplus_an_triplet_types_ok_p (location_t loc, tree start_index, tree length,
}
if (!TREE_CODE (type) == FUNCTION_TYPE)
{
- error_at (loc, "array notations cannot be used with function type");
+ error_at (loc, "array notation cannot be used with function type");
return false;
}
- while (type && (TREE_CODE (type) == POINTER_TYPE
- || TREE_CODE (type) == ARRAY_TYPE))
- {
- type = TREE_TYPE (type);
- if (type && TREE_CODE (type) == FUNCTION_TYPE)
- {
- error_at (loc, "array notations cannot be used with function pointer"
- " arrays");
- return false;
- }
- }
if (!find_rank (loc, start_index, start_index, false, &start_rank)
|| !find_rank (loc, length, length, false, &length_rank)
|| !find_rank (loc, stride, stride, false, &stride_rank))