This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: New cfg code
- To: Jeffrey A Law <law at cygnus dot com>
- Subject: Re: New cfg code
- From: Richard Henderson <rth at cygnus dot com>
- Date: Tue, 3 Aug 1999 02:30:59 -0700
- Cc: gcc at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- References: <31298.933567296@upchuck.cygnus.com>
On Sun, Aug 01, 1999 at 10:14:56PM -0600, Jeffrey A Law wrote:
> Which as far as I can tell has the effect of leaving the CODE_LABEL and
> ADDR_VEC in no-mans land (ie, not in any basic block).
That's correct. It isn't code that's executed -- it's data.
Therefore it doesn't belong in the CFG proper.
> One thought would be to try and have CSE kill the ADDR_VEC when it turns
> the tablejump into a simple jump.
>
> Another would be to have jump kill the unreachable ADDR_VEC.
>
> Another would be to not special case this stuff in find_basic_blocks_1 and
> instead either attach the insns to the previous block via merge_blocks or
> delete the block if we determine it is unreachable.
Nr 2 is my preferred short-term solution. Long term, of course,
we've got to get rid of ADDR_VEC as an instruction completely.
Probably by hanging a SEQUENCE containing the interesting label
and ADDR_VEC off of a reg note on the tablejump insn.
Nr 1 pollutes CSE with stuff it shouldn't be having to think about.
Nr 3 results in uglier CFGs.
Attached is a patch that allows the test to succeed. It's not as
friendly as it might be, as optimization phase sequencing leaves
the (code_label 80) around much longer than I would have liked.
It is gone before final though, so it's not the end of the world.
r~
* jump.c (delete_insn): Delete the addr_vec when deleting a tablejump.
Index: jump.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/jump.c,v
retrieving revision 1.62
diff -c -p -d -r1.62 jump.c
*** jump.c 1999/06/27 02:39:42 1.62
--- jump.c 1999/08/03 09:19:14
*************** delete_insn (insn)
*** 4017,4036 ****
and delete the label if it is now unused. */
if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
! if (--LABEL_NUSES (JUMP_LABEL (insn)) == 0)
! {
! /* This can delete NEXT or PREV,
! either directly if NEXT is JUMP_LABEL (INSN),
! or indirectly through more levels of jumps. */
! delete_insn (JUMP_LABEL (insn));
! /* I feel a little doubtful about this loop,
! but I see no clean and sure alternative way
! to find the first insn after INSN that is not now deleted.
! I hope this works. */
! while (next && INSN_DELETED_P (next))
! next = NEXT_INSN (next);
! return next;
! }
/* Likewise if we're deleting a dispatch table. */
--- 4017,4052 ----
and delete the label if it is now unused. */
if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
! {
! rtx lab = JUMP_LABEL (insn), lab_next;
!
! if (--LABEL_NUSES (lab) == 0)
! {
! /* This can delete NEXT or PREV,
! either directly if NEXT is JUMP_LABEL (INSN),
! or indirectly through more levels of jumps. */
! delete_insn (lab);
!
! /* I feel a little doubtful about this loop,
! but I see no clean and sure alternative way
! to find the first insn after INSN that is not now deleted.
! I hope this works. */
! while (next && INSN_DELETED_P (next))
! next = NEXT_INSN (next);
! return next;
! }
! else if ((lab_next = next_nonnote_insn (lab)) != NULL
! && GET_CODE (lab_next) == JUMP_INSN
! && (GET_CODE (PATTERN (lab_next)) == ADDR_VEC
! || GET_CODE (PATTERN (lab_next)) == ADDR_DIFF_VEC))
! {
! /* If we're deleting the tablejump, delete the dispatch table.
! We may not be able to kill the label immediately preceeding
! just yet, as it might be referenced in code leading up to
! the tablejump. */
! delete_insn (lab_next);
! }
! }
/* Likewise if we're deleting a dispatch table. */