/* If-conversion support.
- Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
This file is part of GCC.
basic_block, int);
static void noce_emit_move_insn (rtx, rtx);
static rtx block_has_only_trap (basic_block);
-static void mark_loop_exit_edges (void);
\f
-/* Sets EDGE_LOOP_EXIT flag for all loop exits. */
-static void
-mark_loop_exit_edges (void)
-{
- struct loops loops;
- basic_block bb;
- edge e;
-
- flow_loops_find (&loops, LOOP_TREE);
- free_dominance_info (CDI_DOMINATORS);
-
- if (loops.num > 1)
- {
- FOR_EACH_BB (bb)
- {
- edge_iterator ei;
- FOR_EACH_EDGE (e, ei, bb->succs)
- {
- if (find_common_loop (bb->loop_father, e->dest->loop_father)
- != bb->loop_father)
- e->flags |= EDGE_LOOP_EXIT;
- else
- e->flags &= ~EDGE_LOOP_EXIT;
- }
- }
- }
-
- flow_loops_free (&loops);
-}
-
/* Count the number of non-jump active insns in BB. */
static int
rtx a = if_info->a;
rtx b = if_info->b;
rtx x = if_info->x;
+ rtx orig_a, orig_b;
rtx insn_a, insn_b;
rtx tmp, target;
int is_mem = 0;
start_sequence ();
+ orig_a = a;
+ orig_b = b;
+
/* If either operand is complex, load it into a register first.
The best way to do this is to copy the original insn. In this
way we preserve any clobbers etc that the insn may have had.
}
if (! general_operand (b, GET_MODE (b)))
{
- rtx set;
+ rtx set, last;
if (no_new_pseudos)
goto end_seq_and_fail;
if (is_mem)
{
tmp = gen_reg_rtx (GET_MODE (b));
- tmp = emit_insn (gen_rtx_SET (VOIDmode,
- tmp,
- b));
+ tmp = gen_rtx_SET (VOIDmode, tmp, b);
}
else if (! insn_b)
goto end_seq_and_fail;
tmp = copy_rtx (insn_b);
set = single_set (tmp);
SET_DEST (set) = b;
- tmp = emit_insn (PATTERN (tmp));
+ tmp = PATTERN (tmp);
}
+
+ /* If insn to set up A clobbers any registers B depends on, try to
+ swap insn that sets up A with the one that sets up B. If even
+ that doesn't help, punt. */
+ last = get_last_insn ();
+ if (last && modified_in_p (orig_b, last))
+ {
+ tmp = emit_insn_before (tmp, get_insns ());
+ if (modified_in_p (orig_a, tmp))
+ goto end_seq_and_fail;
+ }
+ else
+ tmp = emit_insn (tmp);
+
if (recog_memoized (tmp) < 0)
goto end_seq_and_fail;
}
if ((! targetm.cannot_modify_jumps_p ())
&& (!flag_reorder_blocks_and_partition || !no_new_pseudos
|| !targetm.have_named_sections))
- mark_loop_exit_edges ();
+ {
+ struct loops loops;
+
+ flow_loops_find (&loops);
+ mark_loop_exit_edges (&loops);
+ flow_loops_free (&loops);
+ free_dominance_info (CDI_DOMINATORS);
+ }
/* Compute postdominators if we think we'll use them. */
if (HAVE_conditional_execution || life_data_ok)