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.
{
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);
}
}
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));
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;
{
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. */
--- /dev/null
+/* { 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" } } */