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]
Other format: [Raw text]

Re: Crossjumping of tablejumps


Hi,

this patch fixes breakage on s390 because of the labels in constant
pool introduced by my patch for crossjumping of tablejumps.
I apologize for the breakage.
This patch replaces references to one constant pool label (LCx) by
references to the second constant pool label.

Bootstrapped/regtested s390 and x86-64.

It fixes the testcase (from fortran compiler) sent by Ulrich Weigand,
gcc.dg/20030213-1.c and many fortran testcases (because the
miscompilation of part of fortran compiler is fixed).

OK for mainline?

Josef

2003-03-13  Josef Zlomek  <zlomekj at suse dot cz>

	* cfgcleanup.c (try_crossjump_to_edge): If the labels are in constant
	pool replace one constant pool label (LCx) by another.
	* rtlanal.c (replace_label): Replace label also in INSN_LIST (in
	REG_LABEL note).
	(subrtx_p): Renamed to rtx_referenced_p.
	(subrtx_p_1): Renamed to rtx_referenced_p_1, compare the interior of
	LABEL_REF with CODE_LABEL, traverse constants from pool.
	* rtl.h (subrtx_p): Renamed to rtx_referenced_p.
	(get_constant_pool_symbol_ref): New extern function.
	* varasm.c (get_constant_pool_symbol_ref): New function.

Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgcleanup.c,v
retrieving revision 1.77
diff -c -3 -p -r1.77 cfgcleanup.c
*** cfgcleanup.c	10 Mar 2003 18:32:17 -0000	1.77
--- cfgcleanup.c	13 Mar 2003 12:39:26 -0000
*************** outgoing_edges_match (mode, bb1, bb2)
*** 1271,1280 ****
  	     the jump tables are same too. So disable crossjumping of blocks BB1
  	     and BB2 because when deleting the common insns in the end of BB1
  	     by flow_delete_block () the jump table would be deleted too.  */
! 	  /* If LABEL2 is contained in BB1->END do not do anything
  	     because we would loose information when replacing
  	     LABEL1 by LABEL2 and then LABEL2 by LABEL1 in BB1->END.  */
! 	  if (label1 != label2 && !subrtx_p (label2, bb1->end))
  	    {
  	      /* Set IDENTICAL to true when the tables are identical.  */
  	      bool identical = false;
--- 1271,1280 ----
  	     the jump tables are same too. So disable crossjumping of blocks BB1
  	     and BB2 because when deleting the common insns in the end of BB1
  	     by flow_delete_block () the jump table would be deleted too.  */
! 	  /* If LABEL2 is referenced in BB1->END do not do anything
  	     because we would loose information when replacing
  	     LABEL1 by LABEL2 and then LABEL2 by LABEL1 in BB1->END.  */
! 	  if (label1 != label2 && !rtx_referenced_p (label2, bb1->end))
  	    {
  	      /* Set IDENTICAL to true when the tables are identical.  */
  	      bool identical = false;
*************** try_crossjump_to_edge (mode, e1, e2)
*** 1461,1466 ****
--- 1461,1467 ----
  	{
  	  rtx_pair rr;
  	  rtx insn;
+ 	  rtx sym1, sym2;
  
  	  /* Replace references to LABEL1 with LABEL2.  */
  	  rr.r1 = label1;
*************** try_crossjump_to_edge (mode, e1, e2)
*** 1473,1478 ****
--- 1474,1491 ----
  	      if (insn != src1->end)
  		for_each_rtx (&insn, replace_label, &rr);
  	    }
+ 
+ 	  /* If the labels are in constant pool
+ 	     replace the SYMBOL_REF SYM1 by SYM2.  */
+ 	  sym1 = get_constant_pool_symbol_ref (label1);
+ 	  sym2 = get_constant_pool_symbol_ref (label2);
+ 	  if (sym1 && sym2)
+ 	    {
+ 	      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ 		replace_rtx (insn, sym1, copy_rtx (sym2));
+ 	    }
+ 	  else if (sym1 || sym2)
+ 	    abort ();
  	}
      }
  #endif
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.387
diff -c -3 -p -r1.387 rtl.h
*** rtl.h	10 Mar 2003 17:23:44 -0000	1.387
--- rtl.h	13 Mar 2003 12:39:26 -0000
*************** extern rtx mem_for_const_double		PARAMS 
*** 1445,1450 ****
--- 1445,1451 ----
  extern rtx force_const_mem		PARAMS ((enum machine_mode, rtx));
  
  /* In varasm.c  */
+ extern rtx get_constant_pool_symbol_ref	PARAMS ((rtx));
  extern rtx get_pool_constant		PARAMS ((rtx));
  extern rtx get_pool_constant_mark	PARAMS ((rtx, bool *));
  extern enum machine_mode get_pool_mode	PARAMS ((rtx));
