From patchwork Tue May 8 14:56:45 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Iyer, Balaji V" X-Patchwork-Id: 157710 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id B05CAB6EE6 for ; Wed, 9 May 2012 00:57:16 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1337093837; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:From:To:Subject:Date:Message-ID:Content-Type: MIME-Version:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=i8nNSR+ GB7uk1Llo4ltvFCW2+Ws=; b=dRwLgw5UjpigJIeM/vD1ED7HqJPLGONLGYJkZzA WVLMWeFAB2O9iJowNSbcRxCn6fYzDmBUfTl6ghk+Mq9YdCI2RdjLKpPRaPhLtXO6 6b5MuU83XbhXpyP02CLCHs6Xb/zPfE3og8fAgkGIW1sUFZYBbp97NjhnmxZWKfd/ A2g0= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:X-ExtLoop1:Received:Received:Received:From:To:Subject:Date:Message-ID:Content-Type:MIME-Version:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=czp56r8AwAer7uNZS3Y+qpXh+5BcitQEo8P9+aHPS5WIqG8Fcf+jlXc0bmvniB Y9GZ0VGfCJvir2MS7YRahvxarx1EBn/dfy/QzRapm8x1xWl4rcEbnbgYJBGJEWth DIqPf4nVf6FDM9PDA4gi4MIy/L3VsvG17wJLGmsq0UrwY=; Received: (qmail 23984 invoked by alias); 8 May 2012 14:57:08 -0000 Received: (qmail 23737 invoked by uid 22791); 8 May 2012 14:57:04 -0000 X-SWARE-Spam-Status: No, hits=-4.5 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, TW_CD, TW_TM, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mga14.intel.com (HELO mga14.intel.com) (143.182.124.37) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 08 May 2012 14:56:51 +0000 Received: from azsmga002.ch.intel.com ([10.2.17.35]) by azsmga102.ch.intel.com with ESMTP; 08 May 2012 07:56:50 -0700 X-ExtLoop1: 1 Received: from azsmsx601.amr.corp.intel.com ([10.2.121.193]) by AZSMGA002.ch.intel.com with ESMTP; 08 May 2012 07:56:46 -0700 Received: from fmsmsx104.amr.corp.intel.com (10.19.9.35) by azsmsx601.amr.corp.intel.com (10.2.121.193) with Microsoft SMTP Server (TLS) id 8.2.255.0; Tue, 8 May 2012 07:56:46 -0700 Received: from fmsmsx102.amr.corp.intel.com ([169.254.2.250]) by FMSMSX104.amr.corp.intel.com ([169.254.4.244]) with mapi id 14.01.0355.002; Tue, 8 May 2012 07:56:45 -0700 From: "Iyer, Balaji V" To: "gcc-patches@gcc.gnu.org" Subject: [PATCH][Cilkplus] Handling elemental function for C Compiler. Date: Tue, 8 May 2012 14:56:45 +0000 Message-ID: MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hello Everyone, This patch is for the Cilkplus branch affecting mostly the C compiler. This patch will insert elemental functions for C programs. Thanks, Balaji V. Iyer. diff --git a/gcc/ChangeLog.cilk b/gcc/ChangeLog.cilk index d6b28e2..4f01d31 100644 --- a/gcc/ChangeLog.cilk +++ b/gcc/ChangeLog.cilk @@ -1,3 +1,17 @@ +2012-05-07 Balaji V. Iyer + + * c-parser.c (c_parser_declaration_or_fndef): Saved function arguments + for an elemental function. + * elem-function.c (find_elem_fn_parm_type_1): Added step-size parameter. + (find_elem_fn_parm_type): Likewise. + * tree-vect-stmts.c (vect_get_vec_def_for_operand): Added step-size + support for linear clause. Also called elem_fn_linear_init_vector for + linear clause. + (vectorizable_call): When linear clause is set, set the vector type to + constant_def. + (elem_fn_linear_init_vector): New function. + * tree.c (build_elem_fn_linear_vector_from_val): Likewise. + 2012-04-24 Balaji V. Iyer * elem-function.c (find_elem_fn_param_type_1): New function. diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 6af434f..04c8eef 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -1640,7 +1640,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, specs->attrs = NULL_TREE; while (true) { - struct c_declarator *declarator; + struct c_declarator *declarator = NULL; bool dummy = false; timevar_id_t tv; tree fnbody; @@ -1705,6 +1705,11 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, tree d = start_decl (declarator, specs, false, chainon (postfix_attrs, all_prefix_attrs)); + if (d && TREE_CODE (d) == FUNCTION_DECL + && declarator->kind == cdk_function + && lookup_attribute ("vector", all_prefix_attrs) + && declarator && declarator->u.arg_info) + DECL_ARGUMENTS (d) = declarator->u.arg_info->parms; if (d) finish_decl (d, UNKNOWN_LOCATION, NULL_TREE, NULL_TREE, asm_name); diff --git a/gcc/elem-function.c b/gcc/elem-function.c index e6e3650..f3e4985 100644 --- a/gcc/elem-function.c +++ b/gcc/elem-function.c @@ -85,7 +85,7 @@ static tree create_processor_attribute (elem_fn_info *, tree *); /* this is an helper function for find_elem_fn_param_type */ static enum elem_fn_parm_type -find_elem_fn_parm_type_1 (tree fndecl, int parm_no) +find_elem_fn_parm_type_1 (tree fndecl, int parm_no, tree *step_size) { int ii = 0; elem_fn_info *elem_fn_values; @@ -96,7 +96,12 @@ find_elem_fn_parm_type_1 (tree fndecl, int parm_no) for (ii = 0; ii < elem_fn_values->no_lvars; ii++) if (elem_fn_values->linear_location[ii] == parm_no) - return TYPE_LINEAR; + { + if (step_size != NULL) + *step_size = build_int_cst (integer_type_node, + elem_fn_values->linear_steps[ii]); + return TYPE_LINEAR; + } for (ii = 0; ii < elem_fn_values->no_uvars; ii++) if (elem_fn_values->uniform_location[ii] == parm_no) @@ -109,7 +114,7 @@ find_elem_fn_parm_type_1 (tree fndecl, int parm_no) /* this function will return the type of a parameter in elemental function. The choices are UNIFORM or LINEAR. */ enum elem_fn_parm_type -find_elem_fn_parm_type (gimple stmt, tree op) +find_elem_fn_parm_type (gimple stmt, tree op, tree *step_size) { tree fndecl, parm = NULL_TREE; int ii, nargs; @@ -128,7 +133,7 @@ find_elem_fn_parm_type (gimple stmt, tree op) parm = gimple_call_arg (stmt, ii); if (op == parm) { - return_type = find_elem_fn_parm_type_1 (fndecl, 1); + return_type = find_elem_fn_parm_type_1 (fndecl, ii, step_size); return return_type; } } diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 738a5a7..46dd4a8 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "cilk.h" +extern enum elem_fn_parm_type find_elem_fn_parm_type (gimple, tree, tree *); /* Return a variable of type ELEM_TYPE[NELEMS]. */ static tree @@ -1259,8 +1260,8 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def) enum vect_def_type dt; bool is_simple_use; tree vector_type; - - extern enum elem_fn_parm_type find_elem_fn_parm_type (gimple, tree); + enum elem_fn_parm_type parm_type; + tree step_size = NULL_TREE; if (vect_print_dump_info (REPORT_DETAILS)) { @@ -1289,14 +1290,12 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def) && gimple_code (stmt) == GIMPLE_CALL && is_elem_fn (gimple_call_fndecl (stmt))) { - enum elem_fn_parm_type parm_type = find_elem_fn_parm_type (stmt, op); - if (parm_type == TYPE_UNIFORM) + parm_type = find_elem_fn_parm_type (stmt, op, &step_size); + if (parm_type == TYPE_UNIFORM || parm_type == TYPE_LINEAR) dt = vect_constant_def; - else if (parm_type == TYPE_LINEAR) - { - ; - } } + else + parm_type = TYPE_NONE; switch (dt) { @@ -1313,8 +1312,13 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def) /* Create 'vect_cst_ = {cst,cst,...,cst}' */ if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "Create vector_cst. nunits = %d", nunits); - - return vect_init_vector (stmt, op, vector_type, NULL); + if (!flag_enable_cilk + || (parm_type == TYPE_NONE || parm_type == TYPE_UNIFORM)) + return vect_init_vector (stmt, op, vector_type, NULL); + else if (flag_enable_cilk && parm_type == TYPE_LINEAR) + return elem_fn_linear_init_vector (stmt, op, vector_type, + step_size, NULL); + } /* Case 2: operand is defined outside the loop - loop invariant. */ @@ -1640,6 +1644,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, enum { NARROW, NONE, WIDEN } modifier; size_t i, nargs; tree lhs; + tree step_size = NULL_TREE; if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo) return false; @@ -1841,6 +1846,16 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, else { vec_oprnd0 = gimple_call_arg (new_stmt, i); + if (flag_enable_cilk + && gimple_code (new_stmt) == GIMPLE_CALL + && is_elem_fn (gimple_call_fndecl (new_stmt))) + { + enum elem_fn_parm_type parm_type = + find_elem_fn_parm_type (stmt, op, &step_size); + if (parm_type == TYPE_UNIFORM + || parm_type == TYPE_LINEAR) + dt[i] = vect_constant_def; + } vec_oprnd0 = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd0); } @@ -6549,3 +6564,55 @@ supportable_narrowing_operation (enum tree_code code, VEC_free (tree, heap, *interm_types); return false; } + +/* Function vect_init_vector. + + Insert a new stmt (INIT_STMT) that initializes a new variable of type + TYPE with the value VAL. If TYPE is a vector type and VAL does not have + vector type a vector with all elements equal to VAL is created first. + Place the initialization at BSI if it is not NULL. Otherwise, place the + initialization at the loop preheader. + Return the DEF of INIT_STMT. + It will be used in the vectorization of STMT. */ + +tree +elem_fn_linear_init_vector (gimple stmt, tree val, tree type, tree step_size, + gimple_stmt_iterator *gsi) +{ + tree new_var; + gimple init_stmt; + tree vec_oprnd; + tree new_temp; + + if (TREE_CODE (type) == VECTOR_TYPE + && TREE_CODE (TREE_TYPE (val)) != VECTOR_TYPE) + { + if (!types_compatible_p (TREE_TYPE (type), TREE_TYPE (val))) + { + if (CONSTANT_CLASS_P (val)) + val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val); + else + { + new_var = create_tmp_reg (TREE_TYPE (type), NULL); + add_referenced_var (new_var); + init_stmt = gimple_build_assign_with_ops (NOP_EXPR, + new_var, val, + NULL_TREE); + new_temp = make_ssa_name (new_var, init_stmt); + gimple_assign_set_lhs (init_stmt, new_temp); + vect_init_vector_1 (stmt, init_stmt, gsi); + val = new_temp; + } + } + val = build_elem_fn_linear_vector_from_val (type, val, step_size); + } + + new_var = vect_get_new_vect_var (type, vect_simple_var, "cst_"); + add_referenced_var (new_var); + init_stmt = gimple_build_assign (new_var, val); + new_temp = make_ssa_name (new_var, init_stmt); + gimple_assign_set_lhs (init_stmt, new_temp); + vect_init_vector_1 (stmt, init_stmt, gsi); + vec_oprnd = gimple_assign_lhs (init_stmt); + return vec_oprnd; +} diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 095af93..5c2219e 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -861,6 +861,8 @@ extern bool vect_supportable_shift (enum tree_code, tree); extern void vect_get_vec_defs (tree, tree, gimple, VEC (tree, heap) **, VEC (tree, heap) **, slp_tree, int); extern tree vect_gen_perm_mask (tree, unsigned char *); +extern tree elem_fn_linear_init_vector (gimple, tree, tree, tree, + gimple_stmt_iterator *); /* In tree-vect-data-refs.c. */ extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int); diff --git a/gcc/tree.c b/gcc/tree.c index 3311635..7c7e6c6 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -11624,6 +11624,51 @@ build_call_list (tree return_type, tree fn, tree arglist) } +/* Build a vector of type VECTYPE where all the elements are SCs. */ +tree +build_elem_fn_linear_vector_from_val (tree vectype, tree sc, tree step_size) +{ + int i, nunits = TYPE_VECTOR_SUBPARTS (vectype); + + if (sc == error_mark_node) + return sc; + + /* Verify that the vector type is suitable for SC. Note that there + is some inconsistency in the type-system with respect to restrict + qualifications of pointers. Vector types always have a main-variant + element type and the qualification is applied to the vector-type. + So TREE_TYPE (vector-type) does not return a properly qualified + vector element-type. */ + gcc_checking_assert (types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (sc)), + TREE_TYPE (vectype))); + + if (CONSTANT_CLASS_P (sc)) + { + tree *v = XALLOCAVEC (tree, nunits); + for (i = 0; i < nunits; ++i) + // v[i] = sc; + v[i] = build2 (PLUS_EXPR, TREE_TYPE (sc), sc, + fold_build2 (MULT_EXPR, TREE_TYPE (step_size), step_size, + build_int_cst (integer_type_node, i))); + return build_vector (vectype, v); + } + else + { + VEC(constructor_elt, gc) *v = VEC_alloc (constructor_elt, gc, nunits); + for (i = 0; i < nunits; ++i) + { + // CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, sc); + tree tmp = NULL_TREE; + tmp = build2 (PLUS_EXPR, TREE_TYPE (sc), sc, + fold_build2 (MULT_EXPR, TREE_TYPE (step_size), + step_size, + build_int_cst (integer_type_node, i))); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, tmp); + } + return build_constructor (vectype, v); + } +} + diff --git a/gcc/tree.h b/gcc/tree.h index cef639d..2c56e93 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4530,7 +4530,7 @@ extern tree build_call_valist (tree, tree, int, va_list); build_call_array_loc (UNKNOWN_LOCATION, T1, T2, N, T3) extern tree build_call_array_loc (location_t, tree, tree, int, const tree *); extern tree build_call_vec (tree, tree, VEC(tree,gc) *); - +extern tree build_elem_fn_linear_vector_from_val (tree, tree, tree); /* Construct various nodes representing data types. */ extern tree make_signed_type (int);