From patchwork Sun Jan 22 02:03:39 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: 137218 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 3E688B6FA8 for ; Sun, 22 Jan 2012 13:04:14 +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=1327802656; 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=9/755NR mtp+HAfTdlTjyArP+idQ=; b=QXmlbQNfFE17QJ/AWbTs43Ycs/7WSd29GLUd96i yX6izolfpfuicbC4twj1uJ6dkvc5/r3uGCQOPNA0sbv/V7fUPSnYvoj1e5WVnShW P8WtuY7YFpxKU/RgSiIq939mxJ2WpuFF2boeVB82k4rhH09hVCDMMV12klIGvSYM ZTRQ= 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=bHqAuO+thsDQ4XCNJTizFhkOA1WZe94W3Y86hcmoQk1WglOzVYiLt+JfpthBuy Krn/+UC5wWBvY5N7XRZoeTDKZlMc1CFkkWwI43fagbkgLcPjRudqhuTUoT0augdY TyCgW8l24XY70MqVbHAdE6VmF0jsoLgBlDg5Ym7cOQZnY=; Received: (qmail 8167 invoked by alias); 22 Jan 2012 02:04:08 -0000 Received: (qmail 8151 invoked by uid 22791); 22 Jan 2012 02:04:00 -0000 X-SWARE-Spam-Status: No, hits=-4.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, 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; Sun, 22 Jan 2012 02:03:41 +0000 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 21 Jan 2012 18:03:40 -0800 X-ExtLoop1: 1 Received: from azsmsx603.amr.corp.intel.com ([10.2.161.23]) by azsmga001.ch.intel.com with ESMTP; 21 Jan 2012 18:03:40 -0800 Received: from fmsmsx106.amr.corp.intel.com (10.19.9.37) by azsmsx603.amr.corp.intel.com (10.2.161.23) with Microsoft SMTP Server (TLS) id 8.2.255.0; Sat, 21 Jan 2012 19:03:40 -0700 Received: from fmsmsx102.amr.corp.intel.com ([169.254.2.214]) by FMSMSX106.amr.corp.intel.com ([169.254.6.112]) with mapi id 14.01.0355.002; Sat, 21 Jan 2012 18:03:39 -0800 From: "Iyer, Balaji V" To: "gcc-patches@gcc.gnu.org" Subject: [PATCH][Cilkplus] Builtin Array Notation functions in C++ Compiler Date: Sun, 22 Jan 2012 02:03:39 +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 Cilkplus branch in the C++ compiler. This patch will implement builtin functions for array notations. Thanking You, Yours Sincerely, Balaji V. Iyer. diff --git a/gcc/ChangeLog.cilk b/gcc/ChangeLog.cilk index 8d65ca2..11eca8e 100644 --- a/gcc/ChangeLog.cilk +++ b/gcc/ChangeLog.cilk @@ -1,4 +1,11 @@ -2011-01-16 Balaji V. Iyer +2012-01-20 Balaji V. Iyer + + * Makefile.in: Added array-notation-common.c file for compilation. + * array-notation-common.c (mark_cold): New function. + (array_notation_init_builtins): Likewise. + * tree.h: Added a new enum list called "array_notation_reduce_type." + +2012-01-16 Balaji V. Iyer * cilk.c (cilk_remove_annotated_functions): Added a int cast for VEC_length in for-loop condition. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 9732ffc..76d2bc0 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1452,6 +1452,7 @@ OBJS = \ xcoffout.o \ cilk.o \ cilk-low.o \ + array-notation-common.o \ $(out_object_file) \ $(EXTRA_OBJS) \ $(host_hook_obj) @@ -3437,6 +3438,8 @@ lower-subreg.o : lower-subreg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ +array-notation-common.o: array-notation-common.c $(CONFIG_H) $(SYSTEM_H) \ + $(TREE_H) $(RTL_H) $(OPTABS_H) $(GIMPLE_H) $(RECOG_H) cilk.o: cilk.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) $(OPTABS_H) \ $(GIMPLE_H) $(RECOG_H) cilk.h diff --git a/gcc/array-notation-common.c b/gcc/array-notation-common.c new file mode 100644 index 0000000..059adc4 --- /dev/null +++ b/gcc/array-notation-common.c @@ -0,0 +1,101 @@ +/* This file is part of the Intel(R) Cilk(TM) Plus support + This file contains the builtin functions for Array + notations. + Copyright (C) 2012 Free Software Foundation, Inc. + Contributed by Balaji V. Iyer , + Intel Corporation + +This file is part of GCC. + +GCC 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, or (at your option) +any later version. + +GCC 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 +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "langhooks.h" +#include "expr.h" +#include "optabs.h" /* for sync_lock_release in detach */ +#include "recog.h" +#include "cilk.h" +#include "gimple.h" +#include "tree-iterator.h" +#include "c-family/c-common.h" +#include "toplev.h" /* only correct declaration of warning() */ +#include "output.h" +#include "dwarf2out.h" + +static void +mark_cold (tree fndecl) +{ + DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("cold"), NULL_TREE, + DECL_ATTRIBUTES (fndecl)); +} + +void +array_notation_init_builtins (void) +{ + tree func_type = NULL_TREE; + tree new_func = NULL_TREE; + 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_zeros", 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_zeros", 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); + return; +} diff --git a/gcc/c-family/ChangeLog.cilk b/gcc/c-family/ChangeLog.cilk index 5e57983..a4049d0 100644 --- a/gcc/c-family/ChangeLog.cilk +++ b/gcc/c-family/ChangeLog.cilk @@ -1,3 +1,8 @@ +2012-01-20 Balaji V. Iyer + + * c-common.c (c_define_builtins): Added a call to + array_notation_init_builtins function. + 2011-12-09 Balaji V. Iyer * c-common.h: Added build_array_notation_expr prototype. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 708b40c..15145a5 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -49,7 +49,7 @@ along with GCC; see the file COPYING3. If not see #include "libfuncs.h" #include "cilk.h" - +extern void array_notation_init_builtins (void); enum expand_modifier {EXPAND_NORMAL = 0, EXPAND_STACK_PARM, EXPAND_SUM, EXPAND_CONST_ADDRESS, EXPAND_INITIALIZER, EXPAND_WRITE, EXPAND_MEMORY}; @@ -4660,7 +4660,10 @@ c_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node) /* this function will initialize all the builtin functions required by * the cilkplus port */ if (flag_enable_cilk) - cilk_init_builtins(); + { + cilk_init_builtins (); + array_notation_init_builtins (); + } targetm.init_builtins (); diff --git a/gcc/cp/ChangeLog.cilk b/gcc/cp/ChangeLog.cilk index 072a6de..ce50e89 100644 --- a/gcc/cp/ChangeLog.cilk +++ b/gcc/cp/ChangeLog.cilk @@ -1,3 +1,25 @@ +2012-01-20 Balaji V. Iyer + + * call.c (convert_like_real): Type conversion is ignored if array + notation is present as a parameter. + * cp-array-notation.c (find_rank): Added a new parameter called + ignore_builtin_fn. Also handled a case for STATEMENT_LIST. Finally, + added a check to see if the builtin function should be ignored. + (extract_array_notation_exprs): Added a new parameter called + ignore_builtin_fn. Also added a check to see for ignore_builtin_fn. + (replace_array_notations): Likewise. + (build_x_array_notation_expr): Modified find_rank call to add a bool. + Also added a check if the funtion is a builtin array notation function. + Added a bool parameter to extract_array_notation_exprs, find_rank and + replace_array_notations. + (fix_builtin_array_notation_fn): New function. + (is_builtin_array_notation_fn): Likewise. + (build_x_reduce_expr): Likewise. + (contains_array_notation_expr): Likewise. + (fix_unary_array_notation_exprs): Changed the name of the parameter. + Also handled a case check for CALL_EXPR and if so, called + fix_builtin_array_notation_fn. + 2012-01-17 Balaji V. Iyer * cp-array-notation.c (max): New function. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 5413eda..e222e04 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see #include "timevar.h" #include "cilk.h" +extern bool contains_array_notation_expr (tree); /* The various kinds of conversion. */ typedef enum conversion_kind { @@ -5638,13 +5639,16 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, else if (t->kind == ck_identity) break; } - - permerror (input_location, "invalid conversion from %qT to %qT", - TREE_TYPE (expr), totype); - if (fn) - permerror (DECL_SOURCE_LOCATION (fn), - " initializing argument %P of %qD", argnum, fn); - + if (flag_enable_cilk && contains_array_notation_expr (expr)) + ; + else + { + permerror (input_location, "invalid conversion from %qT to %qT", + TREE_TYPE (expr), totype); + if (fn) + permerror (DECL_SOURCE_LOCATION (fn), + " initializing argument %P of %qD", argnum, fn); + } return cp_convert (totype, expr); } diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c index a8667dd..39845f6 100644 --- a/gcc/cp/cp-array-notation.c +++ b/gcc/cp/cp-array-notation.c @@ -45,20 +45,24 @@ #include "bitmap.h" -void replace_array_notations (tree *, tree *, tree *, int); -void find_rank (tree array, int *rank); +void replace_array_notations (tree *, bool, tree *, tree *, int); +void find_rank (tree, bool, int *); static tree fix_conditional_array_notations_1 (tree stmt); tree fix_unary_array_notation_exprs (tree stmt); +static bool is_builtin_array_notation_fn (tree, an_reduce_type *); +static tree build_x_reduce_expr (tree, enum tree_code, tree, tsubst_flags_t, + an_reduce_type); +bool contains_array_notation_expr (tree); /* 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) @@ -73,16 +77,31 @@ 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) { + 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 (); @@ -90,7 +109,7 @@ 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; @@ -100,10 +119,13 @@ find_rank (tree array, int *rank) * 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) @@ -122,18 +144,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) { + 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 */ @@ -142,8 +182,8 @@ 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; } @@ -152,10 +192,11 @@ extract_array_notation_exprs (tree node, tree **array_list, int *list_size) * 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; @@ -172,18 +213,31 @@ 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) { + 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! */ @@ -192,8 +246,9 @@ 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; @@ -235,17 +290,27 @@ build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs, tree ii_tree = NULL_TREE; tree *rhs_list = NULL; int rhs_list_size = 0; + an_reduce_type type = REDUCE_UNKNOWN; - find_rank (lhs, &lhs_rank); - find_rank (rhs, &rhs_rank); + find_rank (lhs, true, &lhs_rank); + find_rank (rhs, true, &rhs_rank); /* If both are scalar, then no reason to do any of the components inside this * function... a simple build_x_modify_expr would do. */ if (lhs_rank == 0 && rhs_rank == 0) return NULL_TREE; + + if (TREE_CODE (rhs) == CALL_EXPR) + { + if (is_builtin_array_notation_fn (CALL_EXPR_FN (rhs), &type)) + { + loop = build_x_reduce_expr (lhs, modifycode, rhs, complain, type); + return loop; + } + } - extract_array_notation_exprs (rhs, &rhs_list, &rhs_list_size); + extract_array_notation_exprs (rhs, true, &rhs_list, &rhs_list_size); if (lhs_rank == 0 && rhs_rank != 0) { @@ -540,7 +605,7 @@ build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs, } } } - replace_array_notations (&rhs, rhs_list, rhs_array_operand, + replace_array_notations (&rhs, true, rhs_list, rhs_array_operand, rhs_list_size); array_expr_rhs = rhs; } @@ -691,11 +756,11 @@ fix_conditional_array_notations_1 (tree stmt) /* otherwise don't 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; @@ -862,7 +927,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++) { @@ -1154,8 +1219,422 @@ fix_array_notation_exprs (tree t) return t; } +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 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); + + switch (an_type) + { + case REDUCE_ADD: + new_var_init = build_x_modify_expr + (*new_var, NOP_EXPR, build_int_cst (new_var_type, 0), 1); + new_expr = build_x_modify_expr (*new_var, PLUS_EXPR, func_parm, 1); + break; + case REDUCE_MUL: + new_var_init = build_x_modify_expr + (*new_var, NOP_EXPR, build_int_cst (new_var_type, 1), 1); + new_expr = build_x_modify_expr (*new_var, MULT_EXPR, func_parm, 1); + break; + case REDUCE_ALL_ZEROS: + new_var_init = build_x_modify_expr + (*new_var, NOP_EXPR, build_int_cst (new_var_type, 1), 1); + /* 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_x_modify_expr + (*new_var, NOP_EXPR, build_int_cst (TREE_TYPE (*new_var), 0), 1); + new_no_expr = build_x_modify_expr (*new_var, NOP_EXPR, *new_var, 1); + new_expr = build_x_conditional_expr (func_parm, new_yes_expr, + new_no_expr, 1); + break; + case REDUCE_ANY_ZEROS: + new_var_init = build_x_modify_expr + (*new_var, NOP_EXPR, build_int_cst (new_var_type, 0), 1); + /* 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_x_modify_expr + (*new_var, NOP_EXPR, build_int_cst (TREE_TYPE (*new_var), 1), 1); + new_yes_expr = build_x_modify_expr (*new_var, NOP_EXPR, *new_var, 1); + new_expr = build_x_conditional_expr (func_parm, new_yes_expr, + new_no_expr, 1); + break; + case REDUCE_MAX: + if (INTEGRAL_TYPE_P (new_var_type)) + new_var_init = build_x_modify_expr + (*new_var, NOP_EXPR, TYPE_MIN_VALUE (new_var_type), 1); + else /* Otherwise, we pick the first item in the array */ + new_var_init = build_x_modify_expr + (*new_var, NOP_EXPR, + build_array_ref (UNKNOWN_LOCATION, + TREE_OPERAND (array_operand[0], 0), + build_int_cst (integer_type_node, 0)), 1); + new_no_expr = build_x_modify_expr (*new_var, NOP_EXPR, *new_var, 1); + new_yes_expr = build_x_modify_expr (*new_var, NOP_EXPR, func_parm, 1); + new_expr = build_x_conditional_expr + (build2 (LT_EXPR, TREE_TYPE (*new_var), *new_var, func_parm), + new_yes_expr, new_no_expr, 1); + break; + case REDUCE_MIN: + if (INTEGRAL_TYPE_P (new_var_type)) + new_var_init = build_x_modify_expr + (*new_var, NOP_EXPR, TYPE_MAX_VALUE (new_var_type), 1); + else /* Otherwise, we the first item in the array */ + new_var_init = build_x_modify_expr + (*new_var, NOP_EXPR, + build_array_ref (UNKNOWN_LOCATION, + TREE_OPERAND (array_operand[0], 0), + build_int_cst (integer_type_node, 0)), 1); + new_no_expr = build_x_modify_expr (*new_var, NOP_EXPR, *new_var, 1); + new_yes_expr = build_x_modify_expr (*new_var, NOP_EXPR, func_parm, 1); + new_expr = build_x_conditional_expr + (build2 (GT_EXPR, TREE_TYPE (*new_var), *new_var, func_parm), + new_yes_expr, new_no_expr, 1); + break; + case REDUCE_MAX_INDEX: + new_var_init = build_x_modify_expr + (*new_var, NOP_EXPR, build_int_cst (new_var_type, 0), 1); + new_no_expr = build_x_modify_expr (*new_var, NOP_EXPR, *new_var, 1); + if (list_size > 1) /* this means there is more than 1 */ + new_yes_expr = build_x_modify_expr (*new_var, NOP_EXPR, array_var[0], + 1); + else + new_yes_expr = build_x_modify_expr + (*new_var, NOP_EXPR, TREE_OPERAND (array_operand[0], 1), 1); + + new_expr = build_x_conditional_expr + (build2 (LT_EXPR, TREE_TYPE (*new_var), *new_var, func_parm), + new_yes_expr, new_no_expr, 1); + break; + case REDUCE_MIN_INDEX: + new_var_init = build_x_modify_expr + (*new_var, NOP_EXPR, build_int_cst (new_var_type, 0), 1); + new_no_expr = build_x_modify_expr (*new_var, NOP_EXPR, *new_var, 1); + if (list_size > 1) + new_yes_expr = build_x_modify_expr (*new_var, NOP_EXPR, array_var[0], + 1); + else + new_yes_expr = build_x_modify_expr + (*new_var, NOP_EXPR, TREE_OPERAND (array_operand[0], 1), 1); + + new_expr = build_x_conditional_expr + (build2 (GT_EXPR, TREE_TYPE (*new_var), *new_var, func_parm), + new_yes_expr, new_no_expr, 1); + break; + default: + gcc_unreachable (); + break; + } + + 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; +} + + tree -fix_unary_array_notation_exprs (tree stmt) +fix_unary_array_notation_exprs (tree orig_stmt) { tree *array_list = NULL; @@ -1166,11 +1645,35 @@ fix_unary_array_notation_exprs (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; - find_rank (stmt, &rank); + tree builtin_loop, stmt = NULL_TREE, new_var = NULL_TREE; + + find_rank (orig_stmt, false, &rank); if (rank == 0) - return stmt; + return orig_stmt; - extract_array_notation_exprs (stmt, &array_list, &list_size); + extract_array_notation_exprs (orig_stmt, false, &array_list, &list_size); + + stmt = alloc_stmt_list (); + for (ii = 0; ii < list_size; ii++) + { + if (TREE_CODE (array_list[ii]) == CALL_EXPR + || TREE_CODE (array_list[ii]) == AGGR_INIT_EXPR) + { + builtin_loop = + fix_builtin_array_notation_fn (array_list[ii], &new_var); + append_to_statement_list (builtin_loop, &stmt); + replace_array_notations (&orig_stmt, false, &array_list[ii], + &new_var, 1); + } + } + append_to_statement_list (orig_stmt, &stmt); + rank = 0; + list_size = 0; + array_list = NULL; + extract_array_notation_exprs (stmt, true, &array_list, &list_size); + find_rank (stmt, true, &rank); + if (rank == 0) + return stmt; if (*array_list == NULL_TREE || list_size == 0) return stmt; @@ -1334,7 +1837,7 @@ fix_unary_array_notation_exprs (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++) { @@ -1416,3 +1919,97 @@ fix_unary_array_notation_exprs (tree stmt) stmt = loop; return stmt; } + +static bool +is_builtin_array_notation_fn (tree func_name, an_reduce_type *type) +{ + const char *function_name; + + if (!func_name) + return false; + + if (TREE_CODE (func_name) == IDENTIFIER_NODE) + function_name = IDENTIFIER_POINTER (DECL_NAME (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; +} + + +static tree +build_x_reduce_expr (tree lhs, enum tree_code modifycode, tree rhs, + tsubst_flags_t complain, an_reduce_type type) +{ + if (!type) + { + return build_x_modify_expr (lhs, modifycode, rhs, complain); + } + return NULL_TREE; +} + +bool +contains_array_notation_expr (tree expr) +{ + tree *array_list = NULL; + int list_size = 0; + + 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/cp/parser.c b/gcc/cp/parser.c index fd35211..3979d78 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -41,7 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pretty-print.h" #include "parser.h" -extern void extract_array_notation_exprs (tree, tree **, int *); +extern void extract_array_notation_exprs (tree, bool, tree **, int *); extern tree fix_unary_array_notation_exprs (tree); struct pragma_simd_values local_simd_values; diff --git a/gcc/testsuite/ChangeLog.cilk b/gcc/testsuite/ChangeLog.cilk index 1071752..9fa7413 100644 --- a/gcc/testsuite/ChangeLog.cilk +++ b/gcc/testsuite/ChangeLog.cilk @@ -1,3 +1,7 @@ +2012-01-21 Balaji V. Iyer + + * g++.dg/cilk-plus/array_notation_tests/builtin_funcs.cc: New. + 2012-01-17 Balaji V. Iyer * g++.dg/cilk-plus/array_notation_tests/predecr_test.cc: New. diff --git a/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/builtin_funcs.cc b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/builtin_funcs.cc new file mode 100644 index 0000000..f5b06da --- /dev/null +++ b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/builtin_funcs.cc @@ -0,0 +1,92 @@ +#if HAVE_IO +#include +#endif +#include + +extern int funct(int x); +extern int funct2(int x, int y); +extern void func_ptr (int *x); + +/* char __sec_reduce_add (int *); */ +int main(int argc, char **argv) +{ + int array[10], array2[10], x = 0, y; + int x_correct, y_correct; + + for (int ii = 0; ii < 10; ii++) + { + array[ii] = 1+ii; + array2[ii]= 2; + } + + x = __sec_reduce_max (array[:] + array2[:]); + y = __sec_reduce_max_ind (array[:] + array2[:]); +#if HAVE_IO + std::cout << "Max = " << x << " Max Index = " << y << std::endl; +#endif + + x = __sec_reduce_max (array[0:5:1] + array2[5:5:1]); + y = __sec_reduce_max_ind (array[0:5] + array2[5:5:1]); +#if HAVE_IO + std::cout << "Max = " << x << " Max Index = " << y << std::endl; +#endif + + x = __sec_reduce_min (array[:] + array2[:]); + y = __sec_reduce_min_ind (array[:] + array2[:]); +#if HAVE_IO + std::cout << "Min = " << x << " Min Index = " << y << std::endl; +#endif + + x = __sec_reduce_min (array[0:5:1] + array2[5:5:1]); + y = __sec_reduce_min_ind (array[0:5] + array2[5:5:1]); +#if HAVE_IO + std::cout << "Min = " << x << " Min Index = " << y << std::endl; +#endif + + x = __sec_reduce_add (array[:] + array2[:]); + y = __sec_reduce_mul (array[:] + array2[:]); + + x_correct = 0; + y_correct = 1; + for (int ii = 0; ii < 10; ii++) + { + x_correct += (array[ii] + array2[ii]); + y_correct *= (array[ii] + array2[ii]); + } +#if HAVE_IO + std::cout << "Add = " << x + << " Multiply = " << y << std::endl; + std::cout << "Add(Correct) = " << x_correct + << " Multiply (Correct) = " << y_correct << std::endl; +#endif + + x = __sec_reduce_add (array[0:5:1] + array2[5:5:1]); + y = __sec_reduce_mul (array[0:5] + array2[5:5:1]); + + x_correct = 0; + y_correct = 1; + for (int ii = 0; ii < 5; ii++) + { + x_correct += (array[ii] + array2[5+ii]); + y_correct *= (array[ii] + array2[5+ii]); + } +#if HAVE_IO + std::cout << "Add = " << x + << " Multiply = " << y << std::endl; + std::cout << "Add(Correct) = " << x_correct + << " Multiply (Correct) = " << y_correct << std::endl; +#endif + + array[:] = argc - atoi ("1"); + + for (int ii = 0; ii < 10; ii++) + array2[ii] = argc - ii; + + x = __sec_reduce_all_zeros (array[0:5:1]); + y = __sec_reduce_any_zeros (array2[:]); +#if HAVE_IO + std::cout << "All Zeros = " << x << " Any Zeros = " << y << std::endl; +#endif + + return 0; +} diff --git a/gcc/tree.h b/gcc/tree.h index 051187d..90f9653 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -73,8 +73,6 @@ struct reduction_values int not_reduced; struct reduction_values *ptr_next; }; - - /* bviyer: Since we can have multiple pragma simd, this will hold the values of * each of the pragma simd and then as soon as it finds a for loop @@ -105,11 +103,19 @@ struct pragma_simd_values struct pragma_simd_values *ptr_next; }; - - - extern struct pragma_simd_values *psv_head; +typedef enum array_notation_reduce_type { + REDUCE_UNKNOWN = 0, + REDUCE_ADD, + REDUCE_MUL, + REDUCE_ALL_ZEROS, + REDUCE_ANY_ZEROS, + REDUCE_MAX, + REDUCE_MIN, + REDUCE_MAX_INDEX, + REDUCE_MIN_INDEX +} an_reduce_type; #undef DEFTREECODE