*************** extern rtx replace_rtx			PARAMS ((rtx, r
*** 1662,1668 ****
  extern rtx replace_regs			PARAMS ((rtx, rtx *, unsigned int,
  						 int));
  extern int replace_label		PARAMS ((rtx *, void *));
! extern int subrtx_p			PARAMS ((rtx, rtx));
  extern bool tablejump_p			PARAMS ((rtx, rtx *, rtx *));
  extern int computed_jump_p		PARAMS ((rtx));
  typedef int (*rtx_function)             PARAMS ((rtx *, void *));
--- 1663,1669 ----
  extern rtx replace_regs			PARAMS ((rtx, rtx *, unsigned int,
  						 int));
  extern int replace_label		PARAMS ((rtx *, void *));
! extern int rtx_referenced_p		PARAMS ((rtx, rtx));
  extern bool tablejump_p			PARAMS ((rtx, rtx *, rtx *));
  extern int computed_jump_p		PARAMS ((rtx));
  typedef int (*rtx_function)             PARAMS ((rtx *, void *));
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtlanal.c,v
retrieving revision 1.148
diff -c -3 -p -r1.148 rtlanal.c
*** rtlanal.c	10 Mar 2003 17:23:44 -0000	1.148
--- rtlanal.c	13 Mar 2003 12:39:26 -0000
*************** Software Foundation, 59 Temple Place - S
*** 38,44 ****
  static int global_reg_mentioned_p_1 PARAMS ((rtx *, void *));
  static void set_of_1		PARAMS ((rtx, rtx, void *));
  static void insn_dependent_p_1	PARAMS ((rtx, rtx, void *));
! static int subrtx_p_1		PARAMS ((rtx *, void *));
  static int computed_jump_p_1	PARAMS ((rtx));
  static void parms_set 		PARAMS ((rtx, rtx, void *));
  static bool hoist_test_store		PARAMS ((rtx, rtx, regset));
--- 38,44 ----
  static int global_reg_mentioned_p_1 PARAMS ((rtx *, void *));
  static void set_of_1		PARAMS ((rtx, rtx, void *));
  static void insn_dependent_p_1	PARAMS ((rtx, rtx, void *));
! static int rtx_referenced_p_1	PARAMS ((rtx *, void *));
  static int computed_jump_p_1	PARAMS ((rtx));
  static void parms_set 		PARAMS ((rtx, rtx, void *));
  static bool hoist_test_store		PARAMS ((rtx, rtx, regset));
*************** replace_label (x, data)
*** 2813,2819 ****
    if (GET_CODE (l) == JUMP_INSN && JUMP_LABEL (l) == old_label)
      JUMP_LABEL (l) = new_label;
    
!   if (GET_CODE (l) != LABEL_REF)
      return 0;
  
    if (XEXP (l, 0) != old_label)
--- 2813,2820 ----
    if (GET_CODE (l) == JUMP_INSN && JUMP_LABEL (l) == old_label)
      JUMP_LABEL (l) = new_label;
    
!   if (GET_CODE (l) != LABEL_REF
!       && GET_CODE (l) != INSN_LIST)
      return 0;
  
    if (XEXP (l, 0) != old_label)
*************** replace_label (x, data)
*** 2826,2851 ****
    return 0;
  }
  
! /* Return RTX_EQUAL_P (*PX, SUBX).  If *PX and SUBX are not equal
!    FOR_EACH_RTX continues traversing, if they are equal FOR_EACH_RTX
!    stops traversing and returns the same value as this function.  */
  
  static int
! subrtx_p_1 (px, subx)
!      rtx *px;
!      void *subx;
  {
!   return rtx_equal_p (*px, (rtx) subx);
  }
  
! /* Return true if SUBX is equal to some subexpression of X.  */
  
  int
! subrtx_p (subx, x)
!      rtx subx;
       rtx x;
  {
!   return for_each_rtx (&x, subrtx_p_1, subx);
  }
  
  /* If INSN is a jump to jumptable insn rturn true and store the label (which
--- 2827,2867 ----
    return 0;
  }
  
! /* When *BODY is equal to X or X is directly referenced by *BODY
!    return nonzero, thus FOR_EACH_RTX stops traversing and returns nonzero
!    too, otherwise FOR_EACH_RTX continues traversing *BODY.  */
  
  static int
! rtx_referenced_p_1 (body, x)
!      rtx *body;
!      void *x;
  {
!   rtx y = (rtx) x;
! 
!   if (*body == NULL_RTX)
!     return y == NULL_RTX;
! 
!   /* Return true if a label_ref *BODY refers to label Y.  */
!   if (GET_CODE (*body) == LABEL_REF && GET_CODE (y) == CODE_LABEL)
!     return XEXP (*body, 0) == y;
! 
!   /* If *BODY is a reference to pool constant traverse the constant.  */
!   if (GET_CODE (*body) == SYMBOL_REF
!       && CONSTANT_POOL_ADDRESS_P (*body))
!     return rtx_referenced_p (y, get_pool_constant (*body));
! 
!   /* By default, compare the RTL expressions.  */
!   return rtx_equal_p (*body, y);
  }
  
! /* Return true if X is referenced in BODY.  */
  
  int
! rtx_referenced_p (x, body)
       rtx x;
+      rtx body;
  {
!   return for_each_rtx (&body, rtx_referenced_p_1, x);
  }
  
  /* If INSN is a jump to jumptable insn rturn true and store the label (which
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.333
diff -c -3 -p -r1.333 varasm.c
*** varasm.c	9 Mar 2003 20:41:30 -0000	1.333
--- varasm.c	13 Mar 2003 12:39:27 -0000
*************** find_pool_constant (f, addr)
*** 3265,3270 ****
--- 3265,3285 ----
    abort ();
  }
  
+ /* Given a CONSTANT, return the corresponding constant pool reference.  */
+ 
+ rtx
+ get_constant_pool_symbol_ref (constant)
+      rtx constant;
+ {
+   struct pool_constant *pool;
+ 
+   for (pool = cfun->varasm->x_first_pool; pool; pool = pool->next)
+     if (rtx_referenced_p (constant, pool->constant))
+       return XEXP (pool->desc->rtl, 0);
+ 
+   return NULL;
+ }
+ 
  /* Given a constant pool SYMBOL_REF, return the corresponding constant.  */
  
  rtx


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