OSDN Git Service

2011-12-07 Martin Jambor <mjambor@suse.cz>
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Dec 2011 10:30:49 +0000 (10:30 +0000)
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Dec 2011 10:30:49 +0000 (10:30 +0000)
PR tree-optimization/50744
* ipa-cp.c (good_cloning_opportunity_p): Assert size_cost is positive,
compute evaluation in HOST_WIDEST_INT.
(safe_add): New function
(propagate_effects): Use safe_add to accumulate effects.

* testsuite/gcc.dg/ipa/pr50744.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182076 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ipa-cp.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/pr50744.c [new file with mode: 0644]

index 487c45a..5028c5f 100644 (file)
@@ -1,3 +1,11 @@
+2011-12-07  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/50744
+       * ipa-cp.c (good_cloning_opportunity_p): Assert size_cost is positive,
+       compute evaluation in HOST_WIDEST_INT.
+       (safe_add): New function
+       (propagate_effects): Use safe_add to accumulate effects.
+
 2011-12-06  Joel Sherrill <joel.sherrill@oarcorp.com>
 
        * config/rs6000/rtems.h: Switch to using global_options_set
index 10e1834..1c5a582 100644 (file)
@@ -1210,19 +1210,19 @@ good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
       || !optimize_function_for_speed_p (DECL_STRUCT_FUNCTION (node->decl)))
     return false;
 
-  gcc_checking_assert (size_cost >= 0);
+  gcc_assert (size_cost > 0);
 
-  /* FIXME:  These decisions need tuning.  */
   if (max_count)
     {
-      int evaluation, factor = (count_sum * 1000) / max_count;
-
-      evaluation = (time_benefit * factor) / size_cost;
+      int factor = (count_sum * 1000) / max_count;
+      HOST_WIDEST_INT evaluation = (((HOST_WIDEST_INT) time_benefit * factor)
+                                   / size_cost);
 
       if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "     good_cloning_opportunity_p (time: %i, "
                 "size: %i, count_sum: " HOST_WIDE_INT_PRINT_DEC
-                ") -> evaluation: %i, threshold: %i\n",
+                ") -> evaluation: " HOST_WIDEST_INT_PRINT_DEC
+                ", threshold: %i\n",
                 time_benefit, size_cost, (HOST_WIDE_INT) count_sum,
                 evaluation, 500);
 
@@ -1230,11 +1230,13 @@ good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
     }
   else
     {
-      int evaluation = (time_benefit * freq_sum) / size_cost;
+      HOST_WIDEST_INT evaluation = (((HOST_WIDEST_INT) time_benefit * freq_sum)
+                                   / size_cost);
 
       if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "     good_cloning_opportunity_p (time: %i, "
-                "size: %i, freq_sum: %i) -> evaluation: %i, threshold: %i\n",
+                "size: %i, freq_sum: %i) -> evaluation: "
+                HOST_WIDEST_INT_PRINT_DEC ", threshold: %i\n",
                 time_benefit, size_cost, freq_sum, evaluation,
                 CGRAPH_FREQ_BASE /2);
 
@@ -1561,6 +1563,20 @@ propagate_constants_topo (struct topo_info *topo)
     }
 }
 
+
+/* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
+   the bigger one if otherwise.  */
+
+static int
+safe_add (int a, int b)
+{
+  if (a > INT_MAX/2 || b > INT_MAX/2)
+    return a > b ? a : b;
+  else
+    return a + b;
+}
+
+
 /* Propagate the estimated effects of individual values along the topological
    from the dependant values to those they depend on.  */
 
@@ -1577,8 +1593,9 @@ propagate_effects (void)
 
       for (val = base; val; val = val->scc_next)
        {
-         time += val->local_time_benefit + val->prop_time_benefit;
-         size += val->local_size_cost + val->prop_size_cost;
+         time = safe_add (time,
+                          val->local_time_benefit + val->prop_time_benefit);
+         size = safe_add (size, val->local_size_cost + val->prop_size_cost);
        }
 
       for (val = base; val; val = val->scc_next)
@@ -1586,8 +1603,10 @@ propagate_effects (void)
          if (src->val
              && cgraph_maybe_hot_edge_p (src->cs))
            {
-             src->val->prop_time_benefit += time;
-             src->val->prop_size_cost += size;
+             src->val->prop_time_benefit = safe_add (time,
+                                               src->val->prop_time_benefit);
+             src->val->prop_size_cost = safe_add (size,
+                                                  src->val->prop_size_cost);
            }
     }
 }
index 507f9df..e87e85f 100644 (file)
@@ -1,3 +1,8 @@
+2011-12-07  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/50744
+       * gcc.dg/ipa/pr50744.c: New test.
+
 2011-12-06  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/51430
