/* Control flow optimization code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
and cold sections.
Basic block partitioning may result in some jumps that appear to
- be optimizable (or blocks that appear to be mergeable), but which really m
- ust be left untouched (they are required to make it safely across
+ be optimizable (or blocks that appear to be mergeable), but which really
+ must be left untouched (they are required to make it safely across
partition boundaries). See the comments at the top of
bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */
for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); )
{
basic_block target, first;
- int counter;
+ int counter, goto_locus;
bool threaded = false;
int nthreaded_edges = 0;
bool may_thread = first_pass | df_get_bb_dirty (b);
target = first = e->dest;
counter = NUM_FIXED_BLOCKS;
+ goto_locus = e->goto_locus;
/* If we are partitioning hot/cold basic_blocks, we don't want to mess
up jumps that cross between hot/cold sections.
new_target = single_succ (target);
if (target == new_target)
counter = n_basic_blocks;
+ else if (!optimize)
+ {
+ /* When not optimizing, ensure that edges or forwarder
+ blocks with different locus are not optimized out. */
+ int locus = single_succ_edge (target)->goto_locus;
+
+ if (locus && goto_locus && !locator_eq (locus, goto_locus))
+ counter = n_basic_blocks;
+ else if (locus)
+ goto_locus = locus;
+
+ if (INSN_P (BB_END (target)))
+ {
+ locus = INSN_LOCATOR (BB_END (target));
+
+ if (locus && goto_locus
+ && !locator_eq (locus, goto_locus))
+ counter = n_basic_blocks;
+ else if (locus)
+ goto_locus = locus;
+ }
+ }
}
/* Allow to thread only over one edge at time to simplify updating
int edge_frequency;
int n = 0;
+ e->goto_locus = goto_locus;
+
/* Don't force if target is exit block. */
if (threaded && target != EXIT_BLOCK_PTR)
{
? rtx_renumbered_equal_p (p1, p2) : rtx_equal_p (p1, p2))
return true;
- /* Do not do EQUIV substitution after reload. First, we're undoing the
- work of reload_cse. Second, we may be undoing the work of the post-
- reload splitting pass. */
- /* ??? Possibly add a new phase switch variable that can be used by
- targets to disallow the troublesome insns after splitting. */
- if (!reload_completed)
- {
- /* The following code helps take care of G++ cleanups. */
- rtx equiv1 = find_reg_equal_equiv_note (i1);
- rtx equiv2 = find_reg_equal_equiv_note (i2);
-
- if (equiv1 && equiv2
- /* If the equivalences are not to a constant, they may
- reference pseudos that no longer exist, so we can't
- use them. */
- && (! reload_completed
- || (CONSTANT_P (XEXP (equiv1, 0))
- && rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0)))))
- {
- rtx s1 = single_set (i1);
- rtx s2 = single_set (i2);
- if (s1 != 0 && s2 != 0
- && rtx_renumbered_equal_p (SET_DEST (s1), SET_DEST (s2)))
- {
- validate_change (i1, &SET_SRC (s1), XEXP (equiv1, 0), 1);
- validate_change (i2, &SET_SRC (s2), XEXP (equiv2, 0), 1);
- if (! rtx_renumbered_equal_p (p1, p2))
- cancel_changes (0);
- else if (apply_change_group ())
- return true;
- }
- }
- }
-
return false;
}
\f
we require the existing branches to have probabilities that are
roughly similar. */
if (match
- && !optimize_size
- && maybe_hot_bb_p (bb1)
- && maybe_hot_bb_p (bb2))
+ && optimize_bb_for_speed_p (bb1)
+ && optimize_bb_for_speed_p (bb2))
{
int prob2;
/* Skip possible basic block header. */
if (LABEL_P (newpos1))
newpos1 = NEXT_INSN (newpos1);
-
- if (NOTE_P (newpos1))
+ if (NOTE_INSN_BASIC_BLOCK_P (newpos1))
newpos1 = NEXT_INSN (newpos1);
redirect_from = split_block (src1, PREV_INSN (newpos1))->src;
/* Don't crossjump if this block ends in a computed jump,
unless we are optimizing for size. */
- if (!optimize_size
+ if (optimize_bb_for_size_p (bb)
&& bb != EXIT_BLOCK_PTR
&& computed_jump_p (BB_END (bb)))
return false;
edge s;
bool changed_here = false;
- /* Delete trivially dead basic blocks. */
- if (EDGE_COUNT (b->preds) == 0)
+ /* Delete trivially dead basic blocks. This is either
+ blocks with no predecessors, or empty blocks with no
+ successors. Empty blocks may result from expanding
+ __builtin_unreachable (). */
+ if (EDGE_COUNT (b->preds) == 0
+ || (EDGE_COUNT (b->succs) == 0 && BB_HEAD (b) == BB_END (b)))
{
c = b->prev_bb;
if (dump_file)
next = NEXT_INSN (insn);
if (LABEL_P (insn)
&& LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
- && JUMP_P (next)
- && (GET_CODE (PATTERN (next)) == ADDR_VEC
- || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
+ && JUMP_TABLE_DATA_P (next))
{
rtx label = insn, jump = next;
static unsigned int
rest_of_handle_jump (void)
{
- delete_unreachable_blocks ();
-
- if (cfun->tail_call_emit)
+ if (crtl->tail_call_emit)
fixup_tail_calls ();
return 0;
}