From patchwork Sun Apr 14 18:45:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Iyer, Balaji V" X-Patchwork-Id: 236452 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id F28502C00EC for ; Mon, 15 Apr 2013 04:45:45 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:content-type:mime-version; q=dns; s=default; b=UsnO1IxZvwm0evzHKloWLyFOhMrav7tlwHv7WvSPhKqs1RCTBd 1Yn4wMVgUqifgo6CZq8vuIlun/dZ2y4vEJ40WBewjznSNrCpz60QTOcZ64cHmMM8 vCCuRS9SIV37v9vlHSFgNSSS34TpV+3Ajc0qCaQ9sbnM2gIIa243Pl/ns= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:content-type:mime-version; s= default; bh=bHW9qywJikGByHMlqogq2cQZ8d0=; b=ByiaVy+zxppmvvEX+0Y+ ZrZBn6wJYOWgiNoNjEp3BJUa9LP1O9zwn+ECGzXE8gcT3P/Rut3cxzk5TVHOKwHx wm9I0ZJHGdx+aExOAOMF/FkM7PXhLxetixW2nkDhabCtYxocQ+mDxkxw9zq77Usx 0qotD2ul82tUc4+N9LRf4rw= Received: (qmail 17258 invoked by alias); 14 Apr 2013 18:45:35 -0000 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 Received: (qmail 17248 invoked by uid 89); 14 Apr 2013 18:45:34 -0000 X-Spam-SWARE-Status: No, score=-3.9 required=5.0 tests=AWL, BAYES_50, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, RP_MATCHES_RCVD, TW_BJ, TW_FN, TW_FP, TW_JC, TW_TJ, TW_TM autolearn=ham version=3.3.1 Received: from mga14.intel.com (HELO mga14.intel.com) (143.182.124.37) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Sun, 14 Apr 2013 18:45:27 +0000 Received: from azsmga002.ch.intel.com ([10.2.17.35]) by azsmga102.ch.intel.com with ESMTP; 14 Apr 2013 11:45:18 -0700 X-ExtLoop1: 1 Received: from fmsmsx104.amr.corp.intel.com ([10.19.9.35]) by AZSMGA002.ch.intel.com with ESMTP; 14 Apr 2013 11:45:17 -0700 Received: from fmsmsx152.amr.corp.intel.com (10.19.17.221) by FMSMSX104.amr.corp.intel.com (10.19.9.35) with Microsoft SMTP Server (TLS) id 14.1.355.2; Sun, 14 Apr 2013 11:45:16 -0700 Received: from fmsmsx102.amr.corp.intel.com ([169.254.2.241]) by fmsmsx152.amr.corp.intel.com ([169.254.7.116]) with mapi id 14.01.0355.002; Sun, 14 Apr 2013 11:45:16 -0700 From: "Iyer, Balaji V" To: "gcc-patches@gcc.gnu.org" CC: "Aldy Hernandez (aldyh@redhat.com)" Subject: [PATCH][cilkplus] replace TREE_LIST and mallocs in pragma simd code with vec_trees Date: Sun, 14 Apr 2013 18:45:16 +0000 Message-ID: MIME-Version: 1.0 Hello Everyone, This patch is for the Cilk Plus branch affecting both C and C++ compilers. It will replace all TREE_LISTs, xmallocs and linked-list implementations with VEC_TREES for #pragma simd implemenation. Thanks, Balaji V. Iyer. Index: gcc/pragma_simd.c =================================================================== --- gcc/pragma_simd.c (revision 197641) +++ gcc/pragma_simd.c (working copy) @@ -24,29 +24,101 @@ #include "config.h" #include "system.h" #include "coretypes.h" -#include "tm.h" #include "tree.h" -#include "langhooks.h" -#include "c/c-tree.h" -#include "c/c-lang.h" -#include "flags.h" -#include "output.h" -#include "intl.h" -#include "target.h" -#include "tree-iterator.h" -#include "bitmap.h" #include "gimple.h" +#include "diagnostic-core.h" #include "cilk.h" -#include "c-family/c-objc.h" - -struct pragma_simd_values *psv_head; +vec *p_simd_info_list; +/* Traverses the global vector P_SIMD_INFO_LIST and returns the node whose + field "INDEX" as PRAGMA_SIMD_INDEX. If no match is found, returns NULL. */ + +static struct pragma_simd_values * +psv_find_node (unsigned int pragma_simd_index) +{ + unsigned int ii = 0; + struct pragma_simd_values *return_value = NULL; + for (ii = 0; ii < vec_safe_length (p_simd_info_list); ii++) + if (pragma_simd_index == (*p_simd_info_list)[ii].index) + return_value = &(*p_simd_info_list)[ii]; + return return_value; +} + +static vec * +psv_find_reduction_list (unsigned int pragma_simd_index) +{ + unsigned int ii = 0; + vec *return_value = NULL; + + for (ii = 0; ii < vec_safe_length (p_simd_info_list); ii++) + if (pragma_simd_index == (*p_simd_info_list)[ii].index) + return_value = ((*p_simd_info_list)[ii].reduction_list); + return return_value; +} + +/* Returns true of all the clauses of KIND in the node with the matching 'index' + field to PRAGMA_SIMD_INDEX. */ + +static bool +clause_resolved_p (enum pragma_simd_kind kind, unsigned int pragma_simd_index) +{ + struct pragma_simd_values *p_simd_node; + if (pragma_simd_index <= INVALID_PRAGMA_SIMD_SLOT) + return true; + + p_simd_node = psv_find_node (pragma_simd_index); + if (!p_simd_node) + return true; + + switch (kind) + { + case P_SIMD_VECTORLENGTH: + if (!vec_safe_is_empty (p_simd_node->vec_length_list)) + return p_simd_node->vlength_OK; + else + return true; + case P_SIMD_PRIVATE: + if (!vec_safe_is_empty (p_simd_node->priv_var_list)) + return p_simd_node->private_OK; + else + return true; + case P_SIMD_LINEAR: + if (!vec_safe_is_empty (p_simd_node->linear_var_list)) + return p_simd_node->linear_OK; + else + return true; + case P_SIMD_REDUCTION: + if (!vec_safe_is_empty (p_simd_node->reduction_list)) + return p_simd_node->reduction_OK; + else + return true; + default: + return false; + } + + /* If we can't find a certain pragma, then just return tur to make sure we + do not assert/halt. */ + return true; +} + +/* Returns true of the node whose field 'index' matches PRAGMA_SIMD_INDEX + has the assert clause. */ + +bool +pragma_simd_assert_requested_p (unsigned int pragma_simd_index) +{ + if (!psv_find_node (pragma_simd_index)) + return false; + else + return psv_find_node (pragma_simd_index)->assert_requested; +} + /* Verify that the <#pragma simd> clauses have been properly resolved. INDEX is the pragma_simd_index into the global table. */ void -pragma_simd_verify_clauses (int index) +pragma_simd_verify_clauses (unsigned int index) { struct pragma_simd_values *vals = psv_find_node (index); location_t loc = vals ? vals->loc : UNKNOWN_LOCATION; @@ -54,646 +126,232 @@ if ((!clause_resolved_p (P_SIMD_VECTORLENGTH, index))) { if (pragma_simd_assert_requested_p (index)) - { - error_at (loc, "vectorlength in pragma simd not picked from list"); - exit (ICE_EXIT_CODE); - } + error_at (loc, "vectorlength in pragma simd not picked from list"); else - warning_at (0, loc, + warning_at (loc, 0, "vectorlength in pragma simd not picked from list"); } if (!clause_resolved_p (P_SIMD_PRIVATE, index)) { if (pragma_simd_assert_requested_p (index)) - { - error_at (loc, "unable to make all variables private"); - exit (ICE_EXIT_CODE); - } + error_at (loc, "unable to make all variables private"); else - warning_at (0, loc, + warning_at (loc, 0, "unable to make all variables private in pragma simd"); } if (!clause_resolved_p (P_SIMD_LINEAR, index)) { if (pragma_simd_assert_requested_p (index)) - { - error_at (loc, "unable to pick requested step-size in pragma simd"); - exit (ICE_EXIT_CODE); - } + error_at (loc, "unable to pick requested step-size in pragma simd"); else warning (loc, "unable to pick requested step-size in pragma simd"); } if (!clause_resolved_p (P_SIMD_REDUCTION, index)) { if (pragma_simd_assert_requested_p (index)) - { - error_at (loc, "unable to satisfy all reductions in pragma simd"); - exit (ICE_EXIT_CODE); - } + error_at (loc, "unable to satisfy all reductions in pragma simd"); else - warning_at (0, loc, "unable to satisfy all reductions in pragma simd"); + warning_at (loc, 0, "unable to satisfy all reductions in pragma simd"); } } -/* Clear the pragma simd data structure. */ +/* Assigns the "OK" field of a certain clause (indicated by KIND) in a node + whose 'index' field matches pragma_simd_index to SET_VALUE. */ + void -clear_pragma_simd_list (void) +set_OK_for_certain_clause (enum pragma_simd_kind kind, bool set_value, + unsigned int pragma_simd_index) { - psv_head = NULL; -} - -/* this function will check and see if a certain clause is resolved - (i.e. checked OK). */ - -bool -clause_resolved_p (enum pragma_simd_kind clause_type, int pragma_simd_index) -{ - struct pragma_simd_values *ps_iter = NULL; - + unsigned int ii = 0; if (pragma_simd_index <= INVALID_PRAGMA_SIMD_SLOT) - return true; - - if (psv_head == NULL) - return true; - - for (ps_iter = psv_head; ps_iter != NULL; ps_iter = ps_iter->ptr_next) - { - if (ps_iter->pragma_encountered && (ps_iter->index == pragma_simd_index)) - { - switch (clause_type) - { - case P_SIMD_VECTORLENGTH: - return ps_iter->vlength_OK; - case P_SIMD_PRIVATE: - return ps_iter->pvars_OK; - case P_SIMD_LINEAR: - return ps_iter->lvars_OK; - case P_SIMD_REDUCTION: - return ps_iter->rvars_OK; - default: - return false; - } - } - } - - /* if we can't find the certain pragma, then just return true to make sure - we do not assert/halt and continue */ - return true; + return; + + for (ii = 0; ii < vec_safe_length (p_simd_info_list); ii++) + if ((*p_simd_info_list)[ii].index == pragma_simd_index) + { + if (kind == P_SIMD_VECTORLENGTH) + (*p_simd_info_list)[ii].vlength_OK = set_value; + else if (kind == P_SIMD_PRIVATE) + (*p_simd_info_list)[ii].private_OK = set_value; + else if (kind == P_SIMD_REDUCTION) + (*p_simd_info_list)[ii].reduction_OK = set_value; + else if (kind == P_SIMD_LINEAR) + (*p_simd_info_list)[ii].linear_OK = set_value; + else + gcc_unreachable (); + break; + } } + -/* this function will go through and check off all the clauses we have - satisfied. */ +/* Clears all the node in *p_simd_info_list. */ void -set_OK_for_certain_clause (enum pragma_simd_kind clause_type, bool set_value, - int pragma_simd_index) +p_simd_nodes_clear (void) { - struct pragma_simd_values *ps_iter = NULL; - - if (pragma_simd_index <= INVALID_PRAGMA_SIMD_SLOT) - return; - - if (!psv_head) - return; - - // FIXME: Why not use psv_find_node? - for (ps_iter = psv_head; ps_iter != NULL; ps_iter = ps_iter->ptr_next) - { - if (ps_iter->pragma_encountered && (ps_iter->index == pragma_simd_index)) - break; - } - if (!ps_iter) - return; - - switch (clause_type) - { - case P_SIMD_VECTORLENGTH: - ps_iter->vlength_OK = set_value; - case P_SIMD_PRIVATE: - ps_iter->pvars_OK = set_value; - case P_SIMD_LINEAR: - ps_iter->lvars_OK = set_value; - case P_SIMD_REDUCTION: - ps_iter->rvars_OK = set_value; - default: - break; - } - - return; + vec_free (p_simd_info_list); } -/* this function will make srue all the reductions given by pragma simd - reduction clauses are satisfied. */ +/* Inserts *P_SIMD_NODE into P_SIMD_INFO_LIST and assigns index of P_SIMD_NODE + to the P_SIMD_INFO_LIST->head->index + 1. Returns the P_SIMD_NODE->index of + type unsigned int. */ -bool -all_reductions_satisfied_p (int pragma_simd_index) +unsigned int +p_simd_head_insert (struct pragma_simd_values *p_simd_node) { - struct pragma_simd_values *ps_iter = NULL; - struct reduction_values *rv_iter = NULL; - - if (psv_head == NULL) - return true; - - if (pragma_simd_index <= INVALID_PRAGMA_SIMD_SLOT) - return true; - - for (ps_iter = psv_head; ps_iter != NULL; ps_iter = ps_iter->ptr_next) + if (p_simd_node) { - for (rv_iter = ps_iter->reduction_vals; rv_iter != NULL; - rv_iter = rv_iter->ptr_next) + if (vec_safe_is_empty (p_simd_info_list)) + p_simd_node->index = INVALID_PRAGMA_SIMD_SLOT + 1; + else { - if (rv_iter->not_reduced != 0) - return false; + unsigned int vec_length = vec_safe_length (p_simd_info_list); + p_simd_node->index = (*p_simd_info_list)[vec_length-1].index + 1; } - } - return true; -} -// FIXME: We should really rewrite all this psv* business to use vectors. -/* Given an index into the pragma simd list (PSV_INDEX), find its - entry and return it. */ + vec_safe_push (p_simd_info_list, *p_simd_node); -struct pragma_simd_values * -psv_find_node (int psv_index) -{ - struct pragma_simd_values *ps_iter = NULL; - - if (psv_index <= INVALID_PRAGMA_SIMD_SLOT) - return NULL; - - if (psv_head == NULL) - return NULL; - - for (ps_iter = psv_head; ps_iter != NULL; ps_iter = ps_iter->ptr_next) - if ((ps_iter->index == psv_index) && ps_iter->pragma_encountered) - return ps_iter; - - gcc_unreachable (); - return NULL; -} - -/* Insert LOCAL_SIMD_VALUES into the global pragma simd table. Return - the index into the table for the new entry. */ - -int -psv_head_insert (struct pragma_simd_values local_simd_values) -{ - struct pragma_simd_values *ps_iter = NULL; - - struct reduction_values *rv_iter = NULL; - - gcc_assert (local_simd_values.pragma_encountered == true); - if (psv_head == NULL) - { - psv_head = (struct pragma_simd_values *) - xcalloc (1, sizeof (struct pragma_simd_values)); - psv_head->loc = local_simd_values.loc; - psv_head->pragma_encountered = local_simd_values.pragma_encountered; - psv_head->index = INVALID_PRAGMA_SIMD_SLOT + 1; - psv_head->types = local_simd_values.types; - - psv_head->vectorlength = local_simd_values.vectorlength; - if (local_simd_values.vectorlength != NULL_TREE) - psv_head->vlength_OK = false; - else - psv_head->vlength_OK = true; - - psv_head->private_vars = local_simd_values.private_vars; - if (local_simd_values.private_vars != NULL_TREE) - psv_head->pvars_OK = false; - else - psv_head->pvars_OK = true; - - psv_head->linear_vars = local_simd_values.linear_vars; - if (local_simd_values.linear_vars != NULL_TREE) - psv_head->lvars_OK = false; - else - psv_head->lvars_OK = true; - - psv_head->linear_steps = local_simd_values.linear_steps; - if (local_simd_values.reduction_vals == NULL) - psv_head->reduction_vals = NULL; - - psv_head->reduction_vals = NULL; - for (rv_iter = local_simd_values.reduction_vals; rv_iter != NULL; - rv_iter = rv_iter->ptr_next) - insert_reduction_values (&psv_head->reduction_vals, - rv_iter->reduction_operator, - rv_iter->tree_reduction_var_list); - - if (local_simd_values.reduction_vals != NULL) - psv_head->rvars_OK = false; - else - psv_head->rvars_OK = true; - - psv_head->ptr_next = NULL; - return psv_head->index; + return p_simd_node->index; } - - for (ps_iter = psv_head; ps_iter->ptr_next != NULL; - ps_iter = ps_iter->ptr_next) - ; - - ps_iter->ptr_next = (struct pragma_simd_values *) - xcalloc (1, sizeof (struct pragma_simd_values)); - - // FIXME: There are a bunch of fields not initialized here: - // i.e. vlength_OK, pvars_OK, linear_steps_size - ps_iter->ptr_next->pragma_encountered = local_simd_values.pragma_encountered; - ps_iter->ptr_next->loc = local_simd_values.loc; - ps_iter->ptr_next->index = ps_iter->index + 1; - ps_iter->ptr_next->types = local_simd_values.types; - ps_iter->ptr_next->vectorlength = local_simd_values.vectorlength; - ps_iter->ptr_next->private_vars = local_simd_values.private_vars; - ps_iter->ptr_next->linear_vars = local_simd_values.linear_vars; - ps_iter->ptr_next->linear_steps = local_simd_values.linear_steps; - ps_iter->ptr_next->ptr_next = NULL; - - ps_iter->ptr_next->reduction_vals = NULL; - for (rv_iter = local_simd_values.reduction_vals; rv_iter; - rv_iter = rv_iter->ptr_next) - insert_reduction_values (&ps_iter->ptr_next->reduction_vals, - rv_iter->reduction_operator, - rv_iter->tree_reduction_var_list); - - return ps_iter->ptr_next->index; + return INVALID_PRAGMA_SIMD_SLOT; } -/* this function wil check if the user requsted the assert command. That is, - the user requested the compiler to halt if the loop is not vectorized. */ -bool -pragma_simd_assert_requested_p (int ps_index) -{ - struct pragma_simd_values *ps_iter = NULL; - if (ps_index == 0) - return 0; +/* Finds the pragma_simd_node whose index matches the pragma_simd_index and + goes through all the vectorlengths specified and returns TRUE if there is + a match. Otherwise, the function returns false. */ - // FIXME: Why not use psv_find_node. - for (ps_iter = psv_head; ps_iter; ps_iter = ps_iter->ptr_next) - { - if ((ps_iter->pragma_encountered == true) && (ps_iter->index == ps_index)) - { - if ((ps_iter->types & P_SIMD_ASSERT)) - return true; - else - return false; - } - } - return false; -} - -/* This function will check to see if the vectorlength found by the - vectorizer falls in the list of acceptable vectorlengths provided by the - user. */ - bool -pragma_simd_acceptable_vlength_p (int ps_index, - int possible_vectorization_factor, - tree scalar_type) +pragma_simd_acceptable_vlength_p (unsigned int pragma_simd_index, + int possible_vect_factor, + tree scalar_type ATTRIBUTE_UNUSED) { - tree size = NULL_TREE; - struct pragma_simd_values *ps_iter = NULL; - int possible_vector_length = 0; - tree ii_tree = NULL_TREE; - tree ii_value = NULL_TREE; - tree vl_tree = NULL_TREE; - size = size_in_bytes (scalar_type); + unsigned int ii = 0, jj = 0; + tree vl_value; - if (ps_index <= INVALID_PRAGMA_SIMD_SLOT) - return true; - if (TREE_CODE (size) == INTEGER_CST) - ; - else - error ("Unable to determine size of scalar type!"); - - possible_vector_length = possible_vectorization_factor; - - vl_tree = build_int_cst (integer_type_node, possible_vector_length); - - // FIXME: Why not use psv_find_node? - for (ps_iter = psv_head; ps_iter != NULL; ps_iter = ps_iter->ptr_next) - { - if ((ps_iter->pragma_encountered == true) && (ps_iter->index == ps_index)) - break; - } - - gcc_assert (ps_iter != NULL); - - if (list_length (ps_iter->vectorlength) == 0) - /* the user has not given any vectorlength, so whatever the vectorizer - the vectorizer found is good enough for us. */ + if (pragma_simd_index <= INVALID_PRAGMA_SIMD_SLOT) return true; + + vl_value = build_int_cst (integer_type_node, possible_vect_factor); - for (ii_tree = ps_iter->vectorlength; ii_tree; ii_tree = TREE_CHAIN (ii_tree)) - { - ii_value = TREE_VALUE (ii_tree); - if ((TREE_CODE (ii_value) == INTEGER_CST) - && tree_int_cst_equal ((const_tree) ii_value, (const_tree) vl_tree)) - /* We found a match, so we return TRUE. */ - return true; - } + for (ii = 0; ii < vec_safe_length (p_simd_info_list); ii++) + if (pragma_simd_index == (*p_simd_info_list)[ii].index) + { + vec *vl_vec = (*p_simd_info_list)[ii].vec_length_list; + if (vec_safe_length (vl_vec) == 0) + return true; + for (jj = 0; jj < vec_safe_length (vl_vec); jj++) + { + if (tree_int_cst_equal ((const_tree) (*vl_vec)[jj], + (const_tree) (vl_value))) + return true; + } + } - /* A match was not found, hence we return a false. */ + /* A match was not found, hence return false. */ return false; } -/* this function will check if we wanted a loop to be vectorized. */ +/* Goes through the private vars of pragma simd structure pointed by PS_INDEX + and checks of DEF_VAR is in the list and if so returns true. */ bool -pragma_simd_vectorize_loop_p (int ps_index) +pragma_simd_is_private_var_p (unsigned int ps_index, tree def_var) { - struct pragma_simd_values *ps_iter = NULL; + struct pragma_simd_values *ps_node = NULL; + tree variable; + unsigned int ii = 0, jj = 0; - if (ps_index <= INVALID_PRAGMA_SIMD_SLOT) + if (def_var == NULL_TREE) return false; - // FIXME: Why not use psv_find_node? - for (ps_iter = psv_head; ps_iter != NULL; ps_iter = ps_iter->ptr_next) - if (ps_iter->index == ps_index) - return ps_iter->pragma_encountered; + ps_node = psv_find_node (ps_index); + if (!ps_node) + return false; - return false; -} - -/* This function will insert the appropriate reduction values asked by pragma - simd reduction into the internal pragma simd list. */ - -void -insert_reduction_values (struct reduction_values **reduction_val_head, - enum tree_code reduction_op, tree var_list) -{ - struct reduction_values *red_iter = NULL; - bool found = false; - if (reduction_val_head == NULL) + /* If it is a SSA_NAME, then this will extract the original variable name. */ + if (TREE_CODE (def_var) == SSA_NAME) { - reduction_val_head = (struct reduction_values **) - xmalloc (sizeof (struct reduction_values *)); - gcc_assert (reduction_val_head != NULL); - } - if (*reduction_val_head == NULL) - { - *reduction_val_head = (struct reduction_values *) - xmalloc (sizeof (struct reduction_values)); - gcc_assert (*reduction_val_head != NULL); - - (*reduction_val_head)->reduction_operator = reduction_op; - (*reduction_val_head)->tree_reduction_var_list = var_list; - (*reduction_val_head)->not_reduced = list_length (var_list); - (*reduction_val_head)->ptr_next = NULL; - return; - } - else - { - for (red_iter = *reduction_val_head; red_iter->ptr_next != NULL; - red_iter = red_iter->ptr_next) + if (SSA_NAME_VAR (def_var) != NULL_TREE) { - if (red_iter->reduction_operator == reduction_op) + def_var = SSA_NAME_VAR (def_var); + if (TREE_CODE (def_var) == VAR_DECL + || TREE_CODE (def_var) == PARM_DECL) { - found = true; - break; + tree variable = DECL_NAME (def_var); + if (variable == NULL_TREE) + return false; + for (ii = 0; ii < vec_safe_length (ps_node->priv_var_list); ii++) + { + tree priv_value = (*(ps_node->priv_var_list))[ii]; + if (simple_cst_equal (priv_value, variable) == 1) + return true; + } } } - - if (found) + else if (SSA_NAME_DEF_STMT (def_var)) { - red_iter->tree_reduction_var_list = - tree_cons (NULL_TREE, var_list, red_iter->tree_reduction_var_list); - red_iter->not_reduced += - list_length (red_iter->tree_reduction_var_list); - } - else - { - red_iter->ptr_next = (struct reduction_values *) - xmalloc (sizeof (struct reduction_values)); - gcc_assert (red_iter->ptr_next != NULL); + bool found = false; + gimple def_stmt = SSA_NAME_DEF_STMT (def_var); - red_iter->ptr_next->reduction_operator = reduction_op; - red_iter->ptr_next->tree_reduction_var_list = var_list; - red_iter->ptr_next->not_reduced = - list_length (red_iter->tree_reduction_var_list); - red_iter->ptr_next->ptr_next = NULL; - } - return; - } -} - -/* this function will check if a same variable is in multiple pragma clause - for example, the following pragma is illegal and this function should flag - them as true: - #pragma simd reduction (+:p) linear(p:1) - */ - -bool -same_var_in_multiple_lists_p (struct pragma_simd_values *ps_values) -{ - tree vl_tree = NULL_TREE, vl_value = NULL_TREE; - tree pr_tree = NULL_TREE, pr_value = NULL_TREE; - tree rd_tree = NULL_TREE, rd_value = NULL_TREE; - struct reduction_values *rd_list = NULL; - - if (ps_values->reduction_vals != NULL) - { - for (rd_list = ps_values->reduction_vals; rd_list != NULL; - rd_list = rd_list->ptr_next) - { - rd_tree = rd_list->tree_reduction_var_list; - vl_tree = ps_values->vectorlength; - pr_tree = ps_values->private_vars; - - while ((vl_tree != NULL_TREE) || (rd_tree != NULL_TREE) - || (pr_tree != NULL_TREE)) + /* We go through all the ops in the def_stmt's RHS. */ + for (size_t ii = 1; ii < gimple_num_ops (def_stmt); ii++) { - if (vl_tree != NULL_TREE) - vl_value = TREE_VALUE (vl_tree); - else - vl_value = NULL_TREE; - - if (pr_tree != NULL_TREE) - pr_value = TREE_VALUE (pr_tree); - else - pr_value = NULL_TREE; + tree var_name, var = gimple_op (def_stmt, ii); + if (!var) + continue; + else if (TREE_CODE (var) == SSA_NAME && SSA_NAME_VAR (var)) + var = SSA_NAME_VAR (var); - if (rd_tree != NULL_TREE) - rd_value = TREE_VALUE (rd_tree); + if (TREE_CODE (var) == VAR_DECL || TREE_CODE (var) == PARM_DECL) + var_name = DECL_NAME (var); else - rd_value = NULL_TREE; + var_name = var; /* It should not get here. */ - if (((vl_value != NULL_TREE || pr_value != NULL_TREE) - && (simple_cst_equal (vl_value, pr_value) == 1)) - || ((vl_value != NULL_TREE || rd_value != NULL_TREE) - && (simple_cst_equal (vl_value, rd_value) == 1)) - || ((pr_value != NULL_TREE || rd_value != NULL_TREE) - && (simple_cst_equal (pr_value, rd_value) == 1))) - return true; - - if (vl_tree != NULL_TREE) - vl_tree = TREE_CHAIN (vl_tree); - - if (pr_tree != NULL_TREE) - pr_tree = TREE_CHAIN (pr_tree); - - if (rd_tree != NULL_TREE) - rd_tree = TREE_CHAIN (rd_tree); + /* Here we go through all the variables in the private list. + If we have a match, then we set found to true. If we didn't + have a match, then found will be false and then we return that. + This means that the variable we are looking in def is dependent + on variables that are not on the private list. */ + for (jj = 0; jj < vec_safe_length (ps_node->priv_var_list); jj++) + { + tree priv_value = (*(ps_node->priv_var_list))[jj]; + if (simple_cst_equal (priv_value, var_name) == 1) + found = true; + } + if (found == false) + return false; } + return found; } } - else - { - while ((vl_tree != NULL_TREE) || (rd_tree != NULL_TREE) - || (pr_tree != NULL_TREE)) - { - if (vl_tree != NULL_TREE) - vl_value = TREE_VALUE (vl_tree); - else - vl_value = NULL_TREE; - - if (pr_tree != NULL_TREE) - pr_value = TREE_VALUE (pr_tree); - else - pr_value = NULL_TREE; + else if (TREE_CODE (def_var) == VAR_DECL || TREE_CODE (def_var) == PARM_DECL) + { + variable = DECL_NAME (def_var); + if (variable == NULL_TREE) + return false; - if (rd_tree != NULL_TREE) - rd_value = TREE_VALUE (rd_tree); - else - rd_value = NULL_TREE; - - /* If either one is not NULL and the trees are equal, then we - say we have found a duplicate. */ - if (((vl_value != NULL_TREE || pr_value != NULL_TREE) - && (simple_cst_equal (vl_value, pr_value) == 1)) - || ((vl_value != NULL_TREE || rd_value != NULL_TREE) - && (simple_cst_equal (vl_value, rd_value) == 1)) - || ((pr_value != NULL_TREE || rd_value != NULL_TREE) - && (simple_cst_equal (pr_value, rd_value) == 1))) + for (ii = 0; ii < vec_safe_length (ps_node->priv_var_list); ii++) + { + tree priv_value = (*(ps_node->priv_var_list))[ii]; + if (simple_cst_equal (priv_value, variable) == 1) return true; - if (vl_tree != NULL_TREE) - vl_tree = TREE_CHAIN (vl_tree); - - if (pr_tree != NULL_TREE) - pr_tree = TREE_CHAIN (pr_tree); - - if (rd_tree != NULL_TREE) - rd_tree = TREE_CHAIN (rd_tree); } } return false; - } -/* This function will check to see if a variable is reduced, if so then it will - mark it as being reduced. */ - -void -check_off_reduction_var (gimple reduc_stmt, int pragma_simd_index) -{ - struct pragma_simd_values *ps_iter = NULL; - struct reduction_values *rv_iter = NULL; - enum tree_code op_code = NOP_EXPR; - tree def = NULL_TREE; - tree ii_iter = NULL_TREE; - tree ii_value = NULL_TREE; - - - if (pragma_simd_index <= INVALID_PRAGMA_SIMD_SLOT) - return; - - if (psv_head == NULL) - return; - - if (!reduc_stmt || gimple_code (reduc_stmt) != GIMPLE_ASSIGN) - return; - else - { - def = gimple_assign_lhs (reduc_stmt); - gcc_assert (def != NULL_TREE); - - if (TREE_CODE (def) == SSA_NAME) - def = SSA_NAME_VAR (def); - op_code = gimple_assign_rhs_code (reduc_stmt); - } - - - // FIXME: Why not use psv_find_node? - for (ps_iter = psv_head; ps_iter != NULL; ps_iter = ps_iter->ptr_next) - if (ps_iter->pragma_encountered && (ps_iter->index == pragma_simd_index)) - break; - - gcc_assert (ps_iter != NULL); - - for (rv_iter = ps_iter->reduction_vals; rv_iter != NULL; - rv_iter = rv_iter->ptr_next) - { - if (rv_iter->reduction_operator == op_code) - { - for (ii_iter = rv_iter->tree_reduction_var_list; ii_iter != NULL_TREE; - ii_iter = TREE_CHAIN (ii_iter)) - { - ii_value = TREE_VALUE (ii_iter); - if (simple_cst_equal (ii_value, DECL_NAME (def))) - rv_iter->not_reduced--; - } - } - } - return; -} - -/* This function will find the step size from the pragma simd linear clause. */ - -HOST_WIDE_INT -find_linear_step_size (int pragma_simd_index, tree var) -{ - tree ii_var_iter = NULL_TREE; - tree ii_var_value = NULL_TREE; - tree ii_step_iter = NULL_TREE; - tree ii_step_value = NULL_TREE; - tree real_var = NULL_TREE; - HOST_WIDE_INT step = 0; - struct pragma_simd_values *ps_iter = NULL; - - if (psv_head == NULL) - return 0; - - if (pragma_simd_index <= INVALID_PRAGMA_SIMD_SLOT) - return 0; - - for (ps_iter = psv_head; ps_iter != NULL; ps_iter = ps_iter->ptr_next) - { - if (ps_iter->pragma_encountered && (ps_iter->index == pragma_simd_index)) - { - ii_var_iter = ps_iter->linear_vars; - ii_step_iter = ps_iter->linear_steps; - - while ((ii_var_iter != NULL_TREE) && (ii_step_iter != NULL_TREE)) - { - ii_var_value = TREE_VALUE (ii_var_iter); - ii_step_value = TREE_VALUE (ii_step_iter); - if (TREE_CODE (var) == SSA_NAME) - real_var = SSA_NAME_VAR (var); - else - real_var = var; - - if (simple_cst_equal (ii_var_value, DECL_NAME (real_var))) - { - step = int_cst_value (ii_step_value); - return step; - } - } - } - } - return 0; -} - -/* Goes through the private vars of pragma simd structure pointed by PS_INDEX +/* Goes through the linear vars of pragma simd structure pointed by PS_INDEX and checks of DEF_VAR is in the list and if so returns true. */ bool -pragma_simd_is_private_var (int ps_index, tree def_var) +pragma_simd_is_linear_var_p (unsigned int ps_index, tree def_var) { struct pragma_simd_values *ps_node = NULL; - tree variable, ii_priv_list; + tree variable; + unsigned int ii = 0, jj = 0; if (def_var == NULL_TREE) return false; @@ -714,11 +372,11 @@ tree variable = DECL_NAME (def_var); if (variable == NULL_TREE) return false; - for (ii_priv_list = ps_node->private_vars; ii_priv_list; - ii_priv_list = TREE_CHAIN (ii_priv_list)) + for (ii = 0; ii < vec_safe_length (ps_node->linear_var_list); + ii++) { - tree ii_priv_value = TREE_VALUE (ii_priv_list); - if (simple_cst_equal (ii_priv_value, variable) == 1) + tree priv_value = (*(ps_node->linear_var_list))[ii]; + if (simple_cst_equal (priv_value, variable) == 1) return true; } } @@ -747,11 +405,11 @@ have a match, then found will be false and then we return that. This means that the variable we are looking in def is dependent on variables that are not on the private list. */ - for (ii_priv_list = ps_node->private_vars; ii_priv_list; - ii_priv_list = TREE_CHAIN (ii_priv_list)) + for (jj = 0; jj < vec_safe_length (ps_node->linear_var_list); + jj++) { - tree ii_priv_value = TREE_VALUE (ii_priv_list); - if (simple_cst_equal (ii_priv_value, var_name) == 1) + tree priv_value = (*(ps_node->linear_var_list))[jj]; + if (simple_cst_equal (priv_value, var_name) == 1) found = true; } if (found == false) @@ -766,13 +424,123 @@ if (variable == NULL_TREE) return false; - for (ii_priv_list = ps_node->private_vars; ii_priv_list; - ii_priv_list = TREE_CHAIN (ii_priv_list)) + for (ii = 0; ii < vec_safe_length (ps_node->priv_var_list); ii++) { - tree ii_priv_value = TREE_VALUE (ii_priv_list); - if (simple_cst_equal (ii_priv_value, variable) == 1) + tree priv_value = (*(ps_node->priv_var_list))[ii]; + if (simple_cst_equal (priv_value, variable) == 1) return true; } } return false; } + +/* Outputs all the index fields in P_SIMD_INFO_LIST global vector to the + file pointed by *FPTR. */ + +void +dump_pragma_simd_values_vec (FILE *fptr) +{ + unsigned int ii = 0; + + if (!fptr) + fptr = stderr; + for (ii = 0; ii < vec_safe_length (p_simd_info_list); ii++) + { + fprintf (fptr, "index = %2d\n", (*p_simd_info_list)[ii].index); + fprintf (fptr, "assert_requested = %s\n", + (*p_simd_info_list)[ii].assert_requested ? "true" : "false"); + } + return; +} + +/* Returns the step size for VAR that is in the linear clause stored in the + pragma_simd_index data vector pointed by pragma_simd_index. */ + +HOST_WIDE_INT +find_linear_step_size (unsigned int pragma_simd_index, tree var) +{ + unsigned int ii = 0; + tree real_var = NULL_TREE; + struct pragma_simd_values *ps_node = psv_find_node (pragma_simd_index); + + if (!ps_node) + return 0; + + if (TREE_CODE (var) == SSA_NAME) + real_var = SSA_NAME_VAR (var); + else + real_var = var; + + for (ii = 0; ii < vec_safe_length (ps_node->linear_var_list); ii++) + if (simple_cst_equal (DECL_NAME (real_var), + (*(ps_node->linear_var_list))[ii])) + return int_cst_value ((*(ps_node->linear_steps_list))[ii]); + + return 0; +} + +/* Returns true when all the reductions_var in the pragma simd data structure + with index field matching PRAGMA_SIMD_INDEX is NULL or has a length of 0. */ + +bool +all_reductions_satisfied_p (unsigned int pragma_simd_index) +{ + unsigned int ii; + bool satisfied = true; + vec *red_list = + psv_find_reduction_list (pragma_simd_index); + + if (!red_list || vec_safe_length (red_list) == 0) + return true; + + for (ii = 0; ii < vec_safe_length (red_list); ii++) + if (vec_safe_length ((*red_list)[ii].reduction_vars) != 0) + satisfied = false; + + return satisfied; +} + +/* If definition variable of REDUC_STMT is marked as a reduction variable + in the pragma simd data structure whose index field matches PS_INDEX, the + variable is removed from the list. */ + +void +check_off_reduction_var (gimple reduc_stmt, unsigned int ps_index) +{ + enum tree_code op_code = NOP_EXPR; + tree def; + bool found = false; + unsigned int ii, jj; + vec *red_list = + psv_find_reduction_list (ps_index); + + if (!red_list || vec_safe_length (red_list) == 0) + return; + + if (!reduc_stmt || gimple_code (reduc_stmt) != GIMPLE_ASSIGN) + return; + + def = gimple_assign_lhs (reduc_stmt); + gcc_assert (def != NULL_TREE); + + if (TREE_CODE (def) == SSA_NAME) + def = SSA_NAME_VAR (def); + op_code = gimple_assign_rhs_code (reduc_stmt); + + for (ii = 0; ii < vec_safe_length (red_list); ii++) + if ((*red_list)[ii].reduction_type == (int) op_code) + { + unsigned int length = vec_safe_length ((*red_list)[ii].reduction_vars); + for (jj = 0; jj < length; jj++) + { + tree var = (*((*red_list)[ii].reduction_vars))[jj]; + if (simple_cst_equal (var, def)) + { + found = true; + break; + } + } + if (found) + (*red_list)[ii].reduction_vars->unordered_remove (jj); + } +} Index: gcc/c-family/c-common.h =================================================================== --- gcc/c-family/c-common.h (revision 197532) +++ gcc/c-family/c-common.h (working copy) @@ -546,6 +546,7 @@ 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 p_simd_valid_stmts_in_body_p (tree); extern tree build_indirect_ref (location_t, tree, ref_operator); extern int field_decl_cmp (const void *, const void *); Index: gcc/c-family/c-pragma.c =================================================================== --- gcc/c-family/c-pragma.c (revision 197532) +++ gcc/c-family/c-pragma.c (working copy) @@ -1347,23 +1347,10 @@ if (flag_enable_cilk && !flag_preprocess_only) { cpp_register_deferred_pragma (parse_in, "cilk", "grainsize", - PRAGMA_CILK_GRAINSIZE, true, false); - cpp_register_deferred_pragma (parse_in, "simd", "", - PRAGMA_SIMD_EMPTY, true, false); - cpp_register_deferred_pragma (parse_in, "simd", "assert", - PRAGMA_SIMD_ASSERT, true, false); - cpp_register_deferred_pragma (parse_in, "simd", "noassert", - PRAGMA_SIMD_NOASSERT, true, false); - cpp_register_deferred_pragma (parse_in, "simd", "vectorlength", - PRAGMA_SIMD_VECTORLENGTH, true, false); - cpp_register_deferred_pragma (parse_in, "simd", "private", - PRAGMA_SIMD_PRIVATE, true, false); - cpp_register_deferred_pragma (parse_in, "simd", "reduction", - PRAGMA_SIMD_REDUCTION, true, false); - cpp_register_deferred_pragma (parse_in, "simd", "linear", - PRAGMA_SIMD_LINEAR, true, false); - } - + PRAGMA_CILK_GRAINSIZE, true, false); + cpp_register_deferred_pragma (parse_in, NULL, "simd", + CILKPLUS_PRAGMA_SIMD, true, false); + } if (!flag_preprocess_only) cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess", PRAGMA_GCC_PCH_PREPROCESS, false, false); Index: gcc/c-family/ChangeLog.cilkplus =================================================================== --- gcc/c-family/ChangeLog.cilkplus (revision 197532) +++ gcc/c-family/ChangeLog.cilkplus (working copy) @@ -1,3 +1,9 @@ +2013-04-14 Balaji V. Iyer + + * c-pragma.c (init_pragma): Added "simd" as a deferred pragma instead + of it being a namespace. Removed all definition of pragma simd's + optional sub-clauses. + 2013-02-05 Balaji V. Iyer * c-cilk.c (extract_for_fields): Added a check if the increment value Index: gcc/c-family/c-pragma.h =================================================================== --- gcc/c-family/c-pragma.h (revision 197532) +++ gcc/c-family/c-pragma.h (working copy) @@ -48,14 +48,9 @@ /* This pragma allows you to get the grainsize of a Cilk for. */ PRAGMA_CILK_GRAINSIZE, - /* Here are all the pragma simd clauses. */ - PRAGMA_SIMD_VECTORLENGTH, - PRAGMA_SIMD_PRIVATE, - PRAGMA_SIMD_LINEAR, - PRAGMA_SIMD_REDUCTION, - PRAGMA_SIMD_NOASSERT, - PRAGMA_SIMD_ASSERT, - PRAGMA_SIMD_EMPTY, + /* Top level clause to handle all pragma simd [sub]clauses. */ + CILKPLUS_PRAGMA_SIMD, + PRAGMA_GCC_PCH_PREPROCESS, PRAGMA_FIRST_EXTERNAL Index: gcc/tree-loop-distribution.c =================================================================== --- gcc/tree-loop-distribution.c (revision 197532) +++ gcc/tree-loop-distribution.c (working copy) @@ -128,7 +128,7 @@ { gimple use_stmt = USE_STMT (use_p); if (flag_enable_cilk - && pragma_simd_is_private_var (loop->pragma_simd_index, def)) + && pragma_simd_is_private_var_p (loop->pragma_simd_index, def)) /* Don't do any more checks for this value. The user has indicated that this variable is private to the loop. */ ; Index: gcc/c/c-parser.c =================================================================== --- gcc/c/c-parser.c (revision 197641) +++ gcc/c/c-parser.c (working copy) @@ -62,7 +62,6 @@ struct c_expr); extern bool contains_array_notation_expr (tree); extern tree expand_array_notation_exprs (tree); -struct pragma_simd_values cilkplus_local_simd_values; /* Initialization routine for this file. */ @@ -116,14 +115,6 @@ C_IS_RESERVED_WORD (id) = 1; ridpointers [(int) c_common_reswords[i].rid] = id; } - - /* Only initialize the first time. After each consumption, the - for-loop handling code (c_finish_loop) will automatically consume - the values and delete the information. */ - memset (&cilkplus_local_simd_values, 0, - sizeof (cilkplus_local_simd_values)); - - clear_pragma_simd_list (); } /* The C lexer intermediates between the lexer in cpplib and c-lex.c @@ -1171,7 +1162,7 @@ static void c_parser_switch_statement (c_parser *); static void c_parser_while_statement (c_parser *); static void c_parser_do_statement (c_parser *); -static void c_parser_for_statement (c_parser *); +static void c_parser_for_statement (c_parser *, struct pragma_simd_values *); static tree c_parser_asm_statement (c_parser *); static tree c_parser_asm_operands (c_parser *); static tree c_parser_asm_goto_operands (c_parser *); @@ -1241,11 +1232,13 @@ // recursive functions. /* Cilk Plus supporting routines. */ static void c_parser_cilk_for_statement (c_parser *, tree); -static void c_parser_simd_linear (c_parser *); -static void c_parser_simd_private (c_parser *); -static void c_parser_simd_assert (c_parser *, bool); -static void c_parser_simd_vectorlength (c_parser *); -static void c_parser_simd_reduction (c_parser *); +static void c_parser_simd_linear (c_parser *, struct pragma_simd_values *); +static void c_parser_simd_private (c_parser *, struct pragma_simd_values *); +static void c_parser_simd_assert (c_parser *, bool, + struct pragma_simd_values *); +static void c_parser_simd_vectorlength (c_parser *, + struct pragma_simd_values *); +static void c_parser_simd_reduction (c_parser *, struct pragma_simd_values *); static tree c_parser_array_notation (location_t, c_parser *, tree, tree); /* Parse a translation unit (C90 6.7, C99 6.9). @@ -4562,7 +4555,7 @@ c_parser_do_statement (parser); break; case RID_FOR: - c_parser_for_statement (parser); + c_parser_for_statement (parser, NULL); break; case RID_CILK_FOR: if (!flag_enable_cilk) @@ -4928,7 +4921,7 @@ c_cont_label = NULL_TREE; body = c_parser_c99_block_statement (parser); c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, - &cilkplus_local_simd_values, true); + NULL, true); add_stmt (c_end_compound_stmt (loc, block, flag_isoc99)); c_break_label = save_break; c_cont_label = save_cont; @@ -4973,7 +4966,7 @@ if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) c_parser_skip_to_end_of_block_or_statement (parser); c_finish_loop (loc, cond, NULL, body, new_break, new_cont, - &cilkplus_local_simd_values, false); + NULL, false); add_stmt (c_end_compound_stmt (loc, block, flag_isoc99)); } @@ -5034,7 +5027,7 @@ */ static void -c_parser_for_statement (c_parser *parser) +c_parser_for_statement (c_parser *parser, struct pragma_simd_values *p_simd_val) { tree block, cond, incr, save_break, save_cont, body; /* The following are only used when parsing an ObjC foreach statement. */ @@ -5189,8 +5182,7 @@ objc_finish_foreach_loop (loc, object_expression, collection_expression, body, c_break_label, c_cont_label); else c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label, - &cilkplus_local_simd_values, - true); + p_simd_val, true); add_stmt (c_end_compound_stmt (loc, block, flag_isoc99 || c_dialect_objc ())); c_break_label = save_break; c_cont_label = save_cont; @@ -8782,506 +8774,555 @@ objc_add_dynamic_declaration (loc, list); } +/* Returns true of a same variable is found in sub-field vectors + linear_var_list, priv_var_list and reduction_list of P_SIMD_VALUES. */ -/* This function will parse the pragma simd assert in the Cilkplus - language extension. The proper syntax are: - #pragma simd assert - #pragma simd noassert - */ +static bool +same_var_in_multiple_lists_p (struct pragma_simd_values *p_simd_values) +{ + size_t ii, jj, kk; + if (!p_simd_values) + return false; + + /* First check linear and private lists. */ + for (ii = 0; ii < vec_safe_length (p_simd_values->linear_var_list); ii++) + for (jj = 0; jj < vec_safe_length (p_simd_values->priv_var_list); jj++) + { + tree linear_var = (*(p_simd_values->linear_var_list))[ii]; + tree priv_var = (*(p_simd_values->priv_var_list))[jj]; + if (simple_cst_equal (linear_var, priv_var) == 1) + { + error_at (p_simd_values->loc, "ill-formed pragma: variable %qE" + " listed in both linear and private pragma simd clause", + priv_var); + return true; + } + } + + /* Now check linear and reduction lists. */ + for (ii = 0; ii < vec_safe_length (p_simd_values->linear_var_list); ii++) + for (jj = 0; jj < vec_safe_length (p_simd_values->reduction_list); jj++) + { + struct reduction_node r_node = (*(p_simd_values->reduction_list))[jj]; + for (kk = 0; kk < vec_safe_length (r_node.reduction_vars); kk++) + { + tree linear_var = (*(p_simd_values->linear_var_list))[ii]; + tree red_var = (*(r_node.reduction_vars))[kk]; + if (simple_cst_equal (linear_var, red_var) == 1) + { + error_at (p_simd_values->loc, + "ill-formed pragma: variable %qE listed in both " + "reduction and linear pragma simd clause", red_var); + return true; + } + } + } + + /* Finally check private and reduction lists. */ + for (ii = 0; ii < vec_safe_length (p_simd_values->priv_var_list); ii++) + for (jj = 0; jj < vec_safe_length (p_simd_values->reduction_list); jj++) + { + struct reduction_node r_node = (*(p_simd_values->reduction_list))[jj]; + for (kk = 0; kk < vec_safe_length (r_node.reduction_vars); kk++) + { + tree priv_var = (*(p_simd_values->priv_var_list))[ii]; + tree red_var = (*(r_node.reduction_vars))[kk]; + if (simple_cst_equal (priv_var, red_var) == 1) + { + error_at (p_simd_values->loc, + "ill-formed pragma: variable %qE listed in both " + "reduction and private pragma simd clause", red_var); + return true; + } + } + } + return false; +} + +/* Main entry point to parsing all PRAGMA SIMD (or SIMD Loops) pragmas. */ + static void -c_parser_simd_assert (c_parser *parser, bool is_assert) +c_parser_simd_construct (c_parser *parser, + struct pragma_simd_values *p_simd_values) { - c_token *token; + c_token *token = c_parser_peek_token (parser); - if (cilkplus_local_simd_values.types == 1) - c_parser_error (parser, "multiple simd assert/noassert pragmas found"); + if (token->type != CPP_PRAGMA_EOL) + c_parser_consume_token (parser); + if (!token->value + || !strcmp (IDENTIFIER_POINTER (token->value), "noassert")) + c_parser_simd_assert (parser, false, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "assert")) + c_parser_simd_assert (parser, false, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "vectorlength")) + c_parser_simd_vectorlength (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "linear")) + c_parser_simd_linear (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "private")) + c_parser_simd_private (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "reduction")) + c_parser_simd_reduction (parser, p_simd_values); else { - if (is_assert == true) - cilkplus_local_simd_values.types |= P_SIMD_ASSERT; - else - cilkplus_local_simd_values.types |= P_SIMD_NOASSERT; + error_at (input_location, "pragma simd clause %s not implemented", + IDENTIFIER_POINTER (token->value)); + c_parser_skip_to_pragma_eol (parser); } +} - cilkplus_local_simd_values.pragma_encountered = true; +/* Parses the pragma simd assert clause of CilkPlus language extension. The + proper syntax are: + #pragma simd assert + #pragma simd noassert + +*/ + +static void +c_parser_simd_assert (c_parser *parser, bool is_assert, + struct pragma_simd_values *p_simd_values) +{ + c_token *token; + + if (is_assert) + { + if (p_simd_values->assert_requested == P_SIMD_NOASSERT) + { + error_at (input_location, "assert and noassert cannot be used in the" + " same pragma"); + c_parser_skip_to_pragma_eol (parser); + return; + } + p_simd_values->assert_requested = P_SIMD_ASSERT; + } + else + { + if (p_simd_values->assert_requested == P_SIMD_ASSERT) + { + error_at (input_location, "assert and noassert cannot be used in the" + " same pragma"); + c_parser_skip_to_pragma_eol (parser); + return; + } + p_simd_values->assert_requested = P_SIMD_NOASSERT; + } + if (c_parser_next_token_is (parser, CPP_NAME)) { token = c_parser_peek_token (parser); c_parser_consume_token (parser); - if (strcmp (IDENTIFIER_POINTER (token->value), "linear") == 0) - c_parser_simd_linear (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "private") == 0) - c_parser_simd_private (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "vectorlength") == 0) - c_parser_simd_vectorlength (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "reduction") == 0) - c_parser_simd_reduction (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "assert") == 0) - c_parser_simd_assert (parser, true); - else if (strcmp (IDENTIFIER_POINTER (token->value), "noassert") == 0) - c_parser_simd_assert (parser, false); + + if (!strcmp (IDENTIFIER_POINTER (token->value), "linear")) + c_parser_simd_linear (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "private")) + c_parser_simd_private (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "reduction")) + c_parser_simd_reduction (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "assert")) + c_parser_simd_assert (parser, true, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "noassert")) + c_parser_simd_assert (parser, false, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "vectorlength")) + c_parser_simd_vectorlength (parser, p_simd_values); else - c_parser_error (parser, "Unknown identifier"); + { + error_at (input_location, "unknown pragma simd clause"); + c_parser_skip_to_pragma_eol (parser); + } } else { c_parser_skip_to_pragma_eol (parser); - if (!c_parser_next_token_is_keyword (parser, RID_FOR)) - c_parser_error (parser, "for statement expected"); - else + if (c_parser_next_token_is_keyword (parser, RID_FOR)) { - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - c_parser_error (parser, "ill-formed pragma: Found same variable in" - " multiple clauses"); - /* If the pragma simd found is true, it means that we should use the - values given in the local_pragma_simd variable. */ - c_parser_for_statement (parser); + if (!same_var_in_multiple_lists_p (p_simd_values)) + c_parser_for_statement (parser, p_simd_values); } + else + error_at (input_location, "for statement expected after pragma simd"); } } -/* This function will parse the pragma simd linear in the Cilkplus language - extension. The syntax is: - #pragma simd linear (:[], ...) - */ +/* Parses the pragma simd linear clause in Cilk Plus language extension. + The syntax is: + #pragma simd linear (:[")) + + if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { + c_parser_skip_to_pragma_eol (parser); + return; + } + else + { while (true) { if (c_parser_next_token_is_not (parser, CPP_NAME)) { c_parser_error (parser, "expected variable"); - c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); - linear_var_list = NULL_TREE; - linear_steps_list = NULL_TREE; + c_parser_skip_to_pragma_eol (parser); + vec_safe_truncate (p_simd_values->linear_var_list, 0); + vec_safe_truncate (p_simd_values->linear_steps_list, 0); break; } linear_var = c_parser_peek_token (parser)->value; c_parser_consume_token (parser); - linear_var_list = tree_cons (NULL_TREE, linear_var, linear_var_list); - + vec_safe_push (p_simd_values->linear_var_list, linear_var); + if (c_parser_next_token_is (parser, CPP_COLON)) { - c_parser_consume_token (parser); + c_parser_consume_token (parser); if (c_parser_next_token_is_not (parser, CPP_NUMBER)) { c_parser_error (parser, "expected step-size"); + vec_safe_truncate (p_simd_values->linear_steps_list, 0); + vec_safe_truncate (p_simd_values->linear_var_list, 0); c_parser_skip_to_pragma_eol (parser); return; } - linear_step = c_parser_peek_token (parser)->value; c_parser_consume_token (parser); - } else if (c_parser_next_token_is (parser, CPP_COMMA) - || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) + || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) linear_step = integer_one_node; else { - c_parser_error (parser, "expected : or , after variable name"); + c_parser_error (parser, "expected ':' or ',' after variable " + "name"); c_parser_skip_to_pragma_eol (parser); return; } + vec_safe_push (p_simd_values->linear_steps_list, linear_step); + if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) { c_parser_consume_token (parser); - linear_steps_list = tree_cons (NULL_TREE, linear_step, - linear_steps_list); break; } - if (c_parser_next_token_is (parser, CPP_COMMA)) - { - c_parser_consume_token (parser); - linear_steps_list = tree_cons (NULL_TREE, linear_step, - linear_steps_list); - } + c_parser_consume_token (parser); } } - else - { - c_parser_error (parser, "expected %<(%>"); - return; - } - gcc_assert (list_length (linear_steps_list) == list_length (linear_var_list)); - - - cilkplus_local_simd_values.linear_steps_size = ii; - cilkplus_local_simd_values.linear_var_size = ii; - if (c_parser_next_token_is (parser, CPP_NAME)) { token = c_parser_peek_token (parser); c_parser_consume_token (parser); - if (strcmp (IDENTIFIER_POINTER (token->value), "linear") == 0) - c_parser_simd_linear (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "private") == 0) - c_parser_simd_private (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "vectorlength") == 0) - c_parser_simd_vectorlength (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "reduction") == 0) - c_parser_simd_reduction (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "assert") == 0) - c_parser_simd_assert (parser, true); - else if (strcmp (IDENTIFIER_POINTER (token->value), "noassert") == 0) - c_parser_simd_assert (parser, false); + + if (!strcmp (IDENTIFIER_POINTER (token->value), "linear")) + c_parser_simd_linear (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "private")) + c_parser_simd_private (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "reduction")) + c_parser_simd_reduction (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "assert")) + c_parser_simd_assert (parser, true, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "noassert")) + c_parser_simd_assert (parser, false, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "vectorlength")) + c_parser_simd_vectorlength (parser, p_simd_values); else - c_parser_error (parser, "Unknown identifier"); + { + error_at (input_location, "unknown pragma simd clause"); + c_parser_skip_to_pragma_eol (parser); + } } else { c_parser_skip_to_pragma_eol (parser); - if (!c_parser_next_token_is_keyword (parser, RID_FOR)) - c_parser_error (parser, "for statement expected"); - else + if (c_parser_next_token_is_keyword (parser, RID_FOR)) { - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - c_parser_error (parser, "ill-formed pragma: Found same variable " - "in multiple clauses "); - /* If the pragma simd found is true, it means that we should use the - values given in the local_pragma_simd variable. */ - c_parser_for_statement (parser); + if (!same_var_in_multiple_lists_p (p_simd_values)) + c_parser_for_statement (parser, p_simd_values); } + else + error_at (input_location, "for statement expected after pragma simd"); } - cilkplus_local_simd_values.pragma_encountered = true; } -/* This function will parse the pragma simd private in the Cilkplus - language extension. The correct syntax is: - #pragma simd private ( [, ]) - */ +/* Parses the private clause of simd pragma that is part of Cilk Plus language + extension. + The correct syntax is: + #pragma simd private ( [, ")) + if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { + c_parser_skip_to_pragma_eol (parser); + vec_safe_truncate (p_simd_values->priv_var_list, 0); + return; + } + else + { while (true) { if (c_parser_next_token_is_not (parser, CPP_NAME)) { - c_parser_error (parser, "expected variable!"); - c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); - private_var_list = NULL_TREE; + error_at (input_location, "expected variable name"); + c_parser_skip_to_pragma_eol (parser); + vec_safe_truncate (p_simd_values->priv_var_list, 0); break; } private_var = c_parser_peek_token (parser)->value; c_parser_consume_token (parser); - - private_var_list = tree_cons (NULL_TREE, private_var, - private_var_list); + vec_safe_push (p_simd_values->priv_var_list, private_var); if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) { c_parser_consume_token (parser); break; } - if (c_parser_next_token_is (parser, CPP_COMMA)) + else if (c_parser_next_token_is (parser, CPP_COMMA)) c_parser_consume_token (parser); } } - else - c_parser_error (parser, "expected %<(%>"); - cilkplus_local_simd_values.private_vars = private_var_list; - - cilkplus_local_simd_values.priv_var_size = list_length (private_var_list); - cilkplus_local_simd_values.priv_var_list = (char **) - xmalloc (sizeof (char *) * cilkplus_local_simd_values.priv_var_size); - - ii = 0; - - for (p = private_var_list; p != NULL_TREE; p = TREE_CHAIN (p)) - { - cilkplus_local_simd_values.priv_var_list[ii] = - xstrdup (IDENTIFIER_POINTER (TREE_VALUE (p))); - ii++; - } - - cilkplus_local_simd_values.priv_var_size = ii; - if (c_parser_next_token_is (parser, CPP_NAME)) { token = c_parser_peek_token (parser); c_parser_consume_token (parser); - if (strcmp (IDENTIFIER_POINTER (token->value), "linear") == 0) - c_parser_simd_linear (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "private") == 0) - c_parser_simd_private (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "vectorlength") == 0) - c_parser_simd_vectorlength (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "reduction") == 0) - c_parser_simd_reduction (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "assert") == 0) - c_parser_simd_assert (parser, true); - else if (strcmp (IDENTIFIER_POINTER (token->value), "noassert") == 0) - c_parser_simd_assert (parser, false); + + if (!strcmp (IDENTIFIER_POINTER (token->value), "linear")) + c_parser_simd_linear (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "private")) + c_parser_simd_private (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "reduction")) + c_parser_simd_reduction (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "assert")) + c_parser_simd_assert (parser, true, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "noassert")) + c_parser_simd_assert (parser, false, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "vectorlength")) + c_parser_simd_vectorlength (parser, p_simd_values); else - c_parser_error (parser, "Unknown identifier"); + { + error_at (input_location, "unknown pragma simd clause"); + c_parser_skip_to_pragma_eol (parser); + } } else { c_parser_skip_to_pragma_eol (parser); - if (!c_parser_next_token_is_keyword (parser, RID_FOR)) - c_parser_error (parser, "for statement expected"); - else + if (c_parser_next_token_is_keyword (parser, RID_FOR)) { - - if (same_var_in_multiple_lists_p(&cilkplus_local_simd_values)) - c_parser_error (parser, "ill-formed pragma: Found same variable" - " in multiple clauses "); - - /* If the pragma simd found is true, it means that we should use the - values given in the local_pragma_simd variable. */ - c_parser_for_statement (parser); + if (!same_var_in_multiple_lists_p (p_simd_values)) + c_parser_for_statement (parser, p_simd_values); } + else + error_at (input_location, "for statement expected after pragma simd"); } } -/* This function will parse the pragma simd vectorlength in the Cilkplus - language extension. The correct syntax is: - #pragma simd vectorlength ( [, ]*) - */ +/* Parses the vectorlength clause of SIMD pragmas that is part of Cilk Plus + language extension. + + The correct syntax is: + #pragma simd vectorlength ( [, ")) + if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { + c_parser_skip_to_pragma_eol (parser); + return; + } + else + { while (true) { - tree token_value = NULL_TREE; - token_value = c_parser_expr_no_commas (parser, NULL).value; - if (!TREE_TYPE (token_value) || !TREE_CONSTANT (token_value) - || !INTEGRAL_TYPE_P (TREE_TYPE (token_value))) + tree vlength_value = c_parser_expr_no_commas (parser, NULL).value; + if (!TREE_TYPE (vlength_value) || !TREE_CONSTANT (vlength_value) + || !INTEGRAL_TYPE_P (TREE_TYPE (vlength_value))) { - c_parser_error (parser, "expected number"); - c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); - vec_length_list = NULL_TREE; + error_at (input_location, "vectorlength must be an integral " + "constant"); + c_parser_skip_to_pragma_eol (parser); + vec_safe_truncate (p_simd_values->vec_length_list, 0); break; } + else + vec_safe_push (p_simd_values->vec_length_list, vlength_value); - v_length_value = token_value; - vec_length_list = tree_cons (NULL_TREE, v_length_value, - vec_length_list); if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) { c_parser_consume_token (parser); break; } - if (c_parser_next_token_is (parser, CPP_COMMA)) + if (c_parser_next_token_is (parser, CPP_COMMA)) c_parser_consume_token (parser); } } - else - c_parser_error (parser, "expected %<(%>"); - - cilkplus_local_simd_values.vec_length_size = list_length (vec_length_list); - - cilkplus_local_simd_values.vec_length_list = - (int *)xmalloc (sizeof (int) * cilkplus_local_simd_values.vec_length_size); - - ii = 0; - for (p = vec_length_list; p != NULL_TREE; p = TREE_CHAIN (p)) - { - cilkplus_local_simd_values.vec_length_list[ii] = - int_cst_value (TREE_VALUE (p)); - ii++; - } - - - cilkplus_local_simd_values.vectorlength = vec_length_list; - cilkplus_local_simd_values.pragma_encountered = true; - if (c_parser_next_token_is (parser, CPP_NAME)) { - token = c_parser_peek_token (parser); + c_token *token = c_parser_peek_token (parser); c_parser_consume_token (parser); - if (strcmp (IDENTIFIER_POINTER (token->value), "linear") == 0) - c_parser_simd_linear (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "private") == 0) - c_parser_simd_private (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "vectorlength") == 0) - c_parser_simd_vectorlength (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "reduction") == 0) - c_parser_simd_reduction (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "assert") == 0) - c_parser_simd_assert (parser, true); - else if (strcmp (IDENTIFIER_POINTER (token->value), "noassert") == 0) - c_parser_simd_assert (parser, false); + + if (!strcmp (IDENTIFIER_POINTER (token->value), "linear")) + c_parser_simd_linear (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "private")) + c_parser_simd_private (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "reduction")) + c_parser_simd_reduction (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "assert")) + c_parser_simd_assert (parser, true, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "noassert")) + c_parser_simd_assert (parser, false, p_simd_values); else - c_parser_error (parser, "Unknown identifier"); + { + error_at (input_location, "unknown pragma simd clause"); + c_parser_skip_to_pragma_eol (parser); + } } else { c_parser_skip_to_pragma_eol (parser); - if (!c_parser_next_token_is_keyword (parser, RID_FOR)) - c_parser_error (parser, "for statement expected"); - else + if (c_parser_next_token_is_keyword (parser, RID_FOR)) { - - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - c_parser_error (parser, "ill-formed pragma: Found same variable in" - " multiple clauses "); - - /* If the pragma simd found is true, it means that we should use the - values given in the local_pragma_simd variable. */ - c_parser_for_statement (parser); + if (!same_var_in_multiple_lists_p (p_simd_values)) + c_parser_for_statement (parser, p_simd_values); } + else + error_at (input_location, "for statement expected after pragma simd"); } } -/* This function will parser the Pragma SIMD Reduction in the Cilkplus language - extension. The correct syntax is: - #pragma simd reduction (: [, ]*) - */ +/* Parses the reduction clause of SIMD pragma that is part of the Cilk Plus + language specification: + The correct syntax is: + #pragma simd reduction (: [, ]) +*/ static void -c_parser_simd_reduction (c_parser *parser) +c_parser_simd_reduction (c_parser *parser, + struct pragma_simd_values *p_simd_values) { - c_token *token; - tree var_list = NULL_TREE; tree vars = NULL_TREE; enum tree_code op_code = PLUS_EXPR; + struct reduction_node red_node; - - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + memset (&red_node, 0, sizeof (struct reduction_node)); + + if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { - switch (c_parser_peek_token (parser)->type) { - case CPP_PLUS: - op_code = PLUS_EXPR; - break; - case CPP_MINUS: - op_code = MINUS_EXPR; - break; - case CPP_MULT: - op_code = MULT_EXPR; - break; - case CPP_AND: - op_code = BIT_AND_EXPR; - break; - case CPP_OR: - op_code = BIT_IOR_EXPR; - break; - case CPP_XOR: - op_code = BIT_XOR_EXPR; - break; - case CPP_OR_OR: - op_code = TRUTH_ORIF_EXPR; - break; - case CPP_AND_AND: - op_code = TRUTH_ANDIF_EXPR; - break; - default: - c_parser_error (parser, "expected one of the following" - "%<+%> %<-%> %<*%> %<&%> %<|%> %<^%> %<||%> %<&&%>"); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); - var_list = NULL_TREE; - vars = NULL_TREE; - return; - } + c_parser_skip_to_pragma_eol (parser); + return; + } + else + { + switch (c_parser_peek_token (parser)->type) + { + case CPP_PLUS: + op_code = PLUS_EXPR; + break; + case CPP_MINUS: + op_code = MINUS_EXPR; + break; + case CPP_MULT: + op_code = MULT_EXPR; + break; + case CPP_AND: + op_code = BIT_AND_EXPR; + break; + case CPP_OR: + op_code = BIT_IOR_EXPR; + break; + case CPP_XOR: + op_code = BIT_XOR_EXPR; + break; + case CPP_OR_OR: + op_code = TRUTH_ORIF_EXPR; + break; + case CPP_AND_AND: + op_code = TRUTH_ANDIF_EXPR; + break; + default: + error_at (input_location, "pragma simd reduction operators must be" + " one of the following: " + "%<+%> %<-%> %<*%> %<&%> %<|%> %<^%> %<||%> %<&&%>"); + c_parser_skip_to_pragma_eol (parser); + return; + } c_parser_consume_token (parser); if (c_parser_next_token_is_not (parser, CPP_COLON)) { c_parser_error (parser, "expected %<:%>"); - c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); - var_list = NULL_TREE; - vars = NULL_TREE; + c_parser_skip_to_pragma_eol (parser); return; } c_parser_consume_token (parser); + + red_node.reduction_type = op_code; while (true) { if (c_parser_next_token_is_not (parser, CPP_NAME)) { c_parser_error (parser, "expected variable name"); - c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); - var_list = NULL_TREE; - vars = NULL_TREE; + c_parser_skip_to_pragma_eol (parser); break; } vars = c_parser_peek_token (parser)->value; c_parser_consume_token (parser); - var_list = tree_cons (NULL_TREE, vars, var_list); - + vec_safe_push (red_node.reduction_vars, vars); + if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) { c_parser_consume_token (parser); + vec_safe_push (p_simd_values->reduction_list, red_node); break; } - if (c_parser_next_token_is (parser, CPP_COMMA)) + if (c_parser_next_token_is (parser, CPP_COMMA)) c_parser_consume_token (parser); } } - else - c_parser_error (parser, "expected %<(%>"); - - insert_reduction_values (&cilkplus_local_simd_values.reduction_vals, op_code, - var_list); - cilkplus_local_simd_values.types |= P_SIMD_REDUCTION; - cilkplus_local_simd_values.pragma_encountered = true; - - if (c_parser_next_token_is (parser, CPP_NAME)) { - token = c_parser_peek_token (parser); + c_token *token = c_parser_peek_token (parser); c_parser_consume_token (parser); - if (strcmp (IDENTIFIER_POINTER (token->value), "linear") == 0) - c_parser_simd_linear (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "private") == 0) - c_parser_simd_private (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "vectorlength") == 0) - c_parser_simd_vectorlength (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "reduction") == 0) - c_parser_simd_reduction (parser); - else if (strcmp (IDENTIFIER_POINTER (token->value), "assert") == 0) - c_parser_simd_assert (parser, true); - else if (strcmp (IDENTIFIER_POINTER (token->value), "noassert") == 0) - c_parser_simd_assert (parser, false); + + if (!strcmp (IDENTIFIER_POINTER (token->value), "linear")) + c_parser_simd_linear (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "private")) + c_parser_simd_private (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "reduction")) + c_parser_simd_reduction (parser, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "assert")) + c_parser_simd_assert (parser, true, p_simd_values); + else if (!strcmp (IDENTIFIER_POINTER (token->value), "noassert")) + c_parser_simd_assert (parser, false, p_simd_values); else - c_parser_error (parser, "Unknown identifier"); + { + error_at (input_location, "unknown/unimplemented pragma simd clause"); + c_parser_skip_to_pragma_eol (parser); + } } else { c_parser_skip_to_pragma_eol (parser); - if (!c_parser_next_token_is_keyword (parser, RID_FOR)) + if (c_parser_next_token_is_keyword (parser, RID_FOR)) { - c_parser_error (parser, "for statement expected"); + if (!same_var_in_multiple_lists_p (p_simd_values)) + c_parser_for_statement (parser, p_simd_values); } - else if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - c_parser_error (parser, " pragma error: Found same variable in" - " multiple clauses"); - else - /* If the pragma simd found is true, it means that we should use the - values given in the local_pragma_simd variable. */ - c_parser_for_statement (parser); + else + error_at (input_location, "for statement expected after pragma simd"); } } @@ -9375,7 +9416,8 @@ { location_t loc = c_parser_peek_token (parser)->location; unsigned int id; - + struct pragma_simd_values p_simd_values; + id = c_parser_peek_token (parser)->pragma_kind; gcc_assert (id != PRAGMA_NONE); @@ -9457,62 +9499,15 @@ c_parser_cilk_grainsize (parser); return false; - case PRAGMA_SIMD_ASSERT: + case CILKPLUS_PRAGMA_SIMD: if (!c_parser_pragma_simd_ok_p (parser, context)) return false; - cilkplus_local_simd_values.loc = loc; + memset (&p_simd_values, 0, sizeof (struct pragma_simd_values)); + p_simd_values.loc = c_parser_peek_token (parser)->location; c_parser_consume_pragma (parser); - c_parser_simd_assert (parser, true); + c_parser_simd_construct (parser, &p_simd_values); return false; - case PRAGMA_SIMD_NOASSERT: - if (!c_parser_pragma_simd_ok_p (parser, context)) - return false; - cilkplus_local_simd_values.loc = loc; - c_parser_consume_pragma (parser); - c_parser_simd_assert (parser, false); - return false; - - case PRAGMA_SIMD_VECTORLENGTH: - if (!c_parser_pragma_simd_ok_p (parser, context)) - return false; - cilkplus_local_simd_values.loc = loc; - c_parser_consume_pragma (parser); - c_parser_simd_vectorlength (parser); - return false; - - case PRAGMA_SIMD_PRIVATE: - if (!c_parser_pragma_simd_ok_p (parser, context)) - return false; - cilkplus_local_simd_values.loc = loc; - c_parser_consume_pragma (parser); - c_parser_simd_private (parser); - return false; - - case PRAGMA_SIMD_LINEAR: - if (!c_parser_pragma_simd_ok_p (parser, context)) - return false; - cilkplus_local_simd_values.loc = loc; - c_parser_consume_pragma (parser); - c_parser_simd_linear (parser); - return false; - - case PRAGMA_SIMD_REDUCTION: - if (!c_parser_pragma_simd_ok_p (parser, context)) - return false; - cilkplus_local_simd_values.loc = loc; - c_parser_consume_pragma (parser); - c_parser_simd_reduction (parser); - return false; - - case PRAGMA_SIMD_EMPTY: - if (!c_parser_pragma_simd_ok_p (parser, context)) - return false; - cilkplus_local_simd_values.loc = loc; - c_parser_consume_pragma (parser); - c_parser_simd_assert (parser, false); - return false; - default: if (id < PRAGMA_FIRST_EXTERNAL) { Index: gcc/c/c-typeck.c =================================================================== --- gcc/c/c-typeck.c (revision 197641) +++ gcc/c/c-typeck.c (working copy) @@ -9052,8 +9052,7 @@ void c_finish_loop (location_t start_locus, tree cond, tree incr, tree body, tree blab, tree clab, - struct pragma_simd_values *cilkplus_ps_values, - bool cond_is_first) + struct pragma_simd_values *p_simd_val, bool cond_is_first) { tree entry = NULL, exit = NULL, t; @@ -9108,16 +9107,16 @@ exit = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, exit, t); } - if (cilkplus_ps_values) + if (flag_enable_cilk && p_simd_val) { - if (cilkplus_ps_values->pragma_encountered == true) - LABEL_EXPR_PRAGMA_SIMD_INDEX (top) = - psv_head_insert (*cilkplus_ps_values); - else + /* If invalid statments are found in the loop-body, then just issue + an error and do not store pragma simd values information. */ + if (!p_simd_valid_stmts_in_body_p (body)) LABEL_EXPR_PRAGMA_SIMD_INDEX (top) = INVALID_PRAGMA_SIMD_SLOT; - memset (&cilkplus_ps_values, 0, sizeof (cilkplus_ps_values)); - } - + else + LABEL_EXPR_PRAGMA_SIMD_INDEX (top) = + p_simd_head_insert (p_simd_val); + } add_stmt (top); } Index: gcc/c/Make-lang.in =================================================================== --- gcc/c/Make-lang.in (revision 197532) +++ gcc/c/Make-lang.in (working copy) @@ -56,7 +56,7 @@ # Language-specific object files for C and Objective C. C_AND_OBJC_OBJS = attribs.o c/c-errors.o c/c-decl.o c/c-typeck.o \ c/c-convert.o c/c-aux-info.o c/c-objc-common.o c/c-parser.o \ - c/c-array-notation.o $(C_COMMON_OBJS) $(C_TARGET_OBJS) + c/c-array-notation.o c/c-pragma-simd.o $(C_COMMON_OBJS) $(C_TARGET_OBJS) # Language-specific object files for C. C_OBJS = c/c-lang.o c-family/stub-objc.o $(C_AND_OBJC_OBJS) @@ -197,3 +197,5 @@ $(C_TREE_H) $(TARGET_H) $(FLAGS_H) intl.h output.h $(EXPR_H) \ langhooks.h tree-iterator.h $(BITMAP_H) $(GIMPLE_H) c-family/c-objc.h +c/c-pragma-simd.o: c/c-pragma-simd.c $(CONFIG_H) $(SYSTEM_H) $(CILK_H) \ + $(DIAGNOSTIC_CORE_H) \ No newline at end of file Index: gcc/c/c-pragma-simd.c =================================================================== --- gcc/c/c-pragma-simd.c (revision 0) +++ gcc/c/c-pragma-simd.c (revision 0) @@ -0,0 +1,82 @@ +/* This file is part of the Intel(R) Cilk(TM) Plus support + This file contains routines to handle Pragma SIMD expression + handling routines in the C Compiler. + Copyright (C) 2013 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 "tree.h" +#include "diagnostic-core.h" +#include "cilk.h" + +/* This function is passed in as a function pointer to walk_tree. *TP is + the current tree pointer, *WALK_SUBTREES is set to 0 by this function if + recursing into TP's subtrees is unnecessary. *DATA is a bool variable that + is set to false if an error has occured. */ + +static tree +find_invalid_stmts (tree *tp, int *walk_subtrees, void *data) +{ + bool *valid = (bool *) data; + location_t loc = EXPR_HAS_LOCATION (*tp) ? EXPR_LOCATION (*tp) : + UNKNOWN_LOCATION; + if (!tp || !*tp) + return NULL_TREE; + else if (TREE_CODE (*tp) == GOTO_EXPR) + { + error_at (loc, "goto/break/continue statments are not allowed inside " + "loops marked with #pragma simd"); + *valid = false; + *walk_subtrees = 0; + } + else if (TREE_CODE (*tp) == CALL_EXPR) + { + tree fndecl = CALL_EXPR_FN (*tp); + + if (TREE_CODE (fndecl) == ADDR_EXPR) + fndecl = TREE_OPERAND (fndecl, 0); + if (TREE_CODE (fndecl) == FUNCTION_DECL) + { + if (setjmp_call_p (fndecl)) + { + error_at (loc, "setjmps are not allowed inside loops marked with" + " #pragma simd"); + *valid = false; + *walk_subtrees = 0; + } + } + } + return NULL_TREE; +} + +/* Walks through all the subtrees of BODY using walk_tree to make sure invalid + statements/expressions are not found inside BODY. Returns false if any + invalid statements are found. */ + +bool +p_simd_valid_stmts_in_body_p (tree body) +{ + bool valid = true; + walk_tree (&body, find_invalid_stmts, (void *) &valid, NULL); + return valid; +} + Property changes on: gcc/c/c-pragma-simd.c ___________________________________________________________________ Added: svn:executable + * Index: gcc/tree.h =================================================================== --- gcc/tree.h (revision 197641) +++ gcc/tree.h (working copy) @@ -46,69 +46,44 @@ #define INVALID_PRAGMA_SIMD_SLOT 35 -typedef enum pragma_simd_kind -{ - P_SIMD_NOASSERT = 0, /* Default is just to noassert. */ - P_SIMD_ASSERT = 1, - P_SIMD_VECTORLENGTH = 2, - P_SIMD_PRIVATE = 4, - P_SIMD_LINEAR = 8, - P_SIMD_REDUCTION = 16 -} pragma_simd_kind; - -struct reduction_values -{ - enum tree_code reduction_operator; - char **reduction_var_list; - tree tree_reduction_var_list; - int not_reduced; - struct reduction_values *ptr_next; -}; - /* Since we can have multiple pragma simds, this holds the values of each of the pragma simds as we are parsing them. An index into this table gets propagated to the tree structure for LABEL_DECL's (as for loops are being parsed), then to the gimple structure for GIMPLE_LABEL's, then to the BB structure, and finally to the loop structure. */ -struct pragma_simd_values -{ - int index; +enum pragma_simd_assert_types { + P_SIMD_ASSERT = 1, + P_SIMD_NOASSERT = 2 +}; - /* Location of the #pragma itself. Ideally, we should keep the - location for each clause so we can give more detailed - diagnostics, but this will work for now. */ - location_t loc; +enum pragma_simd_kind { + P_SIMD_VECTORLENGTH = 0, + P_SIMD_PRIVATE, + P_SIMD_LINEAR, + P_SIMD_REDUCTION +}; - // FIXME: All these need to be commented. - bool pragma_encountered; - unsigned int types; - tree vectorlength; +struct reduction_node { + int reduction_type; + vec *reduction_vars; +}; + +struct pragma_simd_values { + location_t loc; + unsigned int index; + enum pragma_simd_assert_types assert_requested; + vec *linear_var_list; + vec *linear_steps_list; + vec *priv_var_list; + vec *vec_length_list; bool vlength_OK; - int *vec_length_list; - int vec_length_size; - tree private_vars; - bool pvars_OK; - char **priv_var_list; - int priv_var_size; - tree linear_vars; - bool lvars_OK; - char **linear_var_list; - int linear_var_size; - tree linear_steps; - int *linear_steps_list; - int linear_steps_size; - struct reduction_values *reduction_vals; - bool rvars_OK; - struct pragma_simd_values *ptr_next; + bool linear_OK; + bool private_OK; + bool reduction_OK; + vec *reduction_list; }; -// FIXME: This should not be globally visible. Instead we should have -// accessor functions, with a more meaningful name. -extern struct pragma_simd_values *psv_head; - - - #undef DEFTREECODE #undef END_OF_BASE_TREE_CODES @@ -3142,7 +3117,7 @@ struct tree_decl_with_rtl common; int label_decl_uid; int eh_landing_pad_nr; - int pragma_simd_index; + unsigned int pragma_simd_index; }; struct GTY(()) tree_result_decl { @@ -6635,26 +6610,22 @@ /* Cilk Plus supporting functions in pragma_simd.c. */ -extern void pragma_simd_verify_clauses (int); -extern struct pragma_simd_values *psv_find_node (int psv_index); -extern int psv_head_insert (struct pragma_simd_values local_simd_values); -extern bool pragma_simd_acceptable_vlength_p (int ps_index, +extern void pragma_simd_verify_clauses (unsigned int); + +extern unsigned int p_simd_head_insert (struct pragma_simd_values *); +extern bool pragma_simd_acceptable_vlength_p (unsigned int ps_index, int possible_vectorization_factor, tree scalar_type); -extern bool pragma_simd_assert_requested_p (int ps_index); +extern bool pragma_simd_assert_requested_p (unsigned int ps_index); extern bool pragma_simd_vectorize_loop_p (int ps_index); - -extern void insert_reduction_values (struct reduction_values **, - enum tree_code, tree); -extern bool same_var_in_multiple_lists_p (struct pragma_simd_values *ps_values); -extern void check_off_reduction_var (gimple reduc_stmt, int pragma_simd_index); -extern bool all_reductions_satisfied_p (int pragma_simd_index); -extern bool clause_resolved_p (enum pragma_simd_kind clause_type, - int pragma_simd_index); +extern void check_off_reduction_var (gimple reduc_stmt, + unsigned int pragma_simd_index); +extern bool all_reductions_satisfied_p (unsigned int pragma_simd_index); extern void set_OK_for_certain_clause (enum pragma_simd_kind clause_type, bool set_value, - int pragma_simd_index); -extern HOST_WIDE_INT find_linear_step_size (int pragma_simd_index, tree var); + unsigned int pragma_simd_index); +extern HOST_WIDE_INT find_linear_step_size (unsigned int pragma_simd_index, + tree var); #define CILK_FOR_VAR(NODE) TREE_OPERAND (CILK_FOR_STMT_CHECK (NODE), 5) #define CILK_FOR_INIT(NODE) TREE_OPERAND (CILK_FOR_STMT_CHECK (NODE), 0) Index: gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/vlength_comma.c =================================================================== --- gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/vlength_comma.c (revision 197532) +++ gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/vlength_comma.c (working copy) @@ -1,3 +1,7 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -ftree-vectorize -fcilkplus -w" } */ + + int a[100]; int Index: gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/vlength_comma2.c =================================================================== --- gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/vlength_comma2.c (revision 197532) +++ gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/vlength_comma2.c (working copy) @@ -1,3 +1,6 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -ftree-vectorize -fcilkplus -w" } */ + int a[100]; int Index: gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/vlength_comma3.c =================================================================== --- gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/vlength_comma3.c (revision 197532) +++ gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/vlength_comma3.c (working copy) @@ -1,3 +1,7 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -ftree-vectorize -fcilkplus -w" } */ + + int a[100]; int Index: gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/cilkplus_PS_c_execute.exp =================================================================== --- gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/cilkplus_PS_c_execute.exp (revision 197532) +++ gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/cilkplus_PS_c_execute.exp (working copy) @@ -20,47 +20,7 @@ verbose "$tool $libdir" 1 -set library_var [get_multilibs] dg-init -set CILK_TORTURE_OPTIONS [list \ - { -O0 -fcilkplus -lcilkrts -std=c99} \ - { -O1 -fcilkplus -lcilkrts -std=c99} \ - { -O2 -fcilkplus -lcilkrts -std=c99} \ - { -O3 -fcilkplus -lcilkrts -fomit-frame-pointer -funroll-loops -std=c99} \ - { -O3 -fcilkplus -lcilkrts -fomit-frame-pointer -funroll-all-loops -finline-functions -std=c99 } \ - { -O3 -g -fcilkplus -lcilkrts -std=c99} \ - { -Os -fcilkplus -lcilkrts -std=c99} \ - { -O0 -fcilkplus -lcilkrts -std=c99 -flto} \ - { -O1 -fcilkplus -lcilkrts -std=c99 -flto} \ - { -O2 -fcilkplus -lcilkrts -std=c99 -flto} \ - { -O3 -fcilkplus -lcilkrts -fomit-frame-pointer -funroll-loops -std=c99 -flto } \ - { -O3 -fcilkplus -lcilkrts -fomit-frame-pointer -funroll-all-loops -finline-functions -std=c99 -flto} \ - { -O3 -g -fcilkplus -lcilkrts -std=c99 -flto} \ - { -Os -fcilkplus -lcilkrts -std=c99 -flto} ] +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " " " " +dg-finish - -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 Index: gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/p_simd_test1.c =================================================================== --- gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/p_simd_test1.c (revision 197532) +++ gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/p_simd_test1.c (working copy) @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O3 -ftree-vectorize -fcilkplus" } */ +/* { dg-options "-O3 -ftree-vectorize -fcilkplus -w" } */ #define ARRAY_SIZE (256) #if HAVE_IO Index: gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/p_simd_test2.c =================================================================== --- gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/p_simd_test2.c (revision 197532) +++ gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/execute/p_simd_test2.c (working copy) @@ -1,3 +1,7 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -ftree-vectorize -fcilkplus -w" } */ + + #define N 256 #if HAVE_IO #include Index: gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/compile/assert1.c =================================================================== --- gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/compile/assert1.c (revision 197643) +++ gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/compile/assert1.c (working copy) @@ -1,5 +1,5 @@ -// { dg-do compile } -// { dg-options "-O3" } +/* { dg-do compile } */ +/* { dg-options "-O3 -fcilkplus" } */ struct stuff { char asdf; Index: gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/for_body_errors.c =================================================================== --- gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/for_body_errors.c (revision 0) +++ gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/for_body_errors.c (revision 0) @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fcilkplus" } */ + +#include + +int main(void) +{ + int ii = 0; + +#pragma simd + for (ii = 0; ii < 1000; ii++) + break; /* { dg-error "goto/break/continue statments are" } */ + +#pragma simd linear (ii) + for (ii = 0; ii < 1000; ii++) + if (ii) + continue; /* { dg-error "goto/break/continue statments are" } */ + +#pragma simd + for (ii = 0; ii < 1000; ii++) + { +L5: + goto L5; /* { dg-error "goto/break/continue statments are" } */ + } + +#pragma simd + for (ii = 0; ii < 1000; ii++) + { + jmp_buf x; + if (!setjmp (x)) /* { dg-error "setjmps are not allowed inside" } */ + return 5; + } + return 5; +} Index: gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/cilkplus_PS_c_errors.exp =================================================================== --- gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/cilkplus_PS_c_errors.exp (revision 0) +++ gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/cilkplus_PS_c_errors.exp (revision 0) @@ -0,0 +1,24 @@ +# Copyright (C) 2012-2013 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Written by Balaji V. Iyer + + +load_lib gcc-dg.exp + +dg-init +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " " " " +dg-finish Index: gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/same_var_multiple_clauses.c =================================================================== --- gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/same_var_multiple_clauses.c (revision 0) +++ gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/same_var_multiple_clauses.c (revision 0) @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fcilkplus" } */ + +#define N 1000 + +int A[N], B[N], C[N]; +int main (void) +{ + int ii = 0; + +#pragma simd private (B) linear(B:1) /* { dg-error "listed in both linear and private pragma simd " } */ + for (ii = 0; ii < N; ii++) + { + A[ii] = B[ii] + C[ii]; + } + +#pragma simd private (B, C) linear(B:1) /* { dg-error "listed in both linear and private pragma simd " } */ + for (ii = 0; ii < N; ii++) + { + A[ii] = B[ii] + C[ii]; + } + +#pragma simd private (B) linear(C:2, B:1) /* { dg-error "listed in both linear and private pragma simd " } */ + for (ii = 0; ii < N; ii++) + { + A[ii] = B[ii] + C[ii]; + } + +#pragma simd reduction (+:B) linear(B:1) /* { dg-error "listed in both reduction and linear pragma simd" } */ + for (ii = 0; ii < N; ii++) + { + A[ii] = B[ii] + C[ii]; + } + +#pragma simd reduction (+:B) linear(B) /* { dg-error "listed in both reduction and linear pragma simd" } */ + for (ii = 0; ii < N; ii++) + { + A[ii] = B[ii] + C[ii]; + } + +#pragma simd private (B) reduction (+:A) reduction (+:B) /* { dg-error "listed in both reduction and private pragma simd" } */ + for (ii = 0; ii < N; ii++) + { + A[ii] = B[ii] + C[ii]; + } + + return 0; +} Index: gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/opt_error.c =================================================================== --- gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/opt_error.c (revision 0) +++ gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/opt_error.c (revision 0) @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-fcilkplus -O2" } */ + +int main(void) +{ + int ii, A[1000]; +#pragma simd /* { dg-warning "pragma simd is useless without" } */ + for (ii = 0; ii < 1000; ii++) + { + A[ii] = ii; + } + return 0; +} Index: gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/opt_error2.c =================================================================== --- gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/opt_error2.c (revision 0) +++ gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/errors/opt_error2.c (revision 0) @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -Wunknown-pragmas" } */ + +int main(void) +{ + int ii, A[1000]; +#pragma simd /* { dg-warning "ignoring" } */ + for (ii = 0; ii < 1000; ii++) + { + A[ii] = ii; + } + return 0; +} Index: gcc/testsuite/g++.dg/cilk-plus/pragma_simd_tests/errors/for_body_errors.cc =================================================================== --- gcc/testsuite/g++.dg/cilk-plus/pragma_simd_tests/errors/for_body_errors.cc (revision 0) +++ gcc/testsuite/g++.dg/cilk-plus/pragma_simd_tests/errors/for_body_errors.cc (revision 0) @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fcilkplus" } */ + +#include +int main(void) +{ + int ii = 0; + +#pragma simd + for (ii = 0; ii < 1000; ii++) + break; /* { dg-error "break statments are not allowed" } */ + +#pragma simd linear (ii) + for (ii = 0; ii < 1000; ii++) + if (ii) + continue; /* { dg-error "continue statments are not allowed" } */ + +#pragma simd + for (ii = 0; ii < 1000; ii++) + { +L5: + goto L5; /* { dg-error "goto statments are not allowed" } */ + } + +#pragma simd + for (ii = 0; ii < 1000; ii++) + { + try { /* { dg-error "try statements are not allowed" } */ + ii = ii %2; + } + catch (...) + { + } + } + +#pragma simd + for (ii = 0; ii < 1000; ii++) + { + jmp_buf x; + if (!setjmp (x)) /* { dg-error "setjmps are not allowed inside" } */ + return 5; + } + + for (ii = 0; ii < 1000; ii++) + { + try { /* This is OK! */ + ii = ii %2; + } + catch (...) + { + } + } + return 5; +} Index: gcc/cp/Make-lang.in =================================================================== --- gcc/cp/Make-lang.in (revision 197532) +++ gcc/cp/Make-lang.in (working copy) @@ -85,7 +85,8 @@ cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \ cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o cp/optimize.o \ cp/mangle.o cp/cp-objcp-common.o cp/name-lookup.o cp/cxx-pretty-print.o \ - cp/cp-gimplify.o cp/cp-cilk.o cp/cp-array-notation.o $(CXX_C_OBJS) + cp/cp-gimplify.o cp/cp-cilk.o cp/cp-array-notation.o cp/cp-pragma-simd.o \ + $(CXX_C_OBJS) # Language-specific object files for C++. CXX_OBJS = cp/cp-lang.o c-family/stub-objc.o $(CXX_AND_OBJCXX_OBJS) @@ -274,7 +275,8 @@ cp/cp-array-notation.o: cp/cp-array-notation.c $(CXX_TREE_H) $(TM_H) \ $(FLAGS_H) toplev.h $(DIAGNOSTIC_H) convert.h $(C_COMMON_H) $(TARGET_H) \ output.h c-family/c-objc.h - +cp/cp-pragma-simd.o: cp/cp-pragma-simd.c $(CXX_TREE_H) $(FLAGS_H) \ + $(DIAGNOSTIC_H) $(CILK_H) cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ $(C_PRAGMA_H) input.h cp/operators.def $(TM_P_H) \ c-family/c-objc.h Index: gcc/cp/cp-pragma-simd.c =================================================================== --- gcc/cp/cp-pragma-simd.c (revision 0) +++ gcc/cp/cp-pragma-simd.c (revision 0) @@ -0,0 +1,118 @@ + +/* This file is part of the Intel(R) Cilk(TM) Plus support + This file contains routines to handle Pragma SIMD expression + handling routines in the C Compiler. + Copyright (C) 2013 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 "cp-tree.h" +#include "diagnostic-core.h" + + +/* This function is passed in as a function pointer to walk_tree. *TP is + the current tree pointer, *WALK_SUBTREES is set to 0 by this function if + recursing into TP's subtrees is unnecessary. *DATA is a bool variable that + is set to false if an error has occured. */ + +static tree +find_invalid_stmts (tree *tp, int *walk_subtrees, void *data) +{ + bool *valid = (bool *) data; + location_t loc = EXPR_HAS_LOCATION (*tp) ? EXPR_LOCATION (*tp) : + UNKNOWN_LOCATION; + if (!tp || !*tp) + return NULL_TREE; + else if (TREE_CODE (*tp) == GOTO_EXPR) + { + error_at (loc, "goto statments are not allowed inside " + "loops marked with #pragma simd"); + *valid = false; + *walk_subtrees = 0; + } + else if (TREE_CODE (*tp) == BREAK_STMT) + { + error_at (loc, "break statements are not allowed inside loop marked " + "with pragma simd"); + *valid = false; + *walk_subtrees = 0; + } + else if (TREE_CODE (*tp) == CONTINUE_STMT) + { + error_at (loc, "continue statements are not allowed inside the loop " + "marked with pragma simd"); + *walk_subtrees = 0; + *valid = false; + } + else if (TREE_CODE (*tp) == THROW_EXPR) + { + error_at (loc, "throw expressions are not allowed inside the loop " + "marked with pragma simd"); + *walk_subtrees = 0; + *valid = false; + } + else if (TREE_CODE (*tp) == TRY_BLOCK) + { + error_at (loc, "try statements are not allowed inside loop marked with " + "#pragma simd"); + *valid = false; + *walk_subtrees = 0; + } + else if (TREE_CODE (*tp) == CILK_FOR_STMT) + { + error_at (loc, "_Cilk_for statements are not allowed inside loop marked " + "with #pragma simd"); + *valid = false; + *walk_subtrees = 0; + } + else if (TREE_CODE (*tp) == CALL_EXPR) + { + tree fndecl = CALL_EXPR_FN (*tp); + + if (TREE_CODE (fndecl) == ADDR_EXPR) + fndecl = TREE_OPERAND (fndecl, 0); + if (TREE_CODE (fndecl) == FUNCTION_DECL) + { + if (setjmp_call_p (fndecl)) + { + error_at (loc, "setjmps are not allowed inside loops marked with" + " #pragma simd"); + *valid = false; + *walk_subtrees = 0; + } + } + } + return NULL_TREE; +} + + +/* Walks through all the subtrees of BODY using walk_tree to make sure invalid + statements/expressions are not found inside BODY. Returns false if any + invalid statements are found. */ + +bool +p_simd_valid_stmts_in_body_p (tree body) +{ + bool valid = true; + cp_walk_tree (&body, find_invalid_stmts, (void *) &valid, NULL); + return valid; +} Property changes on: gcc/cp/cp-pragma-simd.c ___________________________________________________________________ Added: svn:executable + * Index: gcc/cp/ChangeLog.cilkplus =================================================================== --- gcc/cp/ChangeLog.cilkplus (revision 197532) +++ gcc/cp/ChangeLog.cilkplus (working copy) @@ -1,3 +1,25 @@ +2013-04-14 Balaji V. Iyer + + * Make-lang.in (CXX_AND_OBJCXX_OBJS): Added cp/cp-pragma-simd.o. + * parser.c (cp_lexer_new_main): Removed cilkplus_local_simd_values + global variable. + (cp_parser_for): Likewise. + (cp_parser_simd_handle_next_clause): New function. + (cp_parser_simd_construct): Likewise. + (same_var_in_multiple_lists_p): Likewise. + (cp_parser_pragma): Added CILKPLUS_PRAGMA_SIMD case. Removed the + following cases: PRAGMA_SIMD_ASSERT, PRAGMA_SIMD_EMPTY, + PRAGMA_SIMD_NOASSERT, PRAGMA_SIMD_VECTORLENGTH, PRAGMA_SIMD_PRIVATE, + and PRAGMA_SIMD_LINEAR. + (cp_parser_simd_assert): Changed the function to use vecs instead of + mallocs, TREE_LIST and arrays. Also, added a new parameter to pass in + pragma simd information. + (cp_parser_simd_vectorlength): Likewise. + (cp_parser_simd_linear): Likewise. + (cp_parser_simd_private): Likewise. + (cp_parser_simd_reduction): Likewise. + * cp-pragma-simd.c: New file. + 2013-04-05 Balaji V. Iyer * cp-array-notation.c (build_x_array_notation_expr): Made checking for Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 197532) +++ gcc/cp/parser.c (working copy) @@ -44,7 +44,6 @@ extern void extract_array_notation_exprs (tree, bool, tree **, int *); extern tree fix_unary_array_notation_exprs (tree); extern bool contains_array_notation_expr (tree); -struct pragma_simd_values cilkplus_local_simd_values; /* The lexer. */ @@ -650,30 +649,6 @@ gcc_assert (!lexer->next_token->purged_p); - /* Here we initialize the cilkplus_local_simd_values structure. We only need - it initialized the first time, after each consumptions, for-loop will - automatically consume the values and delete the information. */ - cilkplus_local_simd_values.index = 0; - cilkplus_local_simd_values.pragma_encountered = false; - cilkplus_local_simd_values.types = P_SIMD_NOASSERT; - cilkplus_local_simd_values.vectorlength = NULL_TREE; - cilkplus_local_simd_values.vec_length_list = NULL; - cilkplus_local_simd_values.vec_length_size = 0; - cilkplus_local_simd_values.private_vars = NULL_TREE; - cilkplus_local_simd_values.priv_var_list = NULL; - cilkplus_local_simd_values.priv_var_size = 0; - - cilkplus_local_simd_values.linear_vars = NULL_TREE; - cilkplus_local_simd_values.linear_var_size = 0; - cilkplus_local_simd_values.linear_var_list = NULL; - cilkplus_local_simd_values.linear_steps = NULL_TREE; - cilkplus_local_simd_values.linear_steps_list = NULL; - cilkplus_local_simd_values.linear_steps_size = 0; - cilkplus_local_simd_values.reduction_vals = NULL; - cilkplus_local_simd_values.ptr_next = NULL; - - clear_pragma_simd_list (); - array_notation_label_no = 0; return lexer; @@ -2435,15 +2410,16 @@ static tree cp_parser_cilk_for_expression_iterator (cp_parser *parser); static void cp_parser_simd_vectorlength - (cp_parser *parser, cp_token *pragma_token); + (cp_parser *parser, cp_token *pragma_token, struct pragma_simd_values *); static void cp_parser_simd_private - (cp_parser *parser, cp_token *pragma_token); + (cp_parser *parser, cp_token *pragma_token, struct pragma_simd_values *); static void cp_parser_simd_reduction - (cp_parser *parser, cp_token *pragma_token); + (cp_parser *parser, cp_token *pragma_token, struct pragma_simd_values *); static void cp_parser_simd_linear - (cp_parser *parser, cp_token *pragma_token); + (cp_parser *parser, cp_token *pragma_token, struct pragma_simd_values *); static void cp_parser_simd_assert - (cp_parser *parser, cp_token *pragma_token, bool is_assert); + (cp_parser *parser, cp_token *pragma_token, bool is_assert, + struct pragma_simd_values *); /* Returns nonzero if we are parsing tentatively. */ @@ -9779,19 +9755,10 @@ if (!is_range_for && statement != error_mark_node) { - if (cilkplus_ps_values != NULL) - { - FOR_STMT_PRAGMA_SIMD_INDEX (statement) = - psv_head_insert (*cilkplus_ps_values); - /* Now we initialize them all to zeros. */ - cilkplus_ps_values->pragma_encountered = false; - cilkplus_ps_values->types = P_SIMD_NOASSERT; - cilkplus_ps_values->vectorlength = NULL_TREE; - cilkplus_ps_values->private_vars = NULL_TREE; - cilkplus_ps_values->linear_vars = NULL_TREE; - cilkplus_ps_values->linear_steps = NULL_TREE; - cilkplus_ps_values->reduction_vals = NULL; - } + if (flag_enable_cilk && cilkplus_ps_values + && p_simd_valid_stmts_in_body_p (FOR_BODY (statement))) + FOR_STMT_PRAGMA_SIMD_INDEX (statement) = + p_simd_head_insert (cilkplus_ps_values); else FOR_STMT_PRAGMA_SIMD_INDEX (statement) = INVALID_PRAGMA_SIMD_SLOT; } @@ -28908,6 +28875,50 @@ cp_lexer_get_preprocessor_token (NULL, first_token); } +/* Handles the parsing of next clause for pragma simd. */ +static void +cp_parser_simd_handle_next_clause (cp_parser *parser, const char *token_name, + cp_token *pragma_token, + struct pragma_simd_values *p_simd_values) +{ + if (!strcmp (token_name, "linear")) + cp_parser_simd_linear (parser, pragma_token, p_simd_values); + else if (!strcmp (token_name, "private")) + cp_parser_simd_private (parser, pragma_token, p_simd_values); + else if (!strcmp (token_name, "reduction")) + cp_parser_simd_reduction (parser, pragma_token, p_simd_values); + else if (!strcmp (token_name, "assert")) + cp_parser_simd_assert (parser, pragma_token, true, p_simd_values); + else if (!strcmp (token_name, "noassert")) + cp_parser_simd_assert (parser, pragma_token, false, p_simd_values); + else if (!strcmp (token_name, "vectorlength")) + cp_parser_simd_vectorlength (parser, pragma_token, p_simd_values); + else + { + error_at (input_location, "unknown pragma simd clause: %s", + token_name); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + } +} + +static void +cp_parser_simd_construct (cp_parser *parser, cp_token *pragma_token, + struct pragma_simd_values *p_simd_values) +{ + cp_token *token = cp_lexer_peek_token (parser->lexer); + + if (token->type != CPP_PRAGMA_EOL) + cp_lexer_consume_token (parser->lexer); + + /* This would mean that it has reached CPP_PRAGMA_EOL. */ + if (!token->u.value || token->type == CPP_PRAGMA_EOL) + cp_parser_simd_assert (parser, pragma_token, false, p_simd_values); + else + cp_parser_simd_handle_next_clause (parser, + IDENTIFIER_POINTER (token->u.value), + pragma_token, p_simd_values); +} + /* Normal parsing of a pragma token. Here we can (and must) use the regular lexer. */ @@ -28916,7 +28927,8 @@ { cp_token *pragma_tok; unsigned int id; - + struct pragma_simd_values p_simd_values; + pragma_tok = cp_lexer_consume_token (parser->lexer); gcc_assert (pragma_tok->type == CPP_PRAGMA); parser->lexer->in_pragma = true; @@ -29023,61 +29035,12 @@ } cp_parser_cilk_grainsize (parser, pragma_tok); return true; - - case PRAGMA_SIMD_ASSERT: + case CILKPLUS_PRAGMA_SIMD: if (context == pragma_external) - { - error("%<#pragma simd assert%> may only be used inside a function"); - break; - } - cp_parser_simd_assert (parser, pragma_tok, true); + goto bad_stmt; + memset (&p_simd_values, 0, sizeof (struct pragma_simd_values)); + cp_parser_simd_construct (parser, pragma_tok, &p_simd_values); return true; - - case PRAGMA_SIMD_NOASSERT: - if (context == pragma_external) - { - error("%<#pragma simd assert%> may only be used inside a function"); - break; - } - cp_parser_simd_assert (parser, pragma_tok, false); - return true; - - case PRAGMA_SIMD_VECTORLENGTH: - if (context == pragma_external) - { - error("%<#pragma simd vectorlength%> may only be used inside a function"); - break; - } - cp_parser_simd_vectorlength (parser, pragma_tok); - return true; - - case PRAGMA_SIMD_PRIVATE: - if (context == pragma_external) - { - error("%<#pragma simd private%> may only be used inside a function"); - break; - } - cp_parser_simd_private (parser, pragma_tok); - return true; - - case PRAGMA_SIMD_LINEAR: - if (context == pragma_external) - { - error("%<#pragma simd linear%> may only be used inside a function"); - break; - } - cp_parser_simd_linear (parser, pragma_tok); - return true; - - case PRAGMA_SIMD_REDUCTION: - if (context == pragma_external) - { - error("%<#pragma simd reduction%> may only be used inside a function"); - break; - } - cp_parser_simd_reduction (parser, pragma_tok); - return true; - default: gcc_assert (id >= PRAGMA_FIRST_EXTERNAL); c_invoke_pragma_handler (id); @@ -29439,513 +29402,462 @@ build2 (t_code, TREE_TYPE (name), name, expr)); } -/* This function will parse the pragma simd vectorlength. */ +/* Returns true of a same variable is found in sub-field vectors + linear_var_list, priv_var_list and reduction_list of P_SIMD_VALUES. */ + +static bool +same_var_in_multiple_lists_p (struct pragma_simd_values *p_simd_values) +{ + size_t ii, jj, kk; + if (!p_simd_values) + return false; + + /* First check linear and private lists. */ + for (ii = 0; ii < vec_safe_length (p_simd_values->linear_var_list); ii++) + for (jj = 0; jj < vec_safe_length (p_simd_values->priv_var_list); jj++) + { + tree linear_var = (*(p_simd_values->linear_var_list))[ii]; + tree priv_var = (*(p_simd_values->priv_var_list))[jj]; + if (simple_cst_equal (linear_var, priv_var) == 1) + { + error_at (p_simd_values->loc, "ill-formed pragma: variable %qE" + " listed in both linear and private pragma simd clause", + priv_var); + return true; + } + } + + /* Now check linear and reduction lists. */ + for (ii = 0; ii < vec_safe_length (p_simd_values->linear_var_list); ii++) + for (jj = 0; jj < vec_safe_length (p_simd_values->reduction_list); jj++) + { + struct reduction_node r_node = (*(p_simd_values->reduction_list))[jj]; + for (kk = 0; kk < vec_safe_length (r_node.reduction_vars); kk++) + { + tree linear_var = (*(p_simd_values->linear_var_list))[ii]; + tree red_var = (*(r_node.reduction_vars))[kk]; + if (simple_cst_equal (linear_var, red_var) == 1) + { + error_at (p_simd_values->loc, + "ill-formed pragma: variable %qE listed in both " + "reduction and linear pragma simd clause", red_var); + return true; + } + } + } + + /* Finally check private and reduction lists. */ + for (ii = 0; ii < vec_safe_length (p_simd_values->priv_var_list); ii++) + for (jj = 0; jj < vec_safe_length (p_simd_values->reduction_list); jj++) + { + struct reduction_node r_node = (*(p_simd_values->reduction_list))[jj]; + for (kk = 0; kk < vec_safe_length (r_node.reduction_vars); kk++) + { + tree priv_var = (*(p_simd_values->priv_var_list))[ii]; + tree red_var = (*(r_node.reduction_vars))[kk]; + if (simple_cst_equal (priv_var, red_var) == 1) + { + error_at (p_simd_values->loc, + "ill-formed pragma: variable %qE listed in both " + "reduction and private pragma simd clause", red_var); + return true; + } + } + } + return false; +} + +/* This function will parse the pragma simd assert clause. */ + static void -cp_parser_simd_vectorlength (cp_parser *parser, cp_token *pragma_token) +cp_parser_simd_assert (cp_parser *parser, cp_token *pragma_token, + bool is_assert, struct pragma_simd_values *p_simd_values) { - cp_token *token = NULL; - tree vec_length_list = NULL_TREE, v_length_value = NULL_TREE; - - cilkplus_local_simd_values.pragma_encountered = true; - cilkplus_local_simd_values.types |= P_SIMD_VECTORLENGTH; + cp_token *token; - if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + if (is_assert) { - while (true) + if (p_simd_values->assert_requested == P_SIMD_NOASSERT) { - if (cp_lexer_next_token_is_not (parser->lexer, CPP_NUMBER)) - { - cp_parser_error (parser, "expected number"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - vec_length_list = NULL_TREE; - break; - } - else - { - token = cp_lexer_peek_token (parser->lexer); - if (token != NULL) - v_length_value = token->u.value; - cp_lexer_consume_token (parser->lexer); - vec_length_list = tree_cons (NULL_TREE, v_length_value, - vec_length_list); - } - if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - { - cp_lexer_consume_token (parser->lexer); - break; - } - if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) - cp_lexer_consume_token (parser->lexer); + error_at (input_location, "assert and noassert cannot be used in the" + " same pragma"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; } + p_simd_values->assert_requested = P_SIMD_ASSERT; } - else - cp_parser_error (parser, "expected %<(%>"); - - cilkplus_local_simd_values.vectorlength = vec_length_list; - cilkplus_local_simd_values.pragma_encountered = true; - - - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) - || cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)) + else { + if (p_simd_values->assert_requested == P_SIMD_ASSERT) + { + error_at (input_location, "assert and noassert cannot be used in the" + "same pragma"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; + } + p_simd_values->assert_requested = P_SIMD_NOASSERT; + } + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { token = cp_lexer_peek_token (parser->lexer); cp_lexer_consume_token (parser->lexer); - if (strcmp (IDENTIFIER_POINTER (token->u.value), "linear") == 0) - cp_parser_simd_linear (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "private") == 0) - cp_parser_simd_private (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), - "vectorlength") == 0) - cp_parser_simd_vectorlength (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "assert") == 0) - cp_parser_simd_assert (parser, pragma_token, true); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "noassert") == 0) - cp_parser_simd_assert (parser, pragma_token, false); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "reduction") == 0) - cp_parser_simd_reduction (parser, pragma_token); - else - cp_parser_error (parser, "Unknown identifier"); + cp_parser_simd_handle_next_clause (parser, + IDENTIFIER_POINTER (token->u.value), + pragma_token, p_simd_values); } else { cp_parser_skip_to_pragma_eol (parser, pragma_token); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) - { - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - cp_parser_error (parser, - "ill-formed pragma: Same variable in multiple " - "clause"); - cp_lexer_consume_token (parser->lexer); - cp_parser_for (parser, &cilkplus_local_simd_values); + { + if (!same_var_in_multiple_lists_p (p_simd_values)) + { + cp_lexer_consume_token (parser->lexer); + cp_parser_for (parser, p_simd_values); + } } - else - cp_parser_error (parser, "for statement expected"); - } - return; + else + error_at (input_location, "for statement expression after pragma simd"); + } } -/* This function will parse the pragma simd private clause. */ +/* Parses the pragma simd linear clause in Cilk Plus language extension. + The syntax is: + #pragma simd linear (:[lexer, CPP_NAME)) { - if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) + cp_parser_error (parser, "expected variable-name"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + vec_safe_truncate (p_simd_values->linear_var_list, 0); + vec_safe_truncate (p_simd_values->linear_steps_list, 0); + break; + } + linear_var = cp_lexer_peek_token (parser->lexer)->u.value; + cp_lexer_consume_token (parser->lexer); + vec_safe_push (p_simd_values->linear_var_list, linear_var); + + if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) + { + cp_lexer_consume_token (parser->lexer); + if (cp_lexer_next_token_is_not (parser->lexer, CPP_NUMBER)) { - cp_parser_error (parser, "expected variable"); + cp_parser_error (parser, "expected step-size"); + vec_safe_truncate (p_simd_values->linear_steps_list, 0); + vec_safe_truncate (p_simd_values->linear_var_list, 0); cp_parser_skip_to_pragma_eol (parser, pragma_token); - break; + return; } - else - { - token = cp_lexer_peek_token (parser->lexer); - if (token != NULL) - private_var = token->u.value; - else - { - cp_parser_error (parser, "expected variable"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - /* you exit here because this should NEVER happen. If it does - something very bad is going on */ - exit (-1); - } - cp_lexer_consume_token (parser->lexer); - private_var_list = tree_cons (NULL_TREE, private_var, - private_var_list); - } - if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - { - cp_lexer_consume_token (parser->lexer); - break; - } - if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) - cp_lexer_consume_token (parser->lexer); + linear_step = cp_lexer_peek_token (parser->lexer)->u.value; + cp_lexer_consume_token (parser->lexer); } + else if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA) + || cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + linear_step = integer_one_node; + else + { + cp_parser_error (parser, "expected %<:%> or %<,%> after variable-" + "name"); + vec_safe_truncate (p_simd_values->linear_steps_list, 0); + vec_safe_truncate (p_simd_values->linear_var_list, 0); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; + } + vec_safe_push (p_simd_values->linear_steps_list, linear_step); + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_lexer_consume_token (parser->lexer); + break; + } + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + cp_lexer_consume_token (parser->lexer); } - else - cp_parser_error (parser, "expected %<(%>"); - cilkplus_local_simd_values.pragma_encountered = true; - cilkplus_local_simd_values.types |= P_SIMD_PRIVATE; - cilkplus_local_simd_values.private_vars = private_var_list; - - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) - || cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)) + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { token = cp_lexer_peek_token (parser->lexer); cp_lexer_consume_token (parser->lexer); - if (strcmp (IDENTIFIER_POINTER (token->u.value), "linear") == 0) - cp_parser_simd_linear (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "private") == 0) - cp_parser_simd_private (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), - "vectorlength") == 0) - cp_parser_simd_vectorlength (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "assert") == 0) - cp_parser_simd_assert (parser, pragma_token, true); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "noassert") == 0) - cp_parser_simd_assert (parser, pragma_token, false); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "reduction") == 0) - cp_parser_simd_reduction (parser, pragma_token); - else - cp_parser_error (parser, "Unknown identifier"); + cp_parser_simd_handle_next_clause (parser, + IDENTIFIER_POINTER (token->u.value), + pragma_token, p_simd_values); } else { cp_parser_skip_to_pragma_eol (parser, pragma_token); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) - { - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - cp_parser_error (parser, "ill-formed pragma: Same variable in " - "multiple clause"); - cp_lexer_consume_token (parser->lexer); - cp_parser_for (parser, &cilkplus_local_simd_values); + { + if (!same_var_in_multiple_lists_p (p_simd_values)) + { + cp_lexer_consume_token (parser->lexer); + cp_parser_for (parser, p_simd_values); + } } - else - cp_parser_error (parser, "for statement expected"); - } - return; + else + error_at (input_location, "for statement expression after pragma simd"); + } } -/* This function will handle the pragma simd reduction clause. */ +/* Parses the private clause of simd pragma that is part of Cilk Plus language + extension. + The correct syntax is: + #pragma simd private ( [, lexer); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + vec_safe_truncate (p_simd_values->priv_var_list, 0); + return; + } - switch (token->type) + while (true) + { + if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) { - case CPP_PLUS: - op_code = PLUS_EXPR; - break; - case CPP_MINUS: - op_code = MINUS_EXPR; - break; - case CPP_MULT: - op_code = MULT_EXPR; - break; - case CPP_AND: - op_code = BIT_AND_EXPR; - break; - case CPP_OR: - op_code = BIT_IOR_EXPR; - break; - case CPP_XOR: - op_code = BIT_XOR_EXPR; - break; - case CPP_OR_OR: - op_code = TRUTH_ORIF_EXPR; - break; - case CPP_AND_AND: - op_code = TRUTH_ANDIF_EXPR; - break; - default: - cp_parser_error (parser, "expected one of the following: " - "%<+%> %<-%> %<*%> %<&%> %<|%> %<^%> %<||%> %<&&%>"); + error_at (input_location, "expected variable-name"); cp_parser_skip_to_pragma_eol (parser, pragma_token); - var_list = NULL_TREE; - vars = NULL_TREE; - return; + vec_safe_truncate (p_simd_values->priv_var_list, 0); + break; } + private_var = cp_lexer_peek_token (parser->lexer)->u.value; cp_lexer_consume_token (parser->lexer); - - if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)) + vec_safe_push (p_simd_values->priv_var_list, private_var); + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) { - cp_parser_error (parser, "expected %<:%>"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - var_list = NULL_TREE; - vars = NULL_TREE; - return; - } - - cp_lexer_consume_token (parser->lexer); - - while (true) - { - if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) - { - cp_parser_error (parser, "expected variable name"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - break; - } - token = cp_lexer_peek_token (parser->lexer); cp_lexer_consume_token (parser->lexer); - if (token != NULL) - vars = token->u.value; - else - { - cp_parser_error (parser, "expected variable name"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - exit (-1); - } - var_list = tree_cons (NULL_TREE, vars, var_list); - - if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - { - cp_lexer_consume_token (parser->lexer); - break; - } - - if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) - cp_lexer_consume_token (parser->lexer); + break; } + else if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + cp_lexer_consume_token (parser->lexer); } - else - cp_parser_error (parser, "expected %<(%>"); - - insert_reduction_values (&cilkplus_local_simd_values.reduction_vals, op_code, - var_list); - cilkplus_local_simd_values.types |= P_SIMD_REDUCTION; - cilkplus_local_simd_values.pragma_encountered = true; - - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) - || cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)) + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { token = cp_lexer_peek_token (parser->lexer); cp_lexer_consume_token (parser->lexer); - if (strcmp (IDENTIFIER_POINTER (token->u.value), "linear") == 0) - cp_parser_simd_linear (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "private") == 0) - cp_parser_simd_private (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), - "vectorlength") == 0) - cp_parser_simd_vectorlength (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "assert") == 0) - cp_parser_simd_assert (parser, pragma_token, true); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "noassert") == 0) - cp_parser_simd_assert (parser, pragma_token, false); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "reduction") == 0) - cp_parser_simd_reduction (parser, pragma_token); - else - cp_parser_error (parser, "Unknown identifier"); + cp_parser_simd_handle_next_clause (parser, + IDENTIFIER_POINTER (token->u.value), + pragma_token, p_simd_values); } else { cp_parser_skip_to_pragma_eol (parser, pragma_token); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) - { - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - cp_parser_error (parser, - "ill-formed pragma: Same variable in multiple " - "clause"); - cp_lexer_consume_token (parser->lexer); - cp_parser_for (parser, &cilkplus_local_simd_values); + { + if (!same_var_in_multiple_lists_p (p_simd_values)) + { + cp_lexer_peek_token (parser->lexer); + cp_parser_for (parser, p_simd_values); + } } - else - cp_parser_error (parser, "for statement expected"); - } - return; + else + error_at (input_location, "for statement expression after pragma simd"); + } } -/* This function handles the linear clause of pragma simd of Cilk Plus. */ +/* Parses the vectorlength clause of SIMD pragmas that is part of Cilk Plus + language extension. + The correct syntax is: + #pragma simd vectorlength ( [, lexer, CPP_NAME)) - { - cp_parser_error (parser, "expected variable"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - linear_var_list = NULL_TREE; - linear_steps_list = NULL_TREE; - break; - } - token = cp_lexer_peek_token (parser->lexer); - if (token) - linear_var = token->u.value; + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; + } + while (true) + { + tree vlength_value = cp_parser_expression (parser, false, false, NULL); + if (!TREE_TYPE (vlength_value) || !TREE_CONSTANT (vlength_value) + || !INTEGRAL_TYPE_P (TREE_TYPE (vlength_value))) + { + error_at (input_location, "vectorlength must be an integral" + " constant"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + vec_safe_truncate (p_simd_values->vec_length_list, 0); + break; + } + else + vec_safe_push (p_simd_values->vec_length_list, vlength_value); + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + { cp_lexer_consume_token (parser->lexer); - linear_var_list = tree_cons (NULL_TREE, linear_var, linear_var_list); - if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) - { - cp_lexer_consume_token (parser->lexer); - if (cp_lexer_next_token_is_not (parser->lexer, CPP_NUMBER)) - { - cp_parser_error (parser, "expected step-size"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - linear_var = NULL_TREE; - linear_var_list = NULL_TREE; - break; - } - else - { - token = cp_lexer_peek_token (parser->lexer); - if (token) - linear_step = token->u.value; - cp_lexer_consume_token (parser->lexer); - } - } - else if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA) - || cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - linear_step = integer_one_node; - else - { - cp_parser_error (parser, "expected : or , after variable name"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - return; - } - if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - { - cp_lexer_consume_token (parser->lexer); - linear_steps_list = tree_cons (NULL_TREE, linear_step, - linear_steps_list); - break; - } - if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) - { - cp_lexer_consume_token (parser->lexer); - linear_steps_list = tree_cons (NULL_TREE, linear_step, - linear_steps_list); - } + break; } + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + break; } - else + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { - cp_parser_error (parser, "expected %<(%>"); - return; - } - - gcc_assert (list_length (linear_steps_list) == - list_length (linear_var_list)); - - cilkplus_local_simd_values.linear_vars = linear_var_list; - cilkplus_local_simd_values.linear_var_size = list_length (linear_var_list); - cilkplus_local_simd_values.linear_steps = linear_steps_list; - cilkplus_local_simd_values.linear_steps_size = - list_length (linear_steps_list); - - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) - || cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)) - { - token = cp_lexer_peek_token (parser->lexer); + cp_token *token = cp_lexer_peek_token (parser->lexer); cp_lexer_consume_token (parser->lexer); - if (strcmp (IDENTIFIER_POINTER (token->u.value), "linear") == 0) - cp_parser_simd_linear (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "private") == 0) - cp_parser_simd_private (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), - "vectorlength") == 0) - cp_parser_simd_vectorlength (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "assert") == 0) - cp_parser_simd_assert (parser, pragma_token, true); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "noassert") == 0) - cp_parser_simd_assert (parser, pragma_token, false); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "reduction") == 0) - cp_parser_simd_reduction (parser, pragma_token); - else - cp_parser_error (parser, "Unknown identifier"); + cp_parser_simd_handle_next_clause (parser, + IDENTIFIER_POINTER (token->u.value), + pragma_token, p_simd_values); } else { cp_parser_skip_to_pragma_eol (parser, pragma_token); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) - { - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - cp_parser_error (parser, "ill-formed pragma: Same variable in " - "multiple clause"); - cp_lexer_consume_token (parser->lexer); - cp_parser_for (parser, &cilkplus_local_simd_values); + { + if (!same_var_in_multiple_lists_p (p_simd_values)) + { + cp_lexer_peek_token (parser->lexer); + cp_parser_for (parser, p_simd_values); + } } - else - cp_parser_error (parser, "for statement expected"); - } - return; + else + error_at (input_location, "for statement expression after pragma simd"); + } } -/* This function will parse the pragma simd assert clause. */ +/* Parses the reduction clause of SIMD pragma that is part of the Cilk Plus + language specification: + The correct syntax is: + #pragma simd reduction (: [, ]) +*/ static void -cp_parser_simd_assert (cp_parser *parser, cp_token *pragma_token, - bool is_assert) +cp_parser_simd_reduction (cp_parser *parser, cp_token *pragma_token, + struct pragma_simd_values *p_simd_values) { - cp_token *token; + tree vars = NULL_TREE; + enum tree_code op_code = PLUS_EXPR; + struct reduction_node red_node; - if ((cilkplus_local_simd_values.types == P_SIMD_ASSERT) && is_assert) + memset (&red_node, 0, sizeof (struct reduction_node)); + + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) { - cp_parser_error (parser, "multiple simd assert/noassert pragmas found"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); return; } - else + + switch (cp_lexer_peek_token (parser->lexer)->type) { - if (is_assert) - cilkplus_local_simd_values.types |= P_SIMD_ASSERT; - else - cilkplus_local_simd_values.types |= P_SIMD_NOASSERT; + case CPP_PLUS: + op_code = PLUS_EXPR; + break; + case CPP_MINUS: + op_code = MINUS_EXPR; + break; + case CPP_MULT: + op_code = MULT_EXPR; + break; + case CPP_AND: + op_code = BIT_AND_EXPR; + break; + case CPP_OR: + op_code = BIT_IOR_EXPR; + break; + case CPP_XOR: + op_code = BIT_XOR_EXPR; + break; + case CPP_OR_OR: + op_code = TRUTH_ORIF_EXPR; + break; + case CPP_AND_AND: + op_code = TRUTH_ANDIF_EXPR; + break; + default: + error_at (input_location, "pragma simd reduction operators must be one" + " of the following: " + "%<+%> %<-%> %<*%> %<&%> %<|%> %<^%> %<||%> %<&&%>"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; } - - cilkplus_local_simd_values.pragma_encountered = true; + cp_lexer_consume_token (parser->lexer); + red_node.reduction_type = op_code; + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)) + { + cp_parser_error (parser, "expected %<:%>"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; + } + cp_lexer_consume_token (parser->lexer); - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) - || cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)) + while (true) { - token = cp_lexer_peek_token (parser->lexer); + if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) + { + cp_parser_error (parser, "expected variable-name"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + break; + } + vars = cp_lexer_peek_token (parser->lexer)->u.value; cp_lexer_consume_token (parser->lexer); + vec_safe_push (red_node.reduction_vars, vars); - if (strcmp (IDENTIFIER_POINTER (token->u.value), "linear") == 0) - cp_parser_simd_linear (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "private") == 0) - cp_parser_simd_private (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), - "vectorlength") == 0) - cp_parser_simd_vectorlength (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "assert") == 0) - cp_parser_simd_assert (parser, pragma_token, true); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "noassert") == 0) - cp_parser_simd_assert (parser, pragma_token, false); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "reduction") == 0) - cp_parser_simd_reduction (parser, pragma_token); - else - cp_parser_error (parser, "Unknown identifier"); + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_lexer_consume_token (parser->lexer); + vec_safe_push (p_simd_values->reduction_list, red_node); + break; + } + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + cp_lexer_consume_token (parser->lexer); } + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + cp_token *token = cp_lexer_peek_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + + cp_parser_simd_handle_next_clause (parser, + IDENTIFIER_POINTER (token->u.value), + pragma_token, p_simd_values); + } else { cp_parser_skip_to_pragma_eol (parser, pragma_token); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) - { - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - cp_parser_error (parser, - "ill-formed pragma: Same variable in multiple " - "clause"); - cp_lexer_consume_token (parser->lexer); - cp_parser_for (parser, &cilkplus_local_simd_values); + { + if (!same_var_in_multiple_lists_p (p_simd_values)) + { + cp_lexer_peek_token (parser->lexer); + cp_parser_for (parser, p_simd_values); + } } - else - cp_parser_error (parser, "for statement expected"); - } - return; + else + error_at (input_location, "for statement expression after pragma simd"); + } } + - /* this function will handle the pragma cilk grainsize. The syntax is: #pragma cilk grainsize = */ Index: gcc/cilk.h =================================================================== --- gcc/cilk.h (revision 197532) +++ gcc/cilk.h (working copy) @@ -322,11 +322,16 @@ extern bool is_cilk_must_expand_fn (enum built_in_function); extern bool is_elem_fn_attribute_p (tree); extern bool is_cilk_function_decl (tree, tree); -extern void clear_pragma_simd_list (void); extern tree set_cilk_except_flag (tree); extern tree clear_cilk_except_flag (tree); extern tree set_cilk_except_data (tree); extern void c_install_body_with_frame_cleanup (tree, tree); tree build_cilk_catch_sync (void); -extern bool pragma_simd_is_private_var (int, tree); +extern void p_simd_nodes_clear (void); +extern unsigned int p_simd_head_insert (struct pragma_simd_values *); +extern bool pragma_simd_is_private_var_p (unsigned int, tree); +extern bool pragma_simd_is_linear_var_p (unsigned int, tree); +extern void set_OK_for_certain_clause (enum pragma_simd_kind, bool, + unsigned int); +extern bool pragma_simd_acceptable_vlength_p (unsigned int, int, tree); #endif /* GCC_CILK_H */ Index: gcc/ChangeLog.cilkplus =================================================================== --- gcc/ChangeLog.cilkplus (revision 197532) +++ gcc/ChangeLog.cilkplus (working copy) @@ -1,3 +1,49 @@ +2013-04-14 Balaji V. Iyer + + * c/Make-lang.in (C_AND_OBJC_OBJS): Added c/c-pragma-simd.o. + * c/c-typeck.c (c_finish_loop): Added new parameter to pass in pragma + simd information. + * c/c-parser.c (c_parser_for_statement): Likewise. + (c_parser_simd_pragma): added CILKPLUS_PRAGMA_SIMD case. Removed + PRAGMA_SIMD_ASSERT, PRAGMA_SIMD_VECTORLENGTH, PRAGMA_SIMD_PRIVATE, + PRAGMA_SIMD_LINEAR cases. + (same_var_in_multiple_lists_p): New function. + (c_parser_simd_construct): Likewise. + (c_parser_simd_assert): Changed the function to use vecs intead of + mallocs, linked-list and TREE_LIST. Also, added a parameter to pass in + pragma simd information. + (c_parser_simd_vectorlength): Likewise. + (c_parser_simd_reduction): Likewise. + (c_parser_simd_linear): Likewise. + (c_parser_simd_private): Likewise. + * pragma_simd.c (psv_find_node): Changed the function to use vecs + instead of mallocs, linked-list and TREE_LIST. + (clause_resolved_p): Likewise. + (pragma_simd_assert_requested_p): Likewise. + (pragma_simd_verify_clauses): Likewise. + (set_OK_for_certain_clause): Likewise. + (psv_find_node): Likewise. + (pragma_simd_acceptable_vlength_p): Likewise. + (check_off_reduction_var): Likewise. + (find_linear_step_size): Likewise. + (all_reductions_satisfied_p): Likewise. + (pragma_simd_is_private_var_p): Renamed from pragma_simd_is_private_var. + (p_simd_nodes_clear): New function. + (p_simd_head_insert): Likewise. + (pragma_simd_is_linear_var_p): Likewise. + (dump_pragma_simd_values_vec): Likewise. + (psv_head_insert): Remove. + (insert_reduction_values): Likewise. + (same_var_in_multiple_lists_p): Likewise. + * tree-vectorizer.c (vectorize_loops): Removed function call + pragma_simd_vectorize_loop_p. + * tree.h (struct pragma_simd_values): Replaced dynamic arrays with + vecs. + (tree_label_decl): Made pragma_simd_index unsigned instead of signed. + * cfgloop.h (struct loop): Likewise. + * gimple.h (struct gimple_statement): Likewise. + * c/c-pragma-simd.c: New file. + 2013-04-05 Balaji V. Iyer * c/c-array-notation.c (build_array_notation_expr): Added support to Index: gcc/tree-vectorizer.c =================================================================== --- gcc/tree-vectorizer.c (revision 197641) +++ gcc/tree-vectorizer.c (working copy) @@ -102,10 +102,7 @@ than all previously defined loops. This fact allows us to run only over initial loops skipping newly generated ones. */ FOR_EACH_LOOP (li, loop, 0) - if (((!flag_enable_cilk) && (optimize_loop_nest_for_speed_p (loop))) - || (flag_enable_cilk - && (optimize_loop_nest_for_speed_p (loop) - || pragma_simd_vectorize_loop_p (loop->pragma_simd_index)))) + if (optimize_loop_nest_for_speed_p (loop)) { loop_vec_info loop_vinfo; vect_location = find_loop_location (loop); Index: gcc/cfgloop.h =================================================================== --- gcc/cfgloop.h (revision 197532) +++ gcc/cfgloop.h (working copy) @@ -106,7 +106,7 @@ int num; /* This holds the pragma simd index. */ - int pragma_simd_index; + unsigned int pragma_simd_index; /* Number of loop insns. */ unsigned ninsns; Index: gcc/gimple.h =================================================================== --- gcc/gimple.h (revision 197532) +++ gcc/gimple.h (working copy) @@ -210,7 +210,7 @@ gimple GTY((skip)) prev; /* Index to the PRAGMA simd internal structure. */ - int pragma_simd_index; + unsigned int pragma_simd_index; };