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]

2.95: Fixes for problems caused by sjlj eh patches


The sjlj eh patches broke HPUX support with the native assembler.  The problem
is that references to code labels are put into the constant pool, but the code
labels can be optimized away, leaving undefined references.  To fix this, this
patch sets LABEL_PRESERVE_P when we put a label into the constant pool.

This, in turn, breaks AIX, where we have to put the labels at the head of
case vectors into the constant pool.  Lots of code suddenly fails to remove
unused case vectors.  This patch fixes these, and also moves
delete_barrier_successors, so that the JUMP_LABEL and LABEL_NUSES fields are
set up properly for the calls to delete_insn.

Verified with a bootstrap and testsuite run by David Edelsohn (thanks!)


Bernd

	* flow.c (propagate_block): When trying to delete a case vector, cope
	if its label has LABEL_PRESERVE_P set.
	* jump.c (jump_optimize_1): Move call to delete_barrier_successors to
	a point where JUMP_LABELS and LABEL_NUSES are set up properly.
	(delete_barrier_successors): If deleting a table jump, delete the case
	vector as well.
	* varasm.c (force_const_mem): If we have a label, set LABEL_PRESERVE_P
	so it won't get deleted.

Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.120.4.7
diff -u -p -r1.120.4.7 flow.c
--- flow.c	2001/01/25 14:03:08	1.120.4.7
+++ flow.c	2001/03/27 13:45:32
@@ -2744,15 +2744,23 @@ propagate_block (old, first, last, final
 		{
 		  if (REG_NOTE_KIND (inote) == REG_LABEL)
 		    {
+		      int n_forced;
 		      rtx label = XEXP (inote, 0);
 		      rtx next;
 		      LABEL_NUSES (label)--;

+		      /* The label may be forced if it has been put in the
+		         constant pool.  We can't delete it in this case, but
+		         we still must discard a jump table following it.  */
+		      n_forced = 0;
+		      if (LABEL_PRESERVE_P (label))
+			n_forced++;
+
 		      /* If this label was attached to an ADDR_VEC, it's
 			 safe to delete the ADDR_VEC.  In fact, it's pretty much
 			 mandatory to delete it, because the ADDR_VEC may
 			 be referencing labels that no longer exist.  */
-		      if (LABEL_NUSES (label) == 0
+		      if (LABEL_NUSES (label) == n_forced
 			  && (next = next_nonnote_insn (label)) != NULL
 			  && GET_CODE (next) == JUMP_INSN
 			  && (GET_CODE (PATTERN (next)) == ADDR_VEC
Index: jump.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/jump.c,v
retrieving revision 1.59.4.5
diff -u -p -r1.59.4.5 jump.c
--- jump.c	1999/10/21 06:24:03	1.59.4.5
+++ jump.c	2001/03/27 13:45:34
@@ -200,8 +200,6 @@ jump_optimize_1 (f, cross_jump, noop_mov
   if (flag_exceptions && cross_jump)
     init_insn_eh_region (f, max_uid);

-  delete_barrier_successors (f);
-
   /* Leave some extra room for labels and duplicate exit test insns
      we make.  */
   max_jump_chain = max_uid * 14 / 10;
@@ -224,6 +222,8 @@ jump_optimize_1 (f, cross_jump, noop_mov
   for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1))
     LABEL_NUSES (XEXP (insn, 0))++;

+  delete_barrier_successors (f);
+
   /* Quit now if we just wanted to rebuild the JUMP_LABEL and REG_LABEL
      notes and recompute LABEL_NUSES.  */
   if (mark_labels_only)
@@ -2139,7 +2139,23 @@ delete_barrier_successors (f)
 	  insn = NEXT_INSN (insn);
 	  while (insn != 0 && GET_CODE (insn) != CODE_LABEL)
 	    {
-	      if (GET_CODE (insn) == NOTE
+	      if (GET_CODE (insn) == JUMP_INSN)
+		{
+		  /* Detect when we're deleting a tablejump; get rid of
+		     the jump table as well.  */
+		  rtx next1 = next_nonnote_insn (insn);
+		  rtx next2 = next1 ? next_nonnote_insn (next1) : 0;
+		  if (next2 && GET_CODE (next1) == CODE_LABEL
+		      && (GET_CODE (PATTERN (next2)) == ADDR_VEC
+			  || GET_CODE (PATTERN (next2)) == ADDR_DIFF_VEC))
+		    {
+		      delete_insn (insn);
+		      insn = next2;
+		    }
+		  else
+		    insn = delete_insn (insn);
+		}
+	      else if (GET_CODE (insn) == NOTE
 		  && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)
 		insn = NEXT_INSN (insn);
 	      else
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.59.4.7
diff -u -p -r1.59.4.7 varasm.c
--- varasm.c	2001/02/19 14:02:02	1.59.4.7
+++ varasm.c	2001/03/27 13:45:36
@@ -3495,6 +3495,9 @@ force_const_mem (mode, x)
 	  pop_obstacks ();
 	}

+      if (GET_CODE (x) == LABEL_REF)
+	LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
+
       /* Allocate a pool constant descriptor, fill it in, and chain it in.  */

       pool = (struct pool_constant *) savealloc (sizeof (struct pool_constant));


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