From 2503de8d44bdfaf97b1ba1efb9455af3d206f911 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 11 Nov 2010 23:08:26 +0100 Subject: [PATCH] re PR tree-optimization/40436 (0.5% code size regression caused by r147852) PR tree-optimize/40436 * gcc.dg/tree-ssa/inline-5.c: New testcase. * gcc.dg/tree-ssa/inline-6.c: New testcase. * ipa-inline.c (likely_eliminated_by_inlining_p): Rename to ... (eliminated_by_inlining_prob): ... this one; return 50% probability for SRA. (estimate_function_body_sizes): Update use of eliminated_by_inlining_prob; estimate static function size for 2 instructions. From-SVN: r166624 --- gcc/ChangeLog | 9 ++++ gcc/ipa-inline.c | 54 ++++++++++++++---------- gcc/testsuite/ChangeLog | 7 ++- gcc/testsuite/gcc.dg/tree-ssa/inline-5.c | 35 +++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/inline-6.c | 36 ++++++++++++++++ 5 files changed, 118 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/inline-5.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/inline-6.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index df496e305e2..8ae4ecb8223 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2010-11-11 Jan Hubicka + + PR tree-optimize/40436 + * ipa-inline.c (likely_eliminated_by_inlining_p): Rename to ... + (eliminated_by_inlining_prob): ... this one; return 50% probability for + SRA. + (estimate_function_body_sizes): Update use of eliminated_by_inlining_prob; + estimate static function size for 2 instructions. + 2010-11-11 Joern Rennecke PR target/44749 diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index d4109c5a21f..e8c78f9f5fb 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1861,24 +1861,29 @@ struct gimple_opt_pass pass_early_inline = }; -/* See if statement might disappear after inlining. We are not terribly - sophisficated, basically looking for simple abstraction penalty wrappers. */ +/* See if statement might disappear after inlining. + 0 - means not eliminated + 1 - half of statements goes away + 2 - for sure it is eliminated. + We are not terribly sophisficated, basically looking for simple abstraction + penalty wrappers. */ -static bool -likely_eliminated_by_inlining_p (gimple stmt) +static int +eliminated_by_inlining_prob (gimple stmt) { enum gimple_code code = gimple_code (stmt); switch (code) { case GIMPLE_RETURN: - return true; + return 2; case GIMPLE_ASSIGN: if (gimple_num_ops (stmt) != 2) - return false; + return 0; /* Casts of parameters, loads from parameters passed by reference - and stores to return value or parameters are probably free after - inlining. */ + and stores to return value or parameters are often free after + inlining dua to SRA and further combining. + Assume that half of statements goes away. */ if (gimple_assign_rhs_code (stmt) == CONVERT_EXPR || gimple_assign_rhs_code (stmt) == NOP_EXPR || gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR @@ -1920,11 +1925,11 @@ likely_eliminated_by_inlining_p (gimple stmt) && (is_gimple_reg (rhs) || is_gimple_min_invariant (rhs))) rhs_free = true; if (lhs_free && rhs_free) - return true; + return 1; } - return false; + return 0; default: - return false; + return 0; } } @@ -1935,8 +1940,11 @@ estimate_function_body_sizes (struct cgraph_node *node) { gcov_type time = 0; gcov_type time_inlining_benefit = 0; - int size = 0; - int size_inlining_benefit = 0; + /* Estimate static overhead for function prologue/epilogue and alignment. */ + int size = 2; + /* Benefits are scaled by probability of elimination that is in range + <0,2>. */ + int size_inlining_benefit = 2 * 2; basic_block bb; gimple_stmt_iterator bsi; struct function *my_function = DECL_STRUCT_FUNCTION (node->decl); @@ -1957,6 +1965,7 @@ estimate_function_body_sizes (struct cgraph_node *node) gimple stmt = gsi_stmt (bsi); int this_size = estimate_num_insns (stmt, &eni_size_weights); int this_time = estimate_num_insns (stmt, &eni_time_weights); + int prob; if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -1967,20 +1976,21 @@ estimate_function_body_sizes (struct cgraph_node *node) this_time *= freq; time += this_time; size += this_size; - if (likely_eliminated_by_inlining_p (stmt)) - { - size_inlining_benefit += this_size; - time_inlining_benefit += this_time; - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Likely eliminated\n"); - } + prob = eliminated_by_inlining_prob (stmt); + if (prob == 1 && dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " 50%% will be eliminated by inlining\n"); + if (prob == 2 && dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " will eliminated by inlining\n"); + size_inlining_benefit += this_size * prob; + time_inlining_benefit += this_time * prob; gcc_assert (time >= 0); gcc_assert (size >= 0); } } time = (time + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE; - time_inlining_benefit = ((time_inlining_benefit + CGRAPH_FREQ_BASE / 2) - / CGRAPH_FREQ_BASE); + time_inlining_benefit = ((time_inlining_benefit + CGRAPH_FREQ_BASE) + / (CGRAPH_FREQ_BASE * 2)); + size_inlining_benefit = (size_inlining_benefit + 1) / 2; if (dump_file) fprintf (dump_file, "Overall function body time: %i-%i size: %i-%i\n", (int)time, (int)time_inlining_benefit, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bac2400fe2d..821ad573011 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,9 +1,14 @@ +2010-11-11 Jan Hubicka + + PR tree-optimize/40436 + * gcc.dg/tree-ssa/inline-5.c: New testcase. + * gcc.dg/tree-ssa/inline-6.c: New testcase. + 2010-11-11 Janus Weil * gfortran.dg/proc_decl_24.f90: New. 2010-11-11 Nicola Pero - * objc.dg/property/at-property-20.m: New. * objc.dg/property/synthesize-8.m: New. * obj-c++.dg/property/at-property-20.m: New. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/inline-5.c b/gcc/testsuite/gcc.dg/tree-ssa/inline-5.c new file mode 100644 index 00000000000..1cac5ba010e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/inline-5.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -fdump-tree-optimize" } */ +struct a {int a,b,c,d,e,f;}; + +do_inc (struct a *a) +{ + a->a=a->b; + a->b=a->c; + a->c=a->d; + a->e=a->f; +} + +test(struct a *a) +{ + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); +} +/* { dg-final { scan-tree-dump-times "do_inc.*;" 10 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/inline-6.c b/gcc/testsuite/gcc.dg/tree-ssa/inline-6.c new file mode 100644 index 00000000000..b6ee91d0575 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/inline-6.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -fdump-tree-optimize" } */ +struct a {int a,b,c,d,e,f;}; + +do_inc (struct a *a) +{ + a->a=1; + a->b=2; + a->c=3; + a->e=4; + a->f=5; +} + +test(struct a *a) +{ + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); + do_inc (a); + do_something (a); +} +/* { dg-final { scan-tree-dump-times "do_inc.*;" 10 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */