From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32334 invoked by alias); 2 Sep 2011 15:24:59 -0000 Received: (qmail 32325 invoked by uid 22791); 2 Sep 2011 15:24:57 -0000 X-SWARE-Spam-Status: No, hits=-3.3 required=5.0 tests=AWL,BAYES_00,TW_CP,TW_JF,TW_TM X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 02 Sep 2011 15:24:39 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id BEB478A95F; Fri, 2 Sep 2011 17:24:37 +0200 (CEST) Date: Fri, 02 Sep 2011 15:24:00 -0000 From: Martin Jambor To: GCC Patches Cc: Jan Hubicka Subject: [PATCH] Store jump functions in a VECtor Message-ID: <20110902152437.GD21553@virgil.arch.suse.de> Mail-Followup-To: GCC Patches , Jan Hubicka MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-09/txt/msg00175.txt.bz2 Hi, when I submitted the new IPA-CP a few months ago Honza requested that I store the jump_functions in a VECtor rather than an array in which they are now. The patch below does exactly that. The last remaining such request is to rename ipa_check_create_node_params to "something else." I guess I'll leave this to the next weekend when we'll see each other. I hope I got the ggc stuff right and a GTY marker does not need to be added somewhere. On the other hand, the patch passes bootstrap and testsuite on x86_64-linux and I have successfully LTO-built Firefox with it (which was able to display some complicated pages). OK for trunk? Thanks, Martin 2011-09-02 Martin Jambor * ipa-prop.h (ipa_jump_func_t): New typedef. (struct ipa_edge_args): Removed field argument_count, field jump_functions turned into a vector. (ipa_set_cs_argument_count): Removed. (ipa_get_cs_argument_count): Updated to work on vectors. (ipa_get_ith_jump_func): Likewise. * ipa-prop.c (ipa_count_arguments): Removed. (compute_scalar_jump_functions): Use ipa_get_ith_jump_func to access jump functions. Update caller. (compute_pass_through_member_ptrs): Likewise. (compute_cst_member_ptr_arguments): Likewise. (ipa_compute_jump_functions_for_edge): Get number of arguments from the statement, allocate vector. (ipa_compute_jump_functions): Do not call ipa_count_arguments. (duplicate_ipa_jump_func_array): Removed. (ipa_edge_duplication_hook): Use VEC_copy, do not copy argument count. (ipa_read_node_info): Allocate vector. Index: src/gcc/ipa-prop.c =================================================================== --- src.orig/gcc/ipa-prop.c +++ src/gcc/ipa-prop.c @@ -143,25 +143,6 @@ ipa_initialize_node_params (struct cgrap } } -/* Count number of arguments callsite CS has and store it in - ipa_edge_args structure corresponding to this callsite. */ - -static void -ipa_count_arguments (struct cgraph_edge *cs) -{ - gimple stmt; - int arg_num; - - stmt = cs->call_stmt; - gcc_assert (is_gimple_call (stmt)); - arg_num = gimple_call_num_args (stmt); - if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector) - <= (unsigned) cgraph_edge_max_uid) - VEC_safe_grow_cleared (ipa_edge_args_t, gc, - ipa_edge_args_vector, cgraph_edge_max_uid + 1); - ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num); -} - /* Print the jump functions associated with call graph edge CS to file F. */ static void @@ -696,7 +677,7 @@ compute_known_type_jump_func (tree op, s static void compute_scalar_jump_functions (struct ipa_node_params *info, - struct ipa_jump_func *functions, + struct ipa_edge_args *args, gimple call) { tree arg; @@ -704,12 +685,13 @@ compute_scalar_jump_functions (struct ip for (num = 0; num < gimple_call_num_args (call); num++) { + struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, num); arg = gimple_call_arg (call, num); if (is_gimple_ip_invariant (arg)) { - functions[num].type = IPA_JF_CONST; - functions[num].value.constant = arg; + jfunc->type = IPA_JF_CONST; + jfunc->value.constant = arg; } else if (TREE_CODE (arg) == SSA_NAME) { @@ -718,26 +700,24 @@ compute_scalar_jump_functions (struct ip int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg)); if (index >= 0 - && !detect_type_change_ssa (arg, call, &functions[num])) + && !detect_type_change_ssa (arg, call, jfunc)) { - functions[num].type = IPA_JF_PASS_THROUGH; - functions[num].value.pass_through.formal_id = index; - functions[num].value.pass_through.operation = NOP_EXPR; + jfunc->type = IPA_JF_PASS_THROUGH; + jfunc->value.pass_through.formal_id = index; + jfunc->value.pass_through.operation = NOP_EXPR; } } else { gimple stmt = SSA_NAME_DEF_STMT (arg); if (is_gimple_assign (stmt)) - compute_complex_assign_jump_func (info, &functions[num], - call, stmt, arg); + compute_complex_assign_jump_func (info, jfunc, call, stmt, arg); else if (gimple_code (stmt) == GIMPLE_PHI) - compute_complex_ancestor_jump_func (info, &functions[num], - call, stmt); + compute_complex_ancestor_jump_func (info, jfunc, call, stmt); } } else - compute_known_type_jump_func (arg, &functions[num], call); + compute_known_type_jump_func (arg, jfunc, call); } } @@ -821,7 +801,7 @@ is_parm_modified_before_call (struct par static bool compute_pass_through_member_ptrs (struct ipa_node_params *info, struct param_analysis_info *parms_info, - struct ipa_jump_func *functions, + struct ipa_edge_args *args, gimple call) { bool undecided_members = false; @@ -841,9 +821,11 @@ compute_pass_through_member_ptrs (struct gcc_assert (index >=0); if (!is_parm_modified_before_call (&parms_info[index], call, arg)) { - functions[num].type = IPA_JF_PASS_THROUGH; - functions[num].value.pass_through.formal_id = index; - functions[num].value.pass_through.operation = NOP_EXPR; + struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, + num); + jfunc->type = IPA_JF_PASS_THROUGH; + jfunc->value.pass_through.formal_id = index; + jfunc->value.pass_through.operation = NOP_EXPR; } else undecided_members = true; @@ -969,7 +951,7 @@ determine_cst_member_ptr (gimple call, t associated with the call. */ static void -compute_cst_member_ptr_arguments (struct ipa_jump_func *functions, +compute_cst_member_ptr_arguments (struct ipa_edge_args *args, gimple call) { unsigned num; @@ -977,13 +959,13 @@ compute_cst_member_ptr_arguments (struct for (num = 0; num < gimple_call_num_args (call); num++) { + struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, num); arg = gimple_call_arg (call, num); - if (functions[num].type == IPA_JF_UNKNOWN + if (jfunc->type == IPA_JF_UNKNOWN && type_like_member_ptr_p (TREE_TYPE (arg), &method_field, &delta_field)) - determine_cst_member_ptr (call, arg, method_field, delta_field, - &functions[num]); + determine_cst_member_ptr (call, arg, method_field, delta_field, jfunc); } } @@ -996,29 +978,25 @@ ipa_compute_jump_functions_for_edge (str struct cgraph_edge *cs) { struct ipa_node_params *info = IPA_NODE_REF (cs->caller); - struct ipa_edge_args *arguments = IPA_EDGE_REF (cs); - gimple call; + struct ipa_edge_args *args = IPA_EDGE_REF (cs); + gimple call = cs->call_stmt; + int arg_num = gimple_call_num_args (call); - if (ipa_get_cs_argument_count (arguments) == 0 || arguments->jump_functions) + if (arg_num == 0 || args->jump_functions) return; - arguments->jump_functions = ggc_alloc_cleared_vec_ipa_jump_func - (ipa_get_cs_argument_count (arguments)); - - call = cs->call_stmt; - gcc_assert (is_gimple_call (call)); + VEC_safe_grow_cleared (ipa_jump_func_t, gc, args->jump_functions, arg_num); /* We will deal with constants and SSA scalars first: */ - compute_scalar_jump_functions (info, arguments->jump_functions, call); + compute_scalar_jump_functions (info, args, call); /* Let's check whether there are any potential member pointers and if so, whether we can determine their functions as pass_through. */ - if (!compute_pass_through_member_ptrs (info, parms_info, - arguments->jump_functions, call)) + if (!compute_pass_through_member_ptrs (info, parms_info, args, call)) return; /* Finally, let's check whether we actually pass a new constant member pointer here... */ - compute_cst_member_ptr_arguments (arguments->jump_functions, call); + compute_cst_member_ptr_arguments (args, call); } /* Compute jump functions for all edges - both direct and indirect - outgoing @@ -1038,15 +1016,11 @@ ipa_compute_jump_functions (struct cgrap functions unless they may become known during lto/whopr. */ if (!callee->analyzed && !flag_lto) continue; - ipa_count_arguments (cs); ipa_compute_jump_functions_for_edge (parms_info, cs); } for (cs = node->indirect_calls; cs; cs = cs->next_callee) - { - ipa_count_arguments (cs); - ipa_compute_jump_functions_for_edge (parms_info, cs); - } + ipa_compute_jump_functions_for_edge (parms_info, cs); } /* If RHS looks like a rhs of a statement loading pfn from a member @@ -1900,19 +1874,6 @@ ipa_node_removal_hook (struct cgraph_nod ipa_free_node_params_substructures (IPA_NODE_REF (node)); } -static struct ipa_jump_func * -duplicate_ipa_jump_func_array (const struct ipa_jump_func * src, size_t n) -{ - struct ipa_jump_func *p; - - if (!src) - return NULL; - - p = ggc_alloc_vec_ipa_jump_func (n); - memcpy (p, src, n * sizeof (struct ipa_jump_func)); - return p; -} - /* Hook that is called by cgraph.c when a node is duplicated. */ static void @@ -1920,17 +1881,14 @@ ipa_edge_duplication_hook (struct cgraph __attribute__((unused)) void *data) { struct ipa_edge_args *old_args, *new_args; - int arg_count; ipa_check_create_edge_args (); old_args = IPA_EDGE_REF (src); new_args = IPA_EDGE_REF (dst); - arg_count = ipa_get_cs_argument_count (old_args); - ipa_set_cs_argument_count (new_args, arg_count); - new_args->jump_functions = - duplicate_ipa_jump_func_array (old_args->jump_functions, arg_count); + new_args->jump_functions = VEC_copy (ipa_jump_func_t, gc, + old_args->jump_functions); if (iinlining_processed_edges && bitmap_bit_p (iinlining_processed_edges, src->uid)) @@ -2802,12 +2760,10 @@ ipa_read_node_info (struct lto_input_blo struct ipa_edge_args *args = IPA_EDGE_REF (e); int count = streamer_read_uhwi (ib); - ipa_set_cs_argument_count (args, count); if (!count) continue; + VEC_safe_grow_cleared (ipa_jump_func_t, gc, args->jump_functions, count); - args->jump_functions = ggc_alloc_cleared_vec_ipa_jump_func - (ipa_get_cs_argument_count (args)); for (k = 0; k < ipa_get_cs_argument_count (args); k++) ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), data_in); } @@ -2816,13 +2772,13 @@ ipa_read_node_info (struct lto_input_blo struct ipa_edge_args *args = IPA_EDGE_REF (e); int count = streamer_read_uhwi (ib); - ipa_set_cs_argument_count (args, count); if (count) { - args->jump_functions = ggc_alloc_cleared_vec_ipa_jump_func - (ipa_get_cs_argument_count (args)); + VEC_safe_grow_cleared (ipa_jump_func_t, gc, args->jump_functions, + count); for (k = 0; k < ipa_get_cs_argument_count (args); k++) - ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), data_in); + ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), + data_in); } ipa_read_indirect_edge_info (ib, data_in, e); } Index: src/gcc/ipa-prop.h =================================================================== --- src.orig/gcc/ipa-prop.h +++ src/gcc/ipa-prop.h @@ -119,7 +119,7 @@ struct GTY(()) ipa_member_ptr_cst /* A jump function for a callsite represents the values passed as actual arguments of the callsite. See enum jump_func_type for the various types of jump functions supported. */ -struct GTY (()) ipa_jump_func +typedef struct GTY (()) ipa_jump_func { enum jump_func_type type; /* Represents a value of a jump function. pass_through is used only in jump @@ -133,7 +133,10 @@ struct GTY (()) ipa_jump_func struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through; struct ipa_ancestor_jf_data GTY ((tag ("IPA_JF_ANCESTOR"))) ancestor; } GTY ((desc ("%1.type"))) value; -}; +} ipa_jump_func_t; + +DEF_VEC_O (ipa_jump_func_t); +DEF_VEC_ALLOC_O (ipa_jump_func_t, gc); /* Summary describing a single formal parameter. */ @@ -223,31 +226,19 @@ ipa_is_param_used (struct ipa_node_param arguments. It can be accessed by the IPA_EDGE_REF macro. */ typedef struct GTY(()) ipa_edge_args { - /* Number of actual arguments in this callsite. When set to 0, - this callsite's parameters would not be analyzed by the different - stages of IPA CP. */ - int argument_count; - /* Array of the callsite's jump function of each parameter. */ - struct ipa_jump_func GTY ((length ("%h.argument_count"))) *jump_functions; + /* Vector of the callsite's jump function of each parameter. */ + VEC (ipa_jump_func_t, gc) *jump_functions; } ipa_edge_args_t; /* ipa_edge_args access functions. Please use these to access fields that are or will be shared among various passes. */ -/* Set the number of actual arguments. */ - -static inline void -ipa_set_cs_argument_count (struct ipa_edge_args *args, int count) -{ - args->argument_count = count; -} - /* Return the number of actual arguments. */ static inline int ipa_get_cs_argument_count (struct ipa_edge_args *args) { - return args->argument_count; + return VEC_length (ipa_jump_func_t, args->jump_functions); } /* Returns a pointer to the jump function for the ith argument. Please note @@ -257,8 +248,7 @@ ipa_get_cs_argument_count (struct ipa_ed static inline struct ipa_jump_func * ipa_get_ith_jump_func (struct ipa_edge_args *args, int i) { - gcc_assert (i >= 0 && i <= args->argument_count); - return &args->jump_functions[i]; + return VEC_index (ipa_jump_func_t, args->jump_functions, i); } /* Vectors need to have typedefs of structures. */