diff --git a/gcc/c-family/ChangeLog.cilkplus b/gcc/c-family/ChangeLog.cilkplus index 6591fd1..10db29b 100644 --- a/gcc/c-family/ChangeLog.cilkplus +++ b/gcc/c-family/ChangeLog.cilkplus @@ -1,7 +1,11 @@ +2013-03-22 Balaji V. Iyer + + * c-pretty-print.c (pp_c_expression): Added ARRAY_NOTATION_REF case. + 2013-03-20 Balaji V. Iyer * c-common.c (c_define_builtins): When cilkplus is enabled, the - function array_notation_init_builtins() is called. + function array_notation_init_builtins is called. (c_common_init_ts): Added ARRAY_NOTATION_REF as typed. * c-common.def (ARRAY_NOTATION_REF): New tree. * c-common.h (build_array_notation_expr): New function declaration. diff --git a/gcc/c-family/array-notation-common.c b/gcc/c-family/array-notation-common.c index 7089c8e..b775225 100644 --- a/gcc/c-family/array-notation-common.c +++ b/gcc/c-family/array-notation-common.c @@ -29,19 +29,6 @@ along with GCC; see the file COPYING3. If not see #include "tree-iterator.h" #include "diagnostic-core.h" -int extract_sec_implicit_index_arg (location_t, tree); -bool is_sec_implicit_index_fn (tree); -void array_notation_init_builtins (void); - -/* Mark the FNDECL as cold, meaning that the function specified by FNDECL is - not run as is. */ - -static void -mark_cold (tree fndecl) -{ - DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("cold"), NULL_TREE, - DECL_ATTRIBUTES (fndecl)); -} /* This function inititializes array notation specific builtin information. */ @@ -54,67 +41,56 @@ array_notation_init_builtins (void) func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_add", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_mul", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_all_zero", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_any_zero", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_max", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_min", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_min_ind", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_max_ind", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_any_nonzero", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_all_nonzero", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, integer_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_implicit_index", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, @@ -167,25 +143,23 @@ is_sec_implicit_index_fn (tree func_name) sec_implicit_index function. FN's location in the source file is is indicated by LOCATION. */ -int +HOST_WIDE_INT extract_sec_implicit_index_arg (location_t location, tree fn) { tree fn_arg; HOST_WIDE_INT return_int = 0; - if (!fn) - return -1; if (TREE_CODE (fn) == CALL_EXPR) { fn_arg = CALL_EXPR_ARG (fn, 0); if (really_constant_p (fn_arg)) - return_int = (int) int_cst_value (fn_arg); + return_int = int_cst_value (fn_arg); else { if (location == UNKNOWN_LOCATION && EXPR_HAS_LOCATION (fn)) location = EXPR_LOCATION (fn); error_at (location, "__sec_implicit_index parameter must be a " - "constant integer expression"); + "integer constant expression"); return -1; } } diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index edcff2e..e07085d 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -541,7 +541,7 @@ extern tree build_modify_expr (location_t, tree, tree, enum tree_code, extern tree build_array_notation_expr (location_t, tree, tree, enum tree_code, location_t, tree, tree); extern tree build_array_notation_ref (location_t, tree, tree, tree, tree, tree); -extern void find_rank (tree, bool, size_t *); +extern bool find_rank (location_t, tree, tree, bool, size_t *); extern tree build_indirect_ref (location_t, tree, ref_operator); extern int field_decl_cmp (const void *, const void *); @@ -1173,5 +1173,10 @@ typedef enum array_notation_reduce_type { extern int extract_sec_implicit_index_arg (location_t, tree); extern bool is_sec_implicit_index_fn (tree); extern void array_notation_init_builtins (void); +extern struct c_expr fix_array_notation_expr (location_t, enum tree_code, + struct c_expr); +extern bool contains_array_notation_expr (tree); +extern tree expand_array_notation_exprs (tree); +extern tree fix_conditional_array_notations (tree); #endif /* ! GCC_C_COMMON_H */ diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c index 30c8e80..b8af90c 100644 --- a/gcc/c-family/c-pretty-print.c +++ b/gcc/c-family/c-pretty-print.c @@ -1479,11 +1479,11 @@ pp_c_postfix_expression (c_pretty_printer *pp, tree e) case ARRAY_NOTATION_REF: pp_postfix_expression (pp, ARRAY_NOTATION_ARRAY (e)); pp_c_left_bracket (pp); - pp_postfix_expression (pp, ARRAY_NOTATION_START (e)); + pp_expression (pp, ARRAY_NOTATION_START (e)); pp_colon (pp); - pp_postfix_expression (pp, ARRAY_NOTATION_LENGTH (e)); + pp_expression (pp, ARRAY_NOTATION_LENGTH (e)); pp_colon (pp); - pp_postfix_expression (pp, ARRAY_NOTATION_STRIDE (e)); + pp_expression (pp, ARRAY_NOTATION_STRIDE (e)); pp_c_right_bracket (pp); break; @@ -2161,6 +2161,7 @@ pp_c_expression (c_pretty_printer *pp, tree e) case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: case ARRAY_REF: + case ARRAY_NOTATION_REF: case CALL_EXPR: case COMPONENT_REF: case BIT_FIELD_REF: diff --git a/gcc/c/c-array-notation.c b/gcc/c/c-array-notation.c old mode 100644 new mode 100755 index a3e754a..3d36382 --- a/gcc/c/c-array-notation.c +++ b/gcc/c/c-array-notation.c @@ -31,19 +31,17 @@ #include "gcc.h" #include "c-family/c-common.h" -void replace_array_notations (tree *, bool, vec *, +static void replace_array_notations (tree *, bool, vec *, vec *); -void find_rank (tree, bool, size_t *); -void extract_array_notation_exprs (tree, bool, vec **); -tree fix_conditional_array_notations (tree); -struct c_expr fix_array_notation_expr (location_t, enum tree_code, - struct c_expr); -bool is_builtin_array_notation_fn (tree func_name, an_reduce_type *type); +static void extract_array_notation_exprs (tree, bool, vec **); +static bool is_builtin_array_notation_fn (tree func_name, an_reduce_type *type); static tree fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var); -bool contains_array_notation_expr (tree expr); -tree expand_array_notation_exprs (tree t); +/* This structure holds all the scalar values and its appropriate variable + replacment. It is mainly used by the function that pulls all the invariant + parts that should be executed only once that comes with array notation + expressions. */ struct inv_list { vec *list_values; @@ -51,72 +49,80 @@ struct inv_list }; -/* Returns the rank of ARRAY through the *RANK. The user can specify whether - (s)he wants to step into array_notation-specific builtin functions - (specified by the IGNORE_BUILTIN_FN). +/* Sets *RANK of expression ARRAY, ignoring array notation specific built-in + functions if IGNORE_BUILTIN_FN is true. The ORIG_EXPR is printed out if an + error occured in the rank calculation. The functions returns false if it + encounters an error in rank calculation. For example, an array notation of A[:][:] or B[0:10][0:5:2] or C[5][:][1:0] all have a rank of 2. */ -void -find_rank (tree array, bool ignore_builtin_fn, size_t *rank) +bool +find_rank (location_t loc, tree orig_expr, tree array, bool ignore_builtin_fn, + size_t *rank) { tree ii_tree; - size_t current_rank = 0, ii = 0; + size_t ii = 0, current_rank = 0; an_reduce_type dummy_type = REDUCE_UNKNOWN; + if (!array) - return; + return true; else if (TREE_CODE (array) == ARRAY_NOTATION_REF) { for (ii_tree = array; ii_tree && TREE_CODE (ii_tree) == ARRAY_NOTATION_REF; ii_tree = ARRAY_NOTATION_ARRAY (ii_tree)) current_rank++; - if (*rank == 0) - *rank = current_rank; + if (*rank == 0) + *rank = current_rank; + else if (*rank != current_rank) + { + error_at (loc, "rank mismatch in expression %qE", orig_expr); + return false; + } } else if (TREE_CODE (array) == STATEMENT_LIST) { tree_stmt_iterator ii_tsi; for (ii_tsi = tsi_start (array); !tsi_end_p (ii_tsi); tsi_next (&ii_tsi)) - find_rank (*tsi_stmt_ptr (ii_tsi), ignore_builtin_fn, rank); + if (!find_rank (loc, orig_expr, *tsi_stmt_ptr (ii_tsi), + ignore_builtin_fn, rank)) + return false; } else { if (TREE_CODE (array) == CALL_EXPR) { tree func_name = CALL_EXPR_FN (array); + tree arg; + call_expr_arg_iterator iter; if (TREE_CODE (func_name) == ADDR_EXPR) if (!ignore_builtin_fn) if (is_builtin_array_notation_fn (func_name, &dummy_type)) - /* If it is a builtin function, then we know it returns a - scalar. */ - return; - if (TREE_CODE (TREE_OPERAND (array, 0)) == INTEGER_CST) - { - int length = TREE_INT_CST_LOW (TREE_OPERAND (array, 0)); - for (ii = 0; ii < (size_t) length; ii++) - find_rank (TREE_OPERAND (array, ii), ignore_builtin_fn, rank); - } - else - gcc_unreachable (); + /* If it is a builtin function, then it returns a scalar. */ + return true; + + FOR_EACH_CALL_EXPR_ARG (arg, iter, array) + if (!find_rank (loc, orig_expr, arg, ignore_builtin_fn, rank)) + return false; } else for (ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (array)); ii++) - find_rank (TREE_OPERAND (array, ii), ignore_builtin_fn, rank); + if (!find_rank (loc, orig_expr, TREE_OPERAND (array, ii), + ignore_builtin_fn, rank)) + return false; } - return; + return true; } -/* Extracts all the array notations specified in NODE and stores them in a - dynamic tree array of ARRAY_LIST whose size is stored in *LIST_SIZE. The - user can specify if (s)he wants to ignore the array notations inside the - array-notation specific builtin functions (by setting IGNORE_BUILTIN_FN to - true). */ +/* Extracts all array notations in NODE ans stores in ARRAY_LIST. If + IGNORE_BUILTIN_FN is set, then array notations inside array notation + specific builtin functions are ignored. The NODE can be anything from a + full function to a single variable. */ -void +static void extract_array_notation_exprs (tree node, bool ignore_builtin_fn, vec **array_list) { @@ -148,6 +154,8 @@ extract_array_notation_exprs (tree node, bool ignore_builtin_fn, } else if (TREE_CODE (node) == CALL_EXPR) { + tree arg; + call_expr_arg_iterator iter; if (is_builtin_array_notation_fn (CALL_EXPR_FN (node), &dummy_type)) { if (ignore_builtin_fn) @@ -163,17 +171,9 @@ extract_array_notation_exprs (tree node, bool ignore_builtin_fn, vec_safe_push (*array_list, node); return; } - if (TREE_CODE (TREE_OPERAND (node, 0)) == INTEGER_CST) - { - int length = TREE_INT_CST_LOW (TREE_OPERAND (node, 0)); - for (ii = 0; ii < (size_t) length; ii++) - extract_array_notation_exprs - (TREE_OPERAND (node, ii), ignore_builtin_fn, array_list); - } - else - gcc_unreachable (); /* We should not get here. */ - + FOR_EACH_CALL_EXPR_ARG (arg, iter, node) + extract_array_notation_exprs (arg, ignore_builtin_fn, array_list); } else for (ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (node)); ii++) @@ -183,15 +183,12 @@ extract_array_notation_exprs (tree node, bool ignore_builtin_fn, } -/* Replaces all occurances of array notations in tree ORIG that matches the - ones in LIST with the one in ARRAY_OPERAND. The size of list and - ARRAY_OPERAND is ARRAY_SIZE. For example, ARRAY_OPERAND[x] for some index - 'x' will have the equivalent ARRAY_REF for the ARRAY_NOTATION_REF specified - in LIST[x]. The user can specify if (s)he wants to ignore the array - notations inside the array-notation specific builtin functions (using the - bool variable IGNORE_BUILTIN_FN). */ +/* Replaces all the occurances of array notations in *LIST with the appropriate + one in ARRAY_OPERAND. If IGNORE_BUILTIN_FN is set, then array notations + inside array-notation specific builtin functions are ignored. ORIG can be + anything from a collection of statement lists to a single variable. */ -void +static void replace_array_notations (tree *orig, bool ignore_builtin_fn, vec *list, vec *array_operand) @@ -200,7 +197,7 @@ replace_array_notations (tree *orig, bool ignore_builtin_fn, tree node = NULL_TREE, node_replacement = NULL_TREE; an_reduce_type dummy_type = REDUCE_UNKNOWN; - if (vec_safe_length (list) == 0 || !*orig) + if (!*orig || vec_safe_length (list) == 0) return; if (TREE_CODE (*orig) == ARRAY_NOTATION_REF) @@ -221,6 +218,8 @@ replace_array_notations (tree *orig, bool ignore_builtin_fn, } else if (TREE_CODE (*orig) == CALL_EXPR) { + tree arg; + call_expr_arg_iterator iter; if (is_builtin_array_notation_fn (CALL_EXPR_FN (*orig), &dummy_type)) { if (!ignore_builtin_fn) @@ -244,16 +243,14 @@ replace_array_notations (tree *orig, bool ignore_builtin_fn, } return; } - if (TREE_CODE (TREE_OPERAND (*orig, 0)) == INTEGER_CST) + ii = 0; + FOR_EACH_CALL_EXPR_ARG (arg, iter, *orig) { - int length = TREE_INT_CST_LOW (TREE_OPERAND (*orig, 0)); - for (ii = 0; ii < (size_t) length; ii++) - replace_array_notations - (&TREE_OPERAND (*orig, ii), ignore_builtin_fn, list, - array_operand); - } - else - gcc_unreachable (); /* We should not get here! */ + replace_array_notations (&arg, ignore_builtin_fn, list, + array_operand); + CALL_EXPR_ARG (*orig, ii) = arg; + ii++; + } } else { @@ -264,9 +261,9 @@ replace_array_notations (tree *orig, bool ignore_builtin_fn, return; } -/* This function will find all the scalar expressions in *TP and push it in - DATA struct, typecasted to (void *). If *WALK_SUBTREES is set to 0 then - we have do not go into the *TP's subtrees. */ +/* Find all the scalar expressions in *TP and push it in DATA struct, + typecasted to (void *). If *WALK_SUBTREES is set to 0 then do not go into + the *TP's subtrees. */ static tree find_inv_trees (tree *tp, int *walk_subtrees, void *data) @@ -322,7 +319,9 @@ replace_inv_trees (tree *tp, int *walk_subtrees, void *data) return NULL_TREE; } -/* Replaces all the scalar expressions in *NODE. */ +/* 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. */ tree replace_invariant_exprs (tree *node) @@ -391,13 +390,16 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, tree ii_tree = NULL_TREE, new_modify_expr; 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; /* 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) return error_mark_node; - find_rank (rhs, false, &rhs_rank); + + if (!find_rank (location, rhs, rhs, false, &rhs_rank)) + return error_mark_node; extract_array_notation_exprs (rhs, false, &rhs_list); rhs_list_size = vec_safe_length (rhs_list); @@ -434,8 +436,11 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, lhs_rank = 0; rhs_rank = 0; - find_rank (lhs, true, &lhs_rank); - find_rank (rhs, true, &rhs_rank); + if (!find_rank (location, lhs, lhs, true, &lhs_rank)) + return error_mark_node; + + if (!find_rank (location, rhs, rhs, true, &rhs_rank)) + return error_mark_node; if (lhs_rank == 0 && rhs_rank == 0) { @@ -466,12 +471,22 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, if (lhs_rank == 0 && rhs_rank != 0 && TREE_CODE (rhs) != CALL_EXPR) { tree rhs_base = rhs; - for (ii = 0; ii < (size_t) rhs_rank; ii++) - rhs_base = ARRAY_NOTATION_ARRAY (rhs); + if (TREE_CODE (rhs_base) == ARRAY_NOTATION_REF) + { + for (ii = 0; ii < (size_t) rhs_rank; ii++) + rhs_base = ARRAY_NOTATION_ARRAY (rhs); - error_at (location, "%qD cannot be scalar when %qD is not", lhs, - rhs_base); - return error_mark_node; + error_at (location, "%qE cannot be scalar when %qE is not", lhs, + rhs_base); + return error_mark_node; + } + else + { + error_at (location, "%qE cannot be scalar when %qE is not", lhs, + rhs_base); + return error_mark_node; + } + } if (lhs_rank != 0 && rhs_rank != 0 && lhs_rank != rhs_rank) { @@ -491,6 +506,72 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, return error_mark_node; } + /* 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); + + begin_var = build_decl (location, VAR_DECL, NULL_TREE, + integer_type_node); + lngth_var = build_decl (location, VAR_DECL, NULL_TREE, + integer_type_node); + strde_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))); + add_stmt (build_modify_expr (location, lngth_var, TREE_TYPE (lngth_var), + NOP_EXPR, location, array_lngth, + TREE_TYPE (array_lngth))); + add_stmt (build_modify_expr (location, strde_var, TREE_TYPE (strde_var), + NOP_EXPR, location, array_strde, + TREE_TYPE (array_strde))); + + ARRAY_NOTATION_START (array_node) = begin_var; + ARRAY_NOTATION_LENGTH (array_node) = lngth_var; + 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); + + begin_var = build_decl (location, VAR_DECL, NULL_TREE, + integer_type_node); + lngth_var = build_decl (location, VAR_DECL, NULL_TREE, + integer_type_node); + strde_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))); + add_stmt (build_modify_expr (location, lngth_var, + TREE_TYPE (lngth_var), + NOP_EXPR, location, array_lngth, + TREE_TYPE (array_lngth))); + add_stmt (build_modify_expr (location, strde_var, + TREE_TYPE (strde_var), + NOP_EXPR, location, array_strde, + TREE_TYPE (array_strde))); + + ARRAY_NOTATION_START (array_node) = begin_var; + ARRAY_NOTATION_LENGTH (array_node) = lngth_var; + ARRAY_NOTATION_STRIDE (array_node) = strde_var; + } + } + lhs_vector = XNEWVEC (bool *, lhs_list_size); for (ii = 0; ii < lhs_list_size; ii++) lhs_vector[ii] = XNEWVEC (bool, lhs_rank); @@ -678,8 +759,6 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, rhs_vector[ii][jj] = false; } - - for (ii = 0; ii < lhs_rank; ii++) { if (lhs_vector[0][ii]) @@ -691,7 +770,6 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, NOP_EXPR, location, build_zero_cst (TREE_TYPE (lhs_var[ii])), TREE_TYPE (lhs_var[ii])); - } } @@ -965,19 +1043,19 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, } /* The following statements will do the following: - * : (in order from outermost to innermost) - * if (cond_expr) then go to body_label - * else go to exit_label - * : - * array expression - * - * (the increment, goto and exit_label goes from innermost to - * outermost). - * ii++ and jj++ - * go to if_stmt_label - * : - * - */ + : (in order from outermost to innermost) + if (cond_expr) then go to body_label + else go to exit_label + : + array expression + + (the increment, goto and exit_label goes from innermost to + outermost). + ii++ and jj++ + go to if_stmt_label + : + + */ for (ii = 0; ii < MAX (lhs_rank, rhs_rank); ii++) @@ -1012,7 +1090,9 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, /* Encloses the conditional statement passed in STMT with a loop around it and replaces the condition in STMT with a ARRAY_REF tree-node to the array. - The condition must have a ARRAY_NOTATION_REF tree. */ + The condition must have a ARRAY_NOTATION_REF tree. An expansion of array + notation in STMT is returned in a STATEMENT_LIST. */ + static tree fix_conditional_array_notations_1 (tree stmt) @@ -1027,8 +1107,9 @@ fix_conditional_array_notations_1 (tree stmt) tree *body_label, *body_label_expr, *exit_label, *exit_label_expr; tree *compare_expr, *if_stmt_label, *expr_incr, *ind_init; bool **count_down, **array_vector; + tree begin_var, lngth_var, strde_var; location_t location = UNKNOWN_LOCATION; - + if (TREE_CODE (stmt) == COND_EXPR) cond = COND_EXPR_COND (stmt); else if (TREE_CODE (stmt) == SWITCH_EXPR) @@ -1037,7 +1118,11 @@ fix_conditional_array_notations_1 (tree stmt) /* Otherwise dont even touch the statement. */ return stmt; - find_rank (cond, false, &rank); + location = EXPR_LOCATION (stmt); + + if (!find_rank (location, cond, cond, false, &rank)) + return error_mark_node; + extract_array_notation_exprs (cond, false, &array_list); loop = push_stmt_list (); for (ii = 0; ii < vec_safe_length (array_list); ii++) @@ -1062,7 +1147,9 @@ fix_conditional_array_notations_1 (tree stmt) } } } - find_rank (cond, true, &rank); + + if (!find_rank (location, cond, cond, true, &rank)) + return error_mark_node; if (rank == 0) { add_stmt (stmt); @@ -1076,7 +1163,6 @@ fix_conditional_array_notations_1 (tree stmt) return stmt; list_size = vec_safe_length (array_list); - location = EXPR_LOCATION (stmt); array_ops = XNEWVEC (tree *, list_size); for (ii = 0; ii < list_size; ii++) @@ -1115,6 +1201,42 @@ fix_conditional_array_notations_1 (tree stmt) 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); + + begin_var = build_decl (location, VAR_DECL, NULL_TREE, + integer_type_node); + lngth_var = build_decl (location, VAR_DECL, NULL_TREE, + integer_type_node); + strde_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))); + add_stmt (build_modify_expr (location, lngth_var, + TREE_TYPE (lngth_var), + NOP_EXPR, location, array_lngth, + TREE_TYPE (array_lngth))); + add_stmt (build_modify_expr (location, strde_var, + TREE_TYPE (strde_var), + NOP_EXPR, location, array_strde, + TREE_TYPE (array_strde))); + + ARRAY_NOTATION_START (array_node) = begin_var; + ARRAY_NOTATION_LENGTH (array_node) = lngth_var; + ARRAY_NOTATION_STRIDE (array_node) = strde_var; + } + } + for (ii = 0; ii < list_size; ii++) { tree array_node = (*array_list)[ii]; @@ -1174,7 +1296,6 @@ fix_conditional_array_notations_1 (tree stmt) location, build_int_cst (TREE_TYPE (array_var[ii]), 0), TREE_TYPE (array_var[ii])); - } for (ii = 0; ii < rank ; ii++) @@ -1291,7 +1412,6 @@ fix_conditional_array_notations_1 (tree stmt) XDELETEVEC (if_stmt_label); XDELETEVEC (expr_incr); XDELETEVEC (ind_init); - // XDELETEVEC (array_var); for (ii = 0; ii < list_size; ii++) { @@ -1354,7 +1474,15 @@ fix_array_notation_expr (location_t location, enum tree_code code, tree *compare_expr, *if_stmt_label, *expr_incr, *ind_init; bool **count_down, **array_vector; - find_rank (arg.value, false, &rank); + if (!find_rank (location, arg.value, arg.value, false, &rank)) + { + /* If this function returns a NULL, we convert the tree value in the + structure to error_mark_node and the parser should take care of the + rest. */ + arg.value = error_mark_node; + return arg; + } + if (rank == 0) return arg; @@ -1413,6 +1541,8 @@ fix_array_notation_expr (location_t location, enum tree_code code, jj++; } } + + loop = push_stmt_list (); for (ii = 0; ii < list_size; ii++) { @@ -1451,8 +1581,6 @@ fix_array_notation_expr (location_t location, enum tree_code code, } } - loop = push_stmt_list (); - for (ii = 0; ii < rank; ii++) { array_var[ii] = build_decl (location, VAR_DECL, NULL_TREE, @@ -1531,12 +1659,10 @@ fix_array_notation_expr (location_t location, enum tree_code code, replace_array_notations (&arg.value, 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))); - } + 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++) { @@ -1553,7 +1679,6 @@ fix_array_notation_expr (location_t location, enum tree_code code, array_var[jj], array_length[0][jj]); } } - for (ii = 0; ii < rank; ii++) { @@ -1669,10 +1794,11 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var) || TREE_CODE (func_parm) == EXCESS_PRECISION_EXPR || TREE_CODE (func_parm) == NOP_EXPR) func_parm = TREE_OPERAND (func_parm, 0); - - find_rank (an_builtin_fn, true, &rank); location = EXPR_LOCATION (an_builtin_fn); + + if (!find_rank (location, an_builtin_fn, an_builtin_fn, true, &rank)) + return error_mark_node; if (rank == 0) return an_builtin_fn; @@ -1680,7 +1806,7 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var) && (an_type == REDUCE_MAX_INDEX || an_type == REDUCE_MIN_INDEX)) { error_at (location, "__sec_reduce_min_ind or __sec_reduce_max_ind cannot" - " have arrays with dimension greater than 1."); + " have arrays with dimension greater than 1"); return error_mark_node; } @@ -1712,7 +1838,7 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var) new_var_type = NULL_TREE; break; default: - gcc_unreachable (); /* You should not reach here. */ + gcc_unreachable (); } array_ops = XNEWVEC (tree *, list_size); @@ -1879,12 +2005,11 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var) } 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))); - } + 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++) { @@ -2218,10 +2343,10 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var) return loop; } -/* Returns true of FUNC_NAME is a builtin array notation function. The type of +/* Returns true if FUNC_NAME is a builtin array notation function. The type of function is returned in *TYPE. */ -bool +static bool is_builtin_array_notation_fn (tree func_name, an_reduce_type *type) { const char *function_name = NULL; @@ -2310,7 +2435,7 @@ is_builtin_array_notation_fn (tree func_name, an_reduce_type *type) } -/* Returns true of EXPR (and its subtrees) contain ARRAY_NOTATION_EXPR node. */ +/* Returns true if EXPR (and its subtrees) contain ARRAY_NOTATION_EXPR node. */ bool contains_array_notation_expr (tree expr) @@ -2331,9 +2456,8 @@ contains_array_notation_expr (tree expr) return true; } -/* Replaces array notations in void function call arguments in ARG with loop and - tree-node ARRAY_REF and returns that value in a tree node variable called - LOOP. */ +/* Replaces array notations in void function call arguments in ARG and returns + a STATEMENT_LIST. */ static tree fix_array_notation_call_expr (tree arg) @@ -2347,6 +2471,7 @@ fix_array_notation_call_expr (tree arg) tree *body_label, *body_label_expr, *exit_label, *exit_label_expr; tree *compare_expr, *if_stmt_label, *expr_incr, *ind_init; bool **count_down, **array_vector; + tree begin_var, lngth_var, strde_var; an_reduce_type an_type = REDUCE_UNKNOWN; location_t location = UNKNOWN_LOCATION; @@ -2359,12 +2484,13 @@ fix_array_notation_call_expr (tree arg) return loop; } - find_rank (arg, false, &rank); + if (!find_rank (location, arg, arg, false, &rank)) + return error_mark_node; + if (rank == 0) return arg; extract_array_notation_exprs (arg, true, &array_list); - if (vec_safe_length (array_list) == 0) return arg; @@ -2407,7 +2533,42 @@ fix_array_notation_call_expr (tree arg) count_down[ii] = XNEWVEC (bool, rank); array_var = XNEWVEC (tree, rank); + + loop = 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); + begin_var = build_decl (location, VAR_DECL, NULL_TREE, + integer_type_node); + lngth_var = build_decl (location, VAR_DECL, NULL_TREE, + integer_type_node); + strde_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))); + add_stmt (build_modify_expr (location, lngth_var, + TREE_TYPE (lngth_var), + NOP_EXPR, location, array_lngth, + TREE_TYPE (array_lngth))); + add_stmt (build_modify_expr (location, strde_var, + TREE_TYPE (strde_var), + NOP_EXPR, location, array_strde, + TREE_TYPE (array_strde))); + + ARRAY_NOTATION_START (array_node) = begin_var; + ARRAY_NOTATION_LENGTH (array_node) = lngth_var; + ARRAY_NOTATION_STRIDE (array_node) = strde_var; + } + } for (ii = 0; ii < list_size; ii++) { jj = 0; @@ -2457,8 +2618,6 @@ fix_array_notation_call_expr (tree arg) } } - loop = push_stmt_list (); - for (ii = 0; ii < rank; ii++) { array_var[ii] = build_decl (location, VAR_DECL, NULL_TREE, @@ -2610,7 +2769,9 @@ fix_array_notation_call_expr (tree arg) /* Walks through tree node T and find all the call-statments that do not return - anything and fix up any array notations they may carry. */ + anything and fix up any array notations they may carry. The return value + is the same type as T but with all array notations replaced with appropriate + STATEMENT_LISTS. */ tree expand_array_notation_exprs (tree t) @@ -2665,20 +2826,20 @@ build_array_notation_ref (location_t loc, tree array, tree start_index, tree array_ntn_tree = NULL_TREE; size_t stride_rank = 0, length_rank = 0, start_rank = 0; - if (!TREE_TYPE (start_index) || !INTEGRAL_TYPE_P (TREE_TYPE (start_index))) + if (!INTEGRAL_TYPE_P (TREE_TYPE (start_index))) { error_at (loc, - "start-index of array notation triplet is not an integer."); + "start-index of array notation triplet is not an integer"); return error_mark_node; } - if (!TREE_TYPE (length) || !INTEGRAL_TYPE_P (TREE_TYPE (length))) + if (!INTEGRAL_TYPE_P (TREE_TYPE (length))) { - error_at (loc, "length of array notation triplet is not an integer."); + error_at (loc, "length of array notation triplet is not an integer"); return error_mark_node; } - if (stride && (!TREE_TYPE (stride) || !INTEGRAL_TYPE_P (TREE_TYPE (stride)))) + if (stride && !INTEGRAL_TYPE_P (TREE_TYPE (stride))) { - error_at (loc, "stride of array notation triplet is not an integer."); + error_at (loc, "stride of array notation triplet is not an integer"); return error_mark_node; } if (!stride) @@ -2690,24 +2851,27 @@ build_array_notation_ref (location_t loc, tree array, tree start_index, stride = build_int_cst (TREE_TYPE (start_index), 1); } - find_rank (start_index, false, &start_rank); - find_rank (length, false, &length_rank); - find_rank (stride, false, &stride_rank); + if (!find_rank (loc, start_index, start_index, false, &start_rank)) + return error_mark_node; + if (!find_rank (loc, length, length, false, &length_rank)) + return error_mark_node; + if (!find_rank (loc, stride, stride, false, &stride_rank)) + return error_mark_node; if (start_rank != 0) { error_at (loc, "rank of an array notation triplet's start-index is not " - "zero."); + "zero"); return error_mark_node; } if (length_rank != 0) { - error_at (loc, "rank of an array notation triplet's length is not zero."); + error_at (loc, "rank of an array notation triplet's length is not zero"); return error_mark_node; } if (stride_rank != 0) { - error_at (loc, "rank of array notation triplet's stride is not zero."); + error_at (loc, "rank of array notation triplet's stride is not zero"); return error_mark_node; } @@ -2747,4 +2911,3 @@ find_correct_array_notation_type (tree op) } return return_type; } - diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index ba0a7f9..2ca5a3a 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -11052,14 +11052,14 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, if (TREE_CODE (array_type) == POINTER_TYPE) { error_at (loc, "start-index and length fields necessary for " - "using array notations in pointers."); + "using array notations in pointers"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; } if (TREE_CODE (array_type) == FUNCTION_TYPE) { error_at (loc, "array notations cannot be used with function " - "type."); + "type"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; } @@ -11074,7 +11074,7 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE) { error_at (loc, "array notations cannot be used with " - "function pointer arrays."); + "function pointer arrays"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; @@ -11086,7 +11086,7 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, if (!array_type_domain) { error_at (loc, "start-index and length fields necessary for " - "using array notations in dimensionless arrays."); + "using array notations in dimensionless arrays"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; } @@ -11098,7 +11098,7 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, || !TREE_CONSTANT (TYPE_MAXVAL (array_type_domain))) { error_at (loc, "start-index and length fields necessary for " - "using array notations in variable-length arrays."); + "using array notations in variable-length arrays"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; } @@ -11120,7 +11120,7 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, if (TREE_CODE (array_type) == FUNCTION_TYPE) { error_at (loc, "array notations cannot be used with function " - "type."); + "type"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; } @@ -11138,7 +11138,7 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE) { error_at (loc, "array notations cannot be used with " - "function pointer arrays."); + "function pointer arrays"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 15dc83d..cb2fe4a 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -2309,7 +2309,8 @@ build_array_ref (location_t loc, tree array, tree index) if (flag_enable_cilkplus && contains_array_notation_expr (index)) { size_t rank = 0; - find_rank (index, true, &rank); + if (!find_rank (loc, index, index, true, &rank)) + return error_mark_node; if (rank > 1) { error_at (loc, "rank of the array's index is greater than 1."); diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 627bf69..3ce9969 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -82,6 +82,8 @@ extensions, accepted by GCC in C90 mode and in C++. * x86 specific memory model extensions for transactional memory:: x86 memory models. * Object Size Checking:: Built-in functions for limited buffer overflow checking. +* Cilk Plus Builtins:: Built-in functions that are part of Cilk Plus language + extension. * Other Builtins:: Other built-in functions. * Target Builtins:: Built-in functions specific to particular targets. * Target Format Checks:: Format checks specific to particular targets. @@ -8762,6 +8764,31 @@ Similar to @code{__builtin_bswap32}, except the argument and return types are 64 bit. @end deftypefn +@node Cilk Plus Builtins +@section Cilk Plus C/C++ language extension Built-in Functions. + +GCC provides support for the following built-in reduction funtions if Cilk Plus +is enabled. Cilk Plus can be enabled using the @option{-fcilkplus} flag. + +@itemize @bullet +@item __sec_reduce +@item __sec_reduce_add +@item __sec_reduce_all_nonzero +@item __sec_reduce_all_zero +@item __sec_reduce_any_nonzero +@item __sec_reduce_any_zero +@item __sec_reduce_max +@item __sec_reduce_min +@item __sec_reduce_max_ind +@item __sec_reduce_min_ind +@item __sec_reduce_mul +@item __sec_reduce_mutating +@end itemize + +Further details and examples about these built-in functions are described +in the Cilk Plus language manual which can be found at +@uref{http://www.cilkplus.org}. + @node Target Builtins @section Built-in Functions Specific to Particular Target Machines diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/array_test2.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/array_test2.c index 5fb3680..fd128b1 100644 --- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/array_test2.c +++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/array_test2.c @@ -26,7 +26,7 @@ int main(int argc, char **argv) array[ii] = 10; array2[ii] = 5000000; } - array2[0:10:2] = array[0:10:2]; + array2[0:5:2] = array[0:5:2]; printf("==============================================\n"); for (ii = 0; ii<10; ii++) diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/cilkplus_AN_c_compile.exp b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/cilkplus_AN_c_compile.exp new file mode 100644 index 0000000..a965997 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/cilkplus_AN_c_compile.exp @@ -0,0 +1,34 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Written by Balaji V. Iyer + + +load_lib gcc-dg.exp + +dg-init +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O0 -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O1 -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O2 -ftree-vectorize -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O3 -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O0 -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O1 -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O2 -ftree-vectorize -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O3 -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/array_notation_tests/errors/*.c]] " -O3 -ftree-vectorize -fcilkplus -g" " " +dg-finish diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/compile.exp b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/compile.exp deleted file mode 100644 index 6d7604b..0000000 --- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/compile.exp +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (C) 2013 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -# Written by Balaji V. Iyer - - -load_lib gcc-dg.exp - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O0 -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O1 -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O2 -ftree-vectorize -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O3 -fcilkplus" " " -dg-finish - - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O0 -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O1 -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O2 -ftree-vectorize -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O3 -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/array_notation_tests/errors/*.c]] " -O3 -ftree-vectorize -fcilkplus -g" " " -dg-finish diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/cilkplus_AN_c_errors.exp b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/cilkplus_AN_c_errors.exp new file mode 100644 index 0000000..a965997 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/cilkplus_AN_c_errors.exp @@ -0,0 +1,34 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Written by Balaji V. Iyer + + +load_lib gcc-dg.exp + +dg-init +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O0 -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O1 -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O2 -ftree-vectorize -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O3 -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O0 -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O1 -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O2 -ftree-vectorize -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O3 -fcilkplus" " " +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/array_notation_tests/errors/*.c]] " -O3 -ftree-vectorize -fcilkplus -g" " " +dg-finish diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/decl-ptr-colon.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/decl-ptr-colon.c index 44e7361..4035ed5 100644 --- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/decl-ptr-colon.c +++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/decl-ptr-colon.c @@ -1,16 +1,16 @@ int main(void) { extern int func(int); - int array3[:], x, q; /* { dg-error "array notations cannot be used in declaration." } */ - int array3[1:2:x]; /* { dg-error "array notations cannot be used in declaration." } */ - extern char array3[1:func(x)]; /* { dg-error "array notations cannot be used in declaration." } */ + int array3[:], x, q; /* { dg-error "array notations cannot be used in declaration" } */ + int array3[1:2:x]; /* { dg-error "array notations cannot be used in declaration" } */ + extern char array3[1:func(x)]; /* { dg-error "array notations cannot be used in declaration" } */ int *a, ***b; extern char *c; int array2[10]; - a[:] = 5; /* { dg-error "start-index and length fields necessary for using array notations in pointers." } */ + a[:] = 5; /* { dg-error "start-index and length fields necessary for using array notations in pointers" } */ c[1:2] = 3; /* This is OK. */ (array2)[:] = 5; /* This is OK. */ - b[1:2][1:func(x)][:] = 3; /* { dg-error "start-index and length fields necessary for using array notations in pointers." } */ + b[1:2][1:func(x)][:] = 3; /* { dg-error "start-index and length fields necessary for using array notations in pointers" } */ } diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/errors.exp b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/errors.exp deleted file mode 100644 index 6d7604b..0000000 --- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/errors.exp +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (C) 2013 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -# Written by Balaji V. Iyer - - -load_lib gcc-dg.exp - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O0 -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O1 -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O2 -ftree-vectorize -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O3 -fcilkplus" " " -dg-finish - - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O0 -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O1 -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O2 -ftree-vectorize -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O3 -fcilkplus" " " -dg-finish - -dg-init -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/array_notation_tests/errors/*.c]] " -O3 -ftree-vectorize -fcilkplus -g" " " -dg-finish diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fn_ptr.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fn_ptr.c index 272ef41..82008c0 100644 --- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fn_ptr.c +++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fn_ptr.c @@ -3,16 +3,15 @@ typedef int (*foo)(int); int main(int argc, char **argv) { int array[10], array2[10][10]; - // int array[10], array2[10], value, ii = 0; foo func_array[10]; foo func_array2[10][10]; foo ***func_array_ptr; - array[:] = func_array[:](10); /* { dg-error "array notations cannot be used with function pointer arrays." } */ - func_array[0:5](10); /* { dg-error "array notations cannot be used with function pointer arrays." } */ - func_array2[0:5][:](10); /* { dg-error "array notations cannot be used with function pointer arrays." } */ - array2[0:5][:] = func_array2[0:5][:](10); /* { dg-error "array notations cannot be used with function pointer arrays." } */ - func_array_ptr[0:5][0:4][0:argc:2](argc); /* { dg-error "array notations cannot be used with function pointer arrays." } */ + array[:] = func_array[:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */ + func_array[0:5](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */ + func_array2[0:5][:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */ + array2[0:5][:] = func_array2[0:5][:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */ + func_array_ptr[0:5][0:4][0:argc:2](argc); /* { dg-error "array notations cannot be used with function pointer arrays" } */ return 0; } diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fp_triplet_values.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fp_triplet_values.c index ef39b2b..59c2d1e 100644 --- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fp_triplet_values.c +++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fp_triplet_values.c @@ -25,18 +25,18 @@ void func (int *x) int main2 (int argc, char **argv) { int array[10], array2[10]; - array2[:] = array[1.5:2]; /* { dg-error "start-index of array notation triplet is not an integer." } */ - array2[:] = array[1:2.32333333333]; /* { dg-error "length of array notation triplet is not an integer." } */ - array2[1:2:1.5] = array[:]; /* { dg-error "stride of array notation triplet is not an integer." } */ - func (&array2[1:2.34:3]); /* { dg-error "length of array notation triplet is not an integer." } */ - array2[1.43:9]++; /* { dg-error "start-index of array notation triplet is not an integer." } */ - array2[1:9.3]++; /* { dg-error "length of array notation triplet is not an integer." } */ - array2[1:9:0.3]++; /* { dg-error "stride of array notation triplet is not an integer." } */ + array2[:] = array[1.5:2]; /* { dg-error "start-index of array notation triplet is not an integer" } */ + array2[:] = array[1:2.32333333333]; /* { dg-error "length of array notation triplet is not an integer" } */ + array2[1:2:1.5] = array[:]; /* { dg-error "stride of array notation triplet is not an integer" } */ + func (&array2[1:2.34:3]); /* { dg-error "length of array notation triplet is not an integer" } */ + array2[1.43:9]++; /* { dg-error "start-index of array notation triplet is not an integer" } */ + array2[1:9.3]++; /* { dg-error "length of array notation triplet is not an integer" } */ + array2[1:9:0.3]++; /* { dg-error "stride of array notation triplet is not an integer" } */ - ++array2[1:q:3]; /* { dg-error "length of array notation triplet is not an integer." } */ - array2[:] = array[q:1:3]; /* { dg-error "start-index of array notation triplet is not an integer." } */ - array2[:] = array[1:q:3]; /* { dg-error "length of array notation triplet is not an integer." } */ - array2[:] = array[1:3:q]; /* { dg-error "stride of array notation triplet is not an integer." } */ - func (&array2[1:q:3]); /* { dg-error "length of array notation triplet is not an integer." } */ + ++array2[1:q:3]; /* { dg-error "length of array notation triplet is not an integer" } */ + array2[:] = array[q:1:3]; /* { dg-error "start-index of array notation triplet is not an integer" } */ + array2[:] = array[1:q:3]; /* { dg-error "length of array notation triplet is not an integer" } */ + array2[:] = array[1:3:q]; /* { dg-error "stride of array notation triplet is not an integer" } */ + func (&array2[1:q:3]); /* { dg-error "length of array notation triplet is not an integer" } */ return 0; } diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/rank_mismatch2.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/rank_mismatch2.c new file mode 100644 index 0000000..77955a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/rank_mismatch2.c @@ -0,0 +1,23 @@ +int function_call (int x) +{ + return x; +} + +int main(int argc, char **argv) +{ + int array[100], array2[100][100]; + + array[:] = array[:] + array2[:][:]; /* { dg-error "rank mismatch in expression" } */ + + if (array[:] + array2[:][:]) /* { dg-error "rank mismatch in expression" } */ + return argc == 5; + + argc += function_call (array[:] + array2[5:10:2][:]); /* { dg-error "rank mismatch in expression" } */ + + argc += function_call (function_call (array[:] + array2[5:10:2][:])); /* { dg-error "rank mismatch in expression" } */ + + argc += __sec_reduce_add (array[:], array2[:][:]); /* { dg-error "rank mismatch in expression" } */ + + argc += __sec_reduce_add (array2[:][:]) + argc; /* This is OK. */ + return argc; +} diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/cilkplus_AN_c_execute.exp b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/cilkplus_AN_c_execute.exp new file mode 100644 index 0000000..37d22c5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/cilkplus_AN_c_execute.exp @@ -0,0 +1,60 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# This file was written by Balaji V. Iyer +# Many thanks to the GCC C-torture contributors. + +verbose "$tool $libdir" 1 + +set library_var [get_multilibs] +dg-init +set CILK_TORTURE_OPTIONS [list \ + { -O0 -fcilkplus -std=c99} \ + { -O1 -fcilkplus -std=c99} \ + { -O2 -fcilkplus -std=c99} \ + { -O3 -fcilkplus -fomit-frame-pointer -funroll-loops -std=c99} \ + { -O3 -fcilkplus -fomit-frame-pointer -funroll-all-loops -finline-functions -std=c99 } \ + { -O3 -fcilkplus -fomit-frame-pointer -funroll-all-loops -finline-functions -ftree-vectorize -std=c99 } \ + { -O3 -g -fcilkplus -std=c99} \ + { -Os -fcilkplus -std=c99} ] + + + +if $tracelevel then { + strace $tracelevel +} + +# load support procs +load_lib torture-options.exp +load_lib c-torture.exp + +torture-init +set-torture-options $CILK_TORTURE_OPTIONS {{}} $CILK_TORTURE_OPTIONS + +# +# main test loop +# + +foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.c]] { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $src] then { + continue + } + + c-torture-execute $src +} + +torture-finish diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/exec-once2.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/exec-once2.c new file mode 100644 index 0000000..ba70ab8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/exec-once2.c @@ -0,0 +1,82 @@ +#ifdef HAVE_IO +#include +#endif + + +int func1(int x) +{ + /* If x == 2 then it should return 0. */ + return (x - 2); +} + +int func2(int x) +{ + /* If x == 2 then it should return 1000. */ + return (x * 500); +} + +int func3 (int x) +{ + /* If x == 2 then it should return 1. */ + /* If x == 1 then it should return 0. */ + return (x-1); +} + +int func4(int x) +{ + if (x > 0) + return x; + else + return x--; +} + + +/* This program makes an assumption that argc == 1. */ +int main (int argc, char **argv) +{ + + int array[2500]; + + /* This should set array[0->999] to 5. */ + array[argc-1:func2(++argc):1] = 5; + array[1000:500:1] = 10; /* set all variables in array[1000-->1499] to 10. */ + array[1500:500:1] = 15; /* set all variables in array[1500-->1999] to 15. */ + array[2000:500:1] = 20; /* set all variables in array[2000-->2499] to 20. */ + array[2000:500:1] = 25; /* set all variables in array[2500-->2999] to 25. */ + array[2000:500:1] = 30; /* set all variables in array[3000-->3499] to 30. */ + + argc = func3 (argc); /* This will set argc back to 1. */ +#if HAVE_IO + printf("argc = %d\n", argc); +#endif + /* If the parameters inside the function get evaluated only once, then this + if statement must work fine, i.e. the triplet values will be 0, 1000, 1. + + Otherwise, the program should crash or give some uneasy value. */ + + /* If done correctly, it should boil down to: array[0:1000:1]. */ + if (array[func3(argc):func2(++argc)] != 5) { +#ifdef HAVE_IO + printf ("Should not be there(1).\n"); +#endif + return 1; + } + + /* If done correctly, it should boil down to: array[999:500:-1]. */ + if (func4(array[func2(argc)-1:func2(argc--):func1(argc)]) != 5) { +#ifdef HAVE_IO + printf ("Should not be there(2).\n"); +#endif + return 1; + } + + /* If done correctly, it should boil down to: array[1000:500:1]. */ + if (func4 (func4(array[func2(argc++):500: func1(argc--)])) != 5) { +#ifdef HAVE_IO + printf ("Should not be there(3).\n"); +#endif + return 1; + } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/execute.exp b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/execute.exp deleted file mode 100644 index 37d22c5..0000000 --- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/execute.exp +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (C) 2013 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -# This file was written by Balaji V. Iyer -# Many thanks to the GCC C-torture contributors. - -verbose "$tool $libdir" 1 - -set library_var [get_multilibs] -dg-init -set CILK_TORTURE_OPTIONS [list \ - { -O0 -fcilkplus -std=c99} \ - { -O1 -fcilkplus -std=c99} \ - { -O2 -fcilkplus -std=c99} \ - { -O3 -fcilkplus -fomit-frame-pointer -funroll-loops -std=c99} \ - { -O3 -fcilkplus -fomit-frame-pointer -funroll-all-loops -finline-functions -std=c99 } \ - { -O3 -fcilkplus -fomit-frame-pointer -funroll-all-loops -finline-functions -ftree-vectorize -std=c99 } \ - { -O3 -g -fcilkplus -std=c99} \ - { -Os -fcilkplus -std=c99} ] - - - -if $tracelevel then { - strace $tracelevel -} - -# load support procs -load_lib torture-options.exp -load_lib c-torture.exp - -torture-init -set-torture-options $CILK_TORTURE_OPTIONS {{}} $CILK_TORTURE_OPTIONS - -# -# main test loop -# - -foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.c]] { - # If we're only testing specific files and this isn't one of them, skip it. - if ![runtest_file_p $runtests $src] then { - continue - } - - c-torture-execute $src -} - -torture-finish