ARM libstdc++ failure fix

Jan Hubicka jh@suse.cz
Sun Jul 29 08:33:00 GMT 2001


Hi,
this patch solves crash while building libstdc++ on ARM.  The problem is
that parameter is set via multiple set insn, but the code in except.c
ignore everything except single_set.  Looks like good candidate for
branch too.

Just running testsuite on ARM, going to give it humorous bootstrap on i386
too, where the code is unused.

oops forgot prototype.

Honza

Sun Jul 29 17:30:35 CEST 2001  Jan Hubicka  <jh@suse.cz>
	* except.c (parms_set_data): New function.
	(parms_set): Break out from...
	(sjlj_mark_call_sites): ... here; use note_stores.
Index: except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.c,v
retrieving revision 1.175
diff -c -3 -p -r1.175 except.c
*** except.c	2001/07/25 19:59:39	1.175
--- except.c	2001/07/29 15:29:10
*************** sjlj_assign_call_site_values (dispatch_l
*** 2031,2036 ****
--- 2031,2057 ----
        }
  }
  
+ 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--;
+     }
+ }
+ 
  static void
  sjlj_mark_call_sites (lp_info)
       struct sjlj_lp_info *lp_info;
*************** sjlj_mark_call_sites (lp_info)
*** 2084,2097 ****
        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)
--- 2105,2117 ----
        before = insn;
        if (GET_CODE (insn) == CALL_INSN)
  	{
! 	  struct parms_set_data parm;
  	  
  	  /* 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 (insn); p ; p = XEXP (p, 1))
  	    if (GET_CODE (XEXP (p, 0)) == USE
  		&& GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
*************** sjlj_mark_call_sites (lp_info)
*** 2104,2115 ****
  		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);
  
--- 2124,2135 ----
  		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++;
  	      }
  
  	  /* Search backward for the first set of a register in this set.  */
! 	  while (parm.nregs)
  	    {
  	      before = PREV_INSN (before);
  
*************** sjlj_mark_call_sites (lp_info)
*** 2118,2131 ****
  	      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--;
! 		}
  	    }
  	}
  
--- 2138,2144 ----
  	      if (GET_CODE (before) == CODE_LABEL)
  		abort ();
  
! 	      note_stores (PATTERN (before), parms_set, &parm);
  	    }
  	}
  



More information about the Gcc-patches mailing list