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]

Re: [patches] Re: ARM libstdc++ failure fix


Hi,
here is the updated version.  I am starting the ppc testing.

It contains updated comment about the abort at code label hopefully
explaining about what is going on.

Sun Jul 29 22:27:06 CEST 2001  Jan Hubicka  <jh@suse.cz>

	* rtlanal.c (parms_set, find_first_parameter_load): Break out from...;
	handle multiple sets.
	* except.c (sjlj_mark_call_sites): .... here.
	* gcse.c (insert_insn_end_bb): Use find_first_parameter_load.

Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/except.c,v
retrieving revision 1.176
diff -c -3 -p -r1.176 except.c
*** except.c	2001/07/29 17:01:52	1.176
--- except.c	2001/07/29 20:25:32
*************** sjlj_mark_call_sites (lp_info)
*** 2083,2133 ****
        /* Don't separate a call from it's argument loads.  */
        before = insn;
        if (GET_CODE (insn) == CALL_INSN)
! 	{
! 	  HARD_REG_SET parm_regs;
! 	  int nparm_regs;
! 	  
! 	  /* Since different machines initialize their parameter registers
! 	     in different orders, assume nothing.  Collect the set of all
! 	     parameter registers.  */
! 	  CLEAR_HARD_REG_SET (parm_regs);
! 	  nparm_regs = 0;
! 	  for (p = CALL_INSN_FUNCTION_USAGE (insn); p ; p = XEXP (p, 1))
! 	    if (GET_CODE (XEXP (p, 0)) == USE
! 		&& GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
! 	      {
! 		if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER)
! 		  abort ();
! 
! 		/* We only care about registers which can hold function
! 		   arguments.  */
! 		if (! FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0))))
! 		  continue;
! 
! 		SET_HARD_REG_BIT (parm_regs, REGNO (XEXP (XEXP (p, 0), 0)));
! 		nparm_regs++;
! 	      }
! 
! 	  /* Search backward for the first set of a register in this set.  */
! 	  while (nparm_regs)
! 	    {
! 	      before = PREV_INSN (before);
! 
! 	      /* Given that we've done no other optimizations yet,
! 		 the arguments should be immediately available.  */
! 	      if (GET_CODE (before) == CODE_LABEL)
! 		abort ();
! 
! 	      p = single_set (before);
! 	      if (p && GET_CODE (SET_DEST (p)) == REG
! 		  && REGNO (SET_DEST (p)) < FIRST_PSEUDO_REGISTER
! 		  && TEST_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p))))
! 		{
! 		  CLEAR_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p)));
! 		  nparm_regs--;
! 		}
! 	    }
! 	}
  
        start_sequence ();
        emit_move_insn (mem, GEN_INT (this_call_site));
--- 2083,2089 ----
        /* Don't separate a call from it's argument loads.  */
        before = insn;
        if (GET_CODE (insn) == CALL_INSN)
!          before = find_first_parameter_load (insn, NULL_RTX);
  
        start_sequence ();
        emit_move_insn (mem, GEN_INT (this_call_site));
Index: gcse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gcse.c,v
retrieving revision 1.140
diff -c -3 -p -r1.140 gcse.c
*** gcse.c	2001/07/23 21:35:26	1.140
--- gcse.c	2001/07/29 20:25:33
*************** insert_insn_end_bb (expr, bb, pre)
*** 4649,4686 ****
        /* Since different machines initialize their parameter registers
  	 in different orders, assume nothing.  Collect the set of all
  	 parameter registers.  */
!       CLEAR_HARD_REG_SET (parm_regs);
!       nparm_regs = 0;
!       for (p = CALL_INSN_FUNCTION_USAGE (insn); p ; p = XEXP (p, 1))
! 	if (GET_CODE (XEXP (p, 0)) == USE
! 	    && GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
! 	  {
! 	    if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER)
! 	      abort ();
  
- 	    /* We only care about registers which can hold function
- 	       arguments.  */
- 	    if (! FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0))))
- 	      continue;
- 
- 	    SET_HARD_REG_BIT (parm_regs, REGNO (XEXP (XEXP (p, 0), 0)));
- 	    nparm_regs++;
- 	  }
- 
-       /* Search backward for the first set of a register in this set.  */
-       while (nparm_regs && bb->head != insn)
- 	{
- 	  insn = PREV_INSN (insn);
- 	  p = single_set (insn);
- 	  if (p && GET_CODE (SET_DEST (p)) == REG
- 	      && REGNO (SET_DEST (p)) < FIRST_PSEUDO_REGISTER
- 	      && TEST_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p))))
- 	    {
- 	      CLEAR_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p)));
- 	      nparm_regs--;
- 	    }
- 	}
-       
        /* If we found all the parameter loads, then we want to insert
  	 before the first parameter load.
  
--- 4649,4656 ----
        /* Since different machines initialize their parameter registers
  	 in different orders, assume nothing.  Collect the set of all
  	 parameter registers.  */
