This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

split_edge improvement



I should have checked for this when we originally integrated the split_edge
code -- I ran into the same problem with my optimistic critical edge
splitting experiments.

Basically if we are not careful when we split an edge, we can easily confuse
the loop optimizer.

If loop finds a NOTE_INSN_LOOP_BEGIN that is not immediately followed by a
code label, then it assumes the loop isn't well behaved/phony.

So consider what happens when we want to insert an instruction on the
edge that passes control to the start of a loop such as the edge from 0 -> 1
in this example.

                        E
                        |
                        0
                       / \
                   +->1-->2--->E
                   |  |
                   +--+


We end up creating something like:

(jump_insn (set (pc)
        (if_then_else (geu (reg:CCUNS 89)
                (const_int 0 [0x0]))
            (label_ref 38)
            (pc))) 681 {jump-4} (nil)
    (nil))

(note "" NOTE_INSN_LOOP_BEG)

(note [bb 1] NOTE_INSN_BASIC_BLOCK)

(insn (set (reg:SI 90)
        (plus:SI (reg/v:SI 82)
            (const_int 5 [0x5]))) -1 (nil)
    (nil))

(insn (set (reg/s:SI 85)
        (reg:SI 90)) -1 (nil)
    (nil))

(code_label 6 "" "" [num uses: 1])

Egad.    We would be much better off creating:

jump_insn 53 52 69 (set (pc)
        (if_then_else (geu (reg:CCUNS 89)
                (const_int 0 [0x0]))
            (label_ref 38)
            (pc))) 681 {jump-4} (nil)
    (nil))

(note 69 53 68 [bb 1] NOTE_INSN_BASIC_BLOCK)

(insn 68 69 70 (set (reg:SI 90)
        (plus:SI (reg/v:SI 82)
            (const_int 5 [0x5]))) -1 (nil)
    (nil))

(insn 70 68 15 (set (reg/s:SI 85)
        (reg:SI 90)) -1 (nil)
    (nil))

(note 15 70 23 "" NOTE_INSN_LOOP_BEG)

(code_label 23 15 58 6 "" "" [num uses: 1])


Anyway, this fixes the problem.  At least the loops I'm looking at are now
being recognized as loops.

	* flow.c (split_edge): Take looping structure into account when
	determining where to put the new block note.

	
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.188
diff -c -3 -p -r1.188 flow.c
*** flow.c	1999/11/16 04:51:28	1.188
--- flow.c	1999/11/18 06:42:01
*************** split_edge (edge_in)
*** 1422,1429 ****
    BASIC_BLOCK (i) = bb;
    bb->index = i;
  
!   /* Create the basic block note.  */
!   if (old_succ != EXIT_BLOCK_PTR)
      bb_note = emit_note_before (NOTE_INSN_BASIC_BLOCK, old_succ->head);
    else
      bb_note = emit_note_after (NOTE_INSN_BASIC_BLOCK, get_last_insn ());
--- 1422,1452 ----
    BASIC_BLOCK (i) = bb;
    bb->index = i;
  
!   /* Create the basic block note. 
! 
!      Where we place the note can have a noticable impact on the generated
!      code.  Consider this cfg: 
! 	
! 
! 		        E
! 			|
! 			0
! 		       / \
! 		   +->1-->2--->E
!                    |  |
! 		   +--+
! 
!       If we need to insert an insn on the edge from block 0 to block 1,
!       we want to ensure the instructions we insert are outside of any
!       loop notes that physically sit between block 0 and block 1.  Otherwise
!       we confuse the loop optimizer into thinking the loop is a phony.  */
!   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)
      bb_note = emit_note_before (NOTE_INSN_BASIC_BLOCK, old_succ->head);
    else
      bb_note = emit_note_after (NOTE_INSN_BASIC_BLOCK, get_last_insn ());





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]