diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aa55a95e4a9..50e3e65c45a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2005-05-28 Jan Hubicka + + * tree-ssa-threadupdate.c: (create_edge_and_update_destination_phis): + Update profile. + * value-prof.c (tree_divmod_fixed_value_transform): Be more verbose in + debug output. + (tree_mod_subtract): Fix profile updating code. + (tree_divmod_values_to_profile): Do not produce useless value profilers + for divisions. + 2005-05-28 Kazu Hirata * tree-ssa-dom.c (vrp_element_p): Define. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a6d54b3a4fc..0416c70aed4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2005-05-28 Jan Hubicka + + * tree-prof.exp: Fix comment. + * value-prof-1.c: New. + * value-prof-2.c: New. + * value-prof-3.c: New. + * value-prof-4.c: New. + 2005-05-27 Mark Mitchell PR c++/21614 diff --git a/gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp b/gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp index 307cc2c52ae..9559a80e187 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp +++ b/gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp @@ -15,7 +15,7 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Test the functionality of programs compiled with profile-directed block -# ordering using -fprofile-generate followed by -fprofile-use +# ordering using -fprofile-generate followed by -fbranch-use. load_lib target-supports.exp diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c new file mode 100644 index 00000000000..db3bc950f5a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c @@ -0,0 +1,20 @@ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-tree_profile" } */ +int a[1000]; +int b = 256; +int c = 257; +main () +{ + int i; + int n; + for (i = 0; i < 1000; i++) + { + if (i % 17) + n = c; + else n = b; + a[i] /= n; + } + return 0; +} +/* { dg-final-use { scan-tree-dump "Div.mod by constant n=257 transformation on insn" "tree_profile"} } */ +/* { dg-final-use { scan-tree-dump "if \\(n != 257\\)" "optimized"} } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c new file mode 100644 index 00000000000..c11f7ea20e4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c @@ -0,0 +1,30 @@ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-tree_profile" } */ +unsigned int a[1000]; +unsigned int b = 256; +unsigned int c = 1024; +unsigned int d = 17; +main () +{ + int i; + unsigned int n; + for (i = 0; i < 1000; i++) + { + a[i]=100*i; + } + for (i = 0; i < 1000; i++) + { + if (i % 2) + n = b; + else if (i % 3) + n = c; + else + n = d; + a[i] %= n; + } + return 0; +} +/* { dg-final-use { scan-tree-dump "Mod power of 2 transformation on insn" "tree_profile"} } */ +/* This is part of code checking that n is power of 2, so we are sure that the transformation + didn't get optimized out. */ +/* { dg-final-use { scan-tree-dump "n \\+ \\-1" "optimized"} } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c new file mode 100644 index 00000000000..91ebd376177 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c @@ -0,0 +1,30 @@ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-tree_profile" } */ +unsigned int a[1000]; +unsigned int b = 257; +unsigned int c = 1023; +unsigned int d = 19; +main () +{ + int i; + unsigned int n; + for (i = 0; i < 1000; i++) + { + a[i]=18; + } + for (i = 0; i < 1000; i++) + { + if (i % 2) + n = b; + else if (i % 3) + n = c; + else + n = d; + a[i] %= n; + } + return 0; +} +/* { dg-final-use { scan-tree-dump "Mod subtract transformation on insn" "tree_profile"} } */ +/* This is part of code checking that n is greater than the divisor so we are sure that it + didn't get optimized out. */ +/* { dg-final-use { scan-tree-dump "if \\(n \\>" "optimized"} } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c new file mode 100644 index 00000000000..4fff1123beb --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c @@ -0,0 +1,30 @@ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-tree_profile" } */ +unsigned int a[1000]; +unsigned int b = 999; +unsigned int c = 1002; +unsigned int d = 1003; +main () +{ + int i; + unsigned int n; + for (i = 0; i < 1000; i++) + { + a[i]=1000+i; + } + for (i = 0; i < 1000; i++) + { + if (i % 2) + n = b; + else if (i % 3) + n = c; + else + n = d; + a[i] %= n; + } + return 0; +} +/* { dg-final-use { scan-tree-dump "Mod subtract transformation on insn" "tree_profile"} } */ +/* This is part of code checking that n is greater than the divisor so we are sure that it + didn't get optimized out. */ +/* { dg-final-use { scan-tree-dump "if \\(n \\>" "optimized"} } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index f6bf1db7324..303463850d0 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -299,6 +299,9 @@ create_edge_and_update_destination_phis (struct redirection_data *rd) edge e = make_edge (rd->dup_block, rd->outgoing_edge->dest, EDGE_FALLTHRU); tree phi; + e->probability = REG_BR_PROB_BASE; + e->count = rd->dup_block->count; + /* If there are any PHI nodes at the destination of the outgoing edge from the duplicate block, then we will need to add a new argument to them. The argument should have the same value as the argument diff --git a/gcc/value-prof.c b/gcc/value-prof.c index b96cdcafbf6..e6b45a519e5 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -1221,12 +1221,6 @@ tree_divmod_fixed_value_transform (tree stmt) if (simple_cst_equal (op2, value) != 1 || 2 * count < all) return false; - if (dump_file) - { - fprintf (dump_file, "Div/mod by constant transformation on insn "); - print_generic_stmt (dump_file, stmt, TDF_SLIM); - } - /* Compute probability of taking the optimal path. */ prob = (count * REG_BR_PROB_BASE + all / 2) / all; @@ -1235,6 +1229,16 @@ tree_divmod_fixed_value_transform (tree stmt) val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1); result = tree_divmod_fixed_value (stmt, op, op1, op2, tree_val, prob, count, all); + if (dump_file) + { + fprintf (dump_file, "Div/mod by constant "); + print_generic_expr (dump_file, value, TDF_SLIM); + fprintf (dump_file, "="); + print_generic_expr (dump_file, tree_val, TDF_SLIM); + fprintf (dump_file, " transformation on insn "); + print_generic_stmt (dump_file, stmt, TDF_SLIM); + } + TREE_OPERAND (modify, 1) = result; return true; @@ -1489,11 +1493,11 @@ tree_mod_subtract (tree stmt, tree operation, tree op1, tree op2, e12->flags &= ~EDGE_FALLTHRU; e12->flags |= EDGE_FALSE_VALUE; e12->probability = REG_BR_PROB_BASE - prob1; - e12->count = count1; + e12->count = all - count1; e14 = make_edge (bb, bb4, EDGE_TRUE_VALUE); e14->probability = prob1; - e14->count = all - count1; + e14->count = count1; if (ncounts) /* Assumed to be 0 or 1. */ { @@ -1653,16 +1657,6 @@ tree_divmod_values_to_profile (tree stmt, histogram_values *values) if (is_gimple_reg (divisor)) { - /* Check for a special case where the divisor is power(s) of 2. - This is more aggressive than the RTL version, under the - assumption that later phases will reduce / or % by power of 2 - to something clever most of the time. Signed or unsigned. */ - hist = ggc_alloc (sizeof (*hist)); - hist->hvalue.tree.value = divisor; - hist->hvalue.tree.stmt = stmt; - hist->type = HIST_TYPE_POW2; - VEC_quick_push (histogram_value, *values, hist); - /* Check for the case where the divisor is the same value most of the time. */ hist = ggc_alloc (sizeof (*hist)); @@ -1677,6 +1671,13 @@ tree_divmod_values_to_profile (tree stmt, histogram_values *values) if (TREE_CODE (rhs) == TRUNC_MOD_EXPR && TYPE_UNSIGNED (type)) { + /* Check for a special case where the divisor is power of 2. */ + hist = ggc_alloc (sizeof (*hist)); + hist->hvalue.tree.value = divisor; + hist->hvalue.tree.stmt = stmt; + hist->type = HIST_TYPE_POW2; + VEC_quick_push (histogram_value, *values, hist); + hist = ggc_alloc (sizeof (*hist)); hist->hvalue.tree.stmt = stmt; hist->hvalue.tree.value