+Sun Jul 29 18:59:13 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h (CLEANUP_PRE_LOOP): New.
+ * except.c (finish_eh_generation): Update call of cleanup_cfg.
+ * sibcall.c (optimize_sibling_calls): Likewise.
+ * toplev.c (rest_of_compilation): Likewise.
+ * flow.c (try_forward_edges): Take argument MODE;
+ do not forward over loop pre-headers if CLEANUP_PRE_LOOP.
+ (try_optimize_cfg): Update call of try_forward_edges.
+
+Sun Jul 29 18:59:56 CEST 2001 Roman Zippel <zippel@linux-m68k.org>
+ Jan Hubicka <jh@suse.cz>
+
+ * (validate_replace_rtx_1): Fix simplification of MINUS.
+
2001-07-29 Neil Booth <neil@daikokuya.demon.co.uk>
PR preprocessor/3669
to care REG_DEAD notes. */
#define CLEANUP_PRE_SIBCALL 8 /* Do not get confused by code hidden
inside call_placeholders.. */
+#define CLEANUP_PRE_LOOP 16 /* Take care to preserve syntactic loop
+ notes. */
/* Flags for loop discovery. */
#define LOOP_TREE 1 /* Build loop hierarchy tree. */
rebuild_jump_labels (get_insns ());
find_basic_blocks (get_insns (), max_reg_num (), 0);
- cleanup_cfg (0);
+ cleanup_cfg (CLEANUP_PRE_LOOP);
/* These registers are used by the landing pads. Make sure they
have been generated. */
find_exception_handler_labels ();
rebuild_jump_labels (get_insns ());
find_basic_blocks (get_insns (), max_reg_num (), 0);
- cleanup_cfg (0);
+ cleanup_cfg (CLEANUP_PRE_LOOP);
}
\f
/* This section handles removing dead code for flow. */
static bool can_fallthru PARAMS ((basic_block, basic_block));
static bool try_redirect_by_replacing_jump PARAMS ((edge, basic_block));
static bool try_simplify_condjump PARAMS ((basic_block));
-static bool try_forward_edges PARAMS ((basic_block));
+static bool try_forward_edges PARAMS ((int, basic_block));
static void tidy_fallthru_edges PARAMS ((void));
static int verify_wide_reg_1 PARAMS ((rtx *, void *));
static void verify_wide_reg PARAMS ((int, rtx, rtx));
Return true if sucessful. */
static bool
-try_forward_edges (b)
+try_forward_edges (mode, b)
basic_block b;
+ int mode;
{
bool changed = false;
edge e, next;
/* Bypass trivial infinite loops. */
if (target == target->succ->dest)
counter = n_basic_blocks;
+
+ /* Avoid killing of loop pre-headers, as it is the place loop
+ optimizer wants to hoist code to.
+
+ For fallthru forwarders, the LOOP_BEG note must appear between
+ the header of block and CODE_LABEL of the loop, for non forwarders
+ it must appear before the JUMP_INSN. */
+ if (mode & CLEANUP_PRE_LOOP)
+ {
+ rtx insn = (target->succ->flags & EDGE_FALLTHRU
+ ? target->head : prev_nonnote_insn (target->end));
+
+ if (GET_CODE (insn) != NOTE)
+ insn = NEXT_INSN (insn);
+
+ for (;insn && GET_CODE (insn) != CODE_LABEL && !INSN_P (insn);
+ insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
+ break;
+
+ if (GET_CODE (insn) == NOTE)
+ break;
+ }
target = target->succ->dest, counter++;
}
changed_here = true;
/* Simplify branch to branch. */
- if (try_forward_edges (b))
+ if (try_forward_edges (mode, b))
changed_here = true;
/* Look for shared code between blocks. */
simplify_gen_binary
(PLUS, GET_MODE (x), XEXP (x, 0),
simplify_gen_unary (NEG,
- op0_mode, XEXP (x, 1),
- op0_mode)), 1);
+ GET_MODE (x), XEXP (x, 1),
+ GET_MODE (x))), 1);
break;
case ZERO_EXTEND:
case SIGN_EXTEND:
/* We need cfg information to determine which blocks are succeeded
only by the epilogue. */
find_basic_blocks (insns, max_reg_num (), 0);
- cleanup_cfg (CLEANUP_PRE_SIBCALL);
+ cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);
/* If there are no basic blocks, then there is nothing to do. */
if (n_basic_blocks == 0)
rebuild_jump_labels (insns);
find_exception_handler_labels ();
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (CLEANUP_PRE_SIBCALL);
+ cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);
optimize = saved_optimize;
}
reg_scan (insns, max_reg_num (), 0);
rebuild_jump_labels (insns);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
+ cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP);
copy_loop_headers (insns);
purge_line_number_notes (insns);
open_dump_file (DFI_ssa, decl);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (CLEANUP_EXPENSIVE);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
convert_to_ssa ();
close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
if (optimize > 0)
{
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (CLEANUP_EXPENSIVE);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
/* ??? Run if-conversion before delete_null_pointer_checks,
since the later does not preserve the CFG. This should
timevar_push (TV_JUMP);
rebuild_jump_labels (insns);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (CLEANUP_EXPENSIVE);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
timevar_pop (TV_JUMP);
}
timevar_push (TV_JUMP);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (CLEANUP_EXPENSIVE);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
delete_null_pointer_checks (insns);
timevar_pop (TV_JUMP);
open_dump_file (DFI_gcse, decl);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (CLEANUP_EXPENSIVE);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
tem = gcse_main (insns, rtl_dump_file);
save_csb = flag_cse_skip_blocks;
rebuild_jump_labels (insns);
delete_trivially_dead_insns (insns, max_reg_num (), 0);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (CLEANUP_EXPENSIVE);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
timevar_pop (TV_JUMP);
if (flag_expensive_optimizations)