From patchwork Wed Jan 25 20:04:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Iyer, Balaji V" X-Patchwork-Id: 137851 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id DD0ECB6F68 for ; Thu, 26 Jan 2012 07:04:49 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1328126690; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:From:To:Subject:Date:Message-ID:Content-Type: MIME-Version:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=ZH3Fo4B PD/3ALy2ocRRJGspxaaU=; b=edJmZB7x1EiwB73Bp6LVXNvecLwt12bJ5/jw2+/ KC6ablSjG//xbQoi3Pc1H5AAa1RJxUfTcyAZRQR8QueqAJUhDLgc8dxRIwADnb53 igk+Yp3wLB/A/7SsTu9dCZpW+XFehXfosCmQSjzqwTMCcu9iPCvGP7Mji8d20FpS Tv9Y= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:X-ExtLoop1:Received:Received:Received:From:To:Subject:Date:Message-ID:Content-Type:MIME-Version:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=gSuk3DZkT6nJ4ZtuFXksEjNYKhkOkiyQiXsBVISp4j0CQVBJI1BNcGeqTI2CdF EnN7zxI+n9Crx35QdhKCgk3dn7h8njWBmed+3WtL2USXWH26/e2roDyoVbpaWq2H UjCWBGiS/Ud+esC9dGhJE5SZT/tPG4GL7PtV4aVIm4eM0=; Received: (qmail 10125 invoked by alias); 25 Jan 2012 20:04:42 -0000 Received: (qmail 10069 invoked by uid 22791); 25 Jan 2012 20:04:34 -0000 X-SWARE-Spam-Status: No, hits=-4.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, TW_BJ, TW_TM, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mga14.intel.com (HELO mga14.intel.com) (143.182.124.37) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 25 Jan 2012 20:04:14 +0000 Received: from azsmga002.ch.intel.com ([10.2.17.35]) by azsmga102.ch.intel.com with ESMTP; 25 Jan 2012 12:04:13 -0800 X-ExtLoop1: 1 Received: from azsmsx601.amr.corp.intel.com ([10.2.121.193]) by AZSMGA002.ch.intel.com with ESMTP; 25 Jan 2012 12:04:12 -0800 Received: from fmsmsx151.amr.corp.intel.com (10.19.17.220) by azsmsx601.amr.corp.intel.com (10.2.121.193) with Microsoft SMTP Server (TLS) id 8.2.255.0; Wed, 25 Jan 2012 13:04:12 -0700 Received: from fmsmsx101.amr.corp.intel.com ([169.254.1.197]) by FMSMSX151.amr.corp.intel.com ([169.254.6.135]) with mapi id 14.01.0355.002; Wed, 25 Jan 2012 12:04:12 -0800 From: "Iyer, Balaji V" To: "gcc-patches@gcc.gnu.org" Subject: [PATCH][Cilkplus] Builtin ArrayNotation functions Support (for C Compiler) Date: Wed, 25 Jan 2012 20:04:12 +0000 Message-ID: MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hello Everyone, This patch is for the C compiler in Cilkplus branch. This patch will implement builtin array notation function calls in the C Compiler. Thanking You, Yours Sincerely, Balaji V. Iyer. diff --git a/gcc/ChangeLog.cilk b/gcc/ChangeLog.cilk index 11eca8e..8e4fab9 100644 --- a/gcc/ChangeLog.cilk +++ b/gcc/ChangeLog.cilk @@ -1,3 +1,25 @@ +2012-01-25 Balaji V. Iyer + + * c-array-notation.c (replace_array_notations): Added a new bool as + parameter and added support for it. + (find_rank): Likewise. + (extract_array_notation_exprs): Likewise. + (replace_array_notations): Likewise. + (max): New function. + (fix_builtin_array_notation_fn): Likewise. + (is_builtin_array_notation_fn): Likewise. + (contains_array_notation_expr): Likewise. + (build_array_notation_expr): Added support for builtin function. + Changed all for-loops that have comparison with lhs_rank, with + max (lhs_rank and rhs_rank). Also added a check if array_expr_lhs is + NULL, then we set that equal to lhs. + * c-parser.c (c_parser_expr_no_commas): Added support for array + notations inside function calls (i.e. function that takes array notation + as input and returns a scalar value). + * c-typeck.c (convert_arguments): If array notation is present inside + a function call, then we skip it for now since we will fix it up in a + later step. + 2012-01-20 Balaji V. Iyer * Makefile.in: Added array-notation-common.c file for compilation. diff --git a/gcc/c-array-notation.c b/gcc/c-array-notation.c index ac791eb..1dac533 100644 --- a/gcc/c-array-notation.c +++ b/gcc/c-array-notation.c @@ -38,18 +38,25 @@ #include "gimple.h" #include "c-family/c-objc.h" -void replace_array_notations (tree *, tree *, tree *, int); -void find_rank (tree, int *); -void extract_array_notation_exprs (tree, tree **, int *); +void replace_array_notations (tree *, bool, tree *, tree *, int); +void find_rank (tree, bool, int *); +void extract_array_notation_exprs (tree, bool, tree **, int *); tree fix_conditional_array_notations (tree); struct c_expr fix_array_notation_expr (location_t, enum tree_code, struct c_expr); +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); + +/* This function is to find the rank of an array notation expression. + * For example, an array notation of A[:][:] has a rank of 2. + */ void -find_rank (tree array, int *rank) +find_rank (tree array, bool ignore_builtin_fn, int *rank) { tree ii_tree; int current_rank = 0, ii = 0; - + an_reduce_type dummy_type = REDUCE_UNKNOWN; if (!array) return; else if (TREE_CODE (array) == ARRAY_NOTATION_REF) @@ -64,16 +71,30 @@ find_rank (tree array, int *rank) else if (*rank == 0) *rank = current_rank; } + 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); + } else { - if (TREE_CODE (array) == CALL_EXPR - || TREE_CODE (array) == AGGR_INIT_EXPR) + if (TREE_CODE (array) == CALL_EXPR) { + tree func_name = CALL_EXPR_FN (array); + 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 < length; ii++) - find_rank (TREE_OPERAND (array, ii), rank); + find_rank (TREE_OPERAND (array, ii), ignore_builtin_fn, rank); } else gcc_unreachable (); @@ -81,17 +102,23 @@ find_rank (tree array, int *rank) else { for (ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (array)); ii++) - find_rank (TREE_OPERAND (array, ii), rank); + find_rank (TREE_OPERAND (array, ii), ignore_builtin_fn, rank); } } return; } +/* this function will go through a tree and extract all the array notation + * expressions inside the subtrees + */ void -extract_array_notation_exprs (tree node, tree **array_list, int *list_size) +extract_array_notation_exprs (tree node, bool ignore_builtin_fn, + tree **array_list, int *list_size) { int ii = 0; tree *new_array_list = NULL; + an_reduce_type dummy_type = REDUCE_UNKNOWN; + if (!node) return; else if (TREE_CODE (node) == ARRAY_NOTATION_REF) @@ -110,18 +137,36 @@ extract_array_notation_exprs (tree node, tree **array_list, int *list_size) { tree_stmt_iterator ii_tsi; for (ii_tsi = tsi_start (node); !tsi_end_p (ii_tsi); tsi_next (&ii_tsi)) - extract_array_notation_exprs (*tsi_stmt_ptr (ii_tsi), array_list, - list_size); + extract_array_notation_exprs (*tsi_stmt_ptr (ii_tsi), ignore_builtin_fn, + array_list, list_size); } - else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == AGGR_INIT_EXPR) + else if (TREE_CODE (node) == CALL_EXPR) { + if (is_builtin_array_notation_fn (CALL_EXPR_FN (node), &dummy_type)) + { + if (ignore_builtin_fn) + return; + else + { + ii = *list_size; + new_array_list = (tree *) xrealloc (*array_list, (ii + 1) * + sizeof (tree)); + gcc_assert (new_array_list); + new_array_list[ii] = node; + ii++; + *list_size = ii; + *array_list = new_array_list; + return; + } + } if (TREE_CODE (TREE_OPERAND (node, 0)) == INTEGER_CST) { int length = TREE_INT_CST_LOW (TREE_OPERAND (node, 0)); for (ii = 0; ii < length; ii++) - extract_array_notation_exprs (TREE_OPERAND (node, ii), array_list, - list_size); + extract_array_notation_exprs + (TREE_OPERAND (node, ii), ignore_builtin_fn, array_list, + list_size); } else gcc_unreachable (); /* should not get here */ @@ -130,17 +175,21 @@ extract_array_notation_exprs (tree node, tree **array_list, int *list_size) else { for (ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (node)); ii++) - extract_array_notation_exprs (TREE_OPERAND (node, ii), array_list, - list_size); + extract_array_notation_exprs (TREE_OPERAND (node, ii), + ignore_builtin_fn, array_list, list_size); } return; } +/* this function will replace a subtree that has array notation with the + * appropriate scalar equivalent + */ void -replace_array_notations (tree *orig, tree *list, tree *array_operand, - int array_size) +replace_array_notations (tree *orig, bool ignore_builtin_fn, tree *list, + tree *array_operand, int array_size) { int ii = 0; + an_reduce_type dummy_type = REDUCE_UNKNOWN; if (array_size == 0 || *list == NULL || !*orig) return; @@ -157,18 +206,30 @@ replace_array_notations (tree *orig, tree *list, tree *array_operand, { tree_stmt_iterator ii_tsi; for (ii_tsi = tsi_start (*orig); !tsi_end_p (ii_tsi); tsi_next (&ii_tsi)) - replace_array_notations (tsi_stmt_ptr (ii_tsi), list, array_operand, - array_size); + replace_array_notations (tsi_stmt_ptr (ii_tsi), ignore_builtin_fn, + list, array_operand, array_size); } - else if (TREE_CODE (*orig) == CALL_EXPR - || TREE_CODE (*orig) == AGGR_INIT_EXPR) + else if (TREE_CODE (*orig) == CALL_EXPR) { + if (is_builtin_array_notation_fn (CALL_EXPR_FN (*orig), &dummy_type)) + { + if (!ignore_builtin_fn) + { + for (ii = 0; ii < array_size; ii++) + { + if (*orig == list[ii]) + *orig = array_operand[ii]; + } + } + return; + } if (TREE_CODE (TREE_OPERAND (*orig, 0)) == INTEGER_CST) { int length = TREE_INT_CST_LOW (TREE_OPERAND (*orig, 0)); for (ii = 0; ii < length; ii++) - replace_array_notations (&TREE_OPERAND (*orig, ii), list, - array_operand, array_size); + replace_array_notations + (&TREE_OPERAND (*orig, ii), ignore_builtin_fn, list, + array_operand, array_size); } else gcc_unreachable (); /* should not get here! */ @@ -177,19 +238,30 @@ replace_array_notations (tree *orig, tree *list, tree *array_operand, { for (ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (*orig)); ii++) { - replace_array_notations (&TREE_OPERAND (*orig, ii), list, - array_operand, array_size); + replace_array_notations + (&TREE_OPERAND (*orig, ii), ignore_builtin_fn, list, + array_operand, array_size); } } return; } +/* this is a small function that will give the max of 2 integers */ +static int +max (int x, int y) +{ + if (x > y) + return x; + else + return y; +} + tree build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, enum tree_code modifycode, location_t rhs_loc, tree rhs, tree rhs_origtype) { - bool *lhs_vector = NULL, **rhs_vector = NULL; + bool *lhs_vector = NULL, **rhs_vector = NULL, found_builtin_fn = false; tree *lhs_array = NULL, **rhs_array = NULL; tree array_expr_lhs = NULL_TREE, array_expr_rhs = NULL_TREE; tree array_expr = NULL_TREE; @@ -205,14 +277,67 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, bool *lhs_count_down = NULL, **rhs_count_down = NULL; tree *lhs_compare = NULL, *rhs_compare = NULL, *rhs_array_operand = NULL; int lhs_rank = 0, rhs_rank = 0, ii = 0, jj = 0; - tree ii_tree = NULL_TREE; - tree *rhs_list = NULL; + tree ii_tree = NULL_TREE, new_modify_expr; + tree *rhs_list = NULL, new_var = NULL_TREE, builtin_loop = NULL_TREE; int rhs_list_size = 0; + + find_rank (rhs, false, &rhs_rank); + + extract_array_notation_exprs (rhs, false, &rhs_list, &rhs_list_size); + + loop = push_stmt_list (); + + for (ii = 0; ii < rhs_list_size; ii++) + { + if (TREE_CODE (rhs_list[ii]) == CALL_EXPR) + { + builtin_loop = fix_builtin_array_notation_fn (rhs_list[ii], &new_var); + if (builtin_loop) + { + add_stmt (builtin_loop); + found_builtin_fn = true; + replace_array_notations (&rhs, false, &rhs_list[ii], &new_var, 1); + } + } + } + + lhs_rank = 0; + rhs_rank = 0; + find_rank (lhs, true, &lhs_rank); + find_rank (rhs, true, &rhs_rank); + + if (lhs_rank == 0 && rhs_rank == 0) + { + if (found_builtin_fn) + { + new_modify_expr = build_modify_expr (location, lhs, lhs_origtype, + modifycode, rhs_loc, rhs, + rhs_origtype); + add_stmt (new_modify_expr); + pop_stmt_list (loop); + + return loop; + } + else + { + pop_stmt_list (loop); + return NULL_TREE; + } + } + - find_rank (lhs, &lhs_rank); - find_rank (rhs, &rhs_rank); - extract_array_notation_exprs (rhs, &rhs_list, &rhs_list_size); + /* if (TREE_CODE (rhs) == CALL_EXPR) */ + /* { */ + /* if (is_builtin_array_notation_fn (CALL_EXPR_FN (rhs), &type)) */ + /* { */ + /* loop = build_reduce_expr (location, lhs, lhs_origtype, modifycode, */ + /* rhs_loc, rhs, rhs_origtype); */ + /* return loop; */ + /* } */ + /* } */ + + extract_array_notation_exprs (rhs, true, &rhs_list, &rhs_list_size); if (lhs_rank == 0 && rhs_rank != 0) { @@ -270,12 +395,12 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, * * In both the scenarios, just checking the LHS_RANK is OK */ - body_label = (tree *) xmalloc (sizeof (tree) * lhs_rank); - body_label_expr = (tree *) xmalloc (sizeof (tree) * lhs_rank); - exit_label = (tree *) xmalloc (sizeof (tree) * lhs_rank); - exit_label_expr = (tree *) xmalloc (sizeof (tree) * lhs_rank); - cond_expr = (tree *) xmalloc (sizeof (tree) * lhs_rank); - if_stmt_label = (tree *) xmalloc (sizeof (tree) * lhs_rank); + body_label = (tree *) xmalloc (sizeof (tree) * max (lhs_rank, rhs_rank)); + body_label_expr = (tree *) xmalloc (sizeof (tree) * max (lhs_rank, rhs_rank)); + exit_label = (tree *) xmalloc (sizeof (tree) * max (lhs_rank, rhs_rank)); + exit_label_expr = (tree *) xmalloc (sizeof (tree) * max (lhs_rank, rhs_rank)); + cond_expr = (tree *) xmalloc (sizeof (tree) * max (lhs_rank, rhs_rank)); + if_stmt_label = (tree *) xmalloc (sizeof (tree) * max (lhs_rank, rhs_rank)); lhs_expr_incr = (tree *) xmalloc (sizeof (tree) * lhs_rank); rhs_expr_incr = (tree *) xmalloc (sizeof (tree) * rhs_rank); @@ -354,8 +479,10 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, { rhs_value[ii][jj] = ARRAY_NOTATION_ARRAY (rhs_array[ii][jj]); rhs_start[ii][jj] = ARRAY_NOTATION_START (rhs_array[ii][jj]); - rhs_length[ii][jj] = ARRAY_NOTATION_LENGTH (rhs_array[ii][jj]); - rhs_stride[ii][jj] = ARRAY_NOTATION_STRIDE (rhs_array[ii][jj]); + rhs_length[ii][jj] = + ARRAY_NOTATION_LENGTH (rhs_array[ii][jj]); + rhs_stride[ii][jj] = + ARRAY_NOTATION_STRIDE (rhs_array[ii][jj]); rhs_vector[ii][jj] = true; /* If the stride value is variable (i.e. not constant) then * assume that the length is positive @@ -375,7 +502,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, } } - loop = push_stmt_list(); + for (ii = 0; ii < lhs_rank; ii++) { @@ -385,7 +512,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, TREE_TYPE (lhs_start[ii])); lhs_ind_init[ii] = build_modify_expr (UNKNOWN_LOCATION, lhs_var[ii], TREE_TYPE (lhs_var[ii]), - modifycode, + NOP_EXPR, UNKNOWN_LOCATION, build_int_cst (TREE_TYPE (lhs_start[ii]), 0), TREE_TYPE (lhs_start[ii])); @@ -407,7 +534,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, } - for (ii = 0; ii < lhs_rank ; ii++) + for (ii = 0; ii < max (lhs_rank, rhs_rank); ii++) { /* this will create the if statement label */ if_stmt_label[ii] = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE, @@ -497,9 +624,9 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, } } } - replace_array_notations (&rhs, rhs_list, rhs_array_operand, - rhs_list_size); - array_expr_rhs = rhs; + replace_array_notations (&rhs, true, rhs_list, rhs_array_operand, + rhs_list_size); + array_expr_rhs = rhs; } else { @@ -513,14 +640,16 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, (MODIFY_EXPR, void_type_node, rhs_var[ii], build2 (PLUS_EXPR, TREE_TYPE (rhs_var[ii]), rhs_var[ii], build_int_cst (TREE_TYPE (rhs_var[ii]), 1))); - } - + } + + if (!array_expr_lhs) + array_expr_lhs = lhs; array_expr = build_modify_expr (location, array_expr_lhs, lhs_origtype, modifycode, rhs_loc, array_expr_rhs, rhs_origtype); - for (jj = 0; jj < lhs_rank; jj++) + for (jj = 0; jj < max (lhs_rank, rhs_rank); jj++) { if (rhs_rank && rhs_expr_incr[jj]) { @@ -579,7 +708,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, */ - for (ii = 0; ii < lhs_rank; ii++) + for (ii = 0; ii < max (lhs_rank, rhs_rank); ii++) { add_stmt (lhs_ind_init [ii]); if (rhs_rank) @@ -591,10 +720,11 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, add_stmt (body_label_expr[ii]); } - - add_stmt (array_expr); - for (ii = lhs_rank - 1; ii >= 0; ii--) + if (max (lhs_rank, rhs_rank)) + add_stmt (array_expr); + + for (ii = max (lhs_rank, rhs_rank) - 1; ii >= 0; ii--) { add_stmt (lhs_expr_incr[ii]); if (rhs_rank && rhs_expr_incr[ii]) @@ -629,13 +759,14 @@ fix_conditional_array_notations_1 (tree stmt) else if (TREE_CODE (stmt) == FOR_STMT || TREE_CODE (stmt) == CILK_FOR_STMT) cond = FOR_COND (stmt); else + /* otherwise dont even touch the statement */ return stmt; - find_rank (cond, &rank); + find_rank (cond, true, &rank); if (rank == 0) return stmt; - extract_array_notation_exprs (cond, &array_list, &list_size); + extract_array_notation_exprs (cond, true, &array_list, &list_size); if (*array_list == NULL_TREE || list_size == 0) return stmt; @@ -802,7 +933,7 @@ fix_conditional_array_notations_1 (tree stmt) } } } - replace_array_notations (&stmt, array_list, array_operand, list_size); + replace_array_notations (&stmt, true, array_list, array_operand, list_size); for (ii = 0; ii < rank; ii++) { @@ -915,13 +1046,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, &rank); + find_rank (arg.value, false, &rank); if (rank == 0) - return arg; - - extract_array_notation_exprs (arg.value, &array_list, &list_size); + return arg; - if (*array_list == NULL_TREE || list_size == 0) + + + extract_array_notation_exprs (arg.value, true, &array_list, &list_size); + + if (list_size == 0 || *array_list == NULL_TREE) return arg; array_ops = (tree **) xmalloc (sizeof (tree *) * list_size); @@ -1010,7 +1143,7 @@ fix_array_notation_expr (location_t location, enum tree_code code, } } - loop = push_stmt_list(); + loop = push_stmt_list (); for (ii = 0; ii < rank; ii++) { @@ -1086,7 +1219,8 @@ fix_array_notation_expr (location_t location, enum tree_code code, } } } - replace_array_notations (&arg.value, array_list, array_operand, list_size); + replace_array_notations (&arg.value, true, array_list, array_operand, + list_size); for (ii = 0; ii < rank; ii++) { @@ -1111,6 +1245,7 @@ fix_array_notation_expr (location_t location, enum tree_code code, array_var[jj], array_length[0][jj]); } } + for (ii = 0; ii < rank; ii++) { @@ -1178,4 +1313,593 @@ fix_array_notation_expr (location_t location, enum tree_code code, arg.value = loop; return arg; } + + +static tree +fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var) +{ + tree new_var_type = NULL_TREE, func_parm, new_expr, new_yes_expr, new_no_expr; + tree array_ind_value = NULL_TREE, new_no_ind, new_yes_ind, new_no_list; + tree new_yes_list, new_cond_expr, new_var_init; + an_reduce_type an_type = REDUCE_UNKNOWN; + tree *array_list = NULL; + int list_size = 0; + int rank = 0, ii = 0, jj = 0; + tree **array_ops, *array_var, *array_operand, jj_tree, loop; + tree **array_value, **array_stride, **array_length, **array_start; + 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; + + if (!is_builtin_array_notation_fn (CALL_EXPR_FN (an_builtin_fn), &an_type)) + return NULL_TREE; + + func_parm = CALL_EXPR_ARG (an_builtin_fn, 0); + while (TREE_CODE (func_parm) == CONVERT_EXPR + || TREE_CODE (func_parm) == NOP_EXPR) + func_parm = TREE_OPERAND (func_parm, 0); + + find_rank (an_builtin_fn, false, &rank); + if (rank == 0) + return an_builtin_fn; + else if (rank > 1 + && (an_type == REDUCE_MAX_INDEX || an_type == REDUCE_MIN_INDEX)) + { + error ("__sec_reduce_min_ind or __sec_reduce_max_ind cannot have arrays" + " with dimension greater than 1."); + fnotice (stderr, "confused by earlier errors, bailing out\n"); + exit (ICE_EXIT_CODE); + } + + extract_array_notation_exprs (func_parm, true, &array_list, &list_size); + + switch (an_type) + { + case REDUCE_ADD: + case REDUCE_MUL: + case REDUCE_MAX: + case REDUCE_MIN: + new_var_type = ARRAY_NOTATION_TYPE (array_list[0]); + break; + case REDUCE_ALL_ZEROS: + case REDUCE_ANY_ZEROS: + new_var_type = integer_type_node; + break; + case REDUCE_MAX_INDEX: + case REDUCE_MIN_INDEX: + new_var_type = integer_type_node; + break; + default: + gcc_unreachable (); + } + + + array_ops = (tree **) xmalloc (sizeof (tree *) * list_size); + for (ii = 0; ii < list_size; ii++) + array_ops[ii] = (tree *) xmalloc (sizeof (tree) * rank); + + array_vector = (bool **) xmalloc (sizeof (bool *) * list_size); + for (ii = 0; ii < list_size; ii++) + array_vector[ii] = (bool *) xmalloc (sizeof (bool) * rank); + + array_value = (tree **) xmalloc (sizeof (tree *) * list_size); + array_stride = (tree **) xmalloc (sizeof (tree *) * list_size); + array_length = (tree **) xmalloc (sizeof (tree *) * list_size); + array_start = (tree **) xmalloc (sizeof (tree *) * list_size); + + for (ii = 0; ii < list_size; ii++) + { + array_value[ii] = (tree *) xmalloc (sizeof (tree) * rank); + array_stride[ii] = (tree *) xmalloc (sizeof (tree) * rank); + array_length[ii] = (tree *) xmalloc (sizeof (tree) * rank); + array_start[ii] = (tree *) xmalloc (sizeof (tree) * rank); + } + + body_label = (tree *) xmalloc(sizeof (tree) * rank); + body_label_expr = (tree *) xmalloc (sizeof (tree) * rank); + exit_label = (tree *) xmalloc (sizeof (tree) * rank); + exit_label_expr = (tree *) xmalloc (sizeof (tree) * rank); + compare_expr = (tree *) xmalloc (sizeof (tree) * rank); + if_stmt_label = (tree *) xmalloc (sizeof (tree) * rank); + + expr_incr = (tree *) xmalloc (sizeof (tree) * rank); + ind_init = (tree *) xmalloc (sizeof (tree) * rank); + + count_down = (bool **) xmalloc (sizeof (bool *) * list_size); + for (ii = 0; ii < list_size; ii++) + count_down[ii] = (bool *) xmalloc (sizeof (bool) * rank); + + array_operand = (tree *) xmalloc (sizeof (tree) * list_size); + + array_var = (tree *) xmalloc (sizeof (tree) * rank); + + for (ii = 0; ii < list_size; ii++) + { + jj = 0; + for (jj_tree = array_list[ii]; + jj_tree && TREE_CODE (jj_tree) == ARRAY_NOTATION_REF; + jj_tree = ARRAY_NOTATION_ARRAY (jj_tree)) + { + array_ops[ii][jj] = jj_tree; + jj++; + } + } + + for (ii = 0; ii < list_size; ii++) + { + if (TREE_CODE (array_list[ii]) == ARRAY_NOTATION_REF) + { + for (jj = 0; jj < rank; jj++) + { + if (TREE_CODE (array_ops[ii][jj]) == ARRAY_NOTATION_REF) + { + array_value[ii][jj] = + ARRAY_NOTATION_ARRAY (array_ops[ii][jj]); + array_start[ii][jj] = + ARRAY_NOTATION_START (array_ops[ii][jj]); + array_length[ii][jj] = + ARRAY_NOTATION_LENGTH (array_ops[ii][jj]); + array_stride[ii][jj] = + ARRAY_NOTATION_STRIDE (array_ops[ii][jj]); + array_vector[ii][jj] = true; + + if (!TREE_CONSTANT (array_length[ii][jj])) + count_down[ii][jj] = false; + else if (tree_int_cst_lt + (array_length[ii][jj], + build_int_cst (TREE_TYPE (array_length[ii][jj]), + 0))) + count_down[ii][jj] = true; + else + count_down[ii][jj] = false; + } + else + array_vector[ii][jj] = false; + } + } + } + + loop = alloc_stmt_list (); + + + for (ii = 0; ii < rank; ii++) + { + array_var[ii] = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, + integer_type_node); + ind_init[ii] = + build_modify_expr (UNKNOWN_LOCATION, array_var[ii], + TREE_TYPE (array_var[ii]), NOP_EXPR, + UNKNOWN_LOCATION, + build_int_cst (TREE_TYPE (array_var[ii]), 0), + TREE_TYPE (array_var[ii])); + } + + for (ii = 0; ii < rank ; ii++) + { + /* this will create the if statement label */ + if_stmt_label[ii] = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE, + void_type_node); + DECL_CONTEXT (if_stmt_label[ii]) = current_function_decl; + DECL_ARTIFICIAL (if_stmt_label[ii]) = 0; + DECL_IGNORED_P (if_stmt_label[ii]) = 1; + + /* this label statment will point to the loop body */ + body_label[ii] = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE, + void_type_node); + DECL_CONTEXT (body_label[ii]) = current_function_decl; + DECL_ARTIFICIAL (body_label[ii]) = 0; + DECL_IGNORED_P (body_label[ii]) = 1; + body_label_expr[ii] = build1 (LABEL_EXPR, void_type_node, body_label[ii]); + + /* this will create the exit label..i.e. where the while loop will branch + out of + */ + exit_label[ii] = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE, + void_type_node); + DECL_CONTEXT (exit_label[ii]) = current_function_decl; + DECL_ARTIFICIAL (exit_label[ii]) = 0; + DECL_IGNORED_P (exit_label[ii]) = 1; + exit_label_expr[ii] = build1 (LABEL_EXPR, void_type_node, exit_label[ii]); + } + + for (ii = 0; ii < list_size; ii++) + { + if (array_vector[ii][0]) + { + array_operand[ii] = array_value[ii][rank - 1]; + gcc_assert (array_operand[ii]); + + for (jj = rank - 1; jj >= 0; jj--) + { + if (count_down[ii][jj]) + { + /* Array[start_index - (induction_var * stride)] */ + array_operand[ii] = build_array_ref + (UNKNOWN_LOCATION, array_operand[ii], + build2 (MINUS_EXPR, TREE_TYPE (array_var[jj]), + array_start[ii][jj], + build2 (MULT_EXPR, TREE_TYPE (array_var[jj]), + array_var[jj], array_stride[ii][jj]))); + } + else + { + /* Array[start_index + (induction_var * stride)] */ + array_operand[ii] = build_array_ref + (UNKNOWN_LOCATION, array_operand[ii], + build2 (PLUS_EXPR, TREE_TYPE (array_var[jj]), + array_start[ii][jj], + build2 (MULT_EXPR, TREE_TYPE (array_var[jj]), + array_var[jj], array_stride[ii][jj]))); + } + } + } + } + replace_array_notations (&func_parm, true, array_list, array_operand, + list_size); + + for (ii = 0; ii < rank; ii++) + { + expr_incr[ii] = + build2 (MODIFY_EXPR, void_type_node, array_var[ii], + build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii], + build_int_cst (TREE_TYPE (array_var[ii]), 1))); + } + + for (jj = 0; jj < rank; jj++) + { + if (rank && expr_incr[jj]) + { + if (count_down[0][jj]) + compare_expr[jj] = + build2 (LT_EXPR, boolean_type_node, array_var[jj], + build2 (MULT_EXPR, TREE_TYPE (array_var[jj]), + array_length[0][jj], + build_int_cst (TREE_TYPE (array_var[jj]), -1))); + else + compare_expr[jj] = build2 (LT_EXPR, boolean_type_node, + array_var[jj], array_length[0][jj]); + } + } + + *new_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, new_var_type); + gcc_assert (*new_var); + if (an_type == REDUCE_MAX_INDEX || an_type == REDUCE_MIN_INDEX) + array_ind_value = build_decl + (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, TREE_TYPE (func_parm)); + + switch (an_type) + { + case REDUCE_ADD: + new_var_init = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, build_zero_cst (new_var_type), new_var_type); + new_expr = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), PLUS_EXPR, + UNKNOWN_LOCATION, func_parm, TREE_TYPE (func_parm)); + break; + case REDUCE_MUL: + new_var_init = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, build_one_cst (new_var_type), new_var_type); + new_expr = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), MULT_EXPR, + UNKNOWN_LOCATION, func_parm, TREE_TYPE (func_parm)); + break; + case REDUCE_ALL_ZEROS: + new_var_init = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, build_one_cst (new_var_type), new_var_type); + /* Initially you assume everything is zero, now if we find a case where + * it is NOT true, then we set the result to false. Otherwise + * we just keep the previous value + */ + new_yes_expr = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, build_zero_cst (TREE_TYPE (*new_var)), + TREE_TYPE (*new_var)); + new_no_expr = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var)); + new_cond_expr = build2 (NE_EXPR, TREE_TYPE (func_parm), func_parm, + build_zero_cst (TREE_TYPE (func_parm))); + new_expr = build_conditional_expr + (UNKNOWN_LOCATION, new_cond_expr, false, new_yes_expr, + TREE_TYPE (new_yes_expr), new_no_expr, TREE_TYPE (new_no_expr)); + break; + case REDUCE_ANY_ZEROS: + new_var_init = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, build_zero_cst (new_var_type), new_var_type); + /* Initially we assume there are NO zeros in the list. When we find + * a non-zero, we keep the previous value. If we find a zero, we + * set the value to true + */ + new_no_expr = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, build_one_cst (new_var_type), new_var_type); + new_yes_expr = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var)); + new_cond_expr = build2 (NE_EXPR, TREE_TYPE (func_parm), func_parm, + build_zero_cst (TREE_TYPE (func_parm))); + new_expr = build_conditional_expr + (UNKNOWN_LOCATION, new_cond_expr, false, new_yes_expr, + TREE_TYPE (new_yes_expr), new_no_expr, TREE_TYPE (new_no_expr)); + break; + case REDUCE_MAX: + new_var_init = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, func_parm, new_var_type); + new_no_expr = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var)); + new_yes_expr = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, func_parm, TREE_TYPE (*new_var)); + new_expr = build_conditional_expr + (UNKNOWN_LOCATION, + build2 (LT_EXPR, TREE_TYPE (*new_var), *new_var, func_parm), false, + new_yes_expr, TREE_TYPE (*new_var), new_no_expr, TREE_TYPE (*new_var)); + break; + case REDUCE_MIN: + new_var_init = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, func_parm, new_var_type); + new_no_expr = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var)); + new_yes_expr = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, func_parm, TREE_TYPE (*new_var)); + new_expr = build_conditional_expr + (UNKNOWN_LOCATION, + build2 (GT_EXPR, TREE_TYPE (*new_var), *new_var, func_parm), false, + new_yes_expr, TREE_TYPE (*new_var), new_no_expr, TREE_TYPE (*new_var)); + break; + case REDUCE_MAX_INDEX: + new_var_init = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, build_zero_cst (new_var_type), new_var_type); + new_no_ind = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var)); + new_no_expr = build_modify_expr + (UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value), + NOP_EXPR, + UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value)); + if (list_size > 1) + { + new_yes_ind = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, array_var[0], TREE_TYPE (array_var[0])); + new_yes_expr = build_modify_expr + (UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value), + NOP_EXPR, + UNKNOWN_LOCATION, func_parm, TREE_TYPE (array_operand[0])); + } + else + { + new_yes_ind = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, TREE_OPERAND (array_operand[0], 1), + TREE_TYPE (TREE_OPERAND (array_operand[0], 1))); + new_yes_expr = build_modify_expr + (UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value), + NOP_EXPR, + UNKNOWN_LOCATION, func_parm, TREE_OPERAND (array_operand[0], 1)); + } + new_yes_list = alloc_stmt_list (); + append_to_statement_list (new_yes_ind, &new_yes_list); + append_to_statement_list (new_yes_expr, &new_yes_list); + + new_no_list = alloc_stmt_list (); + append_to_statement_list (new_no_ind, &new_no_list); + append_to_statement_list (new_no_expr, &new_no_list); + + new_expr = build_conditional_expr + (UNKNOWN_LOCATION, + build2 (LT_EXPR, TREE_TYPE (array_ind_value), array_ind_value, + func_parm), + false, + new_yes_list, TREE_TYPE (*new_var), new_no_list, TREE_TYPE (*new_var)); + break; + case REDUCE_MIN_INDEX: + new_var_init = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, build_zero_cst (new_var_type), new_var_type); + new_no_ind = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var)); + new_no_expr = build_modify_expr + (UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value), + NOP_EXPR, + UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value)); + if (list_size > 1) + { + new_yes_ind = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, array_var[0], TREE_TYPE (array_var[0])); + new_yes_expr = build_modify_expr + (UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value), + NOP_EXPR, + UNKNOWN_LOCATION, func_parm, TREE_TYPE (array_operand[0])); + } + else + { + new_yes_ind = build_modify_expr + (UNKNOWN_LOCATION, *new_var, TREE_TYPE (*new_var), NOP_EXPR, + UNKNOWN_LOCATION, TREE_OPERAND (array_operand[0], 1), + TREE_TYPE (TREE_OPERAND (array_operand[0], 1))); + new_yes_expr = build_modify_expr + (UNKNOWN_LOCATION, array_ind_value, TREE_TYPE (array_ind_value), + NOP_EXPR, + UNKNOWN_LOCATION, func_parm, TREE_OPERAND (array_operand[0], 1)); + } + new_yes_list = alloc_stmt_list (); + append_to_statement_list (new_yes_ind, &new_yes_list); + append_to_statement_list (new_yes_expr, &new_yes_list); + + new_no_list = alloc_stmt_list (); + append_to_statement_list (new_no_ind, &new_no_list); + append_to_statement_list (new_no_expr, &new_no_list); + + new_expr = build_conditional_expr + (UNKNOWN_LOCATION, + build2 (GT_EXPR, TREE_TYPE (array_ind_value), array_ind_value, + func_parm), + false, + new_yes_list, TREE_TYPE (*new_var), new_no_list, TREE_TYPE (*new_var)); + break; + default: + gcc_unreachable (); + break; + } + + for (ii = 0; ii < rank; ii++) + append_to_statement_list (ind_init [ii], &loop); + + append_to_statement_list (new_var_init, &loop); + + for (ii = 0; ii < rank; ii++) + { + /* append_to_statement_list (ind_init [ii], &loop); */ + + append_to_statement_list + (build1 (LABEL_EXPR, void_type_node, if_stmt_label[ii]), &loop); + append_to_statement_list + (build3 (COND_EXPR, void_type_node, compare_expr[ii], + build1 (GOTO_EXPR, void_type_node, body_label[ii]), + build1 (GOTO_EXPR, void_type_node, exit_label[ii])), &loop); + append_to_statement_list (body_label_expr[ii], &loop); + } + + append_to_statement_list (new_expr, &loop); + + for (ii = rank - 1; ii >= 0; ii--) + { + append_to_statement_list (expr_incr[ii], &loop); + append_to_statement_list + (build1 (GOTO_EXPR, void_type_node, if_stmt_label[ii]), &loop); + append_to_statement_list (exit_label_expr[ii], &loop); + } + + free (body_label); + free (body_label_expr); + free (exit_label); + free (exit_label_expr); + free (compare_expr); + free (if_stmt_label); + free (expr_incr); + free (ind_init); + free (array_operand); + free (array_var); + + for (ii = 0; ii < list_size; ii++) + { + free (count_down[ii]); + free (array_value[ii]); + free (array_stride[ii]); + free (array_length[ii]); + free (array_start[ii]); + free (array_ops[ii]); + free (array_vector[ii]); + } + + free (count_down); + free (array_value); + free (array_stride); + free (array_length); + free (array_start); + free (array_ops); + free (array_vector); + + + return loop; +} + +static bool +is_builtin_array_notation_fn (tree func_name, an_reduce_type *type) +{ + const char *function_name = NULL; + + if (!func_name) + return false; + + if (TREE_CODE (func_name) == IDENTIFIER_NODE) + function_name = IDENTIFIER_POINTER (func_name); + else if (TREE_CODE (func_name) == ADDR_EXPR) + { + func_name = TREE_OPERAND (func_name, 0); + if (TREE_CODE (func_name) == FUNCTION_DECL) + function_name = IDENTIFIER_POINTER (DECL_NAME (func_name)); + } + if (!function_name) + return false; + + if (!strcmp (function_name, "__sec_reduce_add")) + { + *type = REDUCE_ADD; + return true; + } + else if (!strcmp (function_name, "__sec_reduce_mul")) + { + *type = REDUCE_MUL; + return true; + } + else if (!strcmp (function_name, "__sec_reduce_all_zeros")) + { + *type = REDUCE_ALL_ZEROS; + return true; + } + else if (!strcmp (function_name, "__sec_reduce_any_zeros")) + { + *type = REDUCE_ANY_ZEROS; + return true; + } + else if (!strcmp (function_name, "__sec_reduce_max")) + { + *type = REDUCE_MAX; + return true; + } + else if (!strcmp (function_name, "__sec_reduce_min")) + { + *type = REDUCE_MIN; + return true; + } + else if (!strcmp (function_name, "__sec_reduce_min_ind")) + { + *type = REDUCE_MIN_INDEX; + return true; + } + else if (!strcmp (function_name, "__sec_reduce_max_ind")) + { + *type = REDUCE_MAX_INDEX; + return true; + } + else + { + *type = REDUCE_UNKNOWN; + return false; + } + return false; +} + +bool +contains_array_notation_expr (tree expr) +{ + tree *array_list = NULL; + int list_size = 0; + an_reduce_type type = REDUCE_UNKNOWN; + + if (TREE_CODE (expr) == FUNCTION_DECL) + if (is_builtin_array_notation_fn (DECL_NAME (expr), &type)) + return true; + + + extract_array_notation_exprs (expr, false, &array_list, &list_size); + if (array_list == NULL || list_size == 0) + return false; + else + return true; +} diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 1078ef4..c67ea97 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -62,6 +62,7 @@ extern tree c_build_sync (tree *); extern tree fix_conditional_array_notations (tree); extern struct c_expr fix_array_notation_expr (location_t, enum tree_code, struct c_expr); +extern bool contains_array_notation_expr (tree); struct pragma_simd_values local_simd_values; @@ -5474,11 +5475,11 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after) rhs = default_function_array_read_conversion (exp_location, rhs); /* bviyer: The line below is where the parser has the form: - * A = B + * A = B, where A&B could contain array notation expressions * So this is where we must modify the Array Notation arrays */ - if (TREE_CODE (lhs.value) == ARRAY_NOTATION_REF - || TREE_CODE (rhs.value) == ARRAY_NOTATION_REF) + if (flag_enable_cilk && (contains_array_notation_expr (lhs.value) + || contains_array_notation_expr (rhs.value))) ret.value = build_array_notation_expr (op_location, lhs.value, lhs.original_type, code, exp_location, rhs.value, diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 57dc486..7aa6996 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -110,6 +110,8 @@ static void readonly_warning (tree, enum lvalue_use); static int lvalue_or_else (location_t, const_tree, enum lvalue_use); static void record_maybe_used_decl (tree); static int comptypes_internal (const_tree, const_tree, bool *, bool *); + +extern bool contains_array_notation_expr (tree); /* Return true if EXP is a null pointer constant, false otherwise. */ @@ -3027,6 +3029,8 @@ convert_arguments (tree typelist, VEC(tree,gc) *values, bool npc; tree parmval; + if (flag_enable_cilk && contains_array_notation_expr (val)) + continue; if (type == void_type_node) { if (selector) @@ -3268,11 +3272,16 @@ convert_arguments (tree typelist, VEC(tree,gc) *values, if (typetail != 0 && TREE_VALUE (typetail) != void_type_node) { - error_at (input_location, - "too few arguments to function %qE", function); - if (fundecl && !DECL_BUILT_IN (fundecl)) - inform (DECL_SOURCE_LOCATION (fundecl), "declared here"); - return -1; + if (flag_enable_cilk && contains_array_notation_expr (function)) + ; + else + { + error_at (input_location, + "too few arguments to function %qE", function); + if (fundecl && !DECL_BUILT_IN (fundecl)) + inform (DECL_SOURCE_LOCATION (fundecl), "declared here"); + return -1; + } } return error_args ? -1 : (int) parmnum; @@ -5173,6 +5182,9 @@ convert_for_assignment (location_t location, tree type, tree rhs, tree rname = NULL_TREE; bool objc_ok = false; + if (flag_enable_cilk && contains_array_notation_expr (rhs)) + return rhs; + if (errtype == ic_argpass) { tree selector; @@ -5719,16 +5731,20 @@ convert_for_assignment (location_t location, tree type, tree rhs, or one that results from arithmetic, even including a cast to integer type. */ if (!null_pointer_constant) - WARN_FOR_ASSIGNMENT (location, 0, - G_("passing argument %d of %qE makes " - "pointer from integer without a cast"), - G_("assignment makes pointer from integer " - "without a cast"), - G_("initialization makes pointer from " - "integer without a cast"), - G_("return makes pointer from integer " - "without a cast")); - + { + if (flag_enable_cilk && contains_array_notation_expr (rhs)) + ; + else + WARN_FOR_ASSIGNMENT (location, 0, + G_("passing argument %d of %qE makes " + "pointer from integer without a cast"), + G_("assignment makes pointer from integer " + "without a cast"), + G_("initialization makes pointer from " + "integer without a cast"), + G_("return makes pointer from integer " + "without a cast")); + } return convert (type, rhs); } else if (codel == INTEGER_TYPE && coder == POINTER_TYPE) diff --git a/gcc/testsuite/ChangeLog.cilk b/gcc/testsuite/ChangeLog.cilk index 9fa7413..c032e14 100644 --- a/gcc/testsuite/ChangeLog.cilk +++ b/gcc/testsuite/ChangeLog.cilk @@ -1,3 +1,7 @@ +2012-01-25 Balaji V. Iyer + + * gcc.dg/cilk-plus/array_notation_tests/builtin_func_double.c: New. + 2012-01-21 Balaji V. Iyer * g++.dg/cilk-plus/array_notation_tests/builtin_funcs.cc: New. diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation_tests/builtin_func_double.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation_tests/builtin_func_double.c new file mode 100644 index 0000000..e52bbcc --- /dev/null +++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation_tests/builtin_func_double.c @@ -0,0 +1,73 @@ +#define HAVE_IO 1 + +#if HAVE_IO +#include +#endif +#include + +/* char __sec_reduce_add (int *); */ +int main(int argc, char **argv) +{ + int ii,array[10], y = 0, y_int = 0, array2[10]; + double x, yy, array3[10], array4[10]; + for (ii = 0; ii < 10; ii++) + { + array[ii] = 1+ii; + array2[ii]= 2; + } + + for (ii = 0; ii < 10; ii++) + { + if (ii%2 && ii) + array3[ii] = (double)(1.0000/(double)ii); + else + array3[ii] = (double) ii + 0.10; + array4[ii] = (double) (1.00000/ (double)(ii+1)); + } + + /* array[:] = 5; */ + x = __sec_reduce_max (array3[:] * array4[:]); + y = __sec_reduce_max_ind ( array3[:] * array4[:]); +#if HAVE_IO + for (ii = 0; ii < 10; ii++) + printf("%5.3f ", array3[ii] * array4[ii]); + printf("\n"); + printf("Max = %5.3f\t Max Index = %2d\n", x, y); +#endif + + x = __sec_reduce_min (array3[:] * array4[:]); + y = __sec_reduce_min_ind ( array3[:] * array4[:]); +#if HAVE_IO + for (ii = 0; ii < 10; ii++) + printf("%5.3f ", array3[ii] * array4[ii]); + printf("\n"); + printf("Min = %5.3f\t Min Index = %2d\n", x, y); +#endif + + x = __sec_reduce_add (array3[:] * array4[:]); + yy = __sec_reduce_mul ( array3[:] * array4[:]); +#if HAVE_IO + for (ii = 0; ii < 10; ii++) + printf("%5.3f ", array3[ii] * array4[ii]); + printf("\n"); + printf("Add = %5.3f\t Mul = %f\n", x, y); +#endif + + for (ii = 0; ii < 10; ii++) + { + if (ii%2 && ii) + array3[ii] = (double)(1.0000/(double)ii); + else + array3[ii] = (double) ii + 0.00; + array4[ii] = (double) (1.00000/ (double)(ii+1)); + } + y_int = __sec_reduce_any_zeros (array3[:] * array4[:]); + y = __sec_reduce_all_zeros ( array3[:] * array4[:]); +#if HAVE_IO + for (ii = 0; ii < 10; ii++) + printf("%5.3f ", array3[ii] * array4[ii]); + printf("\n"); + printf("Any Zeros = %d\t All Zeros = %d\n", y_int, y); +#endif + return 0; +}