diff --git a/gcc/testsuite/gcc.dg/ipa/pr50744.c b/gcc/testsuite/gcc.dg/ipa/pr50744.c
new file mode 100644 (file)
index 0000000..0535348
--- /dev/null
@@ -0,0 +1,119 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-optimize-sibling-calls" } */
+
+extern int use_data (void *p_01, void *p_02, void *p_03, void *p_04, void *p_05,
+                    void *p_06, void *p_07, void *p_08, void *p_09, void *p_10,
+                    void *p_11, void *p_12, void *p_13, void *p_14, void *p_15,
+                    void *p_16, void *p_17, void *p_18, void *p_19, void *p_20,
+                    void *p_21, void *p_22, void *p_23, void *p_24, void *p_25,
+                    void *p_26, void *p_27, void *p_28, void *p_29,
+                    void *p_30);
+
+extern int idx (int i, int j, int n);
+
+struct stuff
+{
+  int decision;
+  int *a, *b, *c;
+  int res;
+};
+
+
+#define some_large_stuff(stuff, n) { \
+  int i, j, k; \
+  for (i = 0; i < n; i++) \
+    for (j = 0; j < n; j++) \
+      { \
+       int v = stuff->c[idx(i, j, n)]; \
+       for (k = 0; k < n; k++) \
+         v += stuff->a[idx(i, k, n)] * stuff->b[idx(k,j,n)]; \
+       stuff->c[idx(i, j, n)] = v; \
+      } \
+}
+
+#define recursion if (iter > 0) \
+    foo (stuff, iter - 1, (void *) -1, p_01, p_02, p_03, p_04, p_05, p_06, \
+      p_07, p_08, p_09, p_10, p_11, p_12, p_13, p_14, p_15, p_16, p_17, \
+     p_18, p_19, p_20, p_21, p_22, p_23, p_24, p_25, p_26, p_27, p_28, p_29); \
+    else \
+      foo (stuff, iter, p_01, p_02, p_03, p_04, p_05, p_06, p_07, p_08, p_09, \
+       p_10, p_11, p_12, p_13, p_14, p_15, p_16, p_17, p_18, p_19, p_20, \
+        p_21,p_22, p_23, p_24, p_25, p_26, p_27, p_28, p_29, p_30)
+
+void
+foo (struct stuff *stuff,
+     int iter,
+     void *p_01, void *p_02, void *p_03, void *p_04, void *p_05,
+     void *p_06, void *p_07, void *p_08, void *p_09, void *p_10,
+     void *p_11, void *p_12, void *p_13, void *p_14, void *p_15,
+     void *p_16, void *p_17, void *p_18, void *p_19, void *p_20,
+     void *p_21, void *p_22, void *p_23, void *p_24, void *p_25,
+     void *p_26, void *p_27, void *p_28, void *p_29, void *p_30)
+{
+ switch (stuff->decision)
+   {
+   case 0:
+     some_large_stuff (stuff, 83);
+     stuff->res =
+       use_data (p_01, p_02, p_03, p_04, p_05, p_06, p_07, p_08, p_09, p_10,
+                p_11, p_12, p_13, p_14, p_15, p_16, p_17, p_18, p_19, p_20,
+                p_21, p_22, p_23, p_24, p_25, p_26, p_27, p_28, p_29, p_30);
+     recursion;
+     break;
+
+   case 1:
+     some_large_stuff (stuff, 25);
+     stuff->res =
+       use_data (p_11, p_02, p_03, p_04, p_05, p_06, p_07, p_08, p_09, p_10,
+                p_21, p_12, p_13, p_14, p_15, p_16, p_17, p_18, p_19, p_20,
+                p_01, p_22, p_23, p_24, p_25, p_26, p_27, p_28, p_29, p_30);
+     recursion;
+     break;
+
+   case 3:
+     some_large_stuff (stuff, 139);
+     stuff->res =
+       use_data (p_01, p_12, p_03, p_04, p_05, p_06, p_07, p_08, p_09, p_10,
+                p_11, p_22, p_13, p_14, p_15, p_16, p_17, p_18, p_19, p_20,
+                p_21, p_02, p_23, p_24, p_25, p_26, p_27, p_28, p_29, p_30);
+     recursion;
+     break;
+
+   case 4:
+     some_large_stuff (stuff, 32);
+     stuff->res =
+       use_data (p_01, p_02, p_13, p_04, p_05, p_06, p_07, p_08, p_09, p_10,
+                p_11, p_12, p_23, p_14, p_15, p_16, p_17, p_18, p_19, p_20,
+                p_21, p_22, p_03, p_24, p_25, p_26, p_27, p_28, p_29, p_30);
+     recursion;
+     break;
+
+   case 5:
+     some_large_stuff (stuff, 205);
+     stuff->res =
+       use_data (p_01, p_02, p_03, p_04, p_15, p_06, p_07, p_08, p_09, p_10,
+                p_11, p_12, p_13, p_14, p_25, p_16, p_17, p_18, p_19, p_20,
+                p_21, p_22, p_23, p_24, p_05, p_26, p_27, p_28, p_29, p_30);
+     recursion;
+     break;
+
+   case 6:
+     some_large_stuff (stuff, 64);
+     stuff->res =
+       use_data (p_01, p_02, p_03, p_04, p_05, p_16, p_07, p_08, p_09, p_10,
+                p_11, p_12, p_13, p_14, p_15, p_26, p_17, p_18, p_19, p_20,
+                p_21, p_22, p_23, p_24, p_25, p_06, p_27, p_28, p_29, p_30);
+     recursion;
+     break;
+   }
+}
+
+#define NULL (void *)0
+
+void
+bar (struct stuff *stuff, int iter)
+{
+  foo (stuff, iter, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+}