Пример #1
0
static bool
split_paths ()
{
  bool changed = false;
  loop_p loop;

  loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
  initialize_original_copy_tables ();
  calculate_dominance_info (CDI_DOMINATORS);

  FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
    {
      /* Only split paths if we are optimizing this loop for speed.  */
      if (!optimize_loop_for_speed_p (loop))
	continue;

      /* See if there is a block that we can duplicate to split the
	 path to the loop latch.  */
      basic_block bb
	= find_block_to_duplicate_for_splitting_paths (loop->latch);

      /* BB is the merge point for an IF-THEN-ELSE we want to transform.

	 Essentially we want to create a duplicate of bb and redirect the
	 first predecessor of BB to the duplicate (leaving the second
	 predecessor as is.  This will split the path leading to the latch
	 re-using BB to avoid useless copying.  */
      if (bb && is_feasible_trace (bb))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file,
		     "Duplicating join block %d into predecessor paths\n",
		     bb->index);
	  basic_block pred0 = EDGE_PRED (bb, 0)->src;
	  transform_duplicate (pred0, bb);
	  changed = true;
	}
    }

  loop_optimizer_finalize ();
  free_original_copy_tables ();
  return changed;
}
Пример #2
0
static bool
split_paths ()
{
    bool changed = false;
    loop_p loop;

    loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
    initialize_original_copy_tables ();
    calculate_dominance_info (CDI_DOMINATORS);

    FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
    {
        /* Only split paths if we are optimizing this loop for speed.  */
        if (!optimize_loop_for_speed_p (loop))
            continue;

        /* See if there is a block that we can duplicate to split the
        path to the loop latch.  */
        basic_block bb
            = find_block_to_duplicate_for_splitting_paths (loop->latch);

        /* BB is the merge point for an IF-THEN-ELSE we want to transform.

        Essentially we want to create a duplicate of bb and redirect the
         first predecessor of BB to the duplicate (leaving the second
         predecessor as is.  This will split the path leading to the latch
         re-using BB to avoid useless copying.  */
        if (bb && is_feasible_trace (bb))
        {
            if (dump_file && (dump_flags & TDF_DETAILS))
                fprintf (dump_file,
                         "Duplicating join block %d into predecessor paths\n",
                         bb->index);
            basic_block pred0 = EDGE_PRED (bb, 0)->src;
            transform_duplicate (pred0, bb);
            changed = true;

            /* If BB has an outgoing edge marked as IRREDUCIBLE, then
               duplicating BB may result in an irreducible region turning
               into a natural loop.

               Long term we might want to hook this into the block
               duplication code, but as we've seen with similar changes
               for edge removal, that can be somewhat risky.  */
            if (EDGE_SUCC (bb, 0)->flags & EDGE_IRREDUCIBLE_LOOP
                    || EDGE_SUCC (bb, 1)->flags & EDGE_IRREDUCIBLE_LOOP)
            {
                if (dump_file && (dump_flags & TDF_DETAILS))
                    fprintf (dump_file,
                             "Join block %d has EDGE_IRREDUCIBLE_LOOP set.  "
                             "Scheduling loop fixups.\n",
                             bb->index);
                loops_state_set (LOOPS_NEED_FIXUP);
            }
        }
    }

    loop_optimizer_finalize ();
    free_original_copy_tables ();
    return changed;
}