This is the mail archive of the gcc@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]

Problem: delete_dead_jumptables and constant pool references


Hello,

I'm experiencing problems with the s390 port on mainline that
appear to be caused by frontend code.

The symptom is that dead jumptables are sometimes not deleted, 
which causes references to labels that have already been deleted
to stay in the code, causing subsequent link failures.

Now, I'm not very familiar with the flow.c code, but it appears
that the routine delete_dead_jumptables () should have deleted
those tables.  However, it doesn't on s390, because jump tables
are referenced from the constant pool and hence never have a 
LABEL_NUSES of zero.  (Even after the insn loading the label 
from the pool was deleted, the pool entry itself is never removed
until shortly before outputting the pool.)

However, in the routine propagate_block_delete_insn (), there
is similar code dealing with dead jumptables.  There, an explicit
check is made whether the table is referenced only from the 
constant pool.

I've simply added an equivalent check to delete_dead_jumptables (),
and now my test case compiles correctly.  (See patch below.)

Is this the correct approach to fix the problem?

Bye,
Ulrich



Index: gcc/flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.462
diff -c -p -r1.462 flow.c
*** flow.c	2001/08/10 16:19:07	1.462
--- flow.c	2001/08/13 21:28:05
*************** delete_dead_jumptables ()
*** 4675,4681 ****
      {
        next = NEXT_INSN (insn);
        if (GET_CODE (insn) == CODE_LABEL
! 	  && LABEL_NUSES (insn) == 0
  	  && GET_CODE (next) == JUMP_INSN
  	  && (GET_CODE (PATTERN (next)) == ADDR_VEC
  	      || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
--- 4675,4681 ----
      {
        next = NEXT_INSN (insn);
        if (GET_CODE (insn) == CODE_LABEL
! 	  && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
  	  && GET_CODE (next) == JUMP_INSN
  	  && (GET_CODE (PATTERN (next)) == ADDR_VEC
  	      || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
*************** delete_dead_jumptables ()
*** 4683,4689 ****
  	  if (rtl_dump_file)
  	    fprintf (rtl_dump_file, "Dead jumptable %i removed\n", INSN_UID (insn));
  	  flow_delete_insn (NEXT_INSN (insn));
! 	  flow_delete_insn (insn);
  	  next = NEXT_INSN (next);
  	}
      }
--- 4683,4695 ----
  	  if (rtl_dump_file)
  	    fprintf (rtl_dump_file, "Dead jumptable %i removed\n", INSN_UID (insn));
  	  flow_delete_insn (NEXT_INSN (insn));
! 
! 	  /* The label may be forced if it has been put in the constant
! 	     pool.  If that is the only use we must discard the table
! 	     jump following it, but not the label itself.  */
! 	  if (!LABEL_PRESERVE_P (insn))
! 	    flow_delete_insn (insn);
! 
  	  next = NEXT_INSN (next);
  	}
      }
-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


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