summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c30
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c30
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c30
-rw-r--r--gcc/tree-ssa-threadupdate.c3
-rw-r--r--gcc/value-prof.c37
9 files changed, 151 insertions, 19 deletions
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 <jh@suse.cz>
+
+ * 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 <kazu@cs.umass.edu>
* 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 <jh@suse.cz>
+
+ * 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 <mark@codesourcery.com>
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