@@ -1,7 +1,11 @@
+2013-03-22 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * c-pretty-print.c (pp_c_expression): Added ARRAY_NOTATION_REF case.
+
2013-03-20 Balaji V. Iyer <balaji.v.iyer@intel.com>
* 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.
@@ -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;
}
}
@@ -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 */
@@ -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:
old mode 100644
new mode 100755
@@ -31,19 +31,17 @@
#include "gcc.h"
#include "c-family/c-common.h"
-void replace_array_notations (tree *, bool, vec<tree, va_gc> *,
+static void replace_array_notations (tree *, bool, vec<tree, va_gc> *,
vec<tree, va_gc> *);
-void find_rank (tree, bool, size_t *);
-void extract_array_notation_exprs (tree, bool, vec<tree, va_gc> **);
-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<tree, va_gc> **);
+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<tree, va_gc> *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<tree, va_gc> **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<tree, va_gc> *list,
vec<tree, va_gc> *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<tree, va_gc> *lhs_list = NULL, *rhs_list = NULL;
tree new_var = NULL_TREE, builtin_loop = NULL_TREE;
+ tree begin_var, lngth_var, strde_var;
size_t rhs_list_size = 0, lhs_list_size = 0;
/* 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:
- * <if_stmt_label>: (in order from outermost to innermost)
- * if (cond_expr) then go to body_label
- * else go to exit_label
- * <body_label>:
- * array expression
- *
- * (the increment, goto and exit_label goes from innermost to
- * outermost).
- * ii++ and jj++
- * go to if_stmt_label
- * <exit_label>:
- * <REST OF CODE>
- */
+ <if_stmt_label>: (in order from outermost to innermost)
+ if (cond_expr) then go to body_label
+ else go to exit_label
+ <body_label>:
+ array expression
+
+ (the increment, goto and exit_label goes from innermost to
+ outermost).
+ ii++ and jj++
+ go to if_stmt_label
+ <exit_label>:
+ <REST OF CODE>
+ */
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;
}
-
@@ -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;
@@ -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.");
@@ -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
@@ -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++)
new file mode 100644
@@ -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
+# <http://www.gnu.org/licenses/>.
+
+# Written by Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+
+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
deleted file mode 100644
@@ -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
-# <http://www.gnu.org/licenses/>.
-
-# Written by Balaji V. Iyer <balaji.v.iyer@intel.com>
-
-
-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
new file mode 100644
@@ -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
+# <http://www.gnu.org/licenses/>.
+
+# Written by Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+
+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
@@ -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" } */
}
deleted file mode 100644
@@ -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
-# <http://www.gnu.org/licenses/>.
-
-# Written by Balaji V. Iyer <balaji.v.iyer@intel.com>
-
-
-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
@@ -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;
}
@@ -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;
}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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
+# <http://www.gnu.org/licenses/>.
+
+# This file was written by Balaji V. Iyer <balaji.v.iyer@intel.com>
+# 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
new file mode 100644
@@ -0,0 +1,82 @@
+#ifdef HAVE_IO
+#include <stdio.h>
+#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;
+}
deleted file mode 100644
@@ -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
-# <http://www.gnu.org/licenses/>.
-
-# This file was written by Balaji V. Iyer <balaji.v.iyer@intel.com>
-# 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