This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Avoid messing up of loop notes
- To: gcc-patches at gcc dot gnu dot org, rth at cygnus dot com, patches at x86-64 dot org
- Subject: Avoid messing up of loop notes
- From: Jan Hubicka <jh at suse dot cz>
- Date: Mon, 23 Jul 2001 14:37:54 +0200
Hi,
originally, the loop optimizer ignored 72 loops and we had 22 irreducible regions.
Killing jump pass made irreducible regions disappear and we have only 32 ignored loops.
This patch cuts it to 15 by threading correctly backward edges in syntactic loops.
I am investigating the remaining cases. These seems to be due lack of support for
loop entered by jump on the other label than the first one (?).
CFG and loop notes seems to be consistent now.
Honza
Mon Jul 23 14:34:26 CEST 2001 Jan Hubicka <jh@suse.cz>
* flow.c (back_edge_of_syntactic_loop_p): New.
(split_edge): Use it.
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 12:22:53
*************** 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
*************** redirect_edge_and_branch_force (e, targe
*** 1987,1992 ****
--- 1988,2015 ----
return new_bb;
}
+ /* Helper function for split_edge. Return true in case edge BB1 to BB2
+ is back edge of syntactic loop. */
+ static bool
+ back_edge_of_syntactic_loop_p (bb1, bb2)
+ basic_block bb1, bb2;
+ {
+ rtx insn;
+ int count;
+ if (bb1->index > bb2->index)
+ return false;
+ for (insn = bb1->end; insn != bb2->head && count >= 0;
+ insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == NOTE)
+ {
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
+ count++;
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
+ count--;
+ }
+ return count >= 0;
+ }
+
/* Split a (typically critical) edge. Return the new block.
Abort on abnormal edges.
*************** 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)
--- 2157,2164 ----
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)