!       insn = find_first_parameter_load (insn, bb->head);
  
        /* If we found all the parameter loads, then we want to insert
  	 before the first parameter load.
  
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.281
diff -c -3 -p -r1.281 rtl.h
*** rtl.h	2001/07/29 19:44:42	1.281
--- rtl.h	2001/07/29 20:25:34
*************** extern int auto_inc_p			PARAMS ((rtx));
*** 1432,1437 ****
--- 1432,1438 ----
  extern void remove_node_from_expr_list	PARAMS ((rtx, rtx *));
  extern int insns_safe_to_move_p         PARAMS ((rtx, rtx, rtx *));
  extern int loc_mentioned_in_p		PARAMS ((rtx *, rtx));
+ extern rtx find_first_parameter_load	PARAMS ((rtx, rtx));
  
  /* flow.c */
  
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtlanal.c,v
retrieving revision 1.103
diff -c -3 -p -r1.103 rtlanal.c
*** rtlanal.c	2001/07/29 19:44:42	1.103
--- rtlanal.c	2001/07/29 20:25:35
*************** static void set_of_1		PARAMS ((rtx, rtx,
*** 31,36 ****
--- 31,37 ----
  static void insn_dependent_p_1	PARAMS ((rtx, rtx, void *));
  static int computed_jump_p_1	PARAMS ((rtx));
  static int operand_preference	PARAMS ((rtx));
+ static void parms_set 		PARAMS ((rtx, rtx, void *));
  
  /* Bit flags that specify the machine subtype we are compiling for.
     Bits are tested using macros TARGET_... defined in the tm.h file
*************** subreg_regno (x)
*** 2787,2790 ****
--- 2788,2864 ----
  				     GET_MODE (x));
    return ret;
  
+ }
+ struct parms_set_data
+ {
+   int nregs;
+   HARD_REG_SET regs;
+ };
+ 
+ /* Helper function for noticing stores to parameter registers.  */
+ static void
+ parms_set (x, pat, data)
+ 	rtx x, pat ATTRIBUTE_UNUSED;
+ 	void *data;
+ {
+   struct parms_set_data *d = data;
+   if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
+       && TEST_HARD_REG_BIT (d->regs, REGNO (x)))
+     {
+       CLEAR_HARD_REG_BIT (d->regs, REGNO (x));
+       d->nregs--;
+     }
+ }
+ 
+ /* Look backward for first parameter to be loaded.  
+    Do not skip BOUNDARY.  */
+ rtx
+ find_first_parameter_load (call_insn, boundary)
+      rtx call_insn, boundary;
+ {
+   struct parms_set_data parm;
+   rtx p, before;
+ 
+   /* Since different machines initialize their parameter registers
+      in different orders, assume nothing.  Collect the set of all
+      parameter registers.  */
+   CLEAR_HARD_REG_SET (parm.regs);
+   parm.nregs = 0;
+   for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1))
+     if (GET_CODE (XEXP (p, 0)) == USE
+ 	&& GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
+       {
+ 	if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER)
+ 	  abort ();
+ 
+ 	/* We only care about registers which can hold function
+ 	   arguments.  */
+ 	if (!FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0))))
+ 	  continue;
+ 
+ 	SET_HARD_REG_BIT (parm.regs, REGNO (XEXP (XEXP (p, 0), 0)));
+ 	parm.nregs++;
+       }
+   before = call_insn;
+ 
+   /* Search backward for the first set of a register in this set.  */
+   while (parm.nregs && before != boundary)
+     {
+       before = PREV_INSN (before);
+ 
+       /* It is possible that some loads got CSEed from one call to
+          another.  Stop in that case.  */
+       if (GET_CODE (before) == CALL_INSN)
+ 	break;
+ 
+       /* Our caller needs eighter ensure, that we will find all sets
+          (in case code has not been optimized yet), or take care
+          for possible labels in a way by setting boundary to preceeding
+          CODE_LABEL.  */
+       if (GET_CODE (before) == CODE_LABEL && before != boundary)
+ 	abort ();
+ 
+       note_stores (PATTERN (before), parms_set, &parm);
+     }
+   return before;
  }


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