This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix messing up loop notes 3
- To: gcc-patches at gcc dot gnu dot org, rth at cygnus dot com, patches at x86-64 dot org
- Subject: Fix messing up loop notes 3
- From: Jan Hubicka <jh at suse dot cz>
- Date: Mon, 23 Jul 2001 15:55:09 +0200
Hi,
this patch should complette the messing up notes. There remains 6 cases, where
loop optimizer is confused, but these are caused by the jump.c's header
duplication code I don't want to fix right now. That part should be done
by loop optimizer anyway.
Honza
Mon Jul 23 15:50: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.
Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/basic-block.h,v
retrieving revision 1.103
diff -c -3 -p -r1.103 basic-block.h
*** basic-block.h 2001/07/22 21:42:34 1.103
--- basic-block.h 2001/07/23 13:46:21
*************** enum update_life_extent
*** 542,547 ****
--- 542,549 ----
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. */
Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/except.c,v
retrieving revision 1.174
diff -c -3 -p -r1.174 except.c
*** except.c 2001/07/20 11:30:13 1.174
--- except.c 2001/07/23 13:46:27
*************** finish_eh_generation ()
*** 2348,2354 ****
rebuild_jump_labels (get_insns ());
find_basic_blocks (get_insns (), max_reg_num (), 0);
! cleanup_cfg (0);
/* These registers are used by the landing pads. Make sure they
have been generated. */
--- 2348,2354 ----
rebuild_jump_labels (get_insns ());
find_basic_blocks (get_insns (), max_reg_num (), 0);
! cleanup_cfg (CLEANUP_PRE_LOOP);
/* These registers are used by the landing pads. Make sure they
have been generated. */
*************** finish_eh_generation ()
*** 2371,2377 ****
find_exception_handler_labels ();
rebuild_jump_labels (get_insns ());
find_basic_blocks (get_insns (), max_reg_num (), 0);
! cleanup_cfg (0);
}
/* This section handles removing dead code for flow. */
--- 2371,2377 ----
find_exception_handler_labels ();
rebuild_jump_labels (get_insns ());
find_basic_blocks (get_insns (), max_reg_num (), 0);
! cleanup_cfg (CLEANUP_PRE_LOOP);
}
/* This section handles removing dead code for flow. */
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.434
diff -c -3 -p -r1.434 flow.c
*** flow.c 2001/07/23 07:03:34 1.434
--- flow.c 2001/07/23 13:46:30
*************** static bool try_optimize_cfg PARAMS ((i
*** 396,402 ****
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 void tidy_fallthru_edges PARAMS ((void));
static int verify_wide_reg_1 PARAMS ((rtx *, void *));
static void verify_wide_reg PARAMS ((int, rtx, rtx));
--- 396,402 ----
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 ((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));
*************** static void flow_loops_tree_build PARAMS
*** 484,489 ****
--- 484,490 ----
static int flow_loop_level_compute PARAMS ((struct loop *, int));
static int flow_loops_level_compute PARAMS ((struct loops *));
static void find_sub_basic_blocks PARAMS ((basic_block));
+ static bool back_edge_of_syntactic_loop_p PARAMS ((basic_block, basic_block));
/* Find basic blocks of the current function.
F is the first insn of the function and NREGS the number of register
*************** split_edge (edge_in)
*** 2134,2140 ****
if (old_succ != EXIT_BLOCK_PTR
&& PREV_INSN (old_succ->head)
&& GET_CODE (PREV_INSN (old_succ->head)) == NOTE
! && NOTE_LINE_NUMBER (PREV_INSN (old_succ->head)) == NOTE_INSN_LOOP_BEG)
bb_note = emit_note_before (NOTE_INSN_BASIC_BLOCK,
PREV_INSN (old_succ->head));
else if (old_succ != EXIT_BLOCK_PTR)
--- 2186,2193 ----
if (old_succ != EXIT_BLOCK_PTR
&& PREV_INSN (old_succ->head)
&& GET_CODE (PREV_INSN (old_succ->head)) == NOTE
! && NOTE_LINE_NUMBER (PREV_INSN (old_succ->head)) == NOTE_INSN_LOOP_BEG
! && !back_edge_of_syntactic_loop_p (old_succ, old_pred))
bb_note = emit_note_before (NOTE_INSN_BASIC_BLOCK,
PREV_INSN (old_succ->head));
else if (old_succ != EXIT_BLOCK_PTR)
*************** merge_blocks (e, b, c, mode)
*** 2957,2963 ****
}
/* Otherwise we will need to move code around. Do that only if expensive
transformations are allowed. */
! else if (mode & CLEANUP_EXPENSIVE)
{
edge tmp_edge, c_fallthru_edge;
int c_has_outgoing_fallthru;
--- 3010,3016 ----
}
/* Otherwise we will need to move code around. Do that only if expensive
transformations are allowed. */
! else if ((mode & CLEANUP_EXPENSIVE) && 0)
{
edge tmp_edge, c_fallthru_edge;
int c_has_outgoing_fallthru;
*************** try_simplify_condjump (cbranch_block)
*** 3100,3107 ****
Return true if sucessful. */
static bool
! try_forward_edges (b)
basic_block b;
{
bool changed = false;
edge e, next;
--- 3153,3161 ----
Return true if sucessful. */
static bool
! try_forward_edges (mode, b)
basic_block b;
+ int mode;
{
bool changed = false;
edge e, next;
*************** try_forward_edges (b)
*** 3131,3136 ****
--- 3185,3214 ----
/* 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++;
}
*************** try_optimize_cfg (mode)
*** 3862,3868 ****
changed_here = true;
/* Simplify branch to branch. */
! if (try_forward_edges (b))
changed_here = true;
/* Look for shared code between blocks. */
--- 3942,3948 ----
changed_here = true;
/* Simplify branch to branch. */
! if (try_forward_edges (mode, b))
changed_here = true;
/* Look for shared code between blocks. */
Index: sibcall.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/sibcall.c,v
retrieving revision 1.20
diff -c -3 -p -r1.20 sibcall.c
*** sibcall.c 2001/07/16 20:54:44 1.20
--- sibcall.c 2001/07/23 13:46:33
*************** optimize_sibling_and_tail_recursive_call
*** 569,575 ****
/* 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);
/* If there are no basic blocks, then there is nothing to do. */
if (n_basic_blocks == 0)
--- 569,575 ----
/* 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_PRE_LOOP);
/* If there are no basic blocks, then there is nothing to do. */
if (n_basic_blocks == 0)
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.495
diff -c -3 -p -r1.495 toplev.c
*** toplev.c 2001/07/22 19:34:13 1.495
--- toplev.c 2001/07/23 13:46:34
*************** rest_of_compilation (decl)
*** 2732,2738 ****
rebuild_jump_labels (insns);
find_exception_handler_labels ();
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
! cleanup_cfg (CLEANUP_PRE_SIBCALL);
optimize = saved_optimize;
}
--- 2732,2738 ----
rebuild_jump_labels (insns);
find_exception_handler_labels ();
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
! cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);
optimize = saved_optimize;
}
*************** rest_of_compilation (decl)
*** 2841,2847 ****
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);
copy_loop_headers (insns);
purge_line_number_notes (insns);
--- 2841,2847 ----
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_PRE_LOOP);
copy_loop_headers (insns);
purge_line_number_notes (insns);
*************** rest_of_compilation (decl)
*** 2865,2871 ****
open_dump_file (DFI_ssa, decl);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
! cleanup_cfg (CLEANUP_EXPENSIVE);
convert_to_ssa ();
close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
--- 2865,2871 ----
open_dump_file (DFI_ssa, decl);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
! cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
convert_to_ssa ();
close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
*************** rest_of_compilation (decl)
*** 2930,2936 ****
if (optimize > 0)
{
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
! cleanup_cfg (CLEANUP_EXPENSIVE);
/* ??? Run if-conversion before delete_null_pointer_checks,
since the later does not preserve the CFG. This should
--- 2930,2936 ----
if (optimize > 0)
{
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
! 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
*************** rest_of_compilation (decl)
*** 2987,2993 ****
timevar_push (TV_JUMP);
rebuild_jump_labels (insns);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
! cleanup_cfg (CLEANUP_EXPENSIVE);
timevar_pop (TV_JUMP);
}
--- 2987,2993 ----
timevar_push (TV_JUMP);
rebuild_jump_labels (insns);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
! cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
timevar_pop (TV_JUMP);
}
*************** rest_of_compilation (decl)
*** 3001,3007 ****
timevar_push (TV_JUMP);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
! cleanup_cfg (CLEANUP_EXPENSIVE);
delete_null_pointer_checks (insns);
timevar_pop (TV_JUMP);
--- 3001,3007 ----
timevar_push (TV_JUMP);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
! cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
delete_null_pointer_checks (insns);
timevar_pop (TV_JUMP);
*************** rest_of_compilation (decl)
*** 3035,3041 ****
open_dump_file (DFI_gcse, decl);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
! cleanup_cfg (CLEANUP_EXPENSIVE);
tem = gcse_main (insns, rtl_dump_file);
save_csb = flag_cse_skip_blocks;
--- 3035,3041 ----
open_dump_file (DFI_gcse, decl);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
! cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
tem = gcse_main (insns, rtl_dump_file);
save_csb = flag_cse_skip_blocks;
*************** rest_of_compilation (decl)
*** 3060,3066 ****
tem = tem2 = 0;
timevar_push (TV_JUMP);
rebuild_jump_labels (insns);
! cleanup_cfg (CLEANUP_EXPENSIVE);
timevar_pop (TV_JUMP);
if (flag_expensive_optimizations)
--- 3060,3066 ----
tem = tem2 = 0;
timevar_push (TV_JUMP);
rebuild_jump_labels (insns);
! cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
timevar_pop (TV_JUMP);
if (flag_expensive_optimizations)