OSDN Git Service

PR middle-end/46939
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Dec 2010 01:27:23 +0000 (01:27 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Dec 2010 01:27:23 +0000 (01:27 +0000)
* predic.c (predict_paths_leading_to_edge): New function.
(apply_return_prediction): Use it.
(predict_paths_for_bb): Do not special case abnormals.
* gcc.target/i386/pr46939.c: New testcase.

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

gcc/ChangeLog
gcc/predict.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr46939.c [new file with mode: 0644]

index 08d91db..57de984 100644 (file)
@@ -1,3 +1,10 @@
+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
index c691990..a86708a 100644 (file)
@@ -77,6 +77,7 @@ static sreal real_zero, real_one, real_almost_one, real_br_prob_base,
 static void combine_predictions_for_insn (rtx, basic_block);
 static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
 static void predict_paths_leading_to (basic_block, enum br_predictor, enum prediction);
+static void predict_paths_leading_to_edge (edge, enum br_predictor, enum prediction);
 static bool can_predict_insn_p (const_rtx);
 
 /* Information we hold about each branch predictor.
@@ -1558,8 +1559,8 @@ apply_return_prediction (void)
       {
        pred = return_prediction (PHI_ARG_DEF (phi, i), &direction);
        if (pred != PRED_NO_PREDICTION)
-         predict_paths_leading_to (gimple_phi_arg_edge (phi, i)->src, pred,
-                                   direction);
+         predict_paths_leading_to_edge (gimple_phi_arg_edge (phi, i), pred,
+                                        direction);
       }
 }
 
@@ -1805,8 +1806,8 @@ predict_paths_for_bb (basic_block cur, basic_block bb,
       edge_iterator ei2;
       bool found = false;
 
-      /* Ignore abnormals, we predict them as not taken anyway.  */
-      if (e->flags & (EDGE_EH | EDGE_FAKE | EDGE_ABNORMAL))
+      /* Ignore fake edges and eh, we predict them as not taken anyway.  */
+      if (e->flags & (EDGE_EH | EDGE_FAKE))
        continue;
       gcc_assert (bb == cur || dominated_by_p (CDI_POST_DOMINATORS, cur, bb));
 
@@ -1814,7 +1815,7 @@ predict_paths_for_bb (basic_block cur, basic_block bb,
         and does not lead to BB.  */
       FOR_EACH_EDGE (e2, ei2, e->src->succs)
        if (e2 != e
-           && !(e2->flags & (EDGE_EH | EDGE_FAKE | EDGE_ABNORMAL))
+           && !(e2->flags & (EDGE_EH | EDGE_FAKE))
            && !dominated_by_p (CDI_POST_DOMINATORS, e2->dest, bb))
          {
            found = true;
@@ -1844,6 +1845,31 @@ predict_paths_leading_to (basic_block bb, enum br_predictor pred,
 {
   predict_paths_for_bb (bb, bb, pred, taken);
 }
+
+/* Like predict_paths_leading_to but take edge instead of basic block.  */
+
+static void
+predict_paths_leading_to_edge (edge e, enum br_predictor pred,
+                              enum prediction taken)
+{
+  bool has_nonloop_edge = false;
+  edge_iterator ei;
+  edge e2;
+
+  basic_block bb = e->src;
+  FOR_EACH_EDGE (e2, ei, bb->succs)
+    if (e2->dest != e->src && e2->dest != e->dest
+       && !(e->flags & (EDGE_EH | EDGE_FAKE))
+       && !dominated_by_p (CDI_POST_DOMINATORS, e->src, e2->dest))
+      {
+       has_nonloop_edge = true;
+       break;
+      }
+  if (!has_nonloop_edge)
+    predict_paths_for_bb (bb, bb, pred, taken);
+  else
+    predict_edge_def (e, pred, taken);
+}
 \f
 /* This is used to carry information about basic blocks.  It is
    attached to the AUX field of the standard CFG block.  */
index c10535c..8ca61f4 100644 (file)
@@ -1,3 +1,8 @@
+2010-12-16  Jan Hubicka  <jh@suse.cz>
+
+       PR middle-end/46939
+       * gcc.target/i386/pr46939.c: New testcase.
+
 2010-12-15  Sebastian Pop  <sebastian.pop@amd.com>
 
        PR tree-optimization/46404
diff --git a/gcc/testsuite/gcc.target/i386/pr46939.c b/gcc/testsuite/gcc.target/i386/pr46939.c
new file mode 100644 (file)
index 0000000..2f50e37
--- /dev/null
@@ -0,0 +1,118 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+int
+php_filter_parse_int (char const *str, unsigned int str_len, long *ret)
+{
+  long ctx_value;
+  int sign;
+  int digit;
+  char const *end;
+  int tmp;
+  char const *tmp___0;
+  char const *tmp___1;
+
+  sign = 0;
+  digit = 0;
+  end = str + str_len;
+  switch ((int) *str)
+    {
+    case 45:
+      sign = 1;
+    case 43:
+      str++;
+    default:;
+      break;
+    }
+  if ((unsigned long) str < (unsigned long) end)
+    {
+      if ((int const) *str >= 49)
+       {
+         if ((int const) *str <= 57)
+           {
+             if (sign)
+               {
+                 tmp = -1;
+               }
+             else
+               {
+                 tmp = 1;
+               }
+             tmp___0 = str;
+             str++;
+             ctx_value = (long) (tmp * (int) ((int const) *tmp___0 - 48));
+           }
+         else
+           {
+             return (-1);
+           }
+       }
+      else
+       {
+         return (-1);
+       }
+    }
+  else
+    {
+      return (-1);
+    }
+  if (end - str > 19)
+    {
+      return (-1);
+    }
+  while ((unsigned long) str < (unsigned long) end)
+    {
+      if ((int const) *str >= 48)
+       {
+         if ((int const) *str <= 57)
+           {
+             tmp___1 = str;
+             str++;
+             digit = (int) ((int const) *tmp___1 - 48);
+             if (!sign)
+               {
+                 if (ctx_value <=
+                     (9223372036854775807L - (long) digit) / 10L)
+                   {
+                     ctx_value = ctx_value * 10L + (long) digit;
+                   }
+                 else
+                   {
+                     goto _L;
+                   }
+               }
+             else
+               {
+               _L:
+                 if (sign)
+                   {
+                     if (ctx_value >=
+                         ((-0x7FFFFFFFFFFFFFFF - 1) + (long) digit) / 10L)
+                       {
+                         ctx_value = ctx_value * 10L - (long) digit;
+                       }
+                     else
+                       {
+                         return (-1);
+                       }
+                   }
+                 else
+                   {
+                     return (-1);
+                   }
+               }
+           }
+         else
+           {
+             return (-1);
+           }
+       }
+      else
+       {
+         return (-1);
+       }
+    }
+  *ret = ctx_value;
+  return (1);
+}
+
+/* { dg-final { scan-assembler-not "idiv" } } */