Exemple #1
0
static basic_block
find_block_to_duplicate_for_splitting_paths (basic_block latch)
{
    /* We should have simple latches at this point.  So the latch should
       have a single successor.  This implies the predecessor of the latch
       likely has the loop exit.  And it's that predecessor we're most
       interested in. To keep things simple, we're going to require that
       the latch have a single predecessor too.  */
    if (single_succ_p (latch) && single_pred_p (latch))
    {
        basic_block bb = get_immediate_dominator (CDI_DOMINATORS, latch);
        gcc_assert (single_pred_edge (latch)->src == bb);

        /* If BB has been marked as not to be duplicated, then honor that
        request.  */
        if (ignore_bb_p (bb))
            return NULL;

        gimple *last = gsi_stmt (gsi_last_nondebug_bb (bb));
        /* The immediate dominator of the latch must end in a conditional.  */
        if (!last || gimple_code (last) != GIMPLE_COND)
            return NULL;

        /* We're hoping that BB is a join point for an IF-THEN-ELSE diamond
        region.  Verify that it is.

         First, verify that BB has two predecessors (each arm of the
         IF-THEN-ELSE) and two successors (the latch and exit).  */
        if (EDGE_COUNT (bb->preds) == 2 && EDGE_COUNT (bb->succs) == 2)
        {
            /* Now verify that BB's immediate dominator ends in a
               conditional as well.  */
            basic_block bb_idom = get_immediate_dominator (CDI_DOMINATORS, bb);
            gimple *last = gsi_stmt (gsi_last_nondebug_bb (bb_idom));
            if (!last || gimple_code (last) != GIMPLE_COND)
                return NULL;

            /* And that BB's immediate dominator's successors are the
               predecessors of BB.  */
            if (!find_edge (bb_idom, EDGE_PRED (bb, 0)->src)
                    || !find_edge (bb_idom, EDGE_PRED (bb, 1)->src))
                return NULL;

            /* And that the predecessors of BB each have a single successor.  */
            if (!single_succ_p (EDGE_PRED (bb, 0)->src)
                    || !single_succ_p (EDGE_PRED (bb, 1)->src))
                return NULL;

            /* So at this point we have a simple diamond for an IF-THEN-ELSE
               construct starting at BB_IDOM, with a join point at BB.  BB
               pass control outside the loop or to the loop latch.

               We're going to want to create two duplicates of BB, one for
               each successor of BB_IDOM.  */
            return bb;
        }
    }
    return NULL;
}
static gimple *
get_gimple_control_stmt (basic_block bb)
{
  gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);

  if (gsi_end_p (gsi))
    return NULL;

  gimple *stmt = gsi_stmt (gsi);
  enum gimple_code code = gimple_code (stmt);
  if (code == GIMPLE_COND || code == GIMPLE_SWITCH || code == GIMPLE_GOTO)
    return stmt;
  return NULL;
}