X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fipa-cp.c;h=66de8db7c0a4b7083142e4e7d24841de5fee45c6;hb=fc7a207afb278ff786674fe38579828f382765bf;hp=4b632c0d9fb52389d84a9a99e4516bfc00b0bf7f;hpb=00e1f01e202daa28722e658dcb573c1f10e53ea3;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 4b632c0d9fb..66de8db7c0a 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1,19 +1,19 @@ /* Interprocedural constant propagation Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Razya Ladelsky - + 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 . */ @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see { printf ("value is %d",y); } - + int f (int x) { g (x); @@ -43,32 +43,32 @@ along with GCC; see the file COPYING3. If not see f (3); h (3); } - - + + The IPCP algorithm will find that g's formal argument y is always called with the value 3. The algorithm used is based on "Interprocedural Constant Propagation", by Challahan David, Keith D Cooper, Ken Kennedy, Linda Torczon, Comp86, pg 152-161 - + The optimization is divided into three stages: First stage - intraprocedural analysis ======================================= This phase computes jump_function and modification flags. - + A jump function for a callsite represents the values passed as an actual arguments of a given callsite. There are three types of values: Pass through - the caller's formal parameter is passed as an actual argument. Constant - a constant is passed as an actual argument. Unknown - neither of the above. - + The jump function info, ipa_jump_func, is stored in ipa_edge_args structure (defined in ipa_prop.h and pointed to by cgraph_node->aux) modified_flags are defined in ipa_node_params structure (defined in ipa_prop.h and pointed to by cgraph_edge->aux). - + -ipcp_init_stage() is the first stage driver. Second stage - interprocedural analysis @@ -79,10 +79,10 @@ along with GCC; see the file COPYING3. If not see TOP - unknown. BOTTOM - non constant. CONSTANT - constant value. - + Lattice describing a formal parameter p will have a constant value if all callsites invoking this function have the same constant value passed to p. - + The lattices are stored in ipcp_lattice which is itself in ipa_node_params structure (defined in ipa_prop.h and pointed to by cgraph_edge->aux). @@ -115,7 +115,7 @@ along with GCC; see the file COPYING3. If not see and many calls redirected back to fit the description above. -ipcp_insert_stage() is the third phase driver. - + */ #include "config.h" @@ -473,7 +473,7 @@ ipcp_cloning_candidate_p (struct cgraph_node *node) if (cgraph_maybe_hot_edge_p (e)) n_hot_calls ++; } - + if (!n_calls) { if (dump_file) @@ -487,7 +487,7 @@ ipcp_cloning_candidate_p (struct cgraph_node *node) fprintf (dump_file, "Considering %s for cloning; code would shrink.\n", cgraph_node_name (node)); return true; - } + } if (!flag_ipa_cp_clone) { @@ -578,7 +578,13 @@ build_const_val (struct ipcp_lattice *lat, tree tree_type) /* Compute the proper scale for NODE. It is the ratio between the number of direct calls (represented on the incoming cgraph_edges) and sum of all - invocations of NODE (represented as count in cgraph_node). */ + invocations of NODE (represented as count in cgraph_node). + + FIXME: This code is wrong. Since the callers can be also clones and + the clones are not scaled yet, the sums gets unrealistically high. + To properly compute the counts, we would need to do propagation across + callgraph (as external call to A might imply call to non-clonned B + if A's clone calls clonned B). */ static void ipcp_compute_node_scale (struct cgraph_node *node) { @@ -589,6 +595,12 @@ ipcp_compute_node_scale (struct cgraph_node *node) /* Compute sum of all counts of callers. */ for (cs = node->callers; cs != NULL; cs = cs->next_caller) sum += cs->count; + /* Work around the unrealistically high sum problem. We just don't want + the non-cloned body to have negative or very low frequency. Since + majority of execution time will be spent in clones anyway, this should + give good enough profile. */ + if (sum > node->count * 9 / 10) + sum = node->count * 9 / 10; if (node->count == 0) ipcp_set_node_scale (node, 0); else @@ -621,15 +633,8 @@ ipcp_init_stage (void) ipa_count_arguments (cs); if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) != ipa_get_param_count (IPA_NODE_REF (cs->callee))) - { - /* Handle cases of functions with - a variable number of parameters. */ - ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee)); - if (flag_indirect_inlining) - ipa_compute_jump_functions (cs); - } - else - ipa_compute_jump_functions (cs); + ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee)); + ipa_compute_jump_functions (cs); } } } @@ -1279,7 +1284,7 @@ ipcp_generate_summary (void) ipa_check_create_node_params (); ipa_check_create_edge_args (); ipa_register_cgraph_hooks (); - /* 1. Call the init stage to initialize + /* 1. Call the init stage to initialize the ipa_node_params and ipa_edge_args structures. */ ipcp_init_stage (); }