This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH to squeeze_notes
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Subject: PATCH to squeeze_notes
- From: Jason Merrill <jason_merrill at redhat dot com>
- Date: 22 Aug 2001 15:51:29 +0100
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