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]

PATCH to squeeze_notes


g++.law/cvt7.C was failing with -g -O2 due to block note nesting problems.
I eventually tracked this down to a problem with squeeze_notes being called
with a block note as the END parm, which it does not claim to handle.  This
was due to tidy_fallthru_edge removing some interesting insns at the end of
a block, leaving the block note exposed.  I tried fixing that and adding an
abort to enforce the rule about END not being a squeezable note, but that
broke dead_or_predicable, which tries to handle that situation itself.

It seems to me that the right answer is just to fix squeeze_notes to handle
END being a squeezable note, changing start and end to pass by reference.

At the same time, I've changed merge_blocks_move_predecessor_* to actually
update the start (and now end) pointers in the basic block info, not just
local copies; when we actually go to merge the blocks, we need those
pointers to be correct.  I assume it used to work by accident--it broke
with my initial patch.

Booted and tested i686-pc-linux-gnu.

2001-08-22  Jason Merrill  <jason_merrill@redhat.com>

	* jump.c (squeeze_notes): Take parms by reference.  Handle END being
	a squeezable note.
	* rtl.h: Adjust.
	* ifcvt.c (dead_or_predicable): Adjust.
	* loop.c (find_and_verify_loops): Adjust.
	* stmt.c (expand_end_case): Adjust.
	* flow.c (merge_blocks_move_successor_nojumps): Adjust.  Modify the
	head and end insn pointers in the basic block, not just local copies.
	(merge_blocks_move_predecessor_nojumps): Likewise.

