re PR ipa/44563 (GCC uses a lot of RAM when compiling a large numbers of functions)

PR middle-end/44563 
	* ipa-inline.c: Update doplevel comment. 
	(cgraph_estimate_size_after_inlining): Remove times attribute. 
	(cgraph_mark_inline_edge): Update. 
	(cgraph_mark_inline): Remove. 
	(cgraph_estimate_growth): Update. 
	(cgraph_check_inline_limits): Remove one only argument. 
	(cgraph_edge_badness): Update. 
	(cgraph_decide_recursive_inlining): Update. 
	(cgraph_decide_inlining_of_small_function): Fix handling of tree_can_inline_p 
	and call_stmt_cannot_inline_p. 
	(cgraph_flatten): Likewise. 
	(cgraph_decide_inlining): Update. 
	(cgraph_decide_inlining_incrementally): Fix handling of call_stmt_cannot_inline_p.

From-SVN: r167964
This commit is contained in:
Jan Hubicka 2010-12-17 00:08:02 +00:00
parent 391fbfb8ca
commit 239630dc0c
2 changed files with 181 additions and 85 deletions

View File

@ -1,3 +1,20 @@
2010-12-16 Jan Hubicka <jh@suse.cz>
PR middle-end/44563
* ipa-inline.c: Update doplevel comment.
(cgraph_estimate_size_after_inlining): Remove times attribute.
(cgraph_mark_inline_edge): Update.
(cgraph_mark_inline): Remove.
(cgraph_estimate_growth): Update.
(cgraph_check_inline_limits): Remove one only argument.
(cgraph_edge_badness): Update.
(cgraph_decide_recursive_inlining): Update.
(cgraph_decide_inlining_of_small_function): Fix handling of tree_can_inline_p
and call_stmt_cannot_inline_p.
(cgraph_flatten): Likewise.
(cgraph_decide_inlining): Update.
(cgraph_decide_inlining_incrementally): Fix handling of call_stmt_cannot_inline_p.
2010-12-16 Joseph Myers <joseph@codesourcery.com>
* config/darwin.opt (dylinker, headerpad_max_install_names,
@ -126,6 +143,134 @@
* config/spu/t-spu-elf (dp-bit.c, fp-bit.c): Don't undefine
US_SOFTWARE_GOFAST.
2010-12-14 Jan Hubicka <jh@suse.cz>
* config/darwin.opt (dylinker, headerpad_max_install_names,
keep_private_externs, nofixprebinding, nomultidefs, noprebind,
noseglinkedit, object, prebind, prebind_all_twolevel_modules,
preload, private_bundle, pthread, seglinkedit, twolevel_namespace,
twolevel_namespace_hints, whatsloaded, whyload, y, Mach, X): New
Driver options.
* config/darwin.h (LINK_SPEC): Remove '*' after
headerpad_max_install_names.
2010-12-16 Sebastian Pop <sebastian.pop@amd.com>
PR tree-optimization/46924
* graphite-sese-to-poly.c (detect_commutative_reduction): Do not
detect reductions outside the current SESE region.
* sese.h (stmt_in_sese_p): New.
(defined_in_sese_p): Call stmt_in_sese_p.
2010-12-16 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/46966
* graphite-sese-to-poly.c (build_scop_drs): Call free_gimple_bb for
for bbs that are removed from SCOP_BBS vector.
2010-12-16 Eric Botcazou <ebotcazou@adacore.com>
* tree-ssa-sccvn.c (vn_reference_lookup_3): Always punt if the call to
get_ref_base_and_extent returns -1 as the max size.
2010-12-16 Konrad Eisele <konrad@gaisler.com>
Eric Botcazou <ebotcazou@adacore.com>
Support for LEON processor
* config.gcc (sparc-*-elf*): Deal with sparc-leon specifically.
(sparc-*-linux*): Likewise.
(sparc-*-rtems*): Remove Solaris left-overs.
(sparc*-*-*): Remove obsolete sparc86x setting.
(sparc-leon*): Default to --with-cpu=v8 and --with-tune=leon.
* doc/invoke.texi (SPARC Options): Document -mcpu/-mtune=leon.
* config/sparc/sparc.h (TARGET_CPU_leon): Define.
(TARGET_CPU_sparc86x): Delete.
(TARGET_CPU_cypress): Define as alias to TARGET_CPU_v7.
(TARGET_CPU_f930): Define as alias to TARGET_CPU_sparclite.
(TARGET_CPU_f934): Likewise.
(TARGET_CPU_tsc701): Define as alias to TARGET_CPU_sparclet.
(CPP_CPU_SPEC): Add entry for -mcpu=leon.
(enum processor_type): Add PROCESSOR_LEON. Reorganize.
* config/sparc/sparc.c (leon_costs): New cost array.
(sparc_option_override): Add entry for TARGET_CPU_leon and -mcpu=leon.
Initialize cost array to leon_costs if -mtune=leon.
* config/sparc/sparc.md (cpu attribute): Add leon. Reorganize.
Include leon.md scheduling description.
* config/sparc/leon.md: New file.
* config/sparc/t-elf: Do not assemble Solaris startup files.
* config/sparc/t-leon: New file.
* config/sparc/t-leon3: Likewise.
2010-12-16 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/43655
* tree-ssa-ter.c (is_replaceable_p): Don't use
gimple_references_memory_p for -O0, instead check for load
by looking at rhs.
2010-12-16 Sebastian Pop <sebastian.pop@amd.com>
PR tree-optimization/46404
* graphite-clast-to-gimple.c (gloog): Call scev_reset.
2010-12-16 Anatoly Sokolov <aesok@post.ru>
* config/sh/sh.h (OUTPUT_ADDR_CONST_EXTRA): Remove.
* config/sh/sh.c (sh_asm_output_addr_const_extra): New function.
(TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA): Define.
2010-12-16 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* config/spu/t-spu-elf (LIB2_SIDITI_CONV_FUNC): Define.
* config/spu/spu.h (MIN_UNITS_PER_WORD): Do not define.
(LIBGCC2_UNITS_PER_WORD): Define if not already defined.
2010-12-16 Jakub Jelinek <jakub@redhat.com>
PR debug/46893
* cfgexpand.c (expand_debug_expr): If GET_MODE (op0) is VOIDmode,
use TYPE_MODE (TREE_TYPE (tem)) instead of mode1.
2010-12-16 Chung-Lin Tang <cltang@codesourcery.com>
PR target/46883
* config/arm/arm.md
(zero_extendhisi2 for register input splitter): Change
"register_operand" to "s_register_operand".
(zero_extendqisi2 for register input splitter): Same.
2010-12-16 Jan Hubicka <jh@suse.cz>
PR middle-end/46939
* predic.c (predict_paths_leading_to_edge): New function.
(apply_return_prediction): Use it.
(predict_paths_for_bb): Do not special case abnormals.
2010-12-16 Joseph Myers <joseph@codesourcery.com>
* config.gcc (powerpc-*-lynxos*): Don't add lynx.opt to
extra_options twice.
2010-12-15 Joseph Myers <joseph@codesourcery.com>
* doc/tm.texi.in (US_SOFTWARE_GOFAST): Don't document.
* doc/tm.texi: Regenerate.
* system.h (US_SOFTWARE_GOFAST): Poison.
* config.gcc (enable_gofast): Don't handle.
* config/gofast.h: Remove.
* config/mips/t-gofast: Remove.
* config/fp-bit.c (US_SOFTWARE_GOFAST): Don't handle.
* config/fp-bit.h (US_SOFTWARE_GOFAST): Don't handle.
* config/mips/elforion.h: Don't mention GOFAST in comment.
* config/mips/mips.c: Don't include gofast.h.
(mips_init_libfuncs): Don't call gofast_maybe_init_libfuncs.
* config/mips/t-sr71k (dp-bit.c, fp-bit.c): Don't define
US_SOFTWARE_GOFAST.
* config/sparc/sparc.c: Don't include gofast.h.
(sparc_init_libfuncs): Don't call gofast_maybe_init_libfuncs.
* config/spu/t-spu-elf (dp-bit.c, fp-bit.c): Don't undefine
US_SOFTWARE_GOFAST.
2010-12-14 Jan Hubicka <jh@suse.cz>
* tree.c (get_file_function_name): Avoid using random seed on GLOBAL_sub_I

View File

@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see
There are three major parts of this file:
cgraph_mark_inline implementation
cgraph_mark_inline_edge implementation
This function allows to mark given call inline and performs necessary
modifications of cgraph (production of the clones and updating overall
@ -91,18 +91,6 @@ along with GCC; see the file COPYING3. If not see
optimized allowing it to unfold abstraction penalty on C++ effectively and
cheaply.
pass_ipa_early_inlining
With profiling, the early inlining is also necessary to reduce
instrumentation costs on program with high abstraction penalty (doing
many redundant calls). This can't happen in parallel with early
optimization and profile instrumentation, because we would end up
re-instrumenting already instrumented function bodies we brought in via
inlining.
To avoid this, this pass is executed as IPA pass before profiling. It is
simple wrapper to pass_early_inlining and ensures first inlining.
pass_ipa_inline
This is the main pass implementing simple greedy algorithm to do inlining
@ -110,12 +98,6 @@ along with GCC; see the file COPYING3. If not see
inlining of functions called once. The pass compute just so called inline
plan (representation of inlining to be done in callgraph) and unlike early
inlining it is not performing the inlining itself.
pass_apply_inline
This pass performs actual inlining according to pass_ipa_inline on given
function. Possible the function body before inlining is saved when it is
needed for further inlining later.
*/
#include "config.h"
@ -199,14 +181,14 @@ cgraph_estimate_time_after_inlining (int frequency, struct cgraph_node *to,
return time;
}
/* Estimate self time of the function after inlining WHAT into TO. */
/* Estimate self size of the function after inlining WHAT into TO. */
static inline int
cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to,
cgraph_estimate_size_after_inlining (struct cgraph_node *to,
struct cgraph_node *what)
{
int size = ((what->global.size - inline_summary (what)->size_inlining_benefit)
* times + to->global.size);
+ to->global.size);
gcc_assert (size >= 0);
return size;
}
@ -335,7 +317,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original,
{
to = e->caller;
old_size = e->caller->global.size;
new_size = cgraph_estimate_size_after_inlining (1, to, what);
new_size = cgraph_estimate_size_after_inlining (to, what);
to->global.size = new_size;
to->global.time = cgraph_estimate_time_after_inlining (freq, to, what);
}
@ -352,30 +334,6 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original,
return false;
}
/* Mark all calls of EDGE->CALLEE inlined into EDGE->CALLER. */
static void
cgraph_mark_inline (struct cgraph_edge *edge)
{
struct cgraph_node *to = edge->caller;
struct cgraph_node *what = edge->callee;
struct cgraph_edge *e, *next;
gcc_assert (!edge->call_stmt_cannot_inline_p);
/* Look for all calls, mark them inline and clone recursively
all inlined functions. */
for (e = what->callers; e; e = next)
{
next = e->next_caller;
if (e->caller == to && e->inline_failed)
{
cgraph_mark_inline_edge (e, true, NULL);
if (e == edge)
edge = next;
}
}
}
/* Estimate the growth caused by inlining NODE into all callees. */
static int
@ -393,7 +351,7 @@ cgraph_estimate_growth (struct cgraph_node *node)
if (e->caller == node)
self_recursive = true;
if (e->inline_failed)
growth += (cgraph_estimate_size_after_inlining (1, e->caller, node)
growth += (cgraph_estimate_size_after_inlining (e->caller, node)
- e->caller->global.size);
}
@ -424,21 +382,12 @@ cgraph_estimate_growth (struct cgraph_node *node)
static bool
cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
cgraph_inline_failed_t *reason, bool one_only)
cgraph_inline_failed_t *reason)
{
int times = 0;
struct cgraph_edge *e;
int newsize;
int limit;
HOST_WIDE_INT stack_size_limit, inlined_stack;
if (one_only)
times = 1;
else
for (e = to->callees; e; e = e->next_callee)
if (e->callee == what)
times++;
if (to->global.inlined_to)
to = to->global.inlined_to;
@ -453,7 +402,7 @@ cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
/* Check the size after inlining against the function limits. But allow
the function to shrink if it went over the limits by forced inlining. */
newsize = cgraph_estimate_size_after_inlining (times, to, what);
newsize = cgraph_estimate_size_after_inlining (to, what);
if (newsize >= to->global.size
&& newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
&& newsize > limit)
@ -565,7 +514,7 @@ cgraph_edge_badness (struct cgraph_edge *edge, bool dump)
{
gcov_type badness;
int growth =
(cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee)
(cgraph_estimate_size_after_inlining (edge->caller, edge->callee)
- edge->caller->global.size);
if (edge->callee->local.disregard_inline_limits)
@ -895,7 +844,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node,
/* Make sure that function is small enough to be considered for inlining. */
if (!max_depth
|| cgraph_estimate_size_after_inlining (1, node, node) >= limit)
|| cgraph_estimate_size_after_inlining (node, node) >= limit)
return false;
heap = fibheap_new ();
lookup_recursive_calls (node, node, heap);
@ -921,7 +870,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node,
/* Do the inlining and update list of recursive call during process. */
while (!fibheap_empty (heap)
&& (cgraph_estimate_size_after_inlining (1, node, master_clone)
&& (cgraph_estimate_size_after_inlining (node, master_clone)
<= limit))
{
struct cgraph_edge *curr
@ -1128,7 +1077,7 @@ cgraph_decide_inlining_of_small_functions (void)
callee = edge->callee;
growth = (cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee)
growth = (cgraph_estimate_size_after_inlining (edge->caller, edge->callee)
- edge->caller->global.size);
if (dump_file)
@ -1220,7 +1169,8 @@ cgraph_decide_inlining_of_small_functions (void)
}
continue;
}
if (!tree_can_inline_p (edge))
if (!tree_can_inline_p (edge)
|| edge->call_stmt_cannot_inline_p)
{
if (dump_file)
fprintf (dump_file, " inline_failed:%s.\n",
@ -1244,9 +1194,8 @@ cgraph_decide_inlining_of_small_functions (void)
else
{
struct cgraph_node *callee;
if (edge->call_stmt_cannot_inline_p
|| !cgraph_check_inline_limits (edge->caller, edge->callee,
&edge->inline_failed, true))
if (!cgraph_check_inline_limits (edge->caller, edge->callee,
&edge->inline_failed))
{
if (dump_file)
fprintf (dump_file, " Not inlining into %s:%s.\n",
@ -1368,7 +1317,12 @@ cgraph_flatten (struct cgraph_node *node)
struct cgraph_node *orig_callee;
if (e->call_stmt_cannot_inline_p)
continue;
{
if (dump_file)
fprintf (dump_file, "Not inlining: %s",
cgraph_inline_failed_string (e->inline_failed));
continue;
}
if (!e->callee->analyzed)
{
@ -1555,10 +1509,10 @@ cgraph_decide_inlining (void)
}
if (cgraph_check_inline_limits (node->callers->caller, node,
&reason, false))
&reason))
{
struct cgraph_node *caller = node->callers->caller;
cgraph_mark_inline (node->callers);
cgraph_mark_inline_edge (node->callers, true, NULL);
if (dump_file)
fprintf (dump_file,
" Inlined into %s which now has %i size"
@ -1636,8 +1590,6 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
if (!e->callee->local.disregard_inline_limits
&& (mode != INLINE_ALL || !e->callee->local.inlinable))
continue;
if (e->call_stmt_cannot_inline_p)
continue;
if (dump_file)
fprintf (dump_file,
"Considering to always inline inline candidate %s.\n",
@ -1648,7 +1600,8 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
fprintf (dump_file, "Not inlining: recursive call.\n");
continue;
}
if (!tree_can_inline_p (e))
if (!tree_can_inline_p (e)
|| e->call_stmt_cannot_inline_p)
{
if (dump_file)
fprintf (dump_file,
@ -1675,7 +1628,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
fprintf (dump_file, " Inlining %s into %s.\n",
cgraph_node_name (e->callee),
cgraph_node_name (e->caller));
cgraph_mark_inline (e);
cgraph_mark_inline_edge (e, true, NULL);
inlined = true;
}
@ -1725,25 +1678,24 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
if (((mode == INLINE_SIZE || mode == INLINE_SIZE_NORECURSIVE)
|| (!flag_inline_functions
&& !DECL_DECLARED_INLINE_P (e->callee->decl)))
&& (cgraph_estimate_size_after_inlining (1, e->caller, e->callee)
&& (cgraph_estimate_size_after_inlining (e->caller, e->callee)
> e->caller->global.size + allowed_growth)
&& cgraph_estimate_growth (e->callee) > allowed_growth)
{
if (dump_file)
fprintf (dump_file,
"Not inlining: code size would grow by %i.\n",
cgraph_estimate_size_after_inlining (1, e->caller,
cgraph_estimate_size_after_inlining (e->caller,
e->callee)
- e->caller->global.size);
continue;
}
if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed,
false)
|| e->call_stmt_cannot_inline_p)
if (e->call_stmt_cannot_inline_p
|| !tree_can_inline_p (e))
{
if (dump_file)
fprintf (dump_file, "Not inlining: %s.\n",
cgraph_inline_failed_string (e->inline_failed));
fprintf (dump_file,
"Not inlining: call site not inlinable.\n");
continue;
}
if (!e->callee->analyzed)
@ -1753,11 +1705,10 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
"Not inlining: Function body no longer available.\n");
continue;
}
if (!tree_can_inline_p (e))
if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed))
{
if (dump_file)
fprintf (dump_file,
"Not inlining: %s.",
fprintf (dump_file, "Not inlining: %s.\n",
cgraph_inline_failed_string (e->inline_failed));
continue;
}
@ -1767,7 +1718,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
fprintf (dump_file, " Inlining %s into %s.\n",
cgraph_node_name (e->callee),
cgraph_node_name (e->caller));
cgraph_mark_inline (e);
cgraph_mark_inline_edge (e, true, NULL);
inlined = true;
}
}