Exemplo n.º 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;
}
Exemplo n.º 2
0
static basic_block
hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip,
			       tree cond, edge e_true,
			       bool update_dominators)
{
  tree tmp;
  gcond *cond_stmt;
  edge e_false;
  basic_block new_bb, split_bb = gsi_bb (*gsip);
  bool dominated_e_true = false;

  gcc_assert (e_true->src == split_bb);

  if (update_dominators
      && get_immediate_dominator (CDI_DOMINATORS, e_true->dest) == split_bb)
    dominated_e_true = true;

  tmp = force_gimple_operand_gsi (gsip, cond, /*simple=*/true, NULL,
				  /*before=*/true, GSI_SAME_STMT);
  cond_stmt = gimple_build_cond_from_tree (tmp, NULL_TREE, NULL_TREE);
  gsi_insert_before (gsip, cond_stmt, GSI_SAME_STMT);

  e_false = split_block (split_bb, cond_stmt);
  new_bb = e_false->dest;
  redirect_edge_pred (e_true, split_bb);

  e_true->flags &= ~EDGE_FALLTHRU;
  e_true->flags |= EDGE_TRUE_VALUE;

  e_false->flags &= ~EDGE_FALLTHRU;
  e_false->flags |= EDGE_FALSE_VALUE;
  e_false->probability = REG_BR_PROB_BASE - e_true->probability;
  e_false->count = split_bb->count - e_true->count;
  new_bb->count = e_false->count;

  if (update_dominators)
    {
      if (dominated_e_true)
	set_immediate_dominator (CDI_DOMINATORS, e_true->dest, split_bb);
      set_immediate_dominator (CDI_DOMINATORS, e_false->dest, split_bb);
    }

  return new_bb;
}
Exemplo n.º 3
0
void
copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
	  edge *edges, unsigned n_edges, edge *new_edges,
	  struct loop *base)
{
  unsigned i, j;
  basic_block bb, new_bb, dom_bb;
  edge e;

  /* Duplicate bbs, update dominators, assign bbs to loops.  */
  for (i = 0; i < n; i++)
    {
      /* Duplicate.  */
      bb = bbs[i];
      new_bb = new_bbs[i] = cfg_layout_duplicate_bb (bb, NULL);
      bb->rbi->duplicated = 1;
      /* Add to loop.  */
      add_bb_to_loop (new_bb, bb->loop_father->copy);
      add_to_dominance_info (CDI_DOMINATORS, new_bb);
      /* Possibly set header.  */
      if (bb->loop_father->header == bb && bb->loop_father != base)
	new_bb->loop_father->header = new_bb;
      /* Or latch.  */
      if (bb->loop_father->latch == bb && bb->loop_father != base)
	new_bb->loop_father->latch = new_bb;
    }

  /* Set dominators.  */
  for (i = 0; i < n; i++)
    {
      bb = bbs[i];
      new_bb = new_bbs[i];

      dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
      if (dom_bb->rbi->duplicated)
	{
	  dom_bb = dom_bb->rbi->copy;
	  set_immediate_dominator (CDI_DOMINATORS, new_bb, dom_bb);
	}
    }

  /* Redirect edges.  */
  for (j = 0; j < n_edges; j++)
    new_edges[j] = NULL;
  for (i = 0; i < n; i++)
    {
      new_bb = new_bbs[i];
      bb = bbs[i];

      for (e = new_bb->succ; e; e = e->succ_next)
	{
	  for (j = 0; j < n_edges; j++)
	    if (edges[j] && edges[j]->src == bb && edges[j]->dest == e->dest)
	      new_edges[j] = e;

	  if (!e->dest->rbi->duplicated)
	    continue;
	  redirect_edge_and_branch_force (e, e->dest->rbi->copy);
	}
    }

  /* Clear information about duplicates.  */
  for (i = 0; i < n; i++)
    bbs[i]->rbi->duplicated = 0;
}