*** flow.c.~1~	Thu Aug 16 14:27:19 2001
--- flow.c	Thu Aug 16 15:30:35 2001
*************** static int
*** 3069,3081 ****
  merge_blocks_move_predecessor_nojumps (a, b)
       basic_block a, b;
  {
!   rtx start, end, barrier;
    int index;
  
!   start = a->head;
!   end = a->end;
! 
!   barrier = next_nonnote_insn (end);
    if (GET_CODE (barrier) != BARRIER)
      abort ();
    flow_delete_insn (barrier);
--- 3069,3078 ----
  merge_blocks_move_predecessor_nojumps (a, b)
       basic_block a, b;
  {
!   rtx barrier;
    int index;
  
!   barrier = next_nonnote_insn (a->end);
    if (GET_CODE (barrier) != BARRIER)
      abort ();
    flow_delete_insn (barrier);
*************** merge_blocks_move_predecessor_nojumps (a
*** 3087,3097 ****
       and adjust the block trees appropriately.   Even better would be to have
       a tighter connection between block trees and rtl so that this is not
       necessary.  */
!   start = squeeze_notes (start, end);
  
    /* Scramble the insn chain.  */
!   if (end != PREV_INSN (b->head))
!     reorder_insns (start, end, PREV_INSN (b->head));
  
    if (rtl_dump_file)
      {
--- 3084,3094 ----
       and adjust the block trees appropriately.   Even better would be to have
       a tighter connection between block trees and rtl so that this is not
       necessary.  */
!   squeeze_notes (&a->head, &a->end);
  
    /* Scramble the insn chain.  */
!   if (a->end != PREV_INSN (b->head))
!     reorder_insns (a->head, a->end, PREV_INSN (b->head));
  
    if (rtl_dump_file)
      {
*************** static int
*** 3122,3132 ****
  merge_blocks_move_successor_nojumps (a, b)
       basic_block a, b;
  {
!   rtx start, end, barrier;
  
!   start = b->head;
!   end = b->end;
!   barrier = NEXT_INSN (end);
  
    /* Recognize a jump table following block B.  */
    if (barrier
--- 3119,3127 ----
  merge_blocks_move_successor_nojumps (a, b)
       basic_block a, b;
  {
!   rtx barrier;
  
!   barrier = NEXT_INSN (b->end);
  
    /* Recognize a jump table following block B.  */
    if (barrier
*************** merge_blocks_move_successor_nojumps (a, 
*** 3136,3143 ****
        && (GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_VEC
  	  || GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_DIFF_VEC))
      {
!       end = NEXT_INSN (barrier);
!       barrier = NEXT_INSN (end);
      }
  
    /* There had better have been a barrier there.  Delete it.  */
--- 3131,3138 ----
        && (GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_VEC
  	  || GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_DIFF_VEC))
      {
!       b->end = NEXT_INSN (barrier);
!       barrier = NEXT_INSN (b->end);
      }
  
    /* There had better have been a barrier there.  Delete it.  */
*************** merge_blocks_move_successor_nojumps (a, 
*** 3151,3160 ****
       and adjust the block trees appropriately.   Even better would be to have
       a tighter connection between block trees and rtl so that this is not
       necessary.  */
!   start = squeeze_notes (start, end);
  
    /* Scramble the insn chain.  */
!   reorder_insns (start, end, a->end);
  
    /* Now blocks A and B are contiguous.  Merge them.  */
    merge_blocks_nomove (a, b);
--- 3146,3155 ----
       and adjust the block trees appropriately.   Even better would be to have
       a tighter connection between block trees and rtl so that this is not
       necessary.  */
!   squeeze_notes (&b->head, &b->end);
  
    /* Scramble the insn chain.  */
!   reorder_insns (b->head, b->end, a->end);
  
    /* Now blocks A and B are contiguous.  Merge them.  */
    merge_blocks_nomove (a, b);
*** ifcvt.c.~1~	Thu Aug 16 14:27:19 2001
--- ifcvt.c	Thu Aug 16 15:26:17 2001
*************** dead_or_predicable (test_bb, merge_bb, o
*** 2664,2682 ****
        if (end == merge_bb->end)
  	merge_bb->end = PREV_INSN (head);
  
!       head = squeeze_notes (head, end);
!       if (GET_CODE (end) == NOTE
! 	  && (NOTE_LINE_NUMBER (end) == NOTE_INSN_BLOCK_END
!               || NOTE_LINE_NUMBER (end) == NOTE_INSN_BLOCK_BEG
!               || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_BEG
!               || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_END
!               || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_CONT
!               || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_VTOP))
! 	{
! 	  if (head == end)
! 	    return TRUE;
! 	  end = PREV_INSN (end);
! 	}
  
        reorder_insns (head, end, PREV_INSN (earliest));
      }
--- 2664,2670 ----
        if (end == merge_bb->end)
  	merge_bb->end = PREV_INSN (head);
  
!       squeeze_notes (&head, &end);
  
        reorder_insns (head, end, PREV_INSN (earliest));
      }
*** jump.c.~1~	Thu Aug 16 14:27:19 2001
--- jump.c	Thu Aug 16 16:58:54 2001
*************** duplicate_loop_exit_test (loop_start)
*** 539,557 ****
  }
  
  /* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, loop-end,
!    notes between START and END out before START.  Assume that END is not
!    such a note.  START may be such a note.  Returns the value of the new
!    starting insn, which may be different if the original start was such a
!    note.  */
! 
! rtx
! squeeze_notes (start, end)
!      rtx start, end;
  {
    rtx insn;
    rtx next;
  
!   for (insn = start; insn != end; insn = next)
      {
        next = NEXT_INSN (insn);
        if (GET_CODE (insn) == NOTE
--- 539,562 ----
  }
  
  /* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, loop-end,
!    notes between START and END out before START.  START and END may be such
!    notes.  Returns the values of the new starting and ending insns, which
!    may be different if the original ones were such notes.  */
! 
! void
! squeeze_notes (startp, endp)
!      rtx* startp;
!      rtx* endp;
  {
+   rtx start = *startp;
+   rtx end = *endp;
+ 
    rtx insn;
    rtx next;
+   rtx last = NULL;
+   rtx past_end = NEXT_INSN (end);
  
!   for (insn = start; insn != past_end; insn = next)
      {
        next = NEXT_INSN (insn);
        if (GET_CODE (insn) == NOTE
*************** squeeze_notes (start, end)
*** 575,583 ****
  	      PREV_INSN (next) = prev;
  	    }
  	}
      }
  
!   return start;
  }
  
  /* Return the label before INSN, or put a new label there.  */
--- 580,598 ----
  	      PREV_INSN (next) = prev;
  	    }
  	}
+       else
+ 	last = insn;
      }
  
!   /* There were no real instructions, and we can't represent an empty
!      range.  Die.  */
!   if (start == past_end)
!     abort ();
! 
!   end = last;
! 
!   *startp = start;
!   *endp = end;
  }
  
  /* Return the label before INSN, or put a new label there.  */
*** loop.c.~1~	Tue Aug 14 15:06:58 2001
--- loop.c	Thu Aug 16 15:37:53 2001
*************** find_and_verify_loops (f, loops)
*** 2750,2757 ****
  
  			/* Include the BARRIER after INSN and copy the
  			   block after LOC.  */
! 			new_label = squeeze_notes (new_label,
! 						   last_insn_to_move);
  			reorder_insns (new_label, last_insn_to_move, loc);
  
  			/* All those insns are now in TARGET_LOOP.  */
--- 2750,2756 ----
  
  			/* Include the BARRIER after INSN and copy the
  			   block after LOC.  */
! 			squeeze_notes (&new_label, &last_insn_to_move);
  			reorder_insns (new_label, last_insn_to_move, loc);
  
  			/* All those insns are now in TARGET_LOOP.  */
*** rtl.h.~1~	Thu Aug 16 14:27:19 2001
--- rtl.h	Thu Aug 16 14:59:15 2001
*************** extern void mark_jump_label		PARAMS ((rt
*** 1289,1295 ****
  extern void cleanup_barriers		PARAMS ((void));
  
  /* In jump.c */
! extern rtx squeeze_notes		PARAMS ((rtx, rtx));
  extern rtx delete_insn			PARAMS ((rtx));
  extern void delete_jump			PARAMS ((rtx));
  extern void delete_barrier		PARAMS ((rtx));
--- 1289,1295 ----
  extern void cleanup_barriers		PARAMS ((void));
  
  /* In jump.c */
! extern void squeeze_notes		PARAMS ((rtx *, rtx *));
  extern rtx delete_insn			PARAMS ((rtx));
  extern void delete_jump			PARAMS ((rtx));
  extern void delete_barrier		PARAMS ((rtx));
*** stmt.c.~1~	Tue Aug 14 15:07:00 2001
--- stmt.c	Thu Aug 16 15:40:48 2001
*************** expand_end_case (orig_index)
*** 5175,5181 ****
    int ncases;
    rtx *labelvec;
    register int i;
!   rtx before_case;
    register struct nesting *thiscase = case_stack;
    tree index_expr, index_type;
    int unsignedp;
--- 5175,5181 ----
    int ncases;
    rtx *labelvec;
    register int i;
!   rtx before_case, end;
    register struct nesting *thiscase = case_stack;
    tree index_expr, index_type;
    int unsignedp;
*************** expand_end_case (orig_index)
*** 5541,5548 ****
  #endif
  	}
  
!       before_case = squeeze_notes (NEXT_INSN (before_case), get_last_insn ());
!       reorder_insns (before_case, get_last_insn (),
  		     thiscase->data.case_stmt.start);
      }
    else
--- 5541,5550 ----
  #endif
  	}
  
!       before_case = NEXT_INSN (before_case);
!       end = get_last_insn ();
!       squeeze_notes (&before_case, &end);
!       reorder_insns (before_case, end,
  		     thiscase->data.case_stmt.start);
      }
    else

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