public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: mdbench for g77 & f2c+gcc
@ 1997-08-21 16:02 Furio Ercolessi
  1997-08-21 16:10 ` Reload patch version 2 Bernd Schmidt
  1997-08-21 16:10 ` gcc installation Jeffrey A Law
  0 siblings, 2 replies; 23+ messages in thread
From: Furio Ercolessi @ 1997-08-21 16:02 UTC (permalink / raw)
  To: egcs

> Hi, All

Hi (what a large party!)

> i've benchmarked g77 and f2c+gcc
> using mdbench on Ultrasparc II / 200Mhz
> and Pentium/133Mhz/256k cache.

Thanks for the data, I am putting then online right now

> g77 and gcc were build from egcs-ss-970814.tar.gz sources

Do you have the g77 and gcc release numbers at hand?

> g77 -O6 -funroll-all-loops -fomit-frame-pointer -ffast-math
> -fstrength-reduce -fthread-jumps -mcpu=ultrasparc -mtune=ultrasparc
> mdbnch.f
> 
> 17.56 sec
> 
> not bad, huh!!! official data are
> 
> Sun Ultra 2 (200Mhz), Solaris 2.5.1, SC4.0 FORTRAN [^] ........ 15.7 s+
> 24Apr96

Well, now your data are also official ...
However, I now discovered that I erroneously reported
Sun Ultra 2 (300MHz), Solaris 2.6, f77 SC4.2 [o] .............. 14.6 s+ 16Jul97
where the MHz where incorrectly typed, this was in fact
Sun Ultra 2 (200MHz), Solaris 2.6, f77 SC4.2 [o] .............. 14.6 s+ 16Jul97
which is therefore the best time for this machine.

> my own result with sun f77 4.2 is 16.5 sec

The above time was obtained using
-fast -xO5 -xtarget=native -xarch=v8plus -stackvar -xdepend

> 2. Intel P133/60ns EDO 32M/256K cache, Triton2 HX board 
>    with agressive BIOS settings, Debian/hamm Linux
>    with glibc 2

Also for this case I would appreciate knowing the release numbers
of g77 and gcc.

Thank you very much again

furio ercolessi
SISSA
Trieste, Italy

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: gcc installation
  1997-08-21 16:02 mdbench for g77 & f2c+gcc Furio Ercolessi
  1997-08-21 16:10 ` Reload patch version 2 Bernd Schmidt
@ 1997-08-21 16:10 ` Jeffrey A Law
  1 sibling, 0 replies; 23+ messages in thread
From: Jeffrey A Law @ 1997-08-21 16:10 UTC (permalink / raw)
  To: egcs

  In message <Pine.ULT.3.95.970821091447.4653A-100000@irz301.inf.tu-dresden.de>
you write:
  > I've installed it on another machine now, and the problem with specs has
  > been going away. However, g++ hsn't been installed again. It also
  > wasn't built in the make directory. But explicitly typing 'make g++'
  > goes well ... When I've installed Cygnus's latest release from April this
  > wouldn't happen. So I don't know whats wrong there.
OK.  I'll look into it further.

jeff

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Reload patch version 2
  1997-08-21 16:02 mdbench for g77 & f2c+gcc Furio Ercolessi
@ 1997-08-21 16:10 ` Bernd Schmidt
  1997-08-21 16:10 ` gcc installation Jeffrey A Law
  1 sibling, 0 replies; 23+ messages in thread
From: Bernd Schmidt @ 1997-08-21 16:10 UTC (permalink / raw)
  To: egcs

Here's an updated version of my reload patch.

Changes:
  - moved the spilling code out of reload, and made it consider each insn
    separately.  The code which I introduced in my last patch to walk the
    spill_regs array and select a subset of the spill registers for some
    instructions is gone.
    I think this approach is somewhat cleaner than what the previous patch
    did.
  - got rid of the avoid_return_reg and reload_address_base_reg_class kludges.
    These are ugly and can cause bad code, and the problems can be solved in
    a general way by using register life information in reload.  That should
    also make it possible to use regs which are explicitly mentioned in the
    rtl for spilling on all machines.
    To be able to do this, I moved the code that builds reload_insn_chain
    and the life information to global.c, and added new code in stupid.c to
    do the same in non-optimizing compilation.
  - fixed a couple of silly bugs.

Problems:
  - the two potential code quality problems mentioned in my first mail
    concerning caller-saves which need a spill reg and the code in reorg.c
    which assumes reload regs are dead at a CODE_LABEL still exist.
  - reload isn't exactly fast, but then I didn't spend any time optimizing
    things yet.
  - there are still some cases where the code might spill too many registers.
    Also, the cost calculations for the damage of spilling pseudo regs isn't
    very accurate.
  - Some software, notably the Linux kernel on the i386, contains bogus asm
    statements that need a register from a single class for an input reload,
    but also contain a CLOBBER of that register.  According to a comment in
    reload.c, a CLOBBER makes a register unavailable from before the insn
    until after it, so the asm statements are wrong, and unfortunately the new
    code detects that.  The correct way to write them would be to add an
    output reload that matches the input register and reload it into a dummy
    register.  But sometimes this is hard to do, because the number of
    constraints for an asm statement is restricted by MAX_RECOG_OPERANDS.
    I've added an ugly ugly ugly hack to new_spill_reg to make the most common
    form of the problem work, but I'm not happy with it.  How about using a
    fixed value for MAX_RECOG_OPERANDS (maybe twice the number of registers
    the machine has) so that asm statements can be written correctly?

Ideas/Todo:
  - better error messages: if a fixed/forbidden reg is spilled for an asm,
    give line and source file and don't call fatal.
  - maybe the register life information could be used to generate correct
    REG_DEAD notes.
  - For every spilled pseudo, check the reloaded insns across which it is live
    and if
    * the register is not actually used in any of them
    * there's always a free unused hard reg which the pseudo could cheaply be
      moved into and out of.
    * the total cost of generating these moves is lower than the cost of
      spilling the pseudo
    then generate the appropriate move instructions instead of spilling the
    pseudo.
  - Could extend the above to allocate a stack slot for the pseudo, but keep
    it in a register wherever possible.  This would get kind of hairy, though.
  - Also rather hairy: if a pseudo dies in an instruction, its hard reg could
    still be used for an output reload. Likewise, if it is set in the insn
    and dead before, its hard reg may be used for an input reload.
  - It might be worth a try to make find_reloads reduce the amount of spill
    regs necessary.
    Example:
    (set (reg:SI 1) (mem:SI (plus:SI (reg:SI 2) (reg:SI 3))))
    where reg1 is a hard reg and regs 2 and 3 are pseudos which did not get
    a hard reg.  On the i386, and probably on many other machines, it is
    possible to reload this instruction with just one register:
    movl stack_slot_for_reg2,eax
    addl stack_slot_for_reg3,eax
    movl (eax),reg1
    instead of what reload would currently do:
    movl stack_slot_for_reg2,eax
    movl stack_slot_for_reg3,edx
    movl (eax,edx),reg1
    That could possibly avoid some spills.

I've tested this patch by bootstrapping the C compiler, using the a compiler
that already contained this patch to compile stage1 to make sure that the
code in stupid.c also gets tested.

It would be nice if someone could look over the patch and tell me what I
should change, and how the problems I mentioned should be addressed, so that
this has a chance of being accepted (apart from sending in a copyright
assignment which I'm going to do).
It would also be nice if people would try this, especially on non-x86 machines,
and report bugs.

The patch is against egcs-ss-970814.  I didn't include a detailed ChangeLog,
since this isn't likely to be the final version anyway.

diff -dcrp egcs-ss-970814/Makefile.in egcs-new/Makefile.in
*** egcs-ss-970814/Makefile.in	Fri Aug 15 20:55:20 1997
--- egcs-new/Makefile.in	Thu Aug 21 13:52:10 1997
*************** integrate.o : integrate.c $(CONFIG_H) $(
*** 1293,1299 ****
  
  jump.o : jump.c $(CONFIG_H) $(RTL_H) flags.h hard-reg-set.h regs.h \
     insn-config.h insn-flags.h insn-codes.h expr.h real.h
! stupid.o : stupid.c $(CONFIG_H) $(RTL_H) regs.h hard-reg-set.h flags.h
  
  cse.o : cse.c $(CONFIG_H) $(RTL_H) regs.h hard-reg-set.h flags.h real.h \
     insn-config.h recog.h
--- 1293,1300 ----
  
  jump.o : jump.c $(CONFIG_H) $(RTL_H) flags.h hard-reg-set.h regs.h \
     insn-config.h insn-flags.h insn-codes.h expr.h real.h
! stupid.o : stupid.c $(CONFIG_H) $(RTL_H) regs.h hard-reg-set.h reload.h \
!    flags.h
  
  cse.o : cse.c $(CONFIG_H) $(RTL_H) regs.h hard-reg-set.h flags.h real.h \
     insn-config.h recog.h
*************** regclass.o : regclass.c $(CONFIG_H) $(RT
*** 1313,1319 ****
  local-alloc.o : local-alloc.c $(CONFIG_H) $(RTL_H) flags.h $(BASIC_BLOCK_H) \
     regs.h hard-reg-set.h insn-config.h recog.h output.h
  bitmap.o : bitmap.c $(CONFIG_H) $(RTL_H) flags.h $(BASIC_BLOCK_H) regs.h
! global.o : global.c $(CONFIG_H) $(RTL_H) flags.h  \
     $(BASIC_BLOCK_H) regs.h hard-reg-set.h insn-config.h output.h
  
  reload.o : reload.c $(CONFIG_H) $(RTL_H) flags.h output.h expr.h\
--- 1314,1320 ----
  local-alloc.o : local-alloc.c $(CONFIG_H) $(RTL_H) flags.h $(BASIC_BLOCK_H) \
     regs.h hard-reg-set.h insn-config.h recog.h output.h
  bitmap.o : bitmap.c $(CONFIG_H) $(RTL_H) flags.h $(BASIC_BLOCK_H) regs.h
! global.o : global.c $(CONFIG_H) $(RTL_H) flags.h reload.h \
     $(BASIC_BLOCK_H) regs.h hard-reg-set.h insn-config.h output.h
  
  reload.o : reload.c $(CONFIG_H) $(RTL_H) flags.h output.h expr.h\
diff -dcrp egcs-ss-970814/caller-save.c egcs-new/caller-save.c
*** egcs-ss-970814/caller-save.c	Fri Aug 15 20:55:33 1997
--- egcs-new/caller-save.c	Tue Aug 19 14:50:54 1997
*************** int n_regs_saved;
*** 80,88 ****
  
  static void set_reg_live		PROTO((rtx, rtx));
  static void clear_reg_live		PROTO((rtx));
! static void restore_referenced_regs	PROTO((rtx, rtx, enum machine_mode));
! static int insert_save_restore		PROTO((rtx, int, int,
! 					       enum machine_mode, int));
  \f
  /* Initialize for caller-save.
  
--- 80,89 ----
  
  static void set_reg_live		PROTO((rtx, rtx));
  static void clear_reg_live		PROTO((rtx));
! static void restore_referenced_regs	PROTO((rtx, struct insn_chain *,
! 					       int));
! static int insert_save_restore		PROTO((struct insn_chain *, int, int,
! 					       int, int));
  \f
  /* Initialize for caller-save.
  
*************** setup_save_areas (pchanged)
*** 342,499 ****
  \f
  /* Find the places where hard regs are live across calls and save them.
  
!    INSN_MODE is the mode to assign to any insns that we add.  This is used
     by reload to determine whether or not reloads or register eliminations
     need be done on these insns.  */
  
  void
! save_call_clobbered_regs (insn_mode)
!      enum machine_mode insn_mode;
  {
!   rtx insn;
    int b;
  
!   for (b = 0; b < n_basic_blocks; b++)
!     {
!       regset regs_live = basic_block_live_at_start[b];
!       rtx prev_block_last = PREV_INSN (basic_block_head[b]);
        int i, j;
        int regno;
  
!       /* Compute hard regs live at start of block -- this is the
! 	 real hard regs marked live, plus live pseudo regs that
! 	 have been renumbered to hard regs.  No registers have yet been
! 	 saved because we restore all of them before the end of the basic
! 	 block.  */
! 
!       REG_SET_TO_HARD_REG_SET (hard_regs_live, regs_live);
!       CLEAR_HARD_REG_SET (hard_regs_saved);
!       CLEAR_HARD_REG_SET (hard_regs_need_restore);
!       n_regs_saved = 0;
! 
!       EXECUTE_IF_SET_IN_REG_SET (regs_live, 0, i,
! 				 {
! 				   if ((regno = reg_renumber[i]) >= 0)
! 				     for (j = regno;
! 					  j < regno + HARD_REGNO_NREGS (regno,
! 									PSEUDO_REGNO_MODE (i));
! 					  j++)
! 				       SET_HARD_REG_BIT (hard_regs_live, j);
! 				 });
  
!       /* Now scan the insns in the block, keeping track of what hard
! 	 regs are live as we go.  When we see a call, save the live
! 	 call-clobbered hard regs.  */
  
!       for (insn = basic_block_head[b]; ; insn = NEXT_INSN (insn))
  	{
! 	  RTX_CODE code = GET_CODE (insn);
  
! 	  if (GET_RTX_CLASS (code) == 'i')
! 	    {
! 	      rtx link;
  
! 	      /* If some registers have been saved, see if INSN references
! 		 any of them.  We must restore them before the insn if so.  */
  
! 	      if (n_regs_saved)
! 		restore_referenced_regs (PATTERN (insn), insn, insn_mode);
  
! 	      /* NB: the normal procedure is to first enliven any
! 		 registers set by insn, then deaden any registers that
! 		 had their last use at insn.  This is incorrect now,
! 		 since multiple pseudos may have been mapped to the
! 		 same hard reg, and the death notes are ambiguous.  So
! 		 it must be done in the other, safe, order.  */
  
! 	      for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
! 		if (REG_NOTE_KIND (link) == REG_DEAD)
! 		  clear_reg_live (XEXP (link, 0));
  
! 	      /* When we reach a call, we need to save all registers that are
! 		 live, call-used, not fixed, and not already saved.  We must
! 		 test at this point because registers that die in a CALL_INSN
! 		 are not live across the call and likewise for registers that
! 		 are born in the CALL_INSN.
! 		 
! 		 If registers are filled with parameters for this function,
! 		 and some of these are also being set by this function, then
! 		 they will not appear to die (no REG_DEAD note for them),
! 		 to check if in fact they do, collect the set registers in
! 		 hard_regs_live first.  */
  
! 	      if (code == CALL_INSN)
! 		{
! 		  HARD_REG_SET this_call_sets;
! 		  {
! 		    HARD_REG_SET old_hard_regs_live;
  
! 		    /* Save the hard_regs_live information.  */
! 		    COPY_HARD_REG_SET (old_hard_regs_live, hard_regs_live);
  
! 		    /* Now calculate hard_regs_live for this CALL_INSN
! 		       only.  */
! 		    CLEAR_HARD_REG_SET (hard_regs_live);
! 		    note_stores (PATTERN (insn), set_reg_live);
! 		    COPY_HARD_REG_SET (this_call_sets, hard_regs_live);
  
! 		    /* Restore the hard_regs_live information.  */
! 		    COPY_HARD_REG_SET (hard_regs_live, old_hard_regs_live);
! 		  }
  
! 		  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
! 		    if (call_used_regs[regno] && ! call_fixed_regs[regno]
! 		        && TEST_HARD_REG_BIT (hard_regs_live, regno)
! 			/* It must not be set by this instruction.  */
! 		        && ! TEST_HARD_REG_BIT (this_call_sets, regno)
! 		        && ! TEST_HARD_REG_BIT (hard_regs_saved, regno))
! 		      regno += insert_save_restore (insn, 1, regno, 
! 						    insn_mode, 0);
  
! 		  /* Put the information for this CALL_INSN on top of what
! 		     we already had.  */
! 		  IOR_HARD_REG_SET (hard_regs_live, this_call_sets);
! 		  COPY_HARD_REG_SET (hard_regs_need_restore, hard_regs_saved);
  
! 		  /* Must recompute n_regs_saved.  */
! 		  n_regs_saved = 0;
! 		  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
! 		    if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
! 		      n_regs_saved++;
! 		}
! 	      else
! 		{
! 		  note_stores (PATTERN (insn), set_reg_live);
  #ifdef AUTO_INC_DEC
- 		  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
- 		    if (REG_NOTE_KIND (link) == REG_INC)
- 		      set_reg_live (XEXP (link, 0), NULL_RTX);
- #endif
- 		}
- 
  	      for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
! 		if (REG_NOTE_KIND (link) == REG_UNUSED)
! 		  clear_reg_live (XEXP (link, 0));
  	    }
! 
! 	  if (insn == basic_block_end[b])
! 	    break;
  	}
  
!       /* At the end of the basic block, we must restore any registers that
! 	 remain saved.  If the last insn in the block is a JUMP_INSN, put
! 	 the restore before the insn, otherwise, put it after the insn.  */
  
!       if (n_regs_saved)
! 	for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
! 	  if (TEST_HARD_REG_BIT (hard_regs_need_restore, regno))
! 	    regno += insert_save_restore ((GET_CODE (insn) == JUMP_INSN
! 				  ? insn : NEXT_INSN (insn)), 0,
! 				  regno, insn_mode, MOVE_MAX / UNITS_PER_WORD);
  
!       /* If we added any insns at the start of the block, update the start
! 	 of the block to point at those insns.  */
!       basic_block_head[b] = NEXT_INSN (prev_block_last);
      }
  }
  
--- 343,494 ----
  \f
  /* Find the places where hard regs are live across calls and save them.
  
!    NEED_ELIM is the mode to assign to any insns that we add.  This is used
     by reload to determine whether or not reloads or register eliminations
     need be done on these insns.  */
  
  void
! save_call_clobbered_regs (need_elim)
!      int need_elim;
  {
!   rtx prev_block_last;
!   struct insn_chain *chain;
    int b;
  
!   /* Now scan the insns in each block, keeping track of what hard
!      regs are live as we go.  When we see a call, save the live
!      call-clobbered hard regs.  */
! 
!   b = -1;
!   for (chain = reload_insn_chain; chain; chain = chain->next)
!     {      
        int i, j;
        int regno;
+       rtx insn = chain->insn;
+       enum rtx_code code = GET_CODE (insn);
+       
+       if (chain->block > b)
+ 	{
+ 	  b = chain->block;
+ 	  prev_block_last = PREV_INSN (basic_block_head[b]);
  
! 	  /* Compute hard regs live at start of block.  This information is
! 	     available in the insn chain.  */
  
! 	  CLEAR_HARD_REG_SET (hard_regs_live);
! 	  CLEAR_HARD_REG_SET (hard_regs_saved);
! 	  CLEAR_HARD_REG_SET (hard_regs_need_restore);
! 	  n_regs_saved = 0;
! 	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 	    if (chain->inverse_renum_before[i] != 0)
! 	      SET_HARD_REG_BIT (hard_regs_live, i);
! 	}
  
!       if (GET_RTX_CLASS (code) == 'i')
  	{
! 	  rtx link;
  
! 	  /* If some registers have been saved, see if INSN references
! 	     any of them.  We must restore them before the insn if so.  */
  
! 	  if (n_regs_saved)
! 	    restore_referenced_regs (PATTERN (insn), chain, need_elim);
  
! 	  /* NB: the normal procedure is to first enliven any
! 	     registers set by insn, then deaden any registers that
! 	     had their last use at insn.  This is incorrect now,
! 	     since multiple pseudos may have been mapped to the
! 	     same hard reg, and the death notes are ambiguous.  So
! 	     it must be done in the other, safe, order.  */
  
! 	  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
! 	    if (REG_NOTE_KIND (link) == REG_DEAD)
! 	      clear_reg_live (XEXP (link, 0));
  
! 	  /* When we reach a call, we need to save all registers that are
! 	     live, call-used, not fixed, and not already saved.  We must
! 	     test at this point because registers that die in a CALL_INSN
! 	     are not live across the call and likewise for registers that
! 	     are born in the CALL_INSN.
  
! 	     If registers are filled with parameters for this function,
! 	     and some of these are also being set by this function, then
! 	     they will not appear to die (no REG_DEAD note for them),
! 	     to check if in fact they do, collect the set registers in
! 	     hard_regs_live first.  */
  
! 	  if (code == CALL_INSN)
! 	    {
! 	      HARD_REG_SET this_call_sets;
! 	      {
! 		HARD_REG_SET old_hard_regs_live;
  
! 		/* Save the hard_regs_live information.  */
! 		COPY_HARD_REG_SET (old_hard_regs_live, hard_regs_live);
  
! 		/* Now calculate hard_regs_live for this CALL_INSN
! 		   only.  */
! 		CLEAR_HARD_REG_SET (hard_regs_live);
! 		note_stores (PATTERN (insn), set_reg_live);
! 		COPY_HARD_REG_SET (this_call_sets, hard_regs_live);
  
! 		/* Restore the hard_regs_live information.  */
! 		COPY_HARD_REG_SET (hard_regs_live, old_hard_regs_live);
! 	      }
  
! 	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
! 		if (call_used_regs[regno] && ! call_fixed_regs[regno]
! 		    && TEST_HARD_REG_BIT (hard_regs_live, regno)
! 		    /* It must not be set by this instruction.  */
! 		    && ! TEST_HARD_REG_BIT (this_call_sets, regno)
! 		    && ! TEST_HARD_REG_BIT (hard_regs_saved, regno))
! 		  regno += insert_save_restore (chain, 1, regno, 
! 						need_elim, 0);
  
! 	      /* Put the information for this CALL_INSN on top of what
! 		 we already had.  */
! 	      IOR_HARD_REG_SET (hard_regs_live, this_call_sets);
! 	      COPY_HARD_REG_SET (hard_regs_need_restore, hard_regs_saved);
  
! 	      /* Must recompute n_regs_saved.  */
! 	      n_regs_saved = 0;
! 	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
! 		if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
! 		  n_regs_saved++;
! 	    }
! 	  else
! 	    {
! 	      note_stores (PATTERN (insn), set_reg_live);
  #ifdef AUTO_INC_DEC
  	      for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
! 		if (REG_NOTE_KIND (link) == REG_INC)
! 		  set_reg_live (XEXP (link, 0), NULL_RTX);
! #endif
  	    }
! 	  
! 	  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
! 	    if (REG_NOTE_KIND (link) == REG_UNUSED)
! 	      clear_reg_live (XEXP (link, 0));
  	}
  
!       if (chain->next == 0 || chain->next->block > b)
! 	{
! 	  /* At the end of the basic block, we must restore any registers that
! 	     remain saved.  If the last insn in the block is a JUMP_INSN, put
! 	     the restore before the insn, otherwise, put it after the insn.  */
  
! 	  if (n_regs_saved)
! 	    for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
! 	      if (TEST_HARD_REG_BIT (hard_regs_need_restore, regno))
! 		regno += insert_save_restore ((GET_CODE (insn) == JUMP_INSN
! 					       ? chain : chain->next), 0,
! 					      regno, need_elim,
! 					      MOVE_MAX / UNITS_PER_WORD);
  
! 	  /* If we added any insns at the start of the block, update the start
! 	     of the block to point at those insns.  */
! 	  basic_block_head[b] = NEXT_INSN (prev_block_last);
! 	}
      }
  }
  
*************** clear_reg_live (reg)
*** 556,568 ****
  \f
  /* If any register currently residing in the save area is referenced in X,
     which is part of INSN, emit code to restore the register in front of INSN.
!    INSN_MODE is the mode to assign to any insns that we add.  */
  
  static void
! restore_referenced_regs (x, insn, insn_mode)
       rtx x;
!      rtx insn;
!      enum machine_mode insn_mode;
  {
    enum rtx_code code = GET_CODE (x);
    char *fmt;
--- 551,563 ----
  \f
  /* If any register currently residing in the save area is referenced in X,
     which is part of INSN, emit code to restore the register in front of INSN.
!    NEED_ELIM is the mode to assign to any insns that we add.  */
  
  static void
! restore_referenced_regs (x, chain, need_elim)
       rtx x;
!      struct insn_chain *chain;
!      int need_elim;
  {
    enum rtx_code code = GET_CODE (x);
    char *fmt;
*************** restore_referenced_regs (x, insn, insn_m
*** 581,591 ****
        if (regno >= FIRST_PSEUDO_REGISTER
  	  && reg_equiv_mem[regno] != 0)
  	restore_referenced_regs (XEXP (reg_equiv_mem[regno], 0),
! 				 insn, insn_mode);
        else if (regno >= FIRST_PSEUDO_REGISTER
  	       && reg_equiv_address[regno] != 0)
  	restore_referenced_regs (reg_equiv_address[regno],
! 				 insn, insn_mode);
  
        /* Otherwise if this is a hard register, restore any piece of it that
  	 is currently saved.  */
--- 576,586 ----
        if (regno >= FIRST_PSEUDO_REGISTER
  	  && reg_equiv_mem[regno] != 0)
  	restore_referenced_regs (XEXP (reg_equiv_mem[regno], 0),
! 				 chain, need_elim);
        else if (regno >= FIRST_PSEUDO_REGISTER
  	       && reg_equiv_address[regno] != 0)
  	restore_referenced_regs (reg_equiv_address[regno],
! 				 chain, need_elim);
  
        /* Otherwise if this is a hard register, restore any piece of it that
  	 is currently saved.  */
*************** restore_referenced_regs (x, insn, insn_m
*** 600,606 ****
  
  	  for (i = regno; i < endregno; i++)
  	    if (TEST_HARD_REG_BIT (hard_regs_need_restore, i))
! 	      i += insert_save_restore (insn, 0, i, insn_mode, saveregs);
  	}
  
        return;
--- 595,601 ----
  
  	  for (i = regno; i < endregno; i++)
  	    if (TEST_HARD_REG_BIT (hard_regs_need_restore, i))
! 	      i += insert_save_restore (chain, 0, i, need_elim, saveregs);
  	}
  
        return;
*************** restore_referenced_regs (x, insn, insn_m
*** 610,624 ****
    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
        if (fmt[i] == 'e')
! 	restore_referenced_regs (XEXP (x, i), insn, insn_mode);
        else if (fmt[i] == 'E')
  	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
! 	  restore_referenced_regs (XVECEXP (x, i, j), insn, insn_mode);
      }
  }
  \f
  /* Insert a sequence of insns to save or restore, SAVE_P says which,
!    REGNO.  Place these insns in front of INSN.  INSN_MODE is the mode
     to assign to these insns.   MAXRESTORE is the maximum number of registers
     which should be restored during this call (when SAVE_P == 0).  It should
     never be less than 1 since we only work with entire registers.
--- 605,619 ----
    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
        if (fmt[i] == 'e')
! 	restore_referenced_regs (XEXP (x, i), chain, need_elim);
        else if (fmt[i] == 'E')
  	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
! 	  restore_referenced_regs (XVECEXP (x, i, j), chain, need_elim);
      }
  }
  \f
  /* Insert a sequence of insns to save or restore, SAVE_P says which,
!    REGNO.  Place these insns in front of INSN.  NEED_ELIM is the mode
     to assign to these insns.   MAXRESTORE is the maximum number of registers
     which should be restored during this call (when SAVE_P == 0).  It should
     never be less than 1 since we only work with entire registers.
*************** restore_referenced_regs (x, insn, insn_m
*** 632,645 ****
     Return the extra number of registers saved.  */
  
  static int
! insert_save_restore (insn, save_p, regno, insn_mode, maxrestore)
!      rtx insn;
       int save_p;
       int regno;
!      enum machine_mode insn_mode;
       int maxrestore;
  {
    rtx pat;
    enum insn_code code;
    int i, numregs;
  
--- 627,642 ----
     Return the extra number of registers saved.  */
  
  static int
! insert_save_restore (chain, save_p, regno, need_elim, maxrestore)
!      struct insn_chain *chain;
       int save_p;
       int regno;
!      int need_elim;
       int maxrestore;
  {
+   struct insn_chain *new;
    rtx pat;
+   rtx insn = chain->insn;
    enum insn_code code;
    int i, numregs;
  
*************** insert_save_restore (insn, save_p, regno
*** 662,668 ****
  
    if ((GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
        && reg_referenced_p (cc0_rtx, PATTERN (insn)))
!     insn = prev_nonnote_insn (insn);
  #endif
  
    /* Get the pattern to emit and update our status.  */
--- 659,665 ----
  
    if ((GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
        && reg_referenced_p (cc0_rtx, PATTERN (insn)))
!     chain = chain->prev, insn = chain->insn;
  #endif
  
    /* Get the pattern to emit and update our status.  */
*************** insert_save_restore (insn, save_p, regno
*** 749,758 ****
          }
      }
    /* Emit the insn and set the code and mode.  */
! 
!   insn = emit_insn_before (pat, insn);
!   PUT_MODE (insn, insn_mode);
!   INSN_CODE (insn) = code;
  
    /* Tell our callers how many extra registers we saved/restored */
    return numregs - 1;
--- 746,761 ----
          }
      }
    /* Emit the insn and set the code and mode.  */
!   
!   new = new_insn_chain ();
!   new->prev = chain->prev;
!   new->prev->next = new;
!   chain->prev = new;
!   new->next = chain;
!   new->insn = emit_insn_before (pat, insn);
!   new->block = chain->block;
!   new->need_reload = 0;
!   new->need_elim = need_elim;
  
    /* Tell our callers how many extra registers we saved/restored */
    return numregs - 1;
diff -dcrp egcs-ss-970814/global.c egcs-new/global.c
*** egcs-ss-970814/global.c	Fri Aug 15 20:56:14 1997
--- egcs-new/global.c	Thu Aug 21 14:14:58 1997
*************** Boston, MA 02111-1307, USA.  */
*** 27,32 ****
--- 27,33 ----
  #include "hard-reg-set.h"
  #include "regs.h"
  #include "insn-config.h"
+ #include "reload.h"
  #include "output.h"
  
  /* This pass of the compiler performs global register allocation.
*************** static void mark_reg_death	PROTO((rtx));
*** 265,270 ****
--- 266,275 ----
  static void mark_reg_live_nc	PROTO((int, enum machine_mode));
  static void set_preference	PROTO((rtx, rtx));
  static void dump_conflicts	PROTO((FILE *));
+ static void regno_becomes_live	PROTO((int, enum machine_mode));
+ static void reg_becomes_live	PROTO((rtx, rtx));
+ static void reg_dies		PROTO((int, enum machine_mode));
+ static void build_insn_chain	PROTO((rtx));
  \f
  /* Perform allocation of pseudo-registers not allocated by local_alloc.
     FILE is a file to output debugging information on,
*************** global_alloc (file)
*** 447,464 ****
      if (regs_ever_live[i])
        local_reg_n_refs[i] = 0;
  
-   /* Likewise for regs used in a SCRATCH.  */
-   for (i = 0; i < scratch_list_length; i++)
-     if (scratch_list[i])
-       {
- 	int regno = REGNO (scratch_list[i]);
- 	int lim = regno + HARD_REGNO_NREGS (regno, GET_MODE (scratch_list[i]));
- 	int j;
- 
- 	for (j = regno; j < lim; j++)
- 	  local_reg_n_refs[j] = 0;
-       }
- 	
    /* Allocate the space for the conflict and preference tables and
       initialize them.  */
  
--- 452,457 ----
*************** global_alloc (file)
*** 575,583 ****
  
  #if 0 /* We need to eliminate regs even if there is no rtl code,
  	 for the sake of debugging information.  */
!   if (n_basic_blocks > 0)
  #endif
!     return reload (get_insns (), 1, file);
  }
  
  /* Sort predicate for ordering the allocnos.
--- 568,579 ----
  
  #if 0 /* We need to eliminate regs even if there is no rtl code,
  	 for the sake of debugging information.  */
!   if (n_basic_blocks > 0)      
  #endif
!     {
!       build_insn_chain (get_insns ());
!       return reload (get_insns (), 1, file);
!     }
  }
  
  /* Sort predicate for ordering the allocnos.
*************** mark_elimination (from, to)
*** 1631,1636 ****
--- 1627,1776 ----
  	CLEAR_REGNO_REG_SET (basic_block_live_at_start[i], from);
  	SET_REGNO_REG_SET (basic_block_live_at_start[i], to);
        }
+ }
+ \f
+ /* Used for communication between the following functions.  Holds the
+    current life information.  */
+ static int inverse_renumber[FIRST_PSEUDO_REGISTER];
+ 
+ /* Record in inverse_renumber that register REGNO became live.  */
+ static void
+ regno_becomes_live (regno, mode)
+      int regno;
+      enum machine_mode mode;
+ {
+   int hardregno, nregs;
+   if (regno < FIRST_PSEUDO_REGISTER)
+     {
+       hardregno = regno;
+       if (mode == VOIDmode)
+ 	nregs = 1;
+       else
+ 	nregs = HARD_REGNO_NREGS (regno, mode);
+       regno = -1;
+     }
+   else
+     {
+       hardregno = reg_renumber[regno];
+       if (hardregno < 0)
+ 	return;
+       nregs = HARD_REGNO_NREGS (hardregno, PSEUDO_REGNO_MODE (regno));
+     }
+ 
+   while (nregs--)
+     inverse_renumber[hardregno++] = regno;
+ }
+ 
+ /* Record in inverse_renumber that register REG became live.  This
+    is called via note_stores.  */
+ static void
+ reg_becomes_live (reg, setter)
+      rtx reg, setter;
+ {
+   if (GET_CODE (reg) == REG)
+     regno_becomes_live (REGNO (reg), GET_MODE (reg));
+ }
+ 
+ /* Record in inverse_renumber that register REGNO died.  */
+ static void
+ reg_dies (regno, mode)
+      int regno;
+      enum machine_mode mode;
+ {
+   int hardregno, nregs;
+   if (regno < FIRST_PSEUDO_REGISTER)
+     {
+       hardregno = regno;
+       nregs = HARD_REGNO_NREGS (regno, mode);
+     }
+   else
+     {
+       hardregno = reg_renumber[regno];
+       if (hardregno < 0)
+ 	return;
+       nregs = HARD_REGNO_NREGS (hardregno, PSEUDO_REGNO_MODE (regno));
+     }
+ 
+   while (nregs--)
+     inverse_renumber[hardregno++] = 0;
+ }
+ 
+ /* Walk the insns of the current function and build reload_insn_chain,
+    and record register life information if it is available.  */
+ static void
+ build_insn_chain (first)
+      rtx first;
+ {
+   struct insn_chain **p = &reload_insn_chain;
+   struct insn_chain *prev = 0;
+   int b = 0;
+ 
+   bzero ((char *)inverse_renumber, sizeof inverse_renumber);
+ 
+   for (; first; first = NEXT_INSN (first))
+     {
+       struct insn_chain *c;
+ 
+       if (GET_CODE (first) != NOTE && GET_CODE (first) != BARRIER)
+ 	{
+ 	  c = new_insn_chain ();
+ 	  c->prev = prev;
+ 	  prev = c;
+ 	  *p = c;
+ 	  p = &c->next;
+ 	  c->insn = first;
+ 	  c->block = b;
+ 
+ 	  if (first == basic_block_head[b])
+ 	    {
+ 	      int regno;
+ 	      bzero ((char *)inverse_renumber, sizeof inverse_renumber);
+ 	      EXECUTE_IF_SET_IN_REG_SET (basic_block_live_at_start[b],
+ 					 0, regno,
+ 					  {
+ 					    regno_becomes_live (regno, VOIDmode);
+ 					  });
+ 	    }
+ 
+ 	  bcopy (inverse_renumber, c->inverse_renum_before, sizeof inverse_renumber);
+ 
+ 	  if (GET_RTX_CLASS (GET_CODE (first)) == 'i')
+ 	    {
+ 	      rtx link;
+ 
+ 	      /* Mark the death of everything that dies in this instruction.  */
+ 
+ 	      for (link = REG_NOTES (first); link; link = XEXP (link, 1))
+ 		if (REG_NOTE_KIND (link) == REG_DEAD
+ 		    && GET_CODE (XEXP (link, 0)) == REG)
+ 		  reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0)));
+ 
+ 	      /* Mark everything born in this instruction as live.  */
+ 
+ 	      note_stores (PATTERN (first), reg_becomes_live);
+ 	    }
+ 
+ 	  /* Remember which registers are live at the end of the insn, before
+ 	     killing those with REG_UNUSED notes.  */
+ 	  bcopy (inverse_renumber, c->inverse_renum_after, sizeof inverse_renumber);
+ 
+ 	  if (GET_RTX_CLASS (GET_CODE (first)) == 'i')
+ 	    {
+ 	      rtx link;
+ 
+ 	      /* Mark anything that is set in this insn and then unused as dying.  */
+ 
+ 	      for (link = REG_NOTES (first); link; link = XEXP (link, 1))
+ 		if (REG_NOTE_KIND (link) == REG_UNUSED
+ 		    && GET_CODE (XEXP (link, 0)) == REG)
+ 		  reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0)));
+ 	    }
+ 	}
+ 
+       if (first == basic_block_end[b])
+ 	b++;
+     }
+   *p = 0;
  }
  \f
  /* Print debugging trace information if -greg switch is given,
diff -dcrp egcs-ss-970814/local-alloc.c egcs-new/local-alloc.c
*** egcs-ss-970814/local-alloc.c	Fri Aug 15 20:56:27 1997
--- egcs-new/local-alloc.c	Thu Aug 21 12:25:56 1997
*************** static int *qty_n_calls_crossed;
*** 154,164 ****
  
  static enum reg_class *qty_alternate_class;
  
- /* Element Q is the SCRATCH expression for which this quantity is being
-    allocated or 0 if this quantity is allocating registers.  */
- 
- static rtx *qty_scratch_rtx;
- 
  /* Element Q is nonzero if this quantity has been used in a SUBREG
     that changes its size.  */
  
--- 154,159 ----
*************** static HARD_REG_SET regs_live;
*** 225,235 ****
  
  static HARD_REG_SET *regs_live_at;
  
- int *scratch_block;
- rtx *scratch_list;
- int scratch_list_length;
- static int scratch_index;
- 
  /* Communicate local vars `insn_number' and `insn'
     from `block_alloc' to `reg_is_set', `wipe_dead_reg', and `alloc_qty'.  */
  static int this_insn_number;
--- 220,225 ----
*************** alloc_qty (regno, mode, size, birth)
*** 298,393 ****
    qty_changes_size[qty] = REG_CHANGES_SIZE (regno);
  }
  \f
- /* Similar to `alloc_qty', but allocates a quantity for a SCRATCH rtx
-    used as operand N in INSN.  We assume here that the SCRATCH is used in
-    a CLOBBER.  */
- 
- static void
- alloc_qty_for_scratch (scratch, n, insn, insn_code_num, insn_number)
-      rtx scratch;
-      int n;
-      rtx insn;
-      int insn_code_num, insn_number;
- {
-   register int qty;
-   enum reg_class class;
-   char *p, c;
-   int i;
- 
- #ifdef REGISTER_CONSTRAINTS
-   /* If we haven't yet computed which alternative will be used, do so now.
-      Then set P to the constraints for that alternative.  */
-   if (which_alternative == -1)
-     if (! constrain_operands (insn_code_num, 0))
-       return;
- 
-   for (p = insn_operand_constraint[insn_code_num][n], i = 0;
-        *p && i < which_alternative; p++)
-     if (*p == ',')
-       i++;
- 
-   /* Compute the class required for this SCRATCH.  If we don't need a
-      register, the class will remain NO_REGS.  If we guessed the alternative
-      number incorrectly, reload will fix things up for us.  */
- 
-   class = NO_REGS;
-   while ((c = *p++) != '\0' && c != ',')
-     switch (c)
-       {
-       case '=':  case '+':  case '?':
-       case '#':  case '&':  case '!':
-       case '*':  case '%':  
-       case '0':  case '1':  case '2':  case '3':  case '4':
-       case 'm':  case '<':  case '>':  case 'V':  case 'o':
-       case 'E':  case 'F':  case 'G':  case 'H':
-       case 's':  case 'i':  case 'n':
-       case 'I':  case 'J':  case 'K':  case 'L':
-       case 'M':  case 'N':  case 'O':  case 'P':
- #ifdef EXTRA_CONSTRAINT
-       case 'Q':  case 'R':  case 'S':  case 'T':  case 'U':
- #endif
-       case 'p':
- 	/* These don't say anything we care about.  */
- 	break;
- 
-       case 'X':
- 	/* We don't need to allocate this SCRATCH.  */
- 	return;
- 
-       case 'g': case 'r':
- 	class = reg_class_subunion[(int) class][(int) GENERAL_REGS];
- 	break;
- 
-       default:
- 	class
- 	  = reg_class_subunion[(int) class][(int) REG_CLASS_FROM_LETTER (c)];
- 	break;
-       }
- 
-   if (class == NO_REGS)
-     return;
- 
- #else /* REGISTER_CONSTRAINTS */
- 
-   class = GENERAL_REGS;
- #endif
-   
- 
-   qty = next_qty++;
- 
-   qty_first_reg[qty] = -1;
-   qty_scratch_rtx[qty] = scratch;
-   qty_size[qty] = GET_MODE_SIZE (GET_MODE (scratch));
-   qty_mode[qty] = GET_MODE (scratch);
-   qty_birth[qty] = 2 * insn_number - 1;
-   qty_death[qty] = 2 * insn_number + 1;
-   qty_n_calls_crossed[qty] = 0;
-   qty_min_class[qty] = class;
-   qty_alternate_class[qty] = NO_REGS;
-   qty_n_refs[qty] = 1;
-   qty_changes_size[qty] = 0;
- }
- \f
  /* Main entry point of this file.  */
  
  void
--- 288,293 ----
*************** local_alloc ()
*** 416,433 ****
       See the declarations of these variables, above,
       for what they mean.  */
  
-   /* There can be up to MAX_SCRATCH * N_BASIC_BLOCKS SCRATCHes to allocate.
-      Instead of allocating this much memory from now until the end of
-      reload, only allocate space for MAX_QTY SCRATCHes.  If there are more
-      reload will allocate them.  */
- 
-   scratch_list_length = max_qty;
-   scratch_list = (rtx *) xmalloc (scratch_list_length * sizeof (rtx));
-   bzero ((char *) scratch_list, scratch_list_length * sizeof (rtx));
-   scratch_block = (int *) xmalloc (scratch_list_length * sizeof (int));
-   bzero ((char *) scratch_block, scratch_list_length * sizeof (int));
-   scratch_index = 0;
- 
    qty_phys_reg = (short *) alloca (max_qty * sizeof (short));
    qty_phys_copy_sugg
      = (HARD_REG_SET *) alloca (max_qty * sizeof (HARD_REG_SET));
--- 316,321 ----
*************** local_alloc ()
*** 436,442 ****
    qty_phys_num_sugg = (short *) alloca (max_qty * sizeof (short));
    qty_birth = (int *) alloca (max_qty * sizeof (int));
    qty_death = (int *) alloca (max_qty * sizeof (int));
-   qty_scratch_rtx = (rtx *) alloca (max_qty * sizeof (rtx));
    qty_first_reg = (int *) alloca (max_qty * sizeof (int));
    qty_size = (int *) alloca (max_qty * sizeof (int));
    qty_mode
--- 324,329 ----
*************** local_alloc ()
*** 494,500 ****
  	{
  	  for (i = 0; i < next_qty; i++)
  	    {
- 	      qty_scratch_rtx[i] = 0;
  	      CLEAR_HARD_REG_SET (qty_phys_copy_sugg[i]);
  	      qty_phys_num_copy_sugg[i] = 0;
  	      CLEAR_HARD_REG_SET (qty_phys_sugg[i]);
--- 381,386 ----
*************** local_alloc ()
*** 506,512 ****
  #define CLEAR(vector)  \
  	  bzero ((char *) (vector), (sizeof (*(vector))) * next_qty);
  
- 	  CLEAR (qty_scratch_rtx);
  	  CLEAR (qty_phys_copy_sugg);
  	  CLEAR (qty_phys_num_copy_sugg);
  	  CLEAR (qty_phys_sugg);
--- 392,397 ----
*************** block_alloc (b)
*** 1224,1232 ****
    int max_uid = get_max_uid ();
    int *qty_order;
    int no_conflict_combined_regno = -1;
-   /* Counter to prevent allocating more SCRATCHes than can be stored
-      in SCRATCH_LIST.  */
-   int scratches_allocated = scratch_index;
  
    /* Count the instructions in the basic block.  */
  
--- 1109,1114 ----
*************** block_alloc (b)
*** 1480,1494 ****
  		&& GET_CODE (XEXP (link, 0)) == REG)
  	      wipe_dead_reg (XEXP (link, 0), 1);
  
- 	  /* Allocate quantities for any SCRATCH operands of this insn.  */
- 
- 	  if (insn_code_number >= 0)
- 	    for (i = 0; i < insn_n_operands[insn_code_number]; i++)
- 	      if (GET_CODE (recog_operand[i]) == SCRATCH
- 		  && scratches_allocated++ < scratch_list_length)
- 		alloc_qty_for_scratch (recog_operand[i], i, insn,
- 				       insn_code_number, insn_number);
- 
  	  /* If this is an insn that has a REG_RETVAL note pointing at a 
  	     CLOBBER insn, we have reached the end of a REG_NO_CONFLICT
  	     block, so clear any register number that combined within it.  */
--- 1362,1367 ----
*************** block_alloc (b)
*** 1635,1656 ****
        {
  	for (i = qty_first_reg[q]; i >= 0; i = reg_next_in_qty[i])
  	  reg_renumber[i] = qty_phys_reg[q] + reg_offset[i];
- 	if (qty_scratch_rtx[q])
- 	  {
- 	    if (GET_CODE (qty_scratch_rtx[q]) == REG)
- 	      abort ();
- 	    PUT_CODE (qty_scratch_rtx[q], REG);
- 	    REGNO (qty_scratch_rtx[q]) = qty_phys_reg[q];
- 
- 	    scratch_block[scratch_index] = b;
- 	    scratch_list[scratch_index++] = qty_scratch_rtx[q];
- 
- 	    /* Must clear the USED field, because it will have been set by
- 	       copy_rtx_if_shared, but the leaf_register code expects that
- 	       it is zero in all REG rtx.  copy_rtx_if_shared does not set the
- 	       used bit for REGs, but does for SCRATCHes.  */
- 	    qty_scratch_rtx[q]->used = 0;
- 	  }
        }
  }
  \f
--- 1508,1513 ----
diff -dcrp egcs-ss-970814/reload.h egcs-new/reload.h
*** egcs-ss-970814/reload.h	Fri Aug 15 20:56:44 1997
--- egcs-new/reload.h	Thu Aug 21 10:31:10 1997
*************** extern enum insn_code reload_in_optab[];
*** 130,135 ****
--- 130,202 ----
  extern enum insn_code reload_out_optab[];
  #endif
  
+ struct needs
+ {
+   /* [0] is normal, [1] is nongroup.  */
+   short regs[2][N_REG_CLASSES];
+   short groups[N_REG_CLASSES];
+ };
+ 
+ #ifdef SET_HARD_REG_BIT
+ /* This structure describes instructions which are relevant for reload.  */
+ struct insn_chain 
+ {
+   struct insn_chain *next, *prev;
+ 
+   /* The basic block this insn is in.  */
+   int block;
+   /* The rtx of the insn.  */
+   rtx insn;
+   /* Register life information: For each hard register, contains either
+      -1 if the hard register is live, 0 if it is not live, or a pseudo
+      register number if a pseudo that has been allocated to this hard
+      reg is live.  This information is recorded for the point immediately
+      before the insn (in inverse_renum_before), and for the point within
+      the insn at which all outputs have just been written to (in
+      inverse_renum_after).  */
+   int inverse_renum_before[FIRST_PSEUDO_REGISTER];
+   int inverse_renum_after[FIRST_PSEUDO_REGISTER];
+ 
+   /* For each class, size of group of consecutive regs
+      that is needed for the reloads of this class.  */
+   char group_size[N_REG_CLASSES];
+   /* For each class, the machine mode which requires consecutive
+      groups of regs of that class.
+      If two different modes ever require groups of one class,
+      they must be the same size and equally restrictive for that class,
+      otherwise we can't handle the complexity.  */
+   enum machine_mode group_mode[N_REG_CLASSES];
+ 
+   /* Indicates if a register was counted against the need for
+      groups.  0 means it can count against max_nongroup instead.  */
+   HARD_REG_SET counted_for_groups;
+ 
+   /* Indicates if a register was counted against the need for
+      non-groups.  0 means it can become part of a new group.
+      During choose_reload_regs, 1 here means don't use this reg
+      as part of a group, even if it seems to be otherwise ok.  */
+   HARD_REG_SET counted_for_nongroups;
+ 
+   /* Indicates which registers have already been used for spills.  */
+   HARD_REG_SET used_spill_regs;
+ 
+   /* Describe the needs for reload registers of this insn.  */
+   struct needs need;
+ 
+   /* Nonzero if find_reloads said the insn requires reloading.  */
+   unsigned int need_reload:1;
+   /* Nonzero if eliminate_regs_in_insn said it requires eliminations.  */
+   unsigned int need_elim:1;
+ };
+ 
+ /* A chain of insn_chain structures to describe all non-note insns in
+    a function.  */
+ extern struct insn_chain *reload_insn_chain;
+ 
+ /* Allocate a new insn_chain structure.  */
+ extern struct insn_chain *new_insn_chain PROTO((void));
+ #endif
+ 
  /* Functions from reload.c:  */
  
  /* Return a memory location that will be used to copy X in mode MODE.  
*************** extern void init_save_areas PROTO((void)
*** 239,242 ****
  extern int setup_save_areas PROTO((int *));
  
  /* Find the places where hard regs are live across calls and save them.  */
! extern void save_call_clobbered_regs PROTO((enum machine_mode));
--- 306,309 ----
  extern int setup_save_areas PROTO((int *));
  
  /* Find the places where hard regs are live across calls and save them.  */
! extern void save_call_clobbered_regs PROTO((int));
diff -dcrp egcs-ss-970814/reload1.c egcs-new/reload1.c
*** egcs-ss-970814/reload1.c	Fri Aug 15 20:56:46 1997
--- egcs-new/reload1.c	Thu Aug 21 14:08:51 1997
*************** Boston, MA 02111-1307, USA.  */
*** 57,62 ****
--- 57,64 ----
     available hard regs can be found.  Spilling can invalidate more
     insns, requiring additional need for reloads, so we must keep checking
     until the process stabilizes.
+    If we have register life information, it is often possible to avoid
+    spilling all the pseudos allocated to a reload register.
  
     For machines with different classes of registers, we must keep track
     of the register class needed for each reload, and make sure that
*************** static int *reg_max_ref_width;
*** 118,123 ****
--- 120,128 ----
     constant or memory slot.  */
  static rtx *reg_equiv_init;
  
+ /* Vector to remember old contents of reg_renumber before spilling.  */
+ static short *reg_old_renumber;
+ 
  /* During reload_as_needed, element N contains the last pseudo regno
     reloaded into the Nth reload register.  This vector is in parallel
     with spill_regs.  If that pseudo reg occupied more than one register,
*************** static short spill_reg_order[FIRST_PSEUD
*** 154,160 ****
  /* This reg set indicates registers that may not be used for retrying global
     allocation.  The registers that may not be used include all spill registers
     and the frame pointer (if we are using one).  */
! HARD_REG_SET forbidden_regs;
  
  /* This reg set indicates registers that are not good for spill registers.
     They will not be used to complete groups of spill registers.  This includes
--- 159,170 ----
  /* This reg set indicates registers that may not be used for retrying global
     allocation.  The registers that may not be used include all spill registers
     and the frame pointer (if we are using one).  */
! static HARD_REG_SET forbidden_regs;
! 
! /* This vector of reg sets indicates, for each pseudo, which hard registers may
!    not be used for retrying global allocation, additionally to those in
!    forbidden_regs.  */
! static HARD_REG_SET *pseudo_forbidden_regs;
  
  /* This reg set indicates registers that are not good for spill registers.
     They will not be used to complete groups of spill registers.  This includes
*************** static short spill_regs[FIRST_PSEUDO_REG
*** 173,179 ****
  /* This reg set indicates those registers that have been used a spill
     registers.  This information is used in reorg.c, to help figure out
     what registers are live at any point.  It is assumed that all spill_regs
!    are dead at every CODE_LABEL.  */
  
  HARD_REG_SET used_spill_regs;
  
--- 183,190 ----
  /* This reg set indicates those registers that have been used a spill
     registers.  This information is used in reorg.c, to help figure out
     what registers are live at any point.  It is assumed that all spill_regs
!    are dead at every CODE_LABEL.  
!    @@@ That's a bug!  */
  
  HARD_REG_SET used_spill_regs;
  
*************** HARD_REG_SET used_spill_regs;
*** 182,209 ****
  
  static int last_spill_reg;
  
- /* Describes order of preference for putting regs into spill_regs.
-    Contains the numbers of all the hard regs, in order most preferred first.
-    This order is different for each function.
-    It is set up by order_regs_for_reload.
-    Empty elements at the end contain -1.  */
- static short potential_reload_regs[FIRST_PSEUDO_REGISTER];
- 
  /* 1 for a hard register that appears explicitly in the rtl
     (for example, function value registers, special registers
     used by insns, structure value pointer registers).  */
  static char regs_explicitly_used[FIRST_PSEUDO_REGISTER];
  
- /* Indicates if a register was counted against the need for
-    groups.  0 means it can count against max_nongroup instead.  */
- static HARD_REG_SET counted_for_groups;
- 
- /* Indicates if a register was counted against the need for
-    non-groups.  0 means it can become part of a new group.
-    During choose_reload_regs, 1 here means don't use this reg
-    as part of a group, even if it seems to be otherwise ok.  */
- static HARD_REG_SET counted_for_nongroups;
- 
  /* Indexed by pseudo reg number N,
     says may not delete stores into the real (memory) home of pseudo N.
     This is set if we already substituted a memory equivalent in some uses,
--- 193,203 ----
*************** static rtx spill_stack_slot[FIRST_PSEUDO
*** 237,248 ****
  
  static int spill_stack_slot_width[FIRST_PSEUDO_REGISTER];
  
! /* Indexed by register class and basic block number, nonzero if there is
!    any need for a spill register of that class in that basic block.
!    The pointer is 0 if we did stupid allocation and don't know
!    the structure of basic blocks.  */
  
! char *basic_block_needs[N_REG_CLASSES];
  
  /* First uid used by insns created by reload in this function.
     Used in find_equiv_reg.  */
--- 231,239 ----
  
  static int spill_stack_slot_width[FIRST_PSEUDO_REGISTER];
  
! /* Record which pseudos needed to be spilled.  */
  
! static regset spilled_pseudos;
  
  /* First uid used by insns created by reload in this function.
     Used in find_equiv_reg.  */
*************** enum reg_class reload_address_index_reg_
*** 270,275 ****
--- 261,270 ----
  
  int reload_in_progress = 0;
  
+ /* Nonzero means we couldn't get enough spill regs.  */
+ static int failure;
+ 
+ 
  /* These arrays record the insn_code of insns that may be needed to
     perform input and output reloads of special objects.  They provide a
     place to pass a scratch register.  */
*************** enum insn_code reload_out_optab[NUM_MACH
*** 283,288 ****
--- 278,284 ----
  
  struct obstack reload_obstack;
  char *reload_firstobj;
+ char *reload_startobj;
  
  #define obstack_chunk_alloc xmalloc
  #define obstack_chunk_free free
*************** extern rtx forced_labels;
*** 292,297 ****
--- 288,295 ----
  
  /* Allocation number table from global register allocation.  */
  extern int *reg_allocno;
+ 
+ struct insn_chain *reload_insn_chain;
  \f
  /* This structure is used to record information about register eliminations.
     Each array entry describes one possible way of eliminating a register
*************** static int (*offsets_at)[NUM_ELIMINABLE_
*** 352,379 ****
  
  static int num_labels;
  
- struct hard_reg_n_uses { int regno; int uses; };
  \f
! static int possible_group_p		PROTO((int, int *));
! static void count_possible_groups	PROTO((int *, enum machine_mode *,
! 					       int *, int));
  static int modes_equiv_for_class_p	PROTO((enum machine_mode,
  					       enum machine_mode,
  					       enum reg_class));
  static void spill_failure		PROTO((rtx));
! static int new_spill_reg		PROTO((int, int, int *, int *, int,
  					       FILE *));
  static void delete_dead_insn		PROTO((rtx));
  static void alter_reg  			PROTO((int, int));
- static void mark_scratch_live		PROTO((rtx));
  static void set_label_offsets		PROTO((rtx, rtx, int));
  static int eliminate_regs_in_insn	PROTO((rtx, int));
  static void mark_not_eliminable		PROTO((rtx, rtx));
! static int spill_hard_reg		PROTO((int, int, FILE *, int));
  static void scan_paradoxical_subregs	PROTO((rtx));
  static int hard_reg_use_compare		PROTO((const GENERIC_PTR, const GENERIC_PTR));
! static void order_regs_for_reload	PROTO((int));
! static int compare_spill_regs		PROTO((const GENERIC_PTR, const GENERIC_PTR));
  static void reload_as_needed		PROTO((rtx, int));
  static void forget_old_reloads_1	PROTO((rtx, rtx));
  static int reload_reg_class_lower	PROTO((const GENERIC_PTR, const GENERIC_PTR));
--- 350,377 ----
  
  static int num_labels;
  
  \f
! static int possible_group_p		PROTO((struct insn_chain *, int));
! static void count_possible_groups	PROTO((struct insn_chain *, int));
  static int modes_equiv_for_class_p	PROTO((enum machine_mode,
  					       enum machine_mode,
  					       enum reg_class));
  static void spill_failure		PROTO((rtx));
! static void new_spill_reg		PROTO((struct insn_chain *, int, int,
! 					       int, FILE *));
! static void find_reload_regs		PROTO((struct insn_chain *chain, int,
  					       FILE *));
+ static int finish_spills		PROTO((int, FILE *));
+ static void spill_caller_saved_regs	PROTO((void));
  static void delete_dead_insn		PROTO((rtx));
  static void alter_reg  			PROTO((int, int));
  static void set_label_offsets		PROTO((rtx, rtx, int));
  static int eliminate_regs_in_insn	PROTO((rtx, int));
  static void mark_not_eliminable		PROTO((rtx, rtx));
! static void spill_hard_reg		PROTO((int, FILE *, int));
  static void scan_paradoxical_subregs	PROTO((rtx));
  static int hard_reg_use_compare		PROTO((const GENERIC_PTR, const GENERIC_PTR));
! static void order_regs_for_reload	PROTO((struct insn_chain *, int));
  static void reload_as_needed		PROTO((rtx, int));
  static void forget_old_reloads_1	PROTO((rtx, rtx));
  static int reload_reg_class_lower	PROTO((const GENERIC_PTR, const GENERIC_PTR));
*************** static int reload_reg_free_p		PROTO((int
*** 385,398 ****
  static int reload_reg_free_before_p	PROTO((int, int, enum reload_type));
  static int reload_reg_reaches_end_p	PROTO((int, int, enum reload_type));
  static int reloads_conflict 		PROTO((int, int));
! static int allocate_reload_reg		PROTO((int, rtx, int, int));
! static void choose_reload_regs		PROTO((rtx, rtx));
  static void merge_assigned_reloads	PROTO((rtx));
  static void emit_reload_insns		PROTO((rtx));
  static void delete_output_reload	PROTO((rtx, int, rtx));
  static void inc_for_reload		PROTO((rtx, rtx, int));
  static int constraint_accepts_reg_p	PROTO((char *, rtx));
  static int count_occurrences		PROTO((rtx, rtx));
  static void reload_cse_invalidate_regno	PROTO((int, enum machine_mode, int));
  static int reload_cse_mem_conflict_p	PROTO((rtx, rtx));
  static void reload_cse_invalidate_mem	PROTO((rtx));
--- 383,398 ----
  static int reload_reg_free_before_p	PROTO((int, int, enum reload_type));
  static int reload_reg_reaches_end_p	PROTO((int, int, enum reload_type));
  static int reloads_conflict 		PROTO((int, int));
! static int allocate_reload_reg		PROTO((struct insn_chain *, int, int,
! 					       int));
! static void choose_reload_regs		PROTO((struct insn_chain *, int));
  static void merge_assigned_reloads	PROTO((rtx));
  static void emit_reload_insns		PROTO((rtx));
  static void delete_output_reload	PROTO((rtx, int, rtx));
  static void inc_for_reload		PROTO((rtx, rtx, int));
  static int constraint_accepts_reg_p	PROTO((char *, rtx));
  static int count_occurrences		PROTO((rtx, rtx));
+ 
  static void reload_cse_invalidate_regno	PROTO((int, enum machine_mode, int));
  static int reload_cse_mem_conflict_p	PROTO((rtx, rtx));
  static void reload_cse_invalidate_mem	PROTO((rtx));
*************** init_reload ()
*** 451,517 ****
  
    /* Initialize obstack for our rtl allocation.  */
    gcc_obstack_init (&reload_obstack);
!   reload_firstobj = (char *) obstack_alloc (&reload_obstack, 0);
  
-   /* Decide which register class should be used when reloading
-      addresses.  If we are using SMALL_REGISTER_CLASSES, and any
-      parameters are passed in registers, then we do not want to use
-      those registers when reloading an address.  Otherwise, if a
-      function argument needs a reload, we may wind up clobbering
-      another argument to the function which was already computed.  If
-      we find a subset class which simply avoids those registers, we
-      use it instead.  ??? It would be better to only use the
-      restricted class when we actually are loading function arguments,
-      but that is hard to determine.  */
    reload_address_base_reg_class = BASE_REG_CLASS;
    reload_address_index_reg_class = INDEX_REG_CLASS;
! #ifdef SMALL_REGISTER_CLASSES
!   if (SMALL_REGISTER_CLASSES)
!     {
!       int regno;
!       HARD_REG_SET base, index;
!       enum reg_class *p;
  
!       COPY_HARD_REG_SET (base, reg_class_contents[BASE_REG_CLASS]);
!       COPY_HARD_REG_SET (index, reg_class_contents[INDEX_REG_CLASS]);
!       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
! 	{
! 	  if (FUNCTION_ARG_REGNO_P (regno))
! 	    {
! 	      CLEAR_HARD_REG_BIT (base, regno);
! 	      CLEAR_HARD_REG_BIT (index, regno);
! 	    }
! 	}
!       
!       GO_IF_HARD_REG_EQUAL (base, reg_class_contents[BASE_REG_CLASS],
! 			    baseok);
!       for (p = reg_class_subclasses[BASE_REG_CLASS];
! 	   *p != LIM_REG_CLASSES;
! 	   p++)
! 	{
! 	  GO_IF_HARD_REG_EQUAL (base, reg_class_contents[*p], usebase);
! 	  continue;
! 	usebase:
! 	  reload_address_base_reg_class = *p;
! 	  break;
! 	}
!     baseok:;
  
!       GO_IF_HARD_REG_EQUAL (index, reg_class_contents[INDEX_REG_CLASS],
! 			    indexok);
!       for (p = reg_class_subclasses[INDEX_REG_CLASS];
! 	   *p != LIM_REG_CLASSES;
! 	   p++)
! 	{
! 	  GO_IF_HARD_REG_EQUAL (index, reg_class_contents[*p], useindex);
! 	  continue;
! 	useindex:
! 	  reload_address_index_reg_class = *p;
! 	  break;
! 	}
!     indexok:;
!     }
! #endif /* SMALL_REGISTER_CLASSES */
  }
  
  /* Main entry point for the reload pass.
--- 451,473 ----
  
    /* Initialize obstack for our rtl allocation.  */
    gcc_obstack_init (&reload_obstack);
!   reload_startobj = (char *) obstack_alloc (&reload_obstack, 0);
  
    reload_address_base_reg_class = BASE_REG_CLASS;
    reload_address_index_reg_class = INDEX_REG_CLASS;
! }
  
! /* Allocate an empty insn_chain structure.  */
! struct insn_chain *
! new_insn_chain ()
! {
!   struct insn_chain *c;
  
!   c = obstack_alloc (&reload_obstack, sizeof (struct insn_chain));
!   reload_firstobj = (char *) obstack_alloc (&reload_obstack, 0);
!   c->need_reload = 0;
!   c->need_elim = 0;
!   return c;
  }
  
  /* Main entry point for the reload pass.
*************** reload (first, global, dumpfile)
*** 551,575 ****
    int something_changed;
    int something_needs_reloads;
    int something_needs_elimination;
-   int new_basic_block_needs;
-   enum reg_class caller_save_spill_class = NO_REGS;
-   int caller_save_group_size = 1;
- 
-   /* Nonzero means we couldn't get enough spill regs.  */
-   int failure = 0;
- 
-   /* The basic block number currently being processed for INSN.  */
-   int this_block;
  
    /* Make sure even insns with volatile mem refs are recognizable.  */
    init_recog ();
  
    /* Enable find_equiv_reg to distinguish insns made by reload.  */
    reload_first_uid = get_max_uid ();
  
!   for (i = 0; i < N_REG_CLASSES; i++)
!     basic_block_needs[i] = 0;
! 
  #ifdef SECONDARY_MEMORY_NEEDED
    /* Initialize the secondary memory table.  */
    clear_secondary_mem ();
--- 507,525 ----
    int something_changed;
    int something_needs_reloads;
    int something_needs_elimination;
  
    /* Make sure even insns with volatile mem refs are recognizable.  */
    init_recog ();
  
+   reload_firstobj = (char *) obstack_alloc (&reload_obstack, 0);
+ 
+   spilled_pseudos = ALLOCA_REG_SET ();
+ 
    /* Enable find_equiv_reg to distinguish insns made by reload.  */
    reload_first_uid = get_max_uid ();
  
!   failure = 0;
!   
  #ifdef SECONDARY_MEMORY_NEEDED
    /* Initialize the secondary memory table.  */
    clear_secondary_mem ();
*************** reload (first, global, dumpfile)
*** 604,613 ****
  	  regs_ever_live[i] = 1;
        }
  
-   for (i = 0; i < scratch_list_length; i++)
-     if (scratch_list[i])
-       mark_scratch_live (scratch_list[i]);
- 
    /* Make sure that the last insn in the chain
       is not something that needs reloading.  */
    emit_note (NULL_PTR, NOTE_INSN_DELETED);
--- 554,559 ----
*************** reload (first, global, dumpfile)
*** 636,641 ****
--- 582,591 ----
    bzero ((char *) reg_max_ref_width, max_regno * sizeof (int));
    cannot_omit_stores = (char *) alloca (max_regno);
    bzero (cannot_omit_stores, max_regno);
+   reg_old_renumber = (short *) alloca (max_regno * sizeof (short));
+   bcopy (reg_renumber, reg_old_renumber, max_regno * sizeof (short));
+   pseudo_forbidden_regs
+     = (HARD_REG_SET *) alloca (max_regno * sizeof (HARD_REG_SET));
  
  #ifdef SMALL_REGISTER_CLASSES
    if (SMALL_REGISTER_CLASSES)
*************** reload (first, global, dumpfile)
*** 803,846 ****
      }
  #endif
  
-   /* Compute the order of preference for hard registers to spill.
-      Store them by decreasing preference in potential_reload_regs.  */
- 
-   order_regs_for_reload (global);
- 
-   /* So far, no hard regs have been spilled.  */
-   n_spills = 0;
-   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-     spill_reg_order[i] = -1;
- 
    /* Initialize to -1, which means take the first spill register.  */
    last_spill_reg = -1;
  
-   /* On most machines, we can't use any register explicitly used in the
-      rtl as a spill register.  But on some, we have to.  Those will have
-      taken care to keep the life of hard regs as short as possible.  */
- 
- #ifdef SMALL_REGISTER_CLASSES
-   if (! SMALL_REGISTER_CLASSES)
- #endif
-     COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs);
- 
    /* Spill any hard regs that we know we can't eliminate.  */
    for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
      if (! ep->can_eliminate)
!       spill_hard_reg (ep->from, global, dumpfile, 1);
  
  #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
    if (frame_pointer_needed)
!     spill_hard_reg (HARD_FRAME_POINTER_REGNUM, global, dumpfile, 1);
  #endif
! 
!   if (global)
!     for (i = 0; i < N_REG_CLASSES; i++)
!       {
! 	basic_block_needs[i] = (char *) alloca (n_basic_blocks);
! 	bzero (basic_block_needs[i], n_basic_blocks);
!       }
  
    /* From now on, we need to emit any moves without making new pseudos.  */
    reload_in_progress = 1;
--- 753,772 ----
      }
  #endif
  
    /* Initialize to -1, which means take the first spill register.  */
    last_spill_reg = -1;
  
    /* Spill any hard regs that we know we can't eliminate.  */
+   CLEAR_HARD_REG_SET (used_spill_regs);
    for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
      if (! ep->can_eliminate)
!       spill_hard_reg (ep->from, dumpfile, 1);
  
  #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
    if (frame_pointer_needed)
!     spill_hard_reg (HARD_FRAME_POINTER_REGNUM, dumpfile, 1);
  #endif
!   finish_spills (global, dumpfile);
  
    /* From now on, we need to emit any moves without making new pseudos.  */
    reload_in_progress = 1;
*************** reload (first, global, dumpfile)
*** 860,912 ****
    something_needs_elimination = 0;
    while (something_changed)
      {
!       rtx after_call = 0;
  
-       /* For each class, number of reload regs needed in that class.
- 	 This is the maximum over all insns of the needs in that class
- 	 of the individual insn.  */
-       int max_needs[N_REG_CLASSES];
-       /* For each class, size of group of consecutive regs
- 	 that is needed for the reloads of this class.  */
-       int group_size[N_REG_CLASSES];
-       /* For each class, max number of consecutive groups needed.
- 	 (Each group contains group_size[CLASS] consecutive registers.)  */
-       int max_groups[N_REG_CLASSES];
-       /* For each class, max number needed of regs that don't belong
- 	 to any of the groups.  */
-       int max_nongroups[N_REG_CLASSES];
-       /* For each class, the machine mode which requires consecutive
- 	 groups of regs of that class.
- 	 If two different modes ever require groups of one class,
- 	 they must be the same size and equally restrictive for that class,
- 	 otherwise we can't handle the complexity.  */
-       enum machine_mode group_mode[N_REG_CLASSES];
-       /* Record the insn where each maximum need is first found.  */
-       rtx max_needs_insn[N_REG_CLASSES];
-       rtx max_groups_insn[N_REG_CLASSES];
-       rtx max_nongroups_insn[N_REG_CLASSES];
        rtx x;
        HOST_WIDE_INT starting_frame_size;
        int previous_frame_pointer_needed = frame_pointer_needed;
        static char *reg_class_names[] = REG_CLASS_NAMES;
  
        something_changed = 0;
-       bzero ((char *) max_needs, sizeof max_needs);
-       bzero ((char *) max_groups, sizeof max_groups);
-       bzero ((char *) max_nongroups, sizeof max_nongroups);
-       bzero ((char *) max_needs_insn, sizeof max_needs_insn);
-       bzero ((char *) max_groups_insn, sizeof max_groups_insn);
-       bzero ((char *) max_nongroups_insn, sizeof max_nongroups_insn);
-       bzero ((char *) group_size, sizeof group_size);
-       for (i = 0; i < N_REG_CLASSES; i++)
- 	group_mode[i] = VOIDmode;
- 
-       /* Keep track of which basic blocks are needing the reloads.  */
-       this_block = 0;
- 
-       /* Remember whether any element of basic_block_needs
- 	 changes from 0 to 1 in this pass.  */
-       new_basic_block_needs = 0;
  
        /* Round size of stack frame to BIGGEST_ALIGNMENT.  This must be done
  	 here because the stack size may be a part of the offset computation
--- 786,799 ----
    something_needs_elimination = 0;
    while (something_changed)
      {
!       struct insn_chain *chain;
  
        rtx x;
        HOST_WIDE_INT starting_frame_size;
        int previous_frame_pointer_needed = frame_pointer_needed;
        static char *reg_class_names[] = REG_CLASS_NAMES;
  
        something_changed = 0;
  
        /* Round size of stack frame to BIGGEST_ALIGNMENT.  This must be done
  	 here because the stack size may be a part of the offset computation
*************** reload (first, global, dumpfile)
*** 1010,1032 ****
        if (something_changed)
  	continue;
  
-       /* If caller-saves needs a group, initialize the group to include
- 	 the size and mode required for caller-saves.  */
- 
-       if (caller_save_group_size > 1)
- 	{
- 	  group_mode[(int) caller_save_spill_class] = Pmode;
- 	  group_size[(int) caller_save_spill_class] = caller_save_group_size;
- 	}
- 
        /* Compute the most additional registers needed by any instruction.
  	 Collect information separately for each class of regs.  */
  
!       for (insn = first; insn; insn = NEXT_INSN (insn))
  	{
! 	  if (global && this_block + 1 < n_basic_blocks
! 	      && insn == basic_block_head[this_block+1])
! 	    ++this_block;
  
  	  /* If this is a label, a JUMP_INSN, or has REG_NOTES (which
  	     might include REG_LABEL), we need to see what effects this
--- 897,909 ----
        if (something_changed)
  	continue;
  
        /* Compute the most additional registers needed by any instruction.
  	 Collect information separately for each class of regs.  */
  
!       for (chain = reload_insn_chain; chain; chain = chain->next)
  	{
! 	  rtx insn = chain->insn;
! 	  int this_block = chain->block;
  
  	  /* If this is a label, a JUMP_INSN, or has REG_NOTES (which
  	     might include REG_LABEL), we need to see what effects this
*************** reload (first, global, dumpfile)
*** 1039,1048 ****
  
  	  if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  	    {
- 	      /* Nonzero means don't use a reload reg that overlaps
- 		 the place where a function value can be returned.  */
- 	      rtx avoid_return_reg = 0;
- 
  	      rtx old_body = PATTERN (insn);
  	      int old_code = INSN_CODE (insn);
   	      rtx old_notes = REG_NOTES (insn);
--- 916,921 ----
*************** reload (first, global, dumpfile)
*** 1066,1078 ****
  		 The total number of registers needed is the maximum of the
  		 inputs and outputs.  */
  
- 	      struct needs
- 		{
- 		  /* [0] is normal, [1] is nongroup.  */
- 		  int regs[2][N_REG_CLASSES];
- 		  int groups[N_REG_CLASSES];
- 		};
- 
  	      /* Each `struct needs' corresponds to one RELOAD_... type.  */
  	      struct {
  		struct needs other;
--- 939,944 ----
*************** reload (first, global, dumpfile)
*** 1092,1143 ****
  	      if (num_eliminable)
  		did_elimination = eliminate_regs_in_insn (insn, 0);
  
- #ifdef SMALL_REGISTER_CLASSES
- 	      /* Set avoid_return_reg if this is an insn
- 		 that might use the value of a function call.  */
- 	      if (SMALL_REGISTER_CLASSES && GET_CODE (insn) == CALL_INSN)
- 		{
- 		  if (GET_CODE (PATTERN (insn)) == SET)
- 		    after_call = SET_DEST (PATTERN (insn));
- 		  else if (GET_CODE (PATTERN (insn)) == PARALLEL
- 			   && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
- 		    after_call = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
- 		  else
- 		    after_call = 0;
- 		}
- 	      else if (SMALL_REGISTER_CLASSES
- 		       && after_call != 0
- 		       && !(GET_CODE (PATTERN (insn)) == SET
- 			    && SET_DEST (PATTERN (insn)) == stack_pointer_rtx))
- 		{
- 		  if (reg_referenced_p (after_call, PATTERN (insn)))
- 		    avoid_return_reg = after_call;
- 		  after_call = 0;
- 		}
- #endif /* SMALL_REGISTER_CLASSES */
- 
  	      /* Analyze the instruction.  */
  	      find_reloads (insn, 0, spill_indirect_levels, global,
  			    spill_reg_order);
  
  	      /* Remember for later shortcuts which insns had any reloads or
! 		 register eliminations.
! 
! 		 One might think that it would be worthwhile to mark insns
! 		 that need register replacements but not reloads, but this is
! 		 not safe because find_reloads may do some manipulation of
! 		 the insn (such as swapping commutative operands), which would
! 		 be lost when we restore the old pattern after register
! 		 replacement.  So the actions of find_reloads must be redone in
! 		 subsequent passes or in reload_as_needed.
! 
! 		 However, it is safe to mark insns that need reloads
! 		 but not register replacement.  */
! 
! 	      PUT_MODE (insn, (did_elimination ? QImode
! 			       : n_reloads ? HImode
! 			       : GET_MODE (insn) == DImode ? DImode
! 			       : VOIDmode));
  
  	      /* Discard any register replacements done.  */
  	      if (did_elimination)
--- 958,971 ----
  	      if (num_eliminable)
  		did_elimination = eliminate_regs_in_insn (insn, 0);
  
  	      /* Analyze the instruction.  */
  	      find_reloads (insn, 0, spill_indirect_levels, global,
  			    spill_reg_order);
  
  	      /* Remember for later shortcuts which insns had any reloads or
! 		 register eliminations.  */
! 	      chain->need_elim = did_elimination;
! 	      chain->need_reload = n_reloads > 0;
  
  	      /* Discard any register replacements done.  */
  	      if (did_elimination)
*************** reload (first, global, dumpfile)
*** 1149,1164 ****
  		  something_needs_elimination = 1;
  		}
  
! 	      /* If this insn has no reloads, we need not do anything except
! 		 in the case of a CALL_INSN when we have caller-saves and
! 		 caller-save needs reloads.  */
! 
! 	      if (n_reloads == 0
! 		  && ! (GET_CODE (insn) == CALL_INSN
! 			&& caller_save_spill_class != NO_REGS))
  		continue;
  
  	      something_needs_reloads = 1;
  	      bzero ((char *) &insn_needs, sizeof insn_needs);
  
  	      /* Count each reload once in every class
--- 977,991 ----
  		  something_needs_elimination = 1;
  		}
  
! 	      /* If this insn has no reloads, we need not do anything.  */
! 	      if (n_reloads == 0)
  		continue;
  
  	      something_needs_reloads = 1;
+ 
+ 	      bzero ((char *) chain->group_size, sizeof chain->group_size);
+ 	      for (i = 0; i < N_REG_CLASSES; i++)
+ 		chain->group_mode[i] = VOIDmode;
  	      bzero ((char *) &insn_needs, sizeof insn_needs);
  
  	      /* Count each reload once in every class
*************** reload (first, global, dumpfile)
*** 1183,1198 ****
  			  && ! reload_secondary_p[i]))
    		    continue;
  
- 		  /* Show that a reload register of this class is needed
- 		     in this basic block.  We do not use insn_needs and
- 		     insn_groups because they are overly conservative for
- 		     this purpose.  */
- 		  if (global && ! basic_block_needs[(int) class][this_block])
- 		    {
- 		      basic_block_needs[(int) class][this_block] = 1;
- 		      new_basic_block_needs = 1;
- 		    }
- 
  		  mode = reload_inmode[i];
  		  if (GET_MODE_SIZE (reload_outmode[i]) > GET_MODE_SIZE (mode))
  		    mode = reload_outmode[i];
--- 1010,1015 ----
*************** reload (first, global, dumpfile)
*** 1275,1292 ****
  		      /* Record size and mode of a group of this class.  */
  		      /* If more than one size group is needed,
  			 make all groups the largest needed size.  */
! 		      if (group_size[(int) class] < size)
  			{
! 			  other_mode = group_mode[(int) class];
  			  allocate_mode = mode;
  
! 			  group_size[(int) class] = size;
! 			  group_mode[(int) class] = mode;
  			}
  		      else
  			{
  			  other_mode = mode;
! 			  allocate_mode = group_mode[(int) class];
  			}
  
  		      /* Crash if two dissimilar machine modes both need
--- 1092,1109 ----
  		      /* Record size and mode of a group of this class.  */
  		      /* If more than one size group is needed,
  			 make all groups the largest needed size.  */
! 		      if (chain->group_size[(int) class] < size)
  			{
! 			  other_mode = chain->group_mode[(int) class];
  			  allocate_mode = mode;
  
! 			  chain->group_size[(int) class] = size;
! 			  chain->group_mode[(int) class] = mode;
  			}
  		      else
  			{
  			  other_mode = mode;
! 			  allocate_mode = chain->group_mode[(int) class];
  			}
  
  		      /* Crash if two dissimilar machine modes both need
*************** reload (first, global, dumpfile)
*** 1392,1555 ****
  			    insn_needs.other_addr.groups[i]);
  		}
  
! 	      /* If this is a CALL_INSN and caller-saves will need
! 		 a spill register, act as if the spill register is
! 		 needed for this insn.   However, the spill register
! 		 can be used by any reload of this insn, so we only
! 		 need do something if no need for that class has
! 		 been recorded.
! 
! 		 The assumption that every CALL_INSN will trigger a
! 		 caller-save is highly conservative, however, the number
! 		 of cases where caller-saves will need a spill register but
! 		 a block containing a CALL_INSN won't need a spill register
! 		 of that class should be quite rare.
! 
! 		 If a group is needed, the size and mode of the group will
! 		 have been set up at the beginning of this loop.  */
! 
! 	      if (GET_CODE (insn) == CALL_INSN
! 		  && caller_save_spill_class != NO_REGS)
! 		{
! 		  /* See if this register would conflict with any reload
! 		     that needs a group.  */
! 		  int nongroup_need = 0;
! 		  int *caller_save_needs;
! 
! 		  for (j = 0; j < n_reloads; j++)
! 		    if ((CLASS_MAX_NREGS (reload_reg_class[j],
! 					  (GET_MODE_SIZE (reload_outmode[j])
! 					   > GET_MODE_SIZE (reload_inmode[j]))
! 					  ? reload_outmode[j]
! 					  : reload_inmode[j])
! 			 > 1)
! 			&& reg_classes_intersect_p (caller_save_spill_class,
! 						    reload_reg_class[j]))
! 		      {
! 			nongroup_need = 1;
! 			break;
! 		      }
! 
! 		  caller_save_needs 
! 		    = (caller_save_group_size > 1
! 		       ? insn_needs.other.groups
! 		       : insn_needs.other.regs[nongroup_need]); 
! 
! 		  if (caller_save_needs[(int) caller_save_spill_class] == 0)
! 		    {
! 		      register enum reg_class *p
! 			= reg_class_superclasses[(int) caller_save_spill_class];
! 
! 		      caller_save_needs[(int) caller_save_spill_class]++;
! 
! 		      while (*p != LIM_REG_CLASSES)
! 			caller_save_needs[(int) *p++] += 1;
! 		    }
! 
! 		  /* Show that this basic block will need a register of
!                    this class.  */
! 
! 		  if (global
! 		      && ! (basic_block_needs[(int) caller_save_spill_class]
! 			    [this_block]))
! 		    {
! 		      basic_block_needs[(int) caller_save_spill_class]
! 			[this_block] = 1;
! 		      new_basic_block_needs = 1;
! 		    }
! 		}
! 
! #ifdef SMALL_REGISTER_CLASSES
! 	      /* If this insn stores the value of a function call,
! 		 and that value is in a register that has been spilled,
! 		 and if the insn needs a reload in a class
! 		 that might use that register as the reload register,
! 		 then add add an extra need in that class.
! 		 This makes sure we have a register available that does
! 		 not overlap the return value.  */
! 
! 	      if (SMALL_REGISTER_CLASSES && avoid_return_reg)
! 		{
! 		  int regno = REGNO (avoid_return_reg);
! 		  int nregs
! 		    = HARD_REGNO_NREGS (regno, GET_MODE (avoid_return_reg));
! 		  int r;
! 		  int basic_needs[N_REG_CLASSES], basic_groups[N_REG_CLASSES];
! 
! 		  /* First compute the "basic needs", which counts a
! 		     need only in the smallest class in which it
! 		     is required.  */
! 
! 		  bcopy ((char *) insn_needs.other.regs[0],
! 			 (char *) basic_needs, sizeof basic_needs);
! 		  bcopy ((char *) insn_needs.other.groups,
! 			 (char *) basic_groups, sizeof basic_groups);
! 
! 		  for (i = 0; i < N_REG_CLASSES; i++)
! 		    {
! 		      enum reg_class *p;
! 
! 		      if (basic_needs[i] >= 0)
! 			for (p = reg_class_superclasses[i];
! 			     *p != LIM_REG_CLASSES; p++)
! 			  basic_needs[(int) *p] -= basic_needs[i];
! 
! 		      if (basic_groups[i] >= 0)
! 			for (p = reg_class_superclasses[i];
! 			     *p != LIM_REG_CLASSES; p++)
! 			  basic_groups[(int) *p] -= basic_groups[i];
! 		    }
! 
! 		  /* Now count extra regs if there might be a conflict with
! 		     the return value register.  */
! 
! 		  for (r = regno; r < regno + nregs; r++)
! 		    if (spill_reg_order[r] >= 0)
! 		      for (i = 0; i < N_REG_CLASSES; i++)
! 			if (TEST_HARD_REG_BIT (reg_class_contents[i], r))
! 			  {
! 			    if (basic_needs[i] > 0)
! 			      {
! 				enum reg_class *p;
! 
! 				insn_needs.other.regs[0][i]++;
! 				p = reg_class_superclasses[i];
! 				while (*p != LIM_REG_CLASSES)
! 				  insn_needs.other.regs[0][(int) *p++]++;
! 			      }
! 			    if (basic_groups[i] > 0)
! 			      {
! 				enum reg_class *p;
! 
! 				insn_needs.other.groups[i]++;
! 				p = reg_class_superclasses[i];
! 				while (*p != LIM_REG_CLASSES)
! 				  insn_needs.other.groups[(int) *p++]++;
! 			      }
! 			  }
! 		}
! #endif /* SMALL_REGISTER_CLASSES */
! 
! 	      /* For each class, collect maximum need of any insn.  */
! 
! 	      for (i = 0; i < N_REG_CLASSES; i++)
! 		{
! 		  if (max_needs[i] < insn_needs.other.regs[0][i])
! 		    {
! 		      max_needs[i] = insn_needs.other.regs[0][i];
! 		      max_needs_insn[i] = insn;
! 		    }
! 		  if (max_groups[i] < insn_needs.other.groups[i])
! 		    {
! 		      max_groups[i] = insn_needs.other.groups[i];
! 		      max_groups_insn[i] = insn;
! 		    }
! 		  if (max_nongroups[i] < insn_needs.other.regs[1][i])
! 		    {
! 		      max_nongroups[i] = insn_needs.other.regs[1][i];
! 		      max_nongroups_insn[i] = insn;
! 		    }
! 		}
  	    }
  	  /* Note that there is a continue statement above.  */
  	}
--- 1209,1216 ----
  			    insn_needs.other_addr.groups[i]);
  		}
  
! 	      /* Record the needs for later.  */
! 	      chain->need = insn_needs.other;
  	    }
  	  /* Note that there is a continue statement above.  */
  	}
*************** reload (first, global, dumpfile)
*** 1559,1585 ****
        if (starting_frame_size != get_frame_size ())
  	something_changed = 1;
  
-       if (dumpfile)
- 	for (i = 0; i < N_REG_CLASSES; i++)
- 	  {
- 	    if (max_needs[i] > 0)
- 	      fprintf (dumpfile,
- 			 ";; Need %d reg%s of class %s (for insn %d).\n",
- 		       max_needs[i], max_needs[i] == 1 ? "" : "s",
- 		       reg_class_names[i], INSN_UID (max_needs_insn[i]));
- 	    if (max_nongroups[i] > 0)
- 	      fprintf (dumpfile,
- 		       ";; Need %d nongroup reg%s of class %s (for insn %d).\n",
- 		       max_nongroups[i], max_nongroups[i] == 1 ? "" : "s",
- 		       reg_class_names[i], INSN_UID (max_nongroups_insn[i]));
- 	    if (max_groups[i] > 0)
- 	      fprintf (dumpfile,
- 		       ";; Need %d group%s (%smode) of class %s (for insn %d).\n",
- 		       max_groups[i], max_groups[i] == 1 ? "" : "s",
- 		       mode_name[(int) group_mode[i]],
- 		       reg_class_names[i], INSN_UID (max_groups_insn[i]));
- 	  }
- 			 
        /* If we have caller-saves, set up the save areas and see if caller-save
  	 will need a spill register.  */
  
--- 1220,1225 ----
*************** reload (first, global, dumpfile)
*** 1590,1607 ****
  	       ep++)
  	    ep->previous_offset = ep->max_offset;
  
! 	  if ( ! setup_save_areas (&something_changed)
! 	      && caller_save_spill_class  == NO_REGS)
  	    {
! 	      /* The class we will need depends on whether the machine
! 		 supports the sum of two registers for an address; see
! 	      find_address_reloads for details.  */
! 
! 	      caller_save_spill_class
! 		= double_reg_address_ok ? INDEX_REG_CLASS : BASE_REG_CLASS;
! 	      caller_save_group_size
! 		= CLASS_MAX_NREGS (caller_save_spill_class, Pmode);
  	      something_changed = 1;
  	    }
  	}
  
--- 1230,1240 ----
  	       ep++)
  	    ep->previous_offset = ep->max_offset;
  
! 	  if (! setup_save_areas (&something_changed))
  	    {
! 	      spill_caller_saved_regs ();
  	      something_changed = 1;
+ 	      caller_save_needed = 0;
  	    }
  	}
  
*************** reload (first, global, dumpfile)
*** 1658,1663 ****
--- 1291,1297 ----
  	 registers and see if the frame pointer is needed; it is if there is
  	 no elimination of the frame pointer that we can perform.  */
  
+       CLEAR_REG_SET (spilled_pseudos);
        frame_pointer_needed = 1;
        for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
  	{
*************** reload (first, global, dumpfile)
*** 1668,1674 ****
  	  if (! ep->can_eliminate && ep->can_eliminate_previous)
  	    {
  	      ep->can_eliminate_previous = 0;
! 	      spill_hard_reg (ep->from, global, dumpfile, 1);
  	      something_changed = 1;
  	      num_eliminable--;
  	    }
--- 1302,1308 ----
  	  if (! ep->can_eliminate && ep->can_eliminate_previous)
  	    {
  	      ep->can_eliminate_previous = 0;
! 	      spill_hard_reg (ep->from, dumpfile, 1);
  	      something_changed = 1;
  	      num_eliminable--;
  	    }
*************** reload (first, global, dumpfile)
*** 1679,2037 ****
  	 the hard frame pointer.  */
        if (frame_pointer_needed && ! previous_frame_pointer_needed)
  	{
! 	  spill_hard_reg (HARD_FRAME_POINTER_REGNUM, global, dumpfile, 1);
  	  something_changed = 1;
  	}
  #endif
  
!       /* If all needs are met, we win.  */
! 
!       for (i = 0; i < N_REG_CLASSES; i++)
! 	if (max_needs[i] > 0 || max_groups[i] > 0 || max_nongroups[i] > 0)
! 	  break;
!       if (i == N_REG_CLASSES && !new_basic_block_needs && ! something_changed)
  	break;
  
!       /* Not all needs are met; must spill some hard regs.  */
! 
!       /* Put all registers spilled so far back in potential_reload_regs, but
! 	 put them at the front, since we've already spilled most of the
! 	 pseudos in them (we might have left some pseudos unspilled if they
! 	 were in a block that didn't need any spill registers of a conflicting
! 	 class.  We used to try to mark off the need for those registers,
! 	 but doing so properly is very complex and reallocating them is the
! 	 simpler approach.  First, "pack" potential_reload_regs by pushing 
! 	 any nonnegative entries towards the end.  That will leave room 
! 	 for the registers we already spilled.
! 
! 	 Also, undo the marking of the spill registers from the last time
! 	 around in FORBIDDEN_REGS since we will be probably be allocating
! 	 them again below.
! 
! 	 ??? It is theoretically possible that we might end up not using one
! 	 of our previously-spilled registers in this allocation, even though
! 	 they are at the head of the list.  It's not clear what to do about
! 	 this, but it was no better before, when we marked off the needs met
! 	 by the previously-spilled registers.  With the current code, globals
! 	 can be allocated into these registers, but locals cannot.  */
! 
!       if (n_spills)
! 	{
! 	  for (i = j = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
! 	    if (potential_reload_regs[i] != -1)
! 	      potential_reload_regs[j--] = potential_reload_regs[i];
! 
! 	  for (i = 0; i < n_spills; i++)
! 	    {
! 	      potential_reload_regs[i] = spill_regs[i];
! 	      spill_reg_order[spill_regs[i]] = -1;
! 	      CLEAR_HARD_REG_BIT (forbidden_regs, spill_regs[i]);
! 	    }
! 
! 	  n_spills = 0;
! 	}
! 
!       /* Now find more reload regs to satisfy the remaining need
! 	 Do it by ascending class number, since otherwise a reg
! 	 might be spilled for a big class and might fail to count
! 	 for a smaller class even though it belongs to that class.
! 
! 	 Count spilled regs in `spills', and add entries to
! 	 `spill_regs' and `spill_reg_order'.
! 
! 	 ??? Note there is a problem here.
! 	 When there is a need for a group in a high-numbered class,
! 	 and also need for non-group regs that come from a lower class,
! 	 the non-group regs are chosen first.  If there aren't many regs,
! 	 they might leave no room for a group.
! 
! 	 This was happening on the 386.  To fix it, we added the code
! 	 that calls possible_group_p, so that the lower class won't
! 	 break up the last possible group.
! 
! 	 Really fixing the problem would require changes above
! 	 in counting the regs already spilled, and in choose_reload_regs.
! 	 It might be hard to avoid introducing bugs there.  */
! 
!       CLEAR_HARD_REG_SET (counted_for_groups);
!       CLEAR_HARD_REG_SET (counted_for_nongroups);
! 
!       for (class = 0; class < N_REG_CLASSES; class++)
! 	{
! 	  /* First get the groups of registers.
! 	     If we got single registers first, we might fragment
! 	     possible groups.  */
! 	  while (max_groups[class] > 0)
! 	    {
! 	      /* If any single spilled regs happen to form groups,
! 		 count them now.  Maybe we don't really need
! 		 to spill another group.  */
! 	      count_possible_groups (group_size, group_mode, max_groups,
! 				     class);
! 
! 	      if (max_groups[class] <= 0)
! 		break;
! 
! 	      /* Groups of size 2 (the only groups used on most machines)
! 		 are treated specially.  */
! 	      if (group_size[class] == 2)
! 		{
! 		  /* First, look for a register that will complete a group.  */
! 		  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 		    {
! 		      int other;
! 
! 		      j = potential_reload_regs[i];
! 		      if (j >= 0 && ! TEST_HARD_REG_BIT (bad_spill_regs, j)
! 			  &&
! 			  ((j > 0 && (other = j - 1, spill_reg_order[other] >= 0)
! 			    && TEST_HARD_REG_BIT (reg_class_contents[class], j)
! 			    && TEST_HARD_REG_BIT (reg_class_contents[class], other)
! 			    && HARD_REGNO_MODE_OK (other, group_mode[class])
! 			    && ! TEST_HARD_REG_BIT (counted_for_nongroups,
! 						    other)
! 			    /* We don't want one part of another group.
! 			       We could get "two groups" that overlap!  */
! 			    && ! TEST_HARD_REG_BIT (counted_for_groups, other))
! 			   ||
! 			   (j < FIRST_PSEUDO_REGISTER - 1
! 			    && (other = j + 1, spill_reg_order[other] >= 0)
! 			    && TEST_HARD_REG_BIT (reg_class_contents[class], j)
! 			    && TEST_HARD_REG_BIT (reg_class_contents[class], other)
! 			    && HARD_REGNO_MODE_OK (j, group_mode[class])
! 			    && ! TEST_HARD_REG_BIT (counted_for_nongroups,
! 						    other)
! 			    && ! TEST_HARD_REG_BIT (counted_for_groups,
! 						    other))))
! 			{
! 			  register enum reg_class *p;
! 
! 			  /* We have found one that will complete a group,
! 			     so count off one group as provided.  */
! 			  max_groups[class]--;
! 			  p = reg_class_superclasses[class];
! 			  while (*p != LIM_REG_CLASSES)
! 			    {
! 			      if (group_size [(int) *p] <= group_size [class])
! 				max_groups[(int) *p]--;
! 			      p++;
! 			    }
! 
! 			  /* Indicate both these regs are part of a group.  */
! 			  SET_HARD_REG_BIT (counted_for_groups, j);
! 			  SET_HARD_REG_BIT (counted_for_groups, other);
! 			  break;
! 			}
! 		    }
! 		  /* We can't complete a group, so start one.  */
! #ifdef SMALL_REGISTER_CLASSES
! 		  /* Look for a pair neither of which is explicitly used.  */
! 		  if (SMALL_REGISTER_CLASSES && i == FIRST_PSEUDO_REGISTER)
! 		    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 		      {
! 			int k;
! 			j = potential_reload_regs[i];
! 			/* Verify that J+1 is a potential reload reg.  */
! 			for (k = 0; k < FIRST_PSEUDO_REGISTER; k++)
! 			  if (potential_reload_regs[k] == j + 1)
! 			    break;
! 			if (j >= 0 && j + 1 < FIRST_PSEUDO_REGISTER
! 			    && k < FIRST_PSEUDO_REGISTER
! 			    && spill_reg_order[j] < 0 && spill_reg_order[j + 1] < 0
! 			    && TEST_HARD_REG_BIT (reg_class_contents[class], j)
! 			    && TEST_HARD_REG_BIT (reg_class_contents[class], j + 1)
! 			    && HARD_REGNO_MODE_OK (j, group_mode[class])
! 			    && ! TEST_HARD_REG_BIT (counted_for_nongroups,
! 						    j + 1)
! 			    && ! TEST_HARD_REG_BIT (bad_spill_regs, j + 1)
! 			    /* Reject J at this stage
! 			       if J+1 was explicitly used.  */
! 			    && ! regs_explicitly_used[j + 1])
! 			  break;
! 		      }
! #endif
! 		  /* Now try any group at all
! 		     whose registers are not in bad_spill_regs.  */
! 		  if (i == FIRST_PSEUDO_REGISTER)
! 		    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 		      {
! 			int k;
! 			j = potential_reload_regs[i];
! 			/* Verify that J+1 is a potential reload reg.  */
! 			for (k = 0; k < FIRST_PSEUDO_REGISTER; k++)
! 			  if (potential_reload_regs[k] == j + 1)
! 			    break;
! 			if (j >= 0 && j + 1 < FIRST_PSEUDO_REGISTER
! 			    && k < FIRST_PSEUDO_REGISTER
! 			    && spill_reg_order[j] < 0 && spill_reg_order[j + 1] < 0
! 			    && TEST_HARD_REG_BIT (reg_class_contents[class], j)
! 			    && TEST_HARD_REG_BIT (reg_class_contents[class], j + 1)
! 			    && HARD_REGNO_MODE_OK (j, group_mode[class])
! 			    && ! TEST_HARD_REG_BIT (counted_for_nongroups,
! 						    j + 1)
! 			    && ! TEST_HARD_REG_BIT (bad_spill_regs, j + 1))
! 			  break;
! 		      }
! 
! 		  /* I should be the index in potential_reload_regs
! 		     of the new reload reg we have found.  */
! 
! 		  if (i >= FIRST_PSEUDO_REGISTER)
! 		    {
! 		      /* There are no groups left to spill.  */
! 		      spill_failure (max_groups_insn[class]);
! 		      failure = 1;
! 		      goto failed;
! 		    }
! 		  else
! 		    something_changed
! 		      |= new_spill_reg (i, class, max_needs, NULL_PTR,
! 					global, dumpfile);
! 		}
! 	      else
! 		{
! 		  /* For groups of more than 2 registers,
! 		     look for a sufficient sequence of unspilled registers,
! 		     and spill them all at once.  */
! 		  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 		    {
! 		      int k;
! 
! 		      j = potential_reload_regs[i];
! 		      if (j >= 0
! 			  && j + group_size[class] <= FIRST_PSEUDO_REGISTER
! 			  && HARD_REGNO_MODE_OK (j, group_mode[class]))
! 			{
! 			  /* Check each reg in the sequence.  */
! 			  for (k = 0; k < group_size[class]; k++)
! 			    if (! (spill_reg_order[j + k] < 0
! 				   && ! TEST_HARD_REG_BIT (bad_spill_regs, j + k)
! 				   && TEST_HARD_REG_BIT (reg_class_contents[class], j + k)))
! 			      break;
! 			  /* We got a full sequence, so spill them all.  */
! 			  if (k == group_size[class])
! 			    {
! 			      register enum reg_class *p;
! 			      for (k = 0; k < group_size[class]; k++)
! 				{
! 				  int idx;
! 				  SET_HARD_REG_BIT (counted_for_groups, j + k);
! 				  for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
! 				    if (potential_reload_regs[idx] == j + k)
! 				      break;
! 				  something_changed
! 				    |= new_spill_reg (idx, class,
! 						      max_needs, NULL_PTR,
! 						      global, dumpfile);
! 				}
! 
! 			      /* We have found one that will complete a group,
! 				 so count off one group as provided.  */
! 			      max_groups[class]--;
! 			      p = reg_class_superclasses[class];
! 			      while (*p != LIM_REG_CLASSES)
! 				{
! 				  if (group_size [(int) *p]
! 				      <= group_size [class])
! 				    max_groups[(int) *p]--;
! 				  p++;
! 				}
! 			      break;
! 			    }
! 			}
! 		    }
! 		  /* We couldn't find any registers for this reload.
! 		     Avoid going into an infinite loop.  */
! 		  if (i >= FIRST_PSEUDO_REGISTER)
! 		    {
! 		      /* There are no groups left.  */
! 		      spill_failure (max_groups_insn[class]);
! 		      failure = 1;
! 		      goto failed;
! 		    }
! 		}
! 	    }
! 
! 	  /* Now similarly satisfy all need for single registers.  */
! 
! 	  while (max_needs[class] > 0 || max_nongroups[class] > 0)
! 	    {
! 	      /* If we spilled enough regs, but they weren't counted
! 		 against the non-group need, see if we can count them now.
! 		 If so, we can avoid some actual spilling.  */
! 	      if (max_needs[class] <= 0 && max_nongroups[class] > 0)
! 		for (i = 0; i < n_spills; i++)
! 		  if (TEST_HARD_REG_BIT (reg_class_contents[class],
! 					 spill_regs[i])
! 		      && !TEST_HARD_REG_BIT (counted_for_groups,
! 					     spill_regs[i])
! 		      && !TEST_HARD_REG_BIT (counted_for_nongroups,
! 					     spill_regs[i])
! 		      && max_nongroups[class] > 0)
! 		    {
! 		      register enum reg_class *p;
! 
! 		      SET_HARD_REG_BIT (counted_for_nongroups, spill_regs[i]);
! 		      max_nongroups[class]--;
! 		      p = reg_class_superclasses[class];
! 		      while (*p != LIM_REG_CLASSES)
! 			max_nongroups[(int) *p++]--;
! 		    }
! 	      if (max_needs[class] <= 0 && max_nongroups[class] <= 0)
! 		break;
! 
! 	      /* Consider the potential reload regs that aren't
! 		 yet in use as reload regs, in order of preference.
! 		 Find the most preferred one that's in this class.  */
! 
! 	      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 		if (potential_reload_regs[i] >= 0
! 		    && TEST_HARD_REG_BIT (reg_class_contents[class],
! 					  potential_reload_regs[i])
! 		    /* If this reg will not be available for groups,
! 		       pick one that does not foreclose possible groups.
! 		       This is a kludge, and not very general,
! 		       but it should be sufficient to make the 386 work,
! 		       and the problem should not occur on machines with
! 		       more registers.  */
! 		    && (max_nongroups[class] == 0
! 			|| possible_group_p (potential_reload_regs[i], max_groups)))
! 		  break;
! 
! 	      /* If we couldn't get a register, try to get one even if we
! 		 might foreclose possible groups.  This may cause problems
! 		 later, but that's better than aborting now, since it is
! 		 possible that we will, in fact, be able to form the needed
! 		 group even with this allocation.  */
! 
! 	      if (i >= FIRST_PSEUDO_REGISTER
! 		  && (asm_noperands (max_needs[class] > 0
! 				     ? max_needs_insn[class]
! 				     : max_nongroups_insn[class])
! 		      < 0))
! 		for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 		  if (potential_reload_regs[i] >= 0
! 		      && TEST_HARD_REG_BIT (reg_class_contents[class],
! 					    potential_reload_regs[i]))
! 		    break;
  
! 	      /* I should be the index in potential_reload_regs
! 		 of the new reload reg we have found.  */
  
! 	      if (i >= FIRST_PSEUDO_REGISTER)
! 		{
! 		  /* There are no possible registers left to spill.  */
! 		  spill_failure (max_needs[class] > 0 ? max_needs_insn[class]
! 				 : max_nongroups_insn[class]);
! 		  failure = 1;
! 		  goto failed;
! 		}
! 	      else
! 		something_changed
! 		  |= new_spill_reg (i, class, max_needs, max_nongroups,
! 				    global, dumpfile);
! 	    }
! 	}
      }
  
    /* If global-alloc was run, notify it of any register eliminations we have
--- 1313,1337 ----
  	 the hard frame pointer.  */
        if (frame_pointer_needed && ! previous_frame_pointer_needed)
  	{
! 	  spill_hard_reg (HARD_FRAME_POINTER_REGNUM, dumpfile, 1);
  	  something_changed = 1;
  	}
  #endif
  
!       /* Short cut for functions that don't need reloading.  */
!       if (! something_changed && ! something_needs_reloads)
  	break;
  
!       CLEAR_HARD_REG_SET (used_spill_regs);
!       /* Try to satisfy the needs for each insn.  */
!       for (chain = reload_insn_chain; chain; chain = chain->next)
! 	if (chain->need_reload)
! 	  find_reload_regs (chain, global, dumpfile);
  
!       if (failure)
! 	goto failed;
  
!       something_changed |= finish_spills (global, dumpfile);
      }
  
    /* If global-alloc was run, notify it of any register eliminations we have
*************** reload (first, global, dumpfile)
*** 2042,2054 ****
  	mark_elimination (ep->from, ep->to);
  
    /* Insert code to save and restore call-clobbered hard regs
!      around calls.  Tell if what mode to use so that we will process
!      those insns in reload_as_needed if we have to.  */
  
    if (caller_save_needed)
!     save_call_clobbered_regs (num_eliminable ? QImode
! 			      : caller_save_spill_class != NO_REGS ? HImode
! 			      : VOIDmode);
  
    /* If a pseudo has no hard reg, delete the insns that made the equivalence.
       If that insn didn't set the register (i.e., it copied the register to
--- 1342,1351 ----
  	mark_elimination (ep->from, ep->to);
  
    /* Insert code to save and restore call-clobbered hard regs
!      around calls.  */
  
    if (caller_save_needed)
!     save_call_clobbered_regs (num_eliminable != 0);
  
    /* If a pseudo has no hard reg, delete the insns that made the equivalence.
       If that insn didn't set the register (i.e., it copied the register to
*************** reload (first, global, dumpfile)
*** 2076,2083 ****
       values into or out of the reload registers.  */
  
    if (something_needs_reloads || something_needs_elimination
!       || (caller_save_needed && num_eliminable)
!       || caller_save_spill_class != NO_REGS)
      reload_as_needed (first, global);
  
    /* If we were able to eliminate the frame pointer, show that it is no
--- 1373,1379 ----
       values into or out of the reload registers.  */
  
    if (something_needs_reloads || something_needs_elimination
!       || (caller_save_needed && num_eliminable))
      reload_as_needed (first, global);
  
    /* If we were able to eliminate the frame pointer, show that it is no
*************** reload (first, global, dumpfile)
*** 2177,2209 ****
    if (real_at_ptr)
      free (real_at_ptr);
  
!   if (scratch_list)
!     free (scratch_list);
!   scratch_list = 0;
!   if (scratch_block)
!     free (scratch_block);
!   scratch_block = 0;
! 
!   CLEAR_HARD_REG_SET (used_spill_regs);
!   for (i = 0; i < n_spills; i++)
!     SET_HARD_REG_BIT (used_spill_regs, spill_regs[i]);
  
    return failure;
  }
  \f
  /* Nonzero if, after spilling reg REGNO for non-groups,
     it will still be possible to find a group if we still need one.  */
  
  static int
! possible_group_p (regno, max_groups)
       int regno;
-      int *max_groups;
  {
    int i;
    int class = (int) NO_REGS;
  
    for (i = 0; i < (int) N_REG_CLASSES; i++)
!     if (max_groups[i] > 0)
        {
  	class = i;
  	break;
--- 1473,1645 ----
    if (real_at_ptr)
      free (real_at_ptr);
  
!   FREE_REG_SET (spilled_pseudos);
  
+   obstack_free (&reload_obstack, reload_startobj);
    return failure;
  }
  \f
+ /* Describes order of preference for putting regs into spill_regs.
+    Contains the numbers of all the hard regs, in order most preferred first.
+    This order is different for each function.
+    It is set up by order_regs_for_reload.
+    Empty elements at the end contain -1.  */
+ static short potential_reload_regs[FIRST_PSEUDO_REGISTER];
+ 
+ struct hard_reg_n_uses
+ {
+   int regno;
+   unsigned int uses;
+ };
+ 
+ static int
+ hard_reg_use_compare (p1p, p2p)
+   const GENERIC_PTR p1p;
+   const GENERIC_PTR p2p;
+ {
+   struct hard_reg_n_uses *p1 = (struct hard_reg_n_uses *)p1p,
+ 			 *p2 = (struct hard_reg_n_uses *)p2p;
+   int bad1 = TEST_HARD_REG_BIT (bad_spill_regs, p1->regno);
+   int bad2 = TEST_HARD_REG_BIT (bad_spill_regs, p2->regno);
+   if (bad1 && bad2)
+     return p1->regno - p2->regno;
+   if (bad1)
+     return 1;
+   if (bad2)
+     return -1;
+   if (p1->uses > p2->uses)
+     return 1;
+   if (p1->uses < p2->uses)
+     return -1;
+   /* If regs are equally good, sort by regno,
+      so that the results of qsort leave nothing to chance.  */
+   return p1->regno - p2->regno;
+ }
+ 
+ /* Choose the order to consider regs for use as reload registers
+    based on how much trouble would be caused by spilling one.
+    Store them in order of decreasing preference in potential_reload_regs.  */
+ 
+ static void
+ order_regs_for_reload (chain, global)
+      struct insn_chain *chain;
+      int global;
+ {
+   register int i;
+   register int o = 0;
+ 
+   struct hard_reg_n_uses hard_reg_n_uses[FIRST_PSEUDO_REGISTER];
+ 
+   CLEAR_HARD_REG_SET (bad_spill_regs);
+ 
+   /* Count number of uses of each hard reg by pseudo regs allocated to it
+      and then order them by decreasing use.  */
+ 
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     {
+       int regno;
+ 
+       hard_reg_n_uses[i].regno = i;
+       hard_reg_n_uses[i].uses = 0;
+ 
+       if (fixed_regs[i] || i == HARD_FRAME_POINTER_REGNUM)
+ 	{
+ 	  SET_HARD_REG_BIT (bad_spill_regs, i);
+ 	  continue;
+ 	}
+ 
+       regno = chain->inverse_renum_before[i];
+       if (regno < 0)
+ 	SET_HARD_REG_BIT (bad_spill_regs, i);
+       else if (regno > 0 && ! REGNO_REG_SET_P (spilled_pseudos, regno))
+ 	{
+ 	  /* If allocated by local-alloc, show more uses since
+ 	     we're not going to be able to reallocate it, but
+ 	     we might if allocated by global alloc.  */
+ 	  if (global && reg_allocno[regno] < 0)
+ 	    hard_reg_n_uses[i].uses += (REG_N_REFS (regno) + 1) / 2;
+ 
+ 	  hard_reg_n_uses[i].uses += REG_N_REFS (regno);
+ 	}
+ 
+       regno = chain->inverse_renum_after[i];
+       if (regno < 0)
+ 	SET_HARD_REG_BIT (bad_spill_regs, i);
+       else if (regno > 0 && ! REGNO_REG_SET_P (spilled_pseudos, regno)
+ 	       && regno != chain->inverse_renum_before[i])
+ 	{
+ 	  if (global && reg_allocno[regno] < 0)
+ 	    hard_reg_n_uses[i].uses += (REG_N_REFS (regno) + 1) / 2;
+ 
+ 	  hard_reg_n_uses[i].uses += REG_N_REFS (regno);
+ 	}
+     }
+ 
+ #ifdef ELIMINABLE_REGS
+   /* If registers other than the frame pointer are eliminable, mark them as
+      poor choices.  */
+   for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
+     SET_HARD_REG_BIT (bad_spill_regs, reg_eliminate[i].from);
+ 
+ #endif
+ 
+   /* Prefer registers not so far used, for use in temporary loading.
+      Among them, if REG_ALLOC_ORDER is defined, use that order.
+      Otherwise, prefer registers not preserved by calls.  */
+ 
+ #ifdef REG_ALLOC_ORDER
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     {
+       int regno = reg_alloc_order[i];
+ 
+       if (hard_reg_n_uses[regno].uses == 0
+ 	  && ! TEST_HARD_REG_BIT (bad_spill_regs, regno))
+ 	potential_reload_regs[o++] = regno;
+     }
+ #else
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     {
+       if (hard_reg_n_uses[i].uses == 0 && call_used_regs[i]
+ 	  && ! TEST_HARD_REG_BIT (bad_spill_regs, i))
+ 	potential_reload_regs[o++] = i;
+     }
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     {
+       if (hard_reg_n_uses[i].uses == 0 && ! call_used_regs[i]
+ 	  && ! TEST_HARD_REG_BIT (bad_spill_regs, i))
+ 	potential_reload_regs[o++] = i;
+     }
+ #endif
+ 
+   qsort (hard_reg_n_uses, FIRST_PSEUDO_REGISTER,
+ 	 sizeof hard_reg_n_uses[0], hard_reg_use_compare);
+ 
+   /* Now add the regs that are already used,
+      preferring those used less often.  The fixed and otherwise forbidden
+      registers will be at the end of this list.  */
+ 
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     if (hard_reg_n_uses[i].uses != 0
+ 	&& ! TEST_HARD_REG_BIT (bad_spill_regs, hard_reg_n_uses[i].regno))
+       potential_reload_regs[o++] = hard_reg_n_uses[i].regno;
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     if (TEST_HARD_REG_BIT (bad_spill_regs, hard_reg_n_uses[i].regno))
+       potential_reload_regs[o++] = hard_reg_n_uses[i].regno;
+ }
+ 
  /* Nonzero if, after spilling reg REGNO for non-groups,
     it will still be possible to find a group if we still need one.  */
  
  static int
! possible_group_p (chain, regno)
!      struct insn_chain *chain;
       int regno;
  {
    int i;
    int class = (int) NO_REGS;
  
    for (i = 0; i < (int) N_REG_CLASSES; i++)
!     if (chain->need.groups[i] > 0)
        {
  	class = i;
  	break;
*************** possible_group_p (regno, max_groups)
*** 2238,2265 ****
        if (spill_reg_order[i] < 0
  	  && ! TEST_HARD_REG_BIT (bad_spill_regs, i)
  	  && spill_reg_order[i + 1] >= 0
! 	  && ! TEST_HARD_REG_BIT (counted_for_groups, i + 1)
! 	  && ! TEST_HARD_REG_BIT (counted_for_nongroups, i + 1))
  	return 1;
        if (spill_reg_order[i + 1] < 0
  	  && ! TEST_HARD_REG_BIT (bad_spill_regs, i + 1)
  	  && spill_reg_order[i] >= 0
! 	  && ! TEST_HARD_REG_BIT (counted_for_groups, i)
! 	  && ! TEST_HARD_REG_BIT (counted_for_nongroups, i))
  	return 1;
      }
  
    return 0;
  }
! \f
  /* Count any groups of CLASS that can be formed from the registers recently
     spilled.  */
  
  static void
! count_possible_groups (group_size, group_mode, max_groups, class)
!      int *group_size;
!      enum machine_mode *group_mode;
!      int *max_groups;
       int class;
  {
    HARD_REG_SET new;
--- 1674,1699 ----
        if (spill_reg_order[i] < 0
  	  && ! TEST_HARD_REG_BIT (bad_spill_regs, i)
  	  && spill_reg_order[i + 1] >= 0
! 	  && ! TEST_HARD_REG_BIT (chain->counted_for_groups, i + 1)
! 	  && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, i + 1))
  	return 1;
        if (spill_reg_order[i + 1] < 0
  	  && ! TEST_HARD_REG_BIT (bad_spill_regs, i + 1)
  	  && spill_reg_order[i] >= 0
! 	  && ! TEST_HARD_REG_BIT (chain->counted_for_groups, i)
! 	  && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, i))
  	return 1;
      }
  
    return 0;
  }
! 
  /* Count any groups of CLASS that can be formed from the registers recently
     spilled.  */
  
  static void
! count_possible_groups (chain, class)
!      struct insn_chain *chain;
       int class;
  {
    HARD_REG_SET new;
*************** count_possible_groups (group_size, group
*** 2269,2314 ****
       and mark each group off against the need for such groups.
       But don't count them against ordinary need, yet.  */
  
!   if (group_size[class] == 0)
      return;
  
    CLEAR_HARD_REG_SET (new);
  
    /* Make a mask of all the regs that are spill regs in class I.  */
    for (i = 0; i < n_spills; i++)
!     if (TEST_HARD_REG_BIT (reg_class_contents[class], spill_regs[i])
! 	&& ! TEST_HARD_REG_BIT (counted_for_groups, spill_regs[i])
! 	&& ! TEST_HARD_REG_BIT (counted_for_nongroups, spill_regs[i]))
!       SET_HARD_REG_BIT (new, spill_regs[i]);
  
    /* Find each consecutive group of them.  */
!   for (i = 0; i < FIRST_PSEUDO_REGISTER && max_groups[class] > 0; i++)
      if (TEST_HARD_REG_BIT (new, i)
! 	&& i + group_size[class] <= FIRST_PSEUDO_REGISTER
! 	&& HARD_REGNO_MODE_OK (i, group_mode[class]))
        {
! 	for (j = 1; j < group_size[class]; j++)
  	  if (! TEST_HARD_REG_BIT (new, i + j))
  	    break;
  
! 	if (j == group_size[class])
  	  {
  	    /* We found a group.  Mark it off against this class's need for
  	       groups, and against each superclass too.  */
  	    register enum reg_class *p;
  
! 	    max_groups[class]--;
  	    p = reg_class_superclasses[class];
  	    while (*p != LIM_REG_CLASSES)
  	      {
! 		if (group_size [(int) *p] <= group_size [class])
! 		  max_groups[(int) *p]--;
  		p++;
  	      }
  
  	    /* Don't count these registers again.  */
! 	    for (j = 0; j < group_size[class]; j++)
! 	      SET_HARD_REG_BIT (counted_for_groups, i + j);
  	  }
  
  	/* Skip to the last reg in this group.  When i is incremented above,
--- 1703,1752 ----
       and mark each group off against the need for such groups.
       But don't count them against ordinary need, yet.  */
  
!   if (chain->group_size[class] == 0)
      return;
  
    CLEAR_HARD_REG_SET (new);
  
    /* Make a mask of all the regs that are spill regs in class I.  */
    for (i = 0; i < n_spills; i++)
!     {
!       int regno = spill_regs[i];
! 
!       if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
! 	  && ! TEST_HARD_REG_BIT (chain->counted_for_groups, regno)
! 	  && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, regno))
! 	SET_HARD_REG_BIT (new, regno);
!     }
  
    /* Find each consecutive group of them.  */
!   for (i = 0; i < FIRST_PSEUDO_REGISTER && chain->need.groups[class] > 0; i++)
      if (TEST_HARD_REG_BIT (new, i)
! 	&& i + chain->group_size[class] <= FIRST_PSEUDO_REGISTER
! 	&& HARD_REGNO_MODE_OK (i, chain->group_mode[class]))
        {
! 	for (j = 1; j < chain->group_size[class]; j++)
  	  if (! TEST_HARD_REG_BIT (new, i + j))
  	    break;
  
! 	if (j == chain->group_size[class])
  	  {
  	    /* We found a group.  Mark it off against this class's need for
  	       groups, and against each superclass too.  */
  	    register enum reg_class *p;
  
! 	    chain->need.groups[class]--;
  	    p = reg_class_superclasses[class];
  	    while (*p != LIM_REG_CLASSES)
  	      {
! 		if (chain->group_size [(int) *p] <= chain->group_size [class])
! 		  chain->need.groups[(int) *p]--;
  		p++;
  	      }
  
  	    /* Don't count these registers again.  */
! 	    for (j = 0; j < chain->group_size[class]; j++)
! 	      SET_HARD_REG_BIT (chain->counted_for_groups, i + j);
  	  }
  
  	/* Skip to the last reg in this group.  When i is incremented above,
*************** count_possible_groups (group_size, group
*** 2316,2349 ****
  	i += j - 1;
        }
  }
- \f
- /* ALLOCATE_MODE is a register mode that needs to be reloaded.  OTHER_MODE is
-    another mode that needs to be reloaded for the same register class CLASS.
-    If any reg in CLASS allows ALLOCATE_MODE but not OTHER_MODE, fail.
-    ALLOCATE_MODE will never be smaller than OTHER_MODE.
- 
-    This code used to also fail if any reg in CLASS allows OTHER_MODE but not
-    ALLOCATE_MODE.  This test is unnecessary, because we will never try to put
-    something of mode ALLOCATE_MODE into an OTHER_MODE register.  Testing this
-    causes unnecessary failures on machines requiring alignment of register
-    groups when the two modes are different sizes, because the larger mode has
-    more strict alignment rules than the smaller mode.  */
- 
- static int
- modes_equiv_for_class_p (allocate_mode, other_mode, class)
-      enum machine_mode allocate_mode, other_mode;
-      enum reg_class class;
- {
-   register int regno;
-   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-     {
-       if (TEST_HARD_REG_BIT (reg_class_contents[(int) class], regno)
- 	  && HARD_REGNO_MODE_OK (regno, allocate_mode)
- 	  && ! HARD_REGNO_MODE_OK (regno, other_mode))
- 	return 0;
-     }
-   return 1;
- }
  
  /* Handle the failure to find a register to spill.
     INSN should be one of the insns which needed this particular spill reg.  */
--- 1754,1759 ----
*************** spill_failure (insn)
*** 2358,2392 ****
      fatal_insn ("Unable to find a register to spill.", insn);
  }
  
! /* Add a new register to the tables of available spill-registers
!     (as well as spilling all pseudos allocated to the register).
     I is the index of this register in potential_reload_regs.
     CLASS is the regclass whose need is being satisfied.
!    MAX_NEEDS and MAX_NONGROUPS are the vectors of needs,
!     so that this register can count off against them.
!     MAX_NONGROUPS is 0 if this register is part of a group.
!    GLOBAL and DUMPFILE are the same as the args that `reload' got.  */
  
! static int
! new_spill_reg (i, class, max_needs, max_nongroups, global, dumpfile)
       int i;
       int class;
!      int *max_needs;
!      int *max_nongroups;
!      int global;
       FILE *dumpfile;
  {
    register enum reg_class *p;
-   int val;
    int regno = potential_reload_regs[i];
  
    if (i >= FIRST_PSEUDO_REGISTER)
!     abort ();	/* Caller failed to find any register.  */
  
!   if (fixed_regs[regno] || TEST_HARD_REG_BIT (forbidden_regs, regno))
!     fatal ("fixed or forbidden register was spilled.\n\
  This may be due to a compiler bug or to impossible asm\n\
  statements or clauses.");
  
    /* Make reg REGNO an additional reload reg.  */
  
--- 1768,1813 ----
      fatal_insn ("Unable to find a register to spill.", insn);
  }
  
! /* Add a new register to the tables of available spill-registers.
!    CHAIN is the insn for which the register will be used; we decrease the
!    needs of that insn.
     I is the index of this register in potential_reload_regs.
     CLASS is the regclass whose need is being satisfied.
!    NONGROUP is 0 if this register is part of a group.
!    DUMPFILE is the same as the one that `reload' got.  */
  
! static void
! new_spill_reg (chain, i, class, nongroup, dumpfile)
!      struct insn_chain *chain;
       int i;
       int class;
!      int nongroup;
       FILE *dumpfile;
  {
    register enum reg_class *p;
    int regno = potential_reload_regs[i];
  
    if (i >= FIRST_PSEUDO_REGISTER)
!     {
!       spill_failure (chain->insn);
!       failure = 1;
!       return;
!     }
  
!   if (TEST_HARD_REG_BIT (bad_spill_regs, regno))
!     {
!       /* Some software, notably the Linux kernel on the i386, contains bogus
! 	 asm statements that need a register from a single class for an input
! 	 reload, but also contain a CLOBBER of that register.  According to
! 	 a comment in reload.c, a CLOBBER makes a register unavailable from
! 	 before the insn until after it, so the asm statements are wrong. For
! 	 now, add this kludge.  */
!       if (asm_noperands (PATTERN (chain->insn)) < 0
! 	  || reg_class_size[class] > 1)
! 	fatal ("fixed or forbidden register was spilled.\n\
  This may be due to a compiler bug or to impossible asm\n\
  statements or clauses.");
+     }
  
    /* Make reg REGNO an additional reload reg.  */
  
*************** statements or clauses.");
*** 2394,2442 ****
    spill_regs[n_spills] = regno;
    spill_reg_order[regno] = n_spills;
    if (dumpfile)
!     fprintf (dumpfile, "Spilling reg %d.\n", spill_regs[n_spills]);
  
    /* Clear off the needs we just satisfied.  */
  
!   max_needs[class]--;
    p = reg_class_superclasses[class];
    while (*p != LIM_REG_CLASSES)
!     max_needs[(int) *p++]--;
  
!   if (max_nongroups && max_nongroups[class] > 0)
      {
!       SET_HARD_REG_BIT (counted_for_nongroups, regno);
!       max_nongroups[class]--;
        p = reg_class_superclasses[class];
        while (*p != LIM_REG_CLASSES)
! 	max_nongroups[(int) *p++]--;
      }
  
!   /* Spill every pseudo reg that was allocated to this reg
!      or to something that overlaps this reg.  */
  
!   val = spill_hard_reg (spill_regs[n_spills], global, dumpfile, 0);
  
!   /* If there are some registers still to eliminate and this register
!      wasn't ever used before, additional stack space may have to be
!      allocated to store this register.  Thus, we may have changed the offset
!      between the stack and frame pointers, so mark that something has changed.
!      (If new pseudos were spilled, thus requiring more space, VAL would have
!      been set non-zero by the call to spill_hard_reg above since additional
!      reloads may be needed in that case.
  
!      One might think that we need only set VAL to 1 if this is a call-used
!      register.  However, the set of registers that must be saved by the
!      prologue is not identical to the call-used set.  For example, the
!      register used by the call insn for the return PC is a call-used register,
!      but must be saved by the prologue.  */
!   if (num_eliminable && ! regs_ever_live[spill_regs[n_spills]])
!     val = 1;
  
!   regs_ever_live[spill_regs[n_spills]] = 1;
!   n_spills++;
  
!   return val;
  }
  \f
  /* Delete an unneeded INSN and any previous insns who sole purpose is loading
--- 1815,2169 ----
    spill_regs[n_spills] = regno;
    spill_reg_order[regno] = n_spills;
    if (dumpfile)
!     fprintf (dumpfile, "Spilling reg %d.\n", regno);
!   SET_HARD_REG_BIT (chain->used_spill_regs, regno);
  
    /* Clear off the needs we just satisfied.  */
  
!   chain->need.regs[0][class]--;
    p = reg_class_superclasses[class];
    while (*p != LIM_REG_CLASSES)
!     chain->need.regs[0][(int) *p++]--;
  
!   if (nongroup && chain->need.regs[1][class] > 0)
      {
!       SET_HARD_REG_BIT (chain->counted_for_nongroups, regno);
!       chain->need.regs[1][class]--;
        p = reg_class_superclasses[class];
        while (*p != LIM_REG_CLASSES)
! 	chain->need.regs[1][(int) *p++]--;
      }
  
!   n_spills++;
! }
  
! static void
! find_tworeg_group (chain, class, dumpfile)
!      struct insn_chain *chain;
!      int class;
!      FILE *dumpfile;
! {
!   int i;
!   /* First, look for a register that will complete a group.  */
!   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
!     {
!       int j, other;
  
!       j = potential_reload_regs[i];
!       if (j >= 0 && ! TEST_HARD_REG_BIT (bad_spill_regs, j)
! 	  && ((j > 0 && (other = j - 1, spill_reg_order[other] >= 0)
! 	       && TEST_HARD_REG_BIT (reg_class_contents[class], j)
! 	       && TEST_HARD_REG_BIT (reg_class_contents[class], other)
! 	       && HARD_REGNO_MODE_OK (other, chain->group_mode[class])
! 	       && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, other)
! 	       /* We don't want one part of another group.
! 		  We could get "two groups" that overlap!  */
! 	       && ! TEST_HARD_REG_BIT (chain->counted_for_groups, other))
! 	      ||
! 	      (j < FIRST_PSEUDO_REGISTER - 1
! 	       && (other = j + 1, spill_reg_order[other] >= 0)
! 	       && TEST_HARD_REG_BIT (reg_class_contents[class], j)
! 	       && TEST_HARD_REG_BIT (reg_class_contents[class], other)
! 	       && HARD_REGNO_MODE_OK (j, chain->group_mode[class])
! 	       && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, other)
! 	       && ! TEST_HARD_REG_BIT (chain->counted_for_groups, other))))
! 	{
! 	  register enum reg_class *p;
  
! 	  /* We have found one that will complete a group,
! 	     so count off one group as provided.  */
! 	  chain->need.groups[class]--;
! 	  p = reg_class_superclasses[class];
! 	  while (*p != LIM_REG_CLASSES)
! 	    {
! 	      if (chain->group_size [(int) *p] <= chain->group_size [class])
! 		chain->need.groups[(int) *p]--;
! 	      p++;
! 	    }
  
! 	  /* Indicate both these regs are part of a group.  */
! 	  SET_HARD_REG_BIT (chain->counted_for_groups, j);
! 	  SET_HARD_REG_BIT (chain->counted_for_groups, other);
! 	  break;
! 	}
!     }
!   /* We can't complete a group, so start one.  */
!   if (i == FIRST_PSEUDO_REGISTER)
!     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
!       {
! 	int k, j;
! 	j = potential_reload_regs[i];
! 	/* Verify that J+1 is a potential reload reg.  */
! 	for (k = 0; k < FIRST_PSEUDO_REGISTER; k++)
! 	  if (potential_reload_regs[k] == j + 1)
! 	    break;
! 	if (j >= 0 && j + 1 < FIRST_PSEUDO_REGISTER
! 	    && k < FIRST_PSEUDO_REGISTER
! 	    && spill_reg_order[j] < 0 && spill_reg_order[j + 1] < 0
! 	    && TEST_HARD_REG_BIT (reg_class_contents[class], j)
! 	    && TEST_HARD_REG_BIT (reg_class_contents[class], j + 1)
! 	    && HARD_REGNO_MODE_OK (j, chain->group_mode[class])
! 	    && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, j + 1)
! 	    && ! TEST_HARD_REG_BIT (bad_spill_regs, j + 1))
! 	  break;
!       }
  
!   /* I should be the index in potential_reload_regs
!      of the new reload reg we have found.  */
! 
!   new_spill_reg (chain, i, class, 0, dumpfile);
! }
! 
! static void
! find_group (chain, class, dumpfile)
!      struct insn_chain *chain;
!      int class;
!      FILE *dumpfile;
! {
!   int i;
! 
!   /* For groups of more than 2 registers,
!      look for a sufficient sequence of unspilled registers,
!      and spill them all at once.  */
!   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
!     {
!       int j = potential_reload_regs[i];
! 
!       if (j >= 0
! 	  && j + chain->group_size[class] <= FIRST_PSEUDO_REGISTER
! 	  && HARD_REGNO_MODE_OK (j, chain->group_mode[class]))
! 	{
! 	  int k;
! 	  /* Check each reg in the sequence.  */
! 	  for (k = 0; k < chain->group_size[class]; k++)
! 	    if (! (spill_reg_order[j + k] < 0
! 		   && ! TEST_HARD_REG_BIT (bad_spill_regs, j + k)
! 		   && TEST_HARD_REG_BIT (reg_class_contents[class], j + k)))
! 	      break;
! 	  /* We got a full sequence, so spill them all.  */
! 	  if (k == chain->group_size[class])
! 	    {
! 	      register enum reg_class *p;
! 	      for (k = 0; k < chain->group_size[class]; k++)
! 		{
! 		  int idx;
! 		  SET_HARD_REG_BIT (chain->counted_for_groups, j + k);
! 		  for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
! 		    if (potential_reload_regs[idx] == j + k)
! 		      break;
! 		  new_spill_reg (chain, idx, class, 0, dumpfile);
! 		}
! 
! 	      /* We have found one that will complete a group,
! 		 so count off one group as provided.  */
! 	      chain->need.groups[class]--;
! 	      p = reg_class_superclasses[class];
! 	      while (*p != LIM_REG_CLASSES)
! 		{
! 		  if (chain->group_size [(int) *p]
! 		      <= chain->group_size [class])
! 		    chain->need.groups[(int) *p]--;
! 		  p++;
! 		}
! 	      return;
! 	    }
! 	}
!     }
!   /* There are no groups left.  */
!   spill_failure (chain->insn);
!   failure = 1;
! }
! 
! /* For an insn, given by CHAIN, for which the needs have been calculated,
!    select a set of registers to use for reloading.  */
! static void
! find_reload_regs (chain, global, dumpfile)
!      struct insn_chain *chain;
!      int global;
!      FILE *dumpfile;
! {
!   int i, class;
!   short *group_needs = chain->need.groups;
!   short *simple_needs = chain->need.regs[0];
!   short *nongroup_needs = chain->need.regs[1];
! 
!   if (dumpfile)
!     fprintf (dumpfile, "Spilling for insn %d.\n", INSN_UID (chain->insn));
! 
!   /* Compute the order of preference for hard registers to spill.
!      Store them by decreasing preference in potential_reload_regs.  */
! 
!   order_regs_for_reload (chain, global);
! 
!   /* So far, no hard regs have been spilled.  */
!   n_spills = 0;
!   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
!     spill_reg_order[i] = -1;
! 
!   /* Choose regs by ascending class number, since otherwise a reg
!      might be spilled for a big class and might fail to count
!      for a smaller class even though it belongs to that class.
! 
!      Count spilled regs in `n_spills', and add entries to
!      `spill_regs' and `spill_reg_order'.
! 
!      ??? Note there is a problem here.
!      When there is a need for a group in a high-numbered class,
!      and also need for non-group regs that come from a lower class,
!      the non-group regs are chosen first.  If there aren't many regs,
!      they might leave no room for a group.
! 
!      This was happening on the 386.  To fix it, we added the code
!      that calls possible_group_p, so that the lower class won't
!      break up the last possible group.
! 
!      Really fixing the problem would require changes above
!      in counting the regs already spilled, and in choose_reload_regs.
!      It might be hard to avoid introducing bugs there.  */
! 
!   CLEAR_HARD_REG_SET (chain->used_spill_regs);
!   CLEAR_HARD_REG_SET (chain->counted_for_groups);
!   CLEAR_HARD_REG_SET (chain->counted_for_nongroups);
! 
!   for (class = 0; class < N_REG_CLASSES; class++)
!     {
!       /* First get the groups of registers.
! 	 If we got single registers first, we might fragment
! 	 possible groups.  */
!       while (group_needs[class] > 0)
! 	{
! 	  /* If any single spilled regs happen to form groups,
! 	     count them now.  Maybe we don't really need
! 	     to spill another group.  */
! 	  count_possible_groups (chain, class);
! 
! 	  if (group_needs[class] <= 0)
! 	    break;
! 
! 	  /* Groups of size 2, the only groups used on most machines,
! 	     are treated specially.  */
! 	  if (chain->group_size[class] == 2)
! 	    find_tworeg_group (chain, class, dumpfile);
! 	  else
! 	    find_group (chain, class, dumpfile);
! 	  if (failure)
! 	    return;
! 	}
! 
!       /* Now similarly satisfy all need for single registers.  */
! 
!       while (simple_needs[class] > 0 || nongroup_needs[class] > 0)
! 	{
! 	  /* If we spilled enough regs, but they weren't counted
! 	     against the non-group need, see if we can count them now.
! 	     If so, we can avoid some actual spilling.  */
! 	  if (simple_needs[class] <= 0 && nongroup_needs[class] > 0)
! 	    for (i = 0; i < n_spills; i++)
! 	      {
! 		int regno = spill_regs[i];
! 		if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
! 		    && !TEST_HARD_REG_BIT (chain->counted_for_groups, regno)
! 		    && !TEST_HARD_REG_BIT (chain->counted_for_nongroups, regno)
! 		    && nongroup_needs[class] > 0)
! 		  {
! 		    register enum reg_class *p;
! 
! 		    SET_HARD_REG_BIT (chain->counted_for_nongroups, regno);
! 		    nongroup_needs[class]--;
! 		    p = reg_class_superclasses[class];
! 		    while (*p != LIM_REG_CLASSES)
! 		      nongroup_needs[(int) *p++]--;
! 		  }
! 	      }
! 	  
! 	  if (simple_needs[class] <= 0 && nongroup_needs[class] <= 0)
! 	    break;
! 
! 	  /* Consider the potential reload regs that aren't
! 	     yet in use as reload regs, in order of preference.
! 	     Find the most preferred one that's in this class.  */
! 
! 	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 	    {
! 	      int regno = potential_reload_regs[i];
! 	      if (regno >= 0
! 		  && TEST_HARD_REG_BIT (reg_class_contents[class], regno)
! 		  /* If this reg will not be available for groups,
! 		     pick one that does not foreclose possible groups.
! 		     This is a kludge, and not very general,
! 		     but it should be sufficient to make the 386 work,
! 		     and the problem should not occur on machines with
! 		     more registers.  */
! 		  && (nongroup_needs[class] == 0
! 		      || possible_group_p (chain, regno)))
! 		break;
! 	    }
! 
! 	  /* If we couldn't get a register, try to get one even if we
! 	     might foreclose possible groups.  This may cause problems
! 	     later, but that's better than aborting now, since it is
! 	     possible that we will, in fact, be able to form the needed
! 	     group even with this allocation.  */
! 
! 	  if (i >= FIRST_PSEUDO_REGISTER
! 	      && asm_noperands (chain->insn) < 0)
! 	    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 	      if (potential_reload_regs[i] >= 0
! 		  && TEST_HARD_REG_BIT (reg_class_contents[class],
! 					potential_reload_regs[i]))
! 		break;
! 
! 	  /* I should be the index in potential_reload_regs
! 	     of the new reload reg we have found.  */
! 
! 	  new_spill_reg (chain, i, class, 1, dumpfile);
! 	  if (failure)
! 	    return;
! 	}
!     }
!   
!   /* We know which hard regs to use, now mark the pseudos that live in them
!      as needing to be kicked out.  */
!   for (i = 0; i < n_spills; i++)
!     {
!       int regno = chain->inverse_renum_before[spill_regs[i]];
!       if (regno > 0)
! 	SET_REGNO_REG_SET (spilled_pseudos, regno);
!       regno = chain->inverse_renum_after[spill_regs[i]];
!       if (regno > 0)
! 	SET_REGNO_REG_SET (spilled_pseudos, regno);
!     }
! 
!   IOR_HARD_REG_SET (used_spill_regs, chain->used_spill_regs);
! }
! 
! \f
! /* ALLOCATE_MODE is a register mode that needs to be reloaded.  OTHER_MODE is
!    another mode that needs to be reloaded for the same register class CLASS.
!    If any reg in CLASS allows ALLOCATE_MODE but not OTHER_MODE, fail.
!    ALLOCATE_MODE will never be smaller than OTHER_MODE.
! 
!    This code used to also fail if any reg in CLASS allows OTHER_MODE but not
!    ALLOCATE_MODE.  This test is unnecessary, because we will never try to put
!    something of mode ALLOCATE_MODE into an OTHER_MODE register.  Testing this
!    causes unnecessary failures on machines requiring alignment of register
!    groups when the two modes are different sizes, because the larger mode has
!    more strict alignment rules than the smaller mode.  */
! 
! static int
! modes_equiv_for_class_p (allocate_mode, other_mode, class)
!      enum machine_mode allocate_mode, other_mode;
!      enum reg_class class;
! {
!   register int regno;
!   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
!     {
!       if (TEST_HARD_REG_BIT (reg_class_contents[(int) class], regno)
! 	  && HARD_REGNO_MODE_OK (regno, allocate_mode)
! 	  && ! HARD_REGNO_MODE_OK (regno, other_mode))
! 	return 0;
!     }
!   return 1;
  }
  \f
  /* Delete an unneeded INSN and any previous insns who sole purpose is loading
*************** mark_home_live (regno)
*** 2601,2620 ****
    while (i < lim)
      regs_ever_live[i++] = 1;
  }
- 
- /* Mark the registers used in SCRATCH as being live.  */
- 
- static void
- mark_scratch_live (scratch)
-      rtx scratch;
- {
-   register int i;
-   int regno = REGNO (scratch);
-   int lim = regno + HARD_REGNO_NREGS (regno, GET_MODE (scratch));
- 
-   for (i = regno; i < lim; i++)
-     regs_ever_live[i] = 1;
- }
  \f
  /* This function handles the tracking of elimination offsets around branches.
  
--- 2328,2333 ----
*************** mark_not_eliminable (dest, x)
*** 3637,3643 ****
  }
  \f
  /* Kick all pseudos out of hard register REGNO.
-    If GLOBAL is nonzero, try to find someplace else to put them.
     If DUMPFILE is nonzero, log actions taken on that file.
  
     If CANT_ELIMINATE is nonzero, it means that we are doing this spill
--- 3350,3355 ----
*************** mark_not_eliminable (dest, x)
*** 3648,3668 ****
  
     Return nonzero if any pseudos needed to be kicked out.  */
  
! static int
! spill_hard_reg (regno, global, dumpfile, cant_eliminate)
       register int regno;
-      int global;
       FILE *dumpfile;
       int cant_eliminate;
  {
    enum reg_class class = REGNO_REG_CLASS (regno);
-   int something_changed = 0;
    register int i;
  
-   SET_HARD_REG_BIT (forbidden_regs, regno);
- 
    if (cant_eliminate)
!     regs_ever_live[regno] = 1;
  
    /* Spill every pseudo reg that was allocated to this reg
       or to something that overlaps this reg.  */
--- 3360,3379 ----
  
     Return nonzero if any pseudos needed to be kicked out.  */
  
! static void
! spill_hard_reg (regno, dumpfile, cant_eliminate)
       register int regno;
       FILE *dumpfile;
       int cant_eliminate;
  {
    enum reg_class class = REGNO_REG_CLASS (regno);
    register int i;
  
    if (cant_eliminate)
!     {
!       SET_HARD_REG_BIT (forbidden_regs, regno);
!       regs_ever_live[regno] = 1;
!     }
  
    /* Spill every pseudo reg that was allocated to this reg
       or to something that overlaps this reg.  */
*************** spill_hard_reg (regno, global, dumpfile,
*** 3674,3744 ****
  	    + HARD_REGNO_NREGS (reg_renumber[i],
  				PSEUDO_REGNO_MODE (i))
  	    > regno))
!       {
! 	/* If this register belongs solely to a basic block which needed no
! 	   spilling of any class that this register is contained in,
! 	   leave it be, unless we are spilling this register because
! 	   it was a hard register that can't be eliminated.   */
  
! 	if (! cant_eliminate
! 	    && basic_block_needs[0]
! 	    && REG_BASIC_BLOCK (i) >= 0
! 	    && basic_block_needs[(int) class][REG_BASIC_BLOCK (i)] == 0)
! 	  {
! 	    enum reg_class *p;
  
! 	    for (p = reg_class_superclasses[(int) class];
! 		 *p != LIM_REG_CLASSES; p++)
! 	      if (basic_block_needs[(int) *p][REG_BASIC_BLOCK (i)] > 0)
! 		break;
  
! 	    if (*p == LIM_REG_CLASSES)
! 	      continue;
! 	  }
  
  	/* Mark it as no longer having a hard register home.  */
  	reg_renumber[i] = -1;
  	/* We will need to scan everything again.  */
  	something_changed = 1;
! 	if (global)
! 	  retry_global_alloc (i, forbidden_regs);
  
! 	alter_reg (i, regno);
! 	if (dumpfile)
  	  {
! 	    if (reg_renumber[i] == -1)
! 	      fprintf (dumpfile, " Register %d now on stack.\n\n", i);
! 	    else
! 	      fprintf (dumpfile, " Register %d now in %d.\n\n",
! 		       i, reg_renumber[i]);
  	  }
!       }
!   for (i = 0; i < scratch_list_length; i++)
      {
!       if (scratch_list[i] && REGNO (scratch_list[i]) == regno)
  	{
! 	  if (! cant_eliminate && basic_block_needs[0]
! 	      && ! basic_block_needs[(int) class][scratch_block[i]])
  	    {
! 	      enum reg_class *p;
! 
! 	      for (p = reg_class_superclasses[(int) class];
! 		   *p != LIM_REG_CLASSES; p++)
! 		if (basic_block_needs[(int) *p][scratch_block[i]] > 0)
! 		  break;
  
! 	      if (*p == LIM_REG_CLASSES)
! 		continue;
  	    }
! 	  PUT_CODE (scratch_list[i], SCRATCH);
! 	  scratch_list[i] = 0;
! 	  something_changed = 1;
! 	  continue;
  	}
      }
  
    return something_changed;
  }
  \f
  /* Find all paradoxical subregs within X and update reg_max_ref_width. 
     Also mark any hard registers used to store user variables as
--- 3385,3583 ----
  	    + HARD_REGNO_NREGS (reg_renumber[i],
  				PSEUDO_REGNO_MODE (i))
  	    > regno))
!       SET_REGNO_REG_SET (spilled_pseudos, i);
! }
  
! /* When we notice that caller-saves would need a spill register, kick out all
!    pseudos which are in caller-saved hard registers and live across calls.  */
! static void
! spill_caller_saved_regs ()
! {
!   int i;
  
!   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
!     {
!       int regno = reg_renumber[i];
!       int nregs;
!       if (regno < 0 || REG_N_CALLS_CROSSED (i) > 0)
! 	continue;
!       nregs = HARD_REGNO_NREGS (regno, PSEUDO_REGNO_MODE (i));
!       while (nregs-- > 0)
! 	if (call_used_regs[regno++])
! 	  SET_REGNO_REG_SET (spilled_pseudos, i);
!     }
!   /* We no longer want caller-saves if retry_global_alloc is run.  */
!   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
!     if (call_used_regs[i])
!       SET_HARD_REG_BIT (losing_caller_save_reg_set, i);
! }
  
! /* After choose_reload_regs has been run for all insn that need reloads,
!    and/or spill_hard_regs was called, this function is used to actually
!    spill pseudo registers and try to reallocate them.  It also sets up the
!    spill_regs array for use by choose_reload_regs.  */
! 
! static int
! finish_spills (global, dumpfile)
!      int global;
!      FILE *dumpfile;
! {
!   struct insn_chain *chain;
!   int something_changed = 0;
!   int i;
! 
!   /* Build the spill_regs array for the function.  */
!   /* If there are some registers still to eliminate and one of the spill regs
!      wasn't ever used before, additional stack space may have to be
!      allocated to store this register.  Thus, we may have changed the offset
!      between the stack and frame pointers, so mark that something has changed.
! 
!      One might think that we need only set VAL to 1 if this is a call-used
!      register.  However, the set of registers that must be saved by the
!      prologue is not identical to the call-used set.  For example, the
!      register used by the call insn for the return PC is a call-used register,
!      but must be saved by the prologue.  */
! 
!   n_spills = 0;
!   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
!     if (TEST_HARD_REG_BIT (used_spill_regs, i))
!       {
! 	spill_reg_order[i] = n_spills;
! 	spill_regs[n_spills++] = i;
! 	if (num_eliminable && ! regs_ever_live[i])
! 	  something_changed = 1;
! 	regs_ever_live[i] = 1;
!       }
!     else
!       spill_reg_order[i] = -1;
  
+   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+     if (REGNO_REG_SET_P (spilled_pseudos, i))
+       {
  	/* Mark it as no longer having a hard register home.  */
  	reg_renumber[i] = -1;
  	/* We will need to scan everything again.  */
  	something_changed = 1;
!       }
  
!   if (global)
!     {
!       /* For every insn that needs reloads, set the registers used as spill
! 	 regs in pseudo_forbidden_regs for every pseudo live across the
! 	 insn.  */
!       bzero ((char *) pseudo_forbidden_regs, max_regno * sizeof (HARD_REG_SET));
!       for (chain = reload_insn_chain; chain; chain = chain->next)
! 	{
! 	  rtx insn = chain->insn;
! 	  if (! chain->need_reload)
! 	    continue;
! 	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 	    {
! 	      int regno = chain->inverse_renum_before[i];
! 	      if (regno > 0)
! 		IOR_HARD_REG_SET (pseudo_forbidden_regs[regno],
! 				  chain->used_spill_regs);
! 
! 	      regno = chain->inverse_renum_after[i];
! 	      if (regno > 0)
! 		IOR_HARD_REG_SET (pseudo_forbidden_regs[regno],
! 				  chain->used_spill_regs);
! 	    }
! 	}
! 
!       /* Retry allocating the spilled pseudos.  */
!       for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
! 	if (reg_old_renumber[i] != reg_renumber[i])
  	  {
! 	    HARD_REG_SET forbidden;
! 	    COPY_HARD_REG_SET (forbidden, forbidden_regs);
! 	    IOR_HARD_REG_SET (forbidden, pseudo_forbidden_regs[i]);
! 	    retry_global_alloc (i, forbidden);
  	  }
!     }
! 
!   /* Fix up the register information in the insn chain.  */
!   for (chain = reload_insn_chain; chain; chain = chain->next)
      {
!       regset live_before = ALLOCA_REG_SET();
!       regset live_after = ALLOCA_REG_SET();
! 
!       /* Figure out which off the spilled pseudos are live before and
! 	 after the insn.  Delete the old mappings in the inverse_renum
! 	 arrays.  */
!       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  	{
! 	  int regno = chain->inverse_renum_after[i];
! 	  if (regno >= FIRST_PSEUDO_REGISTER
! 	      && REGNO_REG_SET_P (spilled_pseudos, regno))
  	    {
! 	      chain->inverse_renum_after[i] = 0;
! 	      SET_REGNO_REG_SET (live_after, regno);
! 	    }
  
! 	  regno = chain->inverse_renum_before[i];
! 	  if (regno >= FIRST_PSEUDO_REGISTER
! 	      && REGNO_REG_SET_P (spilled_pseudos, regno))
! 	    {
! 	      chain->inverse_renum_before[i] = 0;
! 	      SET_REGNO_REG_SET (live_before, regno);
  	    }
! 	}
!       /* Now set up the new mappings in inverse_renum.  */
!       for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
! 	{
! 	  int regno = reg_renumber[i];
! 	  if (regno < 0)
! 	    continue;
! 	  if (REGNO_REG_SET_P (live_before, i))
! 	    {
! 	      int nregs = HARD_REGNO_NREGS (regno, PSEUDO_REGNO_MODE (i));
! 	      while (nregs-- > 0)
! 		chain->inverse_renum_before[regno++] = i;
! 	    }
! 	  regno = reg_renumber[i];
! 	  if (REGNO_REG_SET_P (live_after, i))
! 	    {
! 	      int nregs = HARD_REGNO_NREGS (regno, PSEUDO_REGNO_MODE (i));
! 	      while (nregs-- > 0)
! 		chain->inverse_renum_after[regno++] = i;
! 	    }
! 	}
! 
!       /* Mark any unallocated hard regs as available for spills.  That
! 	 makes inheritance work somewhat better.  */
!       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 	if (TEST_HARD_REG_BIT (used_spill_regs, i)
! 	    && chain->inverse_renum_before[i] == 0
! 	    && chain->inverse_renum_after[i] == 0)
! 	  SET_HARD_REG_BIT (chain->used_spill_regs, i);
! 
!       FREE_REG_SET (live_before);
!       FREE_REG_SET (live_after);
!     }
! 
!   /* Let alter_reg modify the reg rtx's for the modified pseudos.  */
!   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
!     {
!       int regno = reg_renumber[i];
!       if (reg_old_renumber[i] == regno)
! 	continue;
!       
!       alter_reg (i, reg_old_renumber[i]);
!       reg_old_renumber[i] = regno;
!       if (dumpfile)
! 	{
! 	  if (regno == -1)
! 	    fprintf (dumpfile, " Register %d now on stack.\n\n", i);
! 	  else
! 	    fprintf (dumpfile, " Register %d now in %d.\n\n",
! 		     i, reg_renumber[i]);
  	}
      }
  
    return something_changed;
  }
+ 
  \f
  /* Find all paradoxical subregs within X and update reg_max_ref_width. 
     Also mark any hard registers used to store user variables as
*************** scan_paradoxical_subregs (x)
*** 3796,3949 ****
      }
  }
  \f
- static int
- hard_reg_use_compare (p1p, p2p)
-   const GENERIC_PTR p1p;
-   const GENERIC_PTR p2p;
- {
-   struct hard_reg_n_uses *p1 = (struct hard_reg_n_uses *)p1p,
- 			 *p2 = (struct hard_reg_n_uses *)p2p;
-   int tem = p1->uses - p2->uses;
-   if (tem != 0) return tem;
-   /* If regs are equally good, sort by regno,
-      so that the results of qsort leave nothing to chance.  */
-   return p1->regno - p2->regno;
- }
- 
- /* Choose the order to consider regs for use as reload registers
-    based on how much trouble would be caused by spilling one.
-    Store them in order of decreasing preference in potential_reload_regs.  */
- 
- static void
- order_regs_for_reload (global)
-      int global;
- {
-   register int i;
-   register int o = 0;
-   int large = 0;
- 
-   struct hard_reg_n_uses hard_reg_n_uses[FIRST_PSEUDO_REGISTER];
- 
-   CLEAR_HARD_REG_SET (bad_spill_regs);
- 
-   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-     potential_reload_regs[i] = -1;
- 
-   /* Count number of uses of each hard reg by pseudo regs allocated to it
-      and then order them by decreasing use.  */
- 
-   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-     {
-       hard_reg_n_uses[i].uses = 0;
-       hard_reg_n_uses[i].regno = i;
-     }
- 
-   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
-     {
-       int regno = reg_renumber[i];
-       if (regno >= 0)
- 	{
- 	  int lim = regno + HARD_REGNO_NREGS (regno, PSEUDO_REGNO_MODE (i));
- 	  while (regno < lim)
- 	    {
- 	      /* If allocated by local-alloc, show more uses since
- 		 we're not going to be able to reallocate it, but
- 		 we might if allocated by global alloc.  */
- 	      if (global && reg_allocno[i] < 0)
- 		hard_reg_n_uses[regno].uses += (REG_N_REFS (i) + 1) / 2;
- 
- 	      hard_reg_n_uses[regno++].uses += REG_N_REFS (i);
- 	    }
- 	}
-       large += REG_N_REFS (i);
-     }
- 
-   /* Now fixed registers (which cannot safely be used for reloading)
-      get a very high use count so they will be considered least desirable.
-      Registers used explicitly in the rtl code are almost as bad.  */
- 
-   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-     {
-       if (fixed_regs[i])
- 	{
- 	  hard_reg_n_uses[i].uses += 2 * large + 2;
- 	  SET_HARD_REG_BIT (bad_spill_regs, i);
- 	}
-       else if (regs_explicitly_used[i])
- 	{
- 	  hard_reg_n_uses[i].uses += large + 1;
- 	  /* ??? We are doing this here because of the potential that
- 	     bad code may be generated if a register explicitly used in
- 	     an insn was used as a spill register for that insn.  But
- 	     not using these are spill registers may lose on some machine.
- 	     We'll have to see how this works out.  */
- #ifdef SMALL_REGISTER_CLASSES
- 	  if (! SMALL_REGISTER_CLASSES)
- #endif
- 	    SET_HARD_REG_BIT (bad_spill_regs, i);
- 	}
-     }
-   hard_reg_n_uses[HARD_FRAME_POINTER_REGNUM].uses += 2 * large + 2;
-   SET_HARD_REG_BIT (bad_spill_regs, HARD_FRAME_POINTER_REGNUM);
- 
- #ifdef ELIMINABLE_REGS
-   /* If registers other than the frame pointer are eliminable, mark them as
-      poor choices.  */
-   for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
-     {
-       hard_reg_n_uses[reg_eliminate[i].from].uses += 2 * large + 2;
-       SET_HARD_REG_BIT (bad_spill_regs, reg_eliminate[i].from);
-     }
- #endif
- 
-   /* Prefer registers not so far used, for use in temporary loading.
-      Among them, if REG_ALLOC_ORDER is defined, use that order.
-      Otherwise, prefer registers not preserved by calls.  */
- 
- #ifdef REG_ALLOC_ORDER
-   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-     {
-       int regno = reg_alloc_order[i];
- 
-       if (hard_reg_n_uses[regno].uses == 0)
- 	potential_reload_regs[o++] = regno;
-     }
- #else
-   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-     {
-       if (hard_reg_n_uses[i].uses == 0 && call_used_regs[i])
- 	potential_reload_regs[o++] = i;
-     }
-   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-     {
-       if (hard_reg_n_uses[i].uses == 0 && ! call_used_regs[i])
- 	potential_reload_regs[o++] = i;
-     }
- #endif
- 
-   qsort (hard_reg_n_uses, FIRST_PSEUDO_REGISTER,
- 	 sizeof hard_reg_n_uses[0], hard_reg_use_compare);
- 
-   /* Now add the regs that are already used,
-      preferring those used less often.  The fixed and otherwise forbidden
-      registers will be at the end of this list.  */
- 
-   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-     if (hard_reg_n_uses[i].uses != 0)
-       potential_reload_regs[o++] = hard_reg_n_uses[i].regno;
- }
- \f
- /* Used in reload_as_needed to sort the spilled regs.  */
- 
- static int
- compare_spill_regs (r1p, r2p)
-      const GENERIC_PTR r1p;
-      const GENERIC_PTR r2p;
- {
-   short r1 = *(short *)r1p, r2 = *(short *)r2p;
-   return r1 - r2;
- }
- 
  /* Reload pseudo-registers into hard regs around each insn as needed.
     Additional register load insns are output before the insn that needs it
     and perhaps store insns after insns that modify the reloaded pseudo reg.
--- 3635,3640 ----
*************** reload_as_needed (first, live_known)
*** 3958,3968 ****
       rtx first;
       int live_known;
  {
!   register rtx insn;
    register int i;
-   int this_block = 0;
    rtx x;
-   rtx after_call = 0;
  
    bzero ((char *) spill_reg_rtx, sizeof spill_reg_rtx);
    bzero ((char *) spill_reg_store, sizeof spill_reg_store);
--- 3649,3657 ----
       rtx first;
       int live_known;
  {
!   struct insn_chain *chain;
    register int i;
    rtx x;
  
    bzero ((char *) spill_reg_rtx, sizeof spill_reg_rtx);
    bzero ((char *) spill_reg_store, sizeof spill_reg_store);
*************** reload_as_needed (first, live_known)
*** 3992,4014 ****
  
    num_not_at_initial_offset = 0;
  
!   /* Order the spilled regs, so that allocate_reload_regs can guarantee to
!      pack registers with group needs.  */
!   if (n_spills > 1)
!     {
!       qsort (spill_regs, n_spills, sizeof (short), compare_spill_regs);
!       for (i = 0; i < n_spills; i++)
! 	spill_reg_order[spill_regs[i]] = i;
!     }
! 
!   for (insn = first; insn;)
      {
!       register rtx next = NEXT_INSN (insn);
! 
!       /* Notice when we move to a new basic block.  */
!       if (live_known && this_block + 1 < n_basic_blocks
! 	  && insn == basic_block_head[this_block+1])
! 	++this_block;
  
        /* If we pass a label, copy the offsets from the label information
  	 into the current offsets of each elimination.  */
--- 3681,3691 ----
  
    num_not_at_initial_offset = 0;
  
!   for (chain = reload_insn_chain; chain; chain = chain->next)
      {
!       rtx insn = chain->insn;
!       rtx old_next = NEXT_INSN (insn);
!       int this_block = chain->block;
  
        /* If we pass a label, copy the offsets from the label information
  	 into the current offsets of each elimination.  */
*************** reload_as_needed (first, live_known)
*** 4028,4060 ****
  
        else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  	{
- 	  rtx avoid_return_reg = 0;
  	  rtx oldpat = PATTERN (insn);
  
- #ifdef SMALL_REGISTER_CLASSES
- 	  /* Set avoid_return_reg if this is an insn
- 	     that might use the value of a function call.  */
- 	  if (SMALL_REGISTER_CLASSES && GET_CODE (insn) == CALL_INSN)
- 	    {
- 	      if (GET_CODE (PATTERN (insn)) == SET)
- 		after_call = SET_DEST (PATTERN (insn));
- 	      else if (GET_CODE (PATTERN (insn)) == PARALLEL
- 		       && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
- 		after_call = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
- 	      else
- 		after_call = 0;
- 	    }
- 	  else if (SMALL_REGISTER_CLASSES
- 		   && after_call != 0
- 		   && !(GET_CODE (PATTERN (insn)) == SET
- 			&& SET_DEST (PATTERN (insn)) == stack_pointer_rtx))
- 	    {
- 	      if (reg_referenced_p (after_call, PATTERN (insn)))
- 		avoid_return_reg = after_call;
- 	      after_call = 0;
- 	    }
- #endif /* SMALL_REGISTER_CLASSES */
- 
  	  /* If this is a USE and CLOBBER of a MEM, ensure that any
  	     references to eliminable registers have been removed.  */
  
--- 3705,3712 ----
*************** reload_as_needed (first, live_known)
*** 4068,4084 ****
  
  	  /* If we need to do register elimination processing, do so.
  	     This might delete the insn, in which case we are done.  */
! 	  if (num_eliminable && GET_MODE (insn) == QImode)
  	    {
  	      eliminate_regs_in_insn (insn, 1);
  	      if (GET_CODE (insn) == NOTE)
! 		{
! 		  insn = next;
! 		  continue;
! 		}
  	    }
  
! 	  if (GET_MODE (insn) == VOIDmode)
  	    n_reloads = 0;
  	  /* First find the pseudo regs that must be reloaded for this insn.
  	     This info is returned in the tables reload_... (see reload.h).
--- 3720,3733 ----
  
  	  /* If we need to do register elimination processing, do so.
  	     This might delete the insn, in which case we are done.  */
! 	  if (num_eliminable && chain->need_elim)
  	    {
  	      eliminate_regs_in_insn (insn, 1);
  	      if (GET_CODE (insn) == NOTE)
! 		continue;
  	    }
  
! 	  if (! chain->need_elim && ! chain->need_reload)
  	    n_reloads = 0;
  	  /* First find the pseudo regs that must be reloaded for this insn.
  	     This info is returned in the tables reload_... (see reload.h).
*************** reload_as_needed (first, live_known)
*** 4099,4124 ****
  	      rtx p;
  	      int class;
  
- 	      /* If this block has not had spilling done for a
- 		 particular clas and we have any non-optionals that need a
- 		 spill reg in that class, abort.  */
- 
- 	      for (class = 0; class < N_REG_CLASSES; class++)
- 		if (basic_block_needs[class] != 0
- 		    && basic_block_needs[class][this_block] == 0)
- 		  for (i = 0; i < n_reloads; i++)
- 		    if (class == (int) reload_reg_class[i]
- 			&& reload_reg_rtx[i] == 0
- 			&& ! reload_optional[i]
- 			&& (reload_in[i] != 0 || reload_out[i] != 0
- 			    || reload_secondary_p[i] != 0))
- 		      fatal_insn ("Non-optional registers need a spill register", insn);
- 
  	      /* Now compute which reload regs to reload them into.  Perhaps
  		 reusing reload regs from previous insns, or else output
  		 load insns to reload them.  Maybe output store insns too.
  		 Record the choices of reload reg in reload_reg_rtx.  */
! 	      choose_reload_regs (insn, avoid_return_reg);
  
  #ifdef SMALL_REGISTER_CLASSES
  	      /* Merge any reloads that we didn't combine for fear of 
--- 3748,3758 ----
  	      rtx p;
  	      int class;
  
  	      /* Now compute which reload regs to reload them into.  Perhaps
  		 reusing reload regs from previous insns, or else output
  		 load insns to reload them.  Maybe output store insns too.
  		 Record the choices of reload reg in reload_reg_rtx.  */
! 	      choose_reload_regs (chain, live_known);
  
  #ifdef SMALL_REGISTER_CLASSES
  	      /* Merge any reloads that we didn't combine for fear of 
*************** reload_as_needed (first, live_known)
*** 4166,4172 ****
  
  	  /* There may have been CLOBBER insns placed after INSN.  So scan
  	     between INSN and NEXT and use them to forget old reloads.  */
! 	  for (x = NEXT_INSN (insn); x != next; x = NEXT_INSN (x))
  	    if (GET_CODE (x) == INSN && GET_CODE (PATTERN (x)) == CLOBBER)
  	      note_stores (PATTERN (x), forget_old_reloads_1);
  
--- 3800,3806 ----
  
  	  /* There may have been CLOBBER insns placed after INSN.  So scan
  	     between INSN and NEXT and use them to forget old reloads.  */
! 	  for (x = NEXT_INSN (insn); x != old_next; x = NEXT_INSN (x))
  	    if (GET_CODE (x) == INSN && GET_CODE (PATTERN (x)) == CLOBBER)
  	      note_stores (PATTERN (x), forget_old_reloads_1);
  
*************** reload_as_needed (first, live_known)
*** 4219,4226 ****
  	  }
  #endif
  
-       insn = next;
- 
  #ifdef USE_C_ALLOCA
        alloca (0);
  #endif
--- 3853,3858 ----
*************** int reload_spill_index[MAX_RELOADS];
*** 5015,5031 ****
     or 0 if we couldn't find a spill reg and we didn't change anything.  */
  
  static int
! allocate_reload_reg (r, insn, last_reload, noerror)
       int r;
-      rtx insn;
       int last_reload;
       int noerror;
  {
!   int i;
!   int pass;
!   int count;
    rtx new;
-   int regno;
  
    /* If we put this reload ahead, thinking it is a group,
       then insist on finding a group.  Otherwise we can grab a
--- 4647,4661 ----
     or 0 if we couldn't find a spill reg and we didn't change anything.  */
  
  static int
! allocate_reload_reg (chain, r, last_reload, noerror)
!      struct insn_chain *chain;
       int r;
       int last_reload;
       int noerror;
  {
!   rtx insn = chain->insn;
!   int i, pass, count, regno;
    rtx new;
  
    /* If we put this reload ahead, thinking it is a group,
       then insist on finding a group.  Otherwise we can grab a
*************** allocate_reload_reg (r, insn, last_reloa
*** 5074,5096 ****
        for (count = 0; count < n_spills; count++)
  	{
  	  int class = (int) reload_reg_class[r];
  
! 	  i = (i + 1) % n_spills;
  
! 	  if (reload_reg_free_p (spill_regs[i], reload_opnum[r],
  				 reload_when_needed[r])
! 	      && TEST_HARD_REG_BIT (reg_class_contents[class], spill_regs[i])
! 	      && HARD_REGNO_MODE_OK (spill_regs[i], reload_mode[r])
  	      /* Look first for regs to share, then for unshared.  But
  		 don't share regs used for inherited reloads; they are
  		 the ones we want to preserve.  */
  	      && (pass
  		  || (TEST_HARD_REG_BIT (reload_reg_used_at_all,
! 					 spill_regs[i])
  		      && ! TEST_HARD_REG_BIT (reload_reg_used_for_inherit,
! 					      spill_regs[i]))))
  	    {
! 	      int nr = HARD_REGNO_NREGS (spill_regs[i], reload_mode[r]);
  	      /* Avoid the problem where spilling a GENERAL_OR_FP_REG
  		 (on 68000) got us two FP regs.  If NR is 1,
  		 we would reject both of them.  */
--- 4704,4730 ----
        for (count = 0; count < n_spills; count++)
  	{
  	  int class = (int) reload_reg_class[r];
+ 	  int regnum;
  
! 	  i++;
! 	  if (i >= n_spills)
! 	    i -= n_spills;
! 	  regnum = spill_regs[i];
  
! 	  if (reload_reg_free_p (regnum, reload_opnum[r],
  				 reload_when_needed[r])
! 	      && TEST_HARD_REG_BIT (reg_class_contents[class], regnum)
! 	      && HARD_REGNO_MODE_OK (regnum, reload_mode[r])
  	      /* Look first for regs to share, then for unshared.  But
  		 don't share regs used for inherited reloads; they are
  		 the ones we want to preserve.  */
  	      && (pass
  		  || (TEST_HARD_REG_BIT (reload_reg_used_at_all,
! 					 regnum)
  		      && ! TEST_HARD_REG_BIT (reload_reg_used_for_inherit,
! 					      regnum))))
  	    {
! 	      int nr = HARD_REGNO_NREGS (regnum, reload_mode[r]);
  	      /* Avoid the problem where spilling a GENERAL_OR_FP_REG
  		 (on 68000) got us two FP regs.  If NR is 1,
  		 we would reject both of them.  */
*************** allocate_reload_reg (r, insn, last_reloa
*** 5108,5122 ****
  		 are available here.
  		 Also, don't use for a group registers that are
  		 needed for nongroups.  */
! 	      if (! TEST_HARD_REG_BIT (counted_for_nongroups, spill_regs[i]))
  		while (nr > 1)
  		  {
! 		    regno = spill_regs[i] + nr - 1;
  		    if (!(TEST_HARD_REG_BIT (reg_class_contents[class], regno)
  			  && spill_reg_order[regno] >= 0
  			  && reload_reg_free_p (regno, reload_opnum[r],
  						reload_when_needed[r])
! 			  && ! TEST_HARD_REG_BIT (counted_for_nongroups,
  						  regno)))
  		      break;
  		    nr--;
--- 4742,4756 ----
  		 are available here.
  		 Also, don't use for a group registers that are
  		 needed for nongroups.  */
! 	      if (! TEST_HARD_REG_BIT (chain->counted_for_nongroups, regnum))
  		while (nr > 1)
  		  {
! 		    regno = regnum + nr - 1;
  		    if (!(TEST_HARD_REG_BIT (reg_class_contents[class], regno)
  			  && spill_reg_order[regno] >= 0
  			  && reload_reg_free_p (regno, reload_opnum[r],
  						reload_when_needed[r])
! 			  && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups,
  						  regno)))
  		      break;
  		    nr--;
*************** allocate_reload_reg (r, insn, last_reloa
*** 5212,5225 ****
     finding a reload reg in the proper class.  */
  
  static void
! choose_reload_regs (insn, avoid_return_reg)
!      rtx insn;
!      rtx avoid_return_reg;
  {
    register int i, j;
    int max_group_size = 1;
    enum reg_class group_class = NO_REGS;
    int inheritance;
  
    rtx save_reload_reg_rtx[MAX_RELOADS];
    char save_reload_inherited[MAX_RELOADS];
--- 4846,4860 ----
     finding a reload reg in the proper class.  */
  
  static void
! choose_reload_regs (chain, global)
!      struct insn_chain *chain;
!      int global;
  {
    register int i, j;
    int max_group_size = 1;
    enum reg_class group_class = NO_REGS;
    int inheritance;
+   rtx insn = chain->insn;
  
    rtx save_reload_reg_rtx[MAX_RELOADS];
    char save_reload_inherited[MAX_RELOADS];
*************** choose_reload_regs (insn, avoid_return_r
*** 5260,5290 ****
        CLEAR_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i]);
      }
  
! #ifdef SMALL_REGISTER_CLASSES
!   /* Don't bother with avoiding the return reg
!      if we have no mandatory reload that could use it.  */
!   if (SMALL_REGISTER_CLASSES && avoid_return_reg)
!     {
!       int do_avoid = 0;
!       int regno = REGNO (avoid_return_reg);
!       int nregs
! 	= HARD_REGNO_NREGS (regno, GET_MODE (avoid_return_reg));
!       int r;
! 
!       for (r = regno; r < regno + nregs; r++)
! 	if (spill_reg_order[r] >= 0)
! 	  for (j = 0; j < n_reloads; j++)
! 	    if (!reload_optional[j] && reload_reg_rtx[j] == 0
! 		&& (reload_in[j] != 0 || reload_out[j] != 0
! 		    || reload_secondary_p[j])
! 		&&
! 		TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[j]], r))
! 	      do_avoid = 1;
!       if (!do_avoid)
! 	avoid_return_reg = 0;
!     }
! #endif /* SMALL_REGISTER_CLASSES */
! 
  #if 0  /* Not needed, now that we can always retry without inheritance.  */
    /* See if we have more mandatory reloads than spill regs.
       If so, then we cannot risk optimizations that could prevent
--- 4895,4902 ----
        CLEAR_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i]);
      }
  
!   IOR_COMPL_HARD_REG_SET (reload_reg_used, chain->used_spill_regs);
!   
  #if 0  /* Not needed, now that we can always retry without inheritance.  */
    /* See if we have more mandatory reloads than spill regs.
       If so, then we cannot risk optimizations that could prevent
*************** choose_reload_regs (insn, avoid_return_r
*** 5295,5304 ****
  
    {
      int tem = 0;
- #ifdef SMALL_REGISTER_CLASSES
-     if (SMALL_REGISTER_CLASSES)
-       tem = (avoid_return_reg != 0);
- #endif
      for (j = 0; j < n_reloads; j++)
        if (! reload_optional[j]
  	  && (reload_in[j] != 0 || reload_out[j] != 0 || reload_secondary_p[j])
--- 4907,4912 ----
*************** choose_reload_regs (insn, avoid_return_r
*** 5311,5332 ****
    }
  #endif
  
- #ifdef SMALL_REGISTER_CLASSES
-   /* Don't use the subroutine call return reg for a reload
-      if we are supposed to avoid it.  */
-   if (SMALL_REGISTER_CLASSES && avoid_return_reg)
-     {
-       int regno = REGNO (avoid_return_reg);
-       int nregs
- 	= HARD_REGNO_NREGS (regno, GET_MODE (avoid_return_reg));
-       int r;
- 
-       for (r = regno; r < regno + nregs; r++)
- 	if (spill_reg_order[r] >= 0)
- 	  SET_HARD_REG_BIT (reload_reg_used, r);
-     }
- #endif /* SMALL_REGISTER_CLASSES */
- 
    /* In order to be certain of getting the registers we need,
       we must sort the reloads into order of increasing register class.
       Then our grabbing of reload registers will parallel the process
--- 4919,4924 ----
*************** choose_reload_regs (insn, avoid_return_r
*** 5463,5469 ****
  		   || reload_secondary_p[reload_order[i]])
  		  && ! reload_optional[reload_order[i]]
  		  && reload_reg_rtx[reload_order[i]] == 0)
! 		allocate_reload_reg (reload_order[i], insn, 0, inheritance);
  #endif
  
  	  /* First see if this pseudo is already available as reloaded
--- 5055,5061 ----
  		   || reload_secondary_p[reload_order[i]])
  		  && ! reload_optional[reload_order[i]]
  		  && reload_reg_rtx[reload_order[i]] == 0)
! 		allocate_reload_reg (chain, reload_order[i], 0, inheritance);
  #endif
  
  	  /* First see if this pseudo is already available as reloaded
*************** choose_reload_regs (insn, avoid_return_r
*** 5720,5726 ****
  	  if (i == n_reloads)
  	    continue;
  
! 	  allocate_reload_reg (r, insn, j == n_reloads - 1, inheritance);
  #endif
  	}
  
--- 5312,5318 ----
  	  if (i == n_reloads)
  	    continue;
  
! 	  allocate_reload_reg (chain, r, j == n_reloads - 1, inheritance);
  #endif
  	}
  
*************** choose_reload_regs (insn, avoid_return_r
*** 5739,5745 ****
  	  if (reload_reg_rtx[r] != 0 || reload_optional[r])
  	    continue;
  
! 	  if (! allocate_reload_reg (r, insn, j == n_reloads - 1, inheritance))
  	    break;
  	}
  
--- 5331,5337 ----
  	  if (reload_reg_rtx[r] != 0 || reload_optional[r])
  	    continue;
  
! 	  if (! allocate_reload_reg (chain, r, j == n_reloads - 1, inheritance))
  	    break;
  	}
  
diff -dcrp egcs-ss-970814/reorg.c egcs-new/reorg.c
*** egcs-ss-970814/reorg.c	Fri Aug 15 20:56:47 1997
--- egcs-new/reorg.c	Tue Aug 19 14:50:54 1997
*************** find_dead_or_set_registers (target, res,
*** 2507,2512 ****
--- 2507,2513 ----
  	  AND_COMPL_HARD_REG_SET (res->regs, pending_dead_regs);
  	  CLEAR_HARD_REG_SET (pending_dead_regs);
  
+ #if 0 /* @@@ This no longer works now that reload is more clever.  */
  	  if (CODE_LABEL_NUMBER (insn) < max_label_num_after_reload)
  	    {
  	      /* All spill registers are dead at a label, so kill all of the
*************** find_dead_or_set_registers (target, res,
*** 2515,2520 ****
--- 2516,2522 ----
  	      AND_COMPL_HARD_REG_SET (scratch, needed.regs);
  	      AND_COMPL_HARD_REG_SET (res->regs, scratch);
  	    }
+ #endif
  	  continue;
  
  	case BARRIER:
diff -dcrp egcs-ss-970814/stupid.c egcs-new/stupid.c
*** egcs-ss-970814/stupid.c	Fri Aug 15 20:56:53 1997
--- egcs-new/stupid.c	Thu Aug 21 15:31:13 1997
*************** Boston, MA 02111-1307, USA.  */
*** 47,52 ****
--- 47,54 ----
  #include "rtl.h"
  #include "hard-reg-set.h"
  #include "regs.h"
+ #include "insn-config.h"
+ #include "reload.h"
  #include "flags.h"
  \f
  /* Vector mapping INSN_UIDs to suids.
*************** static int *reg_where_dead;
*** 79,84 ****
--- 81,94 ----
  
  static int *reg_where_born;
  
+ /* Likewise, but point to the insn_chain structure of the insn at which
+    the reg dies.  */
+ static struct insn_chain **reg_where_dead_chain;
+ 
+ /* More precise versions of the above vectors.  @@@ merge these.  */
+ static int *reg_where_born_exact;
+ static int *reg_where_born_clobber;
+ 
  /* Numbers of pseudo-regs to be allocated, highest priority first.  */
  
  static int *reg_order;
*************** static HARD_REG_SET *after_insn_hard_reg
*** 109,115 ****
  static int stupid_reg_compare	PROTO((const GENERIC_PTR,const GENERIC_PTR));
  static int stupid_find_reg	PROTO((int, enum reg_class, enum machine_mode,
  				       int, int, int));
! static void stupid_mark_refs	PROTO((rtx, rtx));
  \f
  /* Stupid life analysis is for the case where only variables declared
     `register' go in registers.  For this case, we mark all
--- 119,125 ----
  static int stupid_reg_compare	PROTO((const GENERIC_PTR,const GENERIC_PTR));
  static int stupid_find_reg	PROTO((int, enum reg_class, enum machine_mode,
  				       int, int, int));
! static void stupid_mark_refs	PROTO((rtx, struct insn_chain *));
  \f
  /* Stupid life analysis is for the case where only variables declared
     `register' go in registers.  For this case, we mark all
*************** stupid_life_analysis (f, nregs, file)
*** 167,172 ****
--- 177,191 ----
    reg_where_dead = (int *) alloca (nregs * sizeof (int));
    bzero ((char *) reg_where_dead, nregs * sizeof (int));
  
+   reg_where_born_exact = (int *) alloca (nregs * sizeof (int));
+   bzero ((char *) reg_where_born_exact, nregs * sizeof (int));
+ 
+   reg_where_born_clobber = (int *) alloca (nregs * sizeof (int));
+   bzero ((char *) reg_where_born_clobber, nregs * sizeof (int));
+ 
+   reg_where_dead_chain = (struct insn_chain **) alloca (nregs * sizeof (struct insn_chain *));
+   bzero ((char *) reg_where_dead_chain, nregs * sizeof (struct insn_chain *));
+ 
    reg_where_born = (int *) alloca (nregs * sizeof (int));
    bzero ((char *) reg_where_born, nregs * sizeof (int));
  
*************** stupid_life_analysis (f, nregs, file)
*** 206,216 ****
       Also find where each hard register is live
       and record that info in after_insn_hard_regs.
       regs_live[I] is 1 if hard reg I is live
!      at the current point in the scan.  */
  
    for (insn = last; insn; insn = PREV_INSN (insn))
      {
        register HARD_REG_SET *p = after_insn_hard_regs + INSN_SUID (insn);
  
        /* Copy the info in regs_live into the element of after_insn_hard_regs
  	 for the current position in the rtl code.  */
--- 225,239 ----
       Also find where each hard register is live
       and record that info in after_insn_hard_regs.
       regs_live[I] is 1 if hard reg I is live
!      at the current point in the scan.  
!    
!      Build reload_insn_chain while we're walking the insns.  */
  
+   reload_insn_chain = 0;
    for (insn = last; insn; insn = PREV_INSN (insn))
      {
        register HARD_REG_SET *p = after_insn_hard_regs + INSN_SUID (insn);
+       struct insn_chain *chain;
  
        /* Copy the info in regs_live into the element of after_insn_hard_regs
  	 for the current position in the rtl code.  */
*************** stupid_life_analysis (f, nregs, file)
*** 219,230 ****
  	if (regs_live[i])
  	  SET_HARD_REG_BIT (*p, i);
  
        /* Update which hard regs are currently live
  	 and also the birth and death suids of pseudo regs
  	 based on the pattern of this insn.  */
  
        if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
! 	stupid_mark_refs (PATTERN (insn), insn);
  
        if (GET_CODE (insn) == NOTE
  	  && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
--- 242,271 ----
  	if (regs_live[i])
  	  SET_HARD_REG_BIT (*p, i);
  
+       if (GET_CODE (insn) != NOTE && GET_CODE (insn) != BARRIER)
+ 	{
+ 	  chain = new_insn_chain ();
+ 	  if (reload_insn_chain)
+ 	    reload_insn_chain->prev = chain;
+ 	  chain->next = reload_insn_chain;
+ 	  chain->prev = 0;
+ 	  reload_insn_chain = chain;
+ 	  chain->block = 0;
+ 	  chain->insn = insn;
+ 	  bzero ((char *)chain->inverse_renum_after,
+ 		 sizeof chain->inverse_renum_after);
+ 	  bzero ((char *)chain->inverse_renum_before,
+ 		 sizeof chain->inverse_renum_before);
+ 	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ 	    chain->inverse_renum_after[i] = regs_live[i] ? -1 : 0;
+ 	}
+ 
        /* Update which hard regs are currently live
  	 and also the birth and death suids of pseudo regs
  	 based on the pattern of this insn.  */
  
        if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
! 	stupid_mark_refs (PATTERN (insn), chain);
  
        if (GET_CODE (insn) == NOTE
  	  && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
*************** stupid_life_analysis (f, nregs, file)
*** 249,256 ****
  	  /* It is important that this be done after processing the insn's
  	     pattern because we want the function result register to still
  	     be live if it's also used to pass arguments.  */
! 	  stupid_mark_refs (CALL_INSN_FUNCTION_USAGE (insn), insn);
  	}
      }
  
    /* Now decide the order in which to allocate the pseudo registers.  */
--- 290,301 ----
  	  /* It is important that this be done after processing the insn's
  	     pattern because we want the function result register to still
  	     be live if it's also used to pass arguments.  */
! 	  stupid_mark_refs (CALL_INSN_FUNCTION_USAGE (insn), chain);
  	}
+ 
+       if (GET_CODE (insn) != NOTE && GET_CODE (insn) != BARRIER)
+ 	for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ 	  chain->inverse_renum_after[i] = regs_live[i] ? -1 : 0;
      }
  
    /* Now decide the order in which to allocate the pseudo registers.  */
*************** stupid_life_analysis (f, nregs, file)
*** 269,276 ****
        register int r = reg_order[i];
  
        /* Some regnos disappear from the rtl.  Ignore them to avoid crash. 
! 	 Also don't allocate registers that cross a setjmp.  */
!       if (regno_reg_rtx[r] == 0 || regs_crosses_setjmp[r])
  	continue;
  
        /* Now find the best hard-register class for this pseudo register */
--- 314,323 ----
        register int r = reg_order[i];
  
        /* Some regnos disappear from the rtl.  Ignore them to avoid crash. 
! 	 Also don't allocate registers that cross a setjmp.  
!          Also ignore registers we didn't see during the scan.  */
!       if (regno_reg_rtx[r] == 0 || regs_crosses_setjmp[r]
! 	  || reg_where_born[r] == 0 && reg_where_dead[r] == 0)
  	continue;
  
        /* Now find the best hard-register class for this pseudo register */
*************** stupid_life_analysis (f, nregs, file)
*** 292,297 ****
--- 339,379 ----
  					   regs_change_size[r]);
      }
  
+   /* Fill in the pseudo reg information into the insn chain.  
+      @@@ Fixme, this isn't pretty.  */
+   for (i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++)
+     {
+       struct insn_chain *chain;
+       int regno, nregs;
+       int j;
+ 
+       regno = reg_renumber[i];
+       if (regno < 0)
+ 	continue;
+       nregs = HARD_REGNO_NREGS (regno, PSEUDO_REGNO_MODE (i));
+ 
+       chain = reg_where_dead_chain[i];
+       if (reg_where_dead[i] > INSN_SUID (chain->insn))
+ 	for (j = 0; j < nregs; j++)
+ 	  chain->inverse_renum_after[regno + j] = i;
+ 
+       while (INSN_SUID (chain->insn) > reg_where_born_exact[i])
+ 	{
+ 	  for (j = 0; j < nregs; j++)
+ 	    chain->inverse_renum_before[regno + j] = i;
+ 	  chain = chain->prev;
+ 	  if (!chain)
+ 	    break;
+ 	  for (j = 0; j < nregs; j++)
+ 	    chain->inverse_renum_after[regno + j] = i;
+ 	}
+ 
+       if (INSN_SUID (chain->insn) == reg_where_born_exact[i]
+ 	  && reg_where_born_clobber[i])
+ 	for (j = 0; j < nregs; j++)
+ 	  chain->inverse_renum_before[regno + j] = i;
+     }
+ 
    if (file)
      dump_flow_info (file);
  }
*************** stupid_find_reg (call_preserved, class, 
*** 433,444 ****
     INSN is the current insn, supplied so we can find its suid.  */
  
  static void
! stupid_mark_refs (x, insn)
!      rtx x, insn;
  {
    register RTX_CODE code;
    register char *fmt;
    register int regno, i;
  
    if (x == 0)
      return;
--- 515,528 ----
     INSN is the current insn, supplied so we can find its suid.  */
  
  static void
! stupid_mark_refs (x, chain)
!      rtx x;
!      struct insn_chain *chain;
  {
    register RTX_CODE code;
    register char *fmt;
    register int regno, i;
+   rtx insn = chain->insn;
  
    if (x == 0)
      return;
*************** stupid_mark_refs (x, insn)
*** 495,500 ****
--- 579,590 ----
  
  	      reg_where_born[regno] = where_born;
  
+ 	      reg_where_born_exact[regno] = INSN_SUID (insn);
+ 	      reg_where_born_clobber[regno] = (code == CLOBBER);
+ 
+ 	      if (reg_where_dead_chain[regno] == 0)
+ 		reg_where_dead_chain[regno] = chain;
+ 
  	      /* The reg must live at least one insn even
  		 in it is never again used--because it has to go
  		 in SOME hard reg.  Mark it as dying after the current
*************** stupid_mark_refs (x, insn)
*** 535,543 ****
  	 If setting a SUBREG, we treat the entire reg as *used*.  */
        if (code == SET)
  	{
! 	  stupid_mark_refs (SET_SRC (x), insn);
  	  if (GET_CODE (SET_DEST (x)) != REG)
! 	    stupid_mark_refs (SET_DEST (x), insn);
  	}
        return;
      }
--- 625,633 ----
  	 If setting a SUBREG, we treat the entire reg as *used*.  */
        if (code == SET)
  	{
! 	  stupid_mark_refs (SET_SRC (x), chain);
  	  if (GET_CODE (SET_DEST (x)) != REG)
! 	    stupid_mark_refs (SET_DEST (x), chain);
  	}
        return;
      }
*************** stupid_mark_refs (x, insn)
*** 571,581 ****
--- 661,674 ----
  	  /* Pseudo reg: record first use, last use and number of uses.  */
  
  	  reg_where_born[regno] = INSN_SUID (insn);
+ 	  reg_where_born_exact[regno] = INSN_SUID (insn);
+ 	  reg_where_born_clobber[regno] = 0;
  	  REG_N_REFS (regno)++;
  	  if (regs_live[regno] == 0)
  	    {
  	      regs_live[regno] = 1;
  	      reg_where_dead[regno] = INSN_SUID (insn);
+ 	      reg_where_dead_chain[regno] = chain;
  	    }
  	}
        return;
*************** stupid_mark_refs (x, insn)
*** 587,598 ****
    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
        if (fmt[i] == 'e')
! 	stupid_mark_refs (XEXP (x, i), insn);
        if (fmt[i] == 'E')
  	{
  	  register int j;
  	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
! 	    stupid_mark_refs (XVECEXP (x, i, j), insn);
  	}
      }
  }
--- 680,691 ----
    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
        if (fmt[i] == 'e')
! 	stupid_mark_refs (XEXP (x, i), chain);
        if (fmt[i] == 'E')
  	{
  	  register int j;
  	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
! 	    stupid_mark_refs (XVECEXP (x, i, j), chain);
  	}
      }
  }

^ permalink raw reply	[flat|nested] 23+ messages in thread

* gcc installation
       [not found] <200304300904.h3U94wX18945@anatolia.koeri.boun.edu.tr>
@ 2003-04-30 16:18 ` Gonca Orgulu
  0 siblings, 0 replies; 23+ messages in thread
From: Gonca Orgulu @ 2003-04-30 16:18 UTC (permalink / raw)
  To: gcc; +Cc: gonca

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1325 bytes --]

 
 
 Thank you for the information. I think that i completed configuration, but
 the second step "make bootstrap" gives error messages. I attached the log
 files to this message as a tar file. 
 
 Could you please check them?
 
 Gonca
 
 
 Hi,
 
 Gonca Orgulu wrote:
 > I am new for program installation and am not sys admin.  > I tried to understand the instructions, but i think that i did not > understand very well.
 > Probably, my problem for ld is related to the path definition. I am
 > running the program "configure" as root. While as root, the system
 > does not find ld command. Actually, i have link editor program which is in
 > a different path. I tried to give a path for the ld command in configure  > as below,
 >
 > ld='/usr/ccs/bin/ld'
 >
 > I am not sure i am doing correctly. 
 
 Hm, you don't need to run this as root.
 Here in my env I set the PATH pointing to the ccs/bin/ld. I use the 
 tcsh. This is what I put in my .tcshrc:
 
 setenv PATH /usr/local/bin:/usr/ccs/bin:/usr/bin:$PATH
 setenv CONFIG_SHELL /bin/ksh
 
 Then source this .tcshrc and configure the gcc to your needs.
 
 e.g, in a directory called objdir which is on the same level as the gcc-src.
 
 ../gcc/configure --prefix=<where to install>
 
 after configure completes, a make bootstrap should run through. 

 Andreas
 
 
 
 
 
 
 

[-- Attachment #2: Type: APPLICATION/octet-stream, Size: 12800 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: GCC Installation
  2002-10-11  9:48 GCC Installation Mini_Thyagarajan
  2002-10-11  9:55 ` Mini_Thyagarajan
@ 2002-10-11 11:19 ` Mike Stump
  1 sibling, 0 replies; 23+ messages in thread
From: Mike Stump @ 2002-10-11 11:19 UTC (permalink / raw)
  To: Mini_Thyagarajan; +Cc: gcc

Please see the www.cygwin.com site.  I suspect you'll get a faster 
answer asking on the cygwin mailing list.

On Friday, October 11, 2002, at 08:11 AM, Mini_Thyagarajan@hill-rom.com 
wrote:

>       I recently installed gcc in my machine.  I've got all the exe's 
> and
> cygwin.dll in the folder D:\program 
> files\gnu\arm\arm-unknownn-elf\bin.  I
> wrote a Hello.c program which resides in the same directory.  When I 
> tried
> to compile the program using 'gcc hello.c' command, I got the following
> error.
> gcc: Installation problem, cannot exec "cpp0": no such file or 
> directory.
>   I couldn't figure that out.  What does that mean?  What is the 
> solution?

^ permalink raw reply	[flat|nested] 23+ messages in thread

* GCC Installation
  2002-10-11  9:48 GCC Installation Mini_Thyagarajan
@ 2002-10-11  9:55 ` Mini_Thyagarajan
  2002-10-11 11:19 ` Mike Stump
  1 sibling, 0 replies; 23+ messages in thread
From: Mini_Thyagarajan @ 2002-10-11  9:55 UTC (permalink / raw)
  To: gcc

Hi,
      I recently installed gcc in my machine.  I've got all the exe's and
cygwin.dll in the folder D:\program files\gnu\arm\arm-unknownn-elf\bin.  I
wrote a Hello.c program which resides in the same directory.  When I tried
to compile the program using 'gcc hello.c' command, I got the following
error.
gcc: Installation problem, cannot exec "cpp0": no such file or directory.
  I couldn't figure that out.  What does that mean?  What is the solution?
Please advise me.

Thanks in advance,

Mini Thyagarajan,
Development Process Engineer.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* GCC Installation
@ 2002-10-11  9:48 Mini_Thyagarajan
  2002-10-11  9:55 ` Mini_Thyagarajan
  2002-10-11 11:19 ` Mike Stump
  0 siblings, 2 replies; 23+ messages in thread
From: Mini_Thyagarajan @ 2002-10-11  9:48 UTC (permalink / raw)
  To: gcc

Hi,
      I recently installed gcc in my machine.  I've got all the exe's and
cygwin.dll in the folder D:\program files\gnu\arm\arm-unknownn-elf\bin.  I
wrote a Hello.c program which resides in the same directory.  When I tried
to compile the program using 'gcc hello.c' command, I got the following
error.
gcc: Installation problem, cannot exec "cpp0": no such file or directory.
  I couldn't figure that out.  What does that mean?  What is the solution?
Please advise me.

Thanks in advance,

Mini Thyagarajan,
Development Process Engineer.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: gcc installation
  2002-05-22 14:49 gcc installation nicholas
@ 2002-05-22 15:30 ` Kelley Cook
  0 siblings, 0 replies; 23+ messages in thread
From: Kelley Cook @ 2002-05-22 15:30 UTC (permalink / raw)
  To: nicholas, gcc

 >I am trying to install GCC 3.0.4 but as I don't have any earlier
 >version of GCC or any C compiler installed on my system my problem
 >is fairly obvious.  I have looked in your Binaries directory and
 >have found nothing that helps me as I am running OS X 10.1.4.
 >
 >Where can I find a pre-compiled C compiler and how do I set my
 >environment variable CC to that compiler?
 >
 >thanks
 >
 >nicholas

GCC 2.95.3 for Mac OS X comes on the Developer Tools CD, which came with 
10.1

Otherwise the compiler is available from

http://developer.apple.com/tools/compilers.html

You'll need to sign up for a no-cost online membership in the ADC.

Kelley Cook

^ permalink raw reply	[flat|nested] 23+ messages in thread

* gcc installation
@ 2002-05-22 14:49 nicholas
  2002-05-22 15:30 ` Kelley Cook
  0 siblings, 1 reply; 23+ messages in thread
From: nicholas @ 2002-05-22 14:49 UTC (permalink / raw)
  To: gcc

Hey,

I am trying to install GCC 3.0.4 but as I don't have any earlier version 
of GCC or any C compiler installed on my system my problem is fairly 
obvious.  I have looked in your Binaries directory and have found 
nothing that helps me as I am running OS X 10.1.4.

Where can I find a pre-compiled C compiler and how do I set my 
environment variable CC to that compiler?

thanks

nicholas

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: GCC Installation
  2002-04-06 22:22 GCC Installation Rabea Husseis
@ 2002-04-06 22:23 ` Bobby McNulty Junior
  0 siblings, 0 replies; 23+ messages in thread
From: Bobby McNulty Junior @ 2002-04-06 22:23 UTC (permalink / raw)
  To: Rabea Husseis, gcc

You are out of drive space.
I think.

----- Original Message ----- 
From: "Rabea Husseis" <rhusseis@yahoo.com>
To: <gcc@gcc.gnu.org>
Sent: Sunday, April 07, 2002 12:06 AM
Subject: GCC Installation


> Hello...
> 
> I got the blw error every time I try to install gcc
> package:
> 
> 
> #pkgadd -d gcc-2.95.3-sol7-sparc-local
> 
> The following packages are available:
> 1 SMCgcc gcc
> (sparc) 2.95.3
> 
> Select package(s) you wish to process (or 'all' to
> process
> all packages). (default: all) [?,??,q]: 1
> 
> Processing package instance <SMCgcc> from
> </gcc-2.95.3-sol7-sparc-local>
> 
> gcc
> (sparc) 2.95.3
> cpio: Cannot write
> "reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/cc1obj",
> errno
> 28, No space left on device
> cpio: Cannot write
> "reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/cc1plus",
> errn
> o 28, No space left on device
> cpio: Cannot write
> "reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/chillrt0.o",
> e
> rrno 28, No space left on device
> cpio: Cannot write
> "reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/collect2",
> err
> no 28, No space left on device
> cpio: Cannot write
> "reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/cpp0",
> errno 2
> 8, No space left on device
> cpio: Cannot write
> "reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/crtbegin.o",
> e
> rrno 28, No space left on device
> cpio: Cannot write
> "reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/f771",
> errno 2
> 8, No space left on device
> cpio: Cannot write
> "reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/gmon.o",
> errno
> 28, No space left on device
> cpio: Cannot write
> "reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/include/assert
> .h", errno 28, No space left on device
> cpio: Cannot write "
> 
> 
> 
> pkgadd: ERROR: attempt to process datastream failed
> - process </usr/bin/cpio -icdumD -C 512> failed, exit
> code 95
> pkgadd: ERROR: unable to unpack datastream
> 
> Installation of <SMCgcc> failed (internal error).
> No changes were made to the system.
> #
> 
> Can u pls advise how I can over come this problem? I
> alrady tried to install "gcc-3.0.3-sol7-sparc-local"
> but still the same.
> 
> Thanx
> 
> Rabea 
> 
> __________________________________________________
> Do You Yahoo!?
> Yahoo! Tax Center - online filing with TurboTax
> http://taxes.yahoo.com/


^ permalink raw reply	[flat|nested] 23+ messages in thread

* GCC Installation
@ 2002-04-06 22:22 Rabea Husseis
  2002-04-06 22:23 ` Bobby McNulty Junior
  0 siblings, 1 reply; 23+ messages in thread
From: Rabea Husseis @ 2002-04-06 22:22 UTC (permalink / raw)
  To: gcc

Hello...

I got the blw error every time I try to install gcc
package:


#pkgadd -d gcc-2.95.3-sol7-sparc-local

The following packages are available:
1 SMCgcc gcc
(sparc) 2.95.3

Select package(s) you wish to process (or 'all' to
process
all packages). (default: all) [?,??,q]: 1

Processing package instance <SMCgcc> from
</gcc-2.95.3-sol7-sparc-local>

gcc
(sparc) 2.95.3
cpio: Cannot write
"reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/cc1obj",
errno
28, No space left on device
cpio: Cannot write
"reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/cc1plus",
errn
o 28, No space left on device
cpio: Cannot write
"reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/chillrt0.o",
e
rrno 28, No space left on device
cpio: Cannot write
"reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/collect2",
err
no 28, No space left on device
cpio: Cannot write
"reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/cpp0",
errno 2
8, No space left on device
cpio: Cannot write
"reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/crtbegin.o",
e
rrno 28, No space left on device
cpio: Cannot write
"reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/f771",
errno 2
8, No space left on device
cpio: Cannot write
"reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/gmon.o",
errno
28, No space left on device
cpio: Cannot write
"reloc/lib/gcc-lib/sparc-sun-solaris2.7/2.95.3/include/assert
.h", errno 28, No space left on device
cpio: Cannot write "



pkgadd: ERROR: attempt to process datastream failed
- process </usr/bin/cpio -icdumD -C 512> failed, exit
code 95
pkgadd: ERROR: unable to unpack datastream

Installation of <SMCgcc> failed (internal error).
No changes were made to the system.
#

Can u pls advise how I can over come this problem? I
alrady tried to install "gcc-3.0.3-sol7-sparc-local"
but still the same.

Thanx

Rabea 

__________________________________________________
Do You Yahoo!?
Yahoo! Tax Center - online filing with TurboTax
http://taxes.yahoo.com/

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: gcc installation
  2002-01-17 11:58 gcc installation Justin R. Gortner
@ 2002-01-17 12:14 ` Andrea 'Fyre Wyzard' Bocci
  0 siblings, 0 replies; 23+ messages in thread
From: Andrea 'Fyre Wyzard' Bocci @ 2002-01-17 12:14 UTC (permalink / raw)
  To: Justin R. Gortner, gcc

At 13.36 17/01/2002 (GMT -0800), Justin R. Gortner wrote:
>GCC Team,
>
>I'm not sure if you answer these types of question via e-mail, but here it
>goes anyhow; I just installed Mandrake Linux on my computer. It has GCC on
>it now but I need to update it. I downloaded and uncompressed
>gcc-g++2.95.2.tar.gz, but I have no idea how to update the existing gcc with
>these files. If you could just give me a set of instructions to a newbie it
>would really be a great help! Thanks,
>
>Justin R. Gortner of Virginia Tech

You're best option would be to download the RPM packages for it - they are 
much easier to install and update.
You can get them from, eg., http://rpmfind.net.
Just search gcc, gcc-g++, and any other packages you might need. Then pick 
which version you like (for Mandrake).

If you really want to update from the sources, you need to download also 
gcc-2.95.2.tar.gz, and read the instructions at http://gcc.gnu.org/install/.

HTH
fwyzard

^ permalink raw reply	[flat|nested] 23+ messages in thread

* gcc installation
@ 2002-01-17 11:58 Justin R. Gortner
  2002-01-17 12:14 ` Andrea 'Fyre Wyzard' Bocci
  0 siblings, 1 reply; 23+ messages in thread
From: Justin R. Gortner @ 2002-01-17 11:58 UTC (permalink / raw)
  To: gcc

GCC Team,

I'm not sure if you answer these types of question via e-mail, but here it
goes anyhow; I just installed Mandrake Linux on my computer. It has GCC on
it now but I need to update it. I downloaded and uncompressed
gcc-g++2.95.2.tar.gz, but I have no idea how to update the existing gcc with
these files. If you could just give me a set of instructions to a newbie it
would really be a great help! Thanks,

Justin R. Gortner of Virginia Tech

^ permalink raw reply	[flat|nested] 23+ messages in thread

* RE: gcc installation
  2001-06-05  9:46 Radisa Maksimovic
  2001-06-05 11:05 ` Joe Buck
@ 2001-06-06  3:26 ` Robert McNulty Junior
  1 sibling, 0 replies; 23+ messages in thread
From: Robert McNulty Junior @ 2001-06-06  3:26 UTC (permalink / raw)
  To: marirad, gcc

CC=gcc ../name-of-directory/configure

-----Original Message-----
From: gcc-owner@gcc.gnu.org [ mailto:gcc-owner@gcc.gnu.org]On Behalf Of
Radisa Maksimovic
Sent: Tuesday, June 05, 2001 11:50 AM
To: gcc@gcc.gnu.org
Subject: gcc installation


Hi;
I downloaded the recompiled version of gcc-2.95.3 for Solaris8 Intel but
can't
run srcdir/configure because don't know which value to set for the
variable CC.
I get this message: "The command 'cc -o conftest -g conftest.c' failed".

"You must set the environment variable CC to a working compiler".
Sorry but I'm new at this, am trying to learn C++ by myself.
Your help would be highly appreciated.
Thank you.

Carmen Lacassi

_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: gcc installation
  2001-06-05  9:46 Radisa Maksimovic
@ 2001-06-05 11:05 ` Joe Buck
  2001-06-06  3:26 ` Robert McNulty Junior
  1 sibling, 0 replies; 23+ messages in thread
From: Joe Buck @ 2001-06-05 11:05 UTC (permalink / raw)
  To: marirad; +Cc: gcc

> I downloaded the recompiled version of gcc-2.95.3 for Solaris8 Intel but
> can't
> run srcdir/configure because don't know which value to set for the
> variable CC.

You can't build the compiler from source if your machine does not already
have a C compiler.  If you have no compiler you need to install
precompiled binaries instead.

For Solaris, try http://www.sunfreeware.com/ .

^ permalink raw reply	[flat|nested] 23+ messages in thread

* gcc installation
@ 2001-06-05  9:46 Radisa Maksimovic
  2001-06-05 11:05 ` Joe Buck
  2001-06-06  3:26 ` Robert McNulty Junior
  0 siblings, 2 replies; 23+ messages in thread
From: Radisa Maksimovic @ 2001-06-05  9:46 UTC (permalink / raw)
  To: gcc

Hi;
I downloaded the recompiled version of gcc-2.95.3 for Solaris8 Intel but
can't
run srcdir/configure because don't know which value to set for the
variable CC.
I get this message: "The command 'cc -o conftest -g conftest.c' failed".

"You must set the environment variable CC to a working compiler".
Sorry but I'm new at this, am trying to learn C++ by myself.
Your help would be highly appreciated.
Thank you.

Carmen Lacassi

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: gcc installation
  2000-11-13  4:34 michal
@ 2000-11-13 20:04 ` Alexandre Oliva
  0 siblings, 0 replies; 23+ messages in thread
From: Alexandre Oliva @ 2000-11-13 20:04 UTC (permalink / raw)
  To: michal; +Cc: gcc

On Nov 13, 2000, michal <michal017@yahoo.com> wrote:

> Hi.. I have a problem installing gcc on a Alpha
> machine with Tru64 Unix.

You failed to mention it is Tru64 v5.0.  That was released after GCC
2.95.2, so GCC 2.95.2 doesn't support it.  IIRC, it's just a minor
glitch in gcc/configure{,.in} that detects osf4.* but not 5.*, and
adjusting it to match 5.* is enough.

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

^ permalink raw reply	[flat|nested] 23+ messages in thread

* gcc installation
@ 2000-11-13  4:34 michal
  2000-11-13 20:04 ` Alexandre Oliva
  0 siblings, 1 reply; 23+ messages in thread
From: michal @ 2000-11-13  4:34 UTC (permalink / raw)
  To: gcc

Hi.. I have a problem installing gcc on a Alpha
machine with Tru64 Unix.
I first run ./configure which seems to be OK, it
creates the Makefile.  Then I run Make which runs with
a few warnings and halts on the linking part with:
ld:
Unresolved:
ASM_FILE_START
error..
What should I do?
thanks
michael

__________________________________________________
Do You Yahoo!?
Yahoo! Calendar - Get organized for the holidays!
http://calendar.yahoo.com/

^ permalink raw reply	[flat|nested] 23+ messages in thread

* GCC installation
@ 2000-02-14  2:52 Salvatore Sciortino
  0 siblings, 0 replies; 23+ messages in thread
From: Salvatore Sciortino @ 2000-02-14  2:52 UTC (permalink / raw)
  To: gcc

I have successfully installed 
the complete gcc-2.95.2 under alphaev56-dec-osf4.0f

Regards
S. Sciortino

^ permalink raw reply	[flat|nested] 23+ messages in thread

* GCC Installation
@ 2000-01-08 14:42 Deb, A. (Anindya)
  0 siblings, 0 replies; 23+ messages in thread
From: Deb, A. (Anindya) @ 2000-01-08 14:42 UTC (permalink / raw)
  To: gcc

I want to instal the gcc c and preferably, c++ compilers on my SGI
workstation
running Irix6.5 OS. I have downloaded a file  "gcc-2.95.2.tar.gz" from
the website " ftp://gcc.gnu.org/pub/gcc/releases/index.html " (full
distribution option). Where can I find clear guidelines (steps) on
installation? Also, have I downloaded the correct file? 

Thank you very much. 
 
Regards,

Anindya Deb.
E-Mail: adeb@ford.com

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: gcc installation
  1997-08-21  6:32 f/runtime configure for x-builds? Mumit Khan
@ 1997-08-21  8:00 ` Thomas Weise
  0 siblings, 0 replies; 23+ messages in thread
From: Thomas Weise @ 1997-08-21  8:00 UTC (permalink / raw)
  To: egcs

I've installed it on another machine now, and the problem with specs has
been going away. However, g++ hsn't been installed again. It also
wasn't built in the make directory. But explicitly typing 'make g++'
goes well ... When I've installed Cygnus's latest release from April this
wouldn't happen. So I don't know whats wrong there.

Thomas Weise, http://www.inf.tu-dresden.de/~tw4
Dresden University of Technology, Department of Computer Science  

On Tue, 19 Aug 1997, Jeffrey A Law wrote:

>   In message <Pine.ULT.3.95.970819173626.27159C-100000@irz301.inf.tu-dresden.de
> >you write:
>   > is not a bug report for gcc itself. But can someone please tell me,
>   > why (1) there will  be no configuration spec installed (on Linux
>   > /usr/lib/gcc-lib/i586-pc-linux-gnulibc1/egcs-2.90.00/specs) and whether
> Weird.  It's installed on other platforms.  I'm not aware of any
> linux specific code which would cause specs not to get installed.
> 
>   > (2) g++ seems to be no longer supported (I know that it just calls gcc,
>   > however I've installed both languages, c AND c++).
> Similarly.
> 
> Where there any errors during the "make install"?  Did g++ and
> the specs file get built in the object directory?
> 
> 
> jeff
> 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: gcc installation
  1997-08-19 19:00 xm-alpha.h alloca patch Richard Henderson
@ 1997-08-19 19:08 ` Jeffrey A Law
  0 siblings, 0 replies; 23+ messages in thread
From: Jeffrey A Law @ 1997-08-19 19:08 UTC (permalink / raw)
  To: egcs

  In message <Pine.ULT.3.95.970819173626.27159C-100000@irz301.inf.tu-dresden.de
>you write:
  > is not a bug report for gcc itself. But can someone please tell me,
  > why (1) there will  be no configuration spec installed (on Linux
  > /usr/lib/gcc-lib/i586-pc-linux-gnulibc1/egcs-2.90.00/specs) and whether
Weird.  It's installed on other platforms.  I'm not aware of any
linux specific code which would cause specs not to get installed.

  > (2) g++ seems to be no longer supported (I know that it just calls gcc,
  > however I've installed both languages, c AND c++).
Similarly.

Where there any errors during the "make install"?  Did g++ and
the specs file get built in the object directory?


jeff

^ permalink raw reply	[flat|nested] 23+ messages in thread

* gcc installation
  1997-08-19 16:06 Minor SS issue Peter Seebach
@ 1997-08-19 17:54 ` Thomas Weise
  0 siblings, 0 replies; 23+ messages in thread
From: Thomas Weise @ 1997-08-19 17:54 UTC (permalink / raw)
  To: egcs

Hi,

so far I've installed snapshot egcs-ss-970814 successfully, and this
is not a bug report for gcc itself. But can someone please tell me,
why (1) there will  be no configuration spec installed (on Linux
/usr/lib/gcc-lib/i586-pc-linux-gnulibc1/egcs-2.90.00/specs) and whether
(2) g++ seems to be no longer supported (I know that it just calls gcc,
however I've installed both languages, c AND c++).

Apart from this I'm really impressed. All  of the C++ bugs I've had on my
list have been fixed (and there were a few). I'm wondering why this
version shouldn't be better than the broken 2.7.2 (at least some FSF
people might belief this..)

Thomas.

Thomas Weise, http://www.inf.tu-dresden.de/~tw4
Dresden University of Technology, Department of Computer Science  

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2003-04-30 10:01 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-08-21 16:02 mdbench for g77 & f2c+gcc Furio Ercolessi
1997-08-21 16:10 ` Reload patch version 2 Bernd Schmidt
1997-08-21 16:10 ` gcc installation Jeffrey A Law
     [not found] <200304300904.h3U94wX18945@anatolia.koeri.boun.edu.tr>
2003-04-30 16:18 ` Gonca Orgulu
  -- strict thread matches above, loose matches on Subject: below --
2002-10-11  9:48 GCC Installation Mini_Thyagarajan
2002-10-11  9:55 ` Mini_Thyagarajan
2002-10-11 11:19 ` Mike Stump
2002-05-22 14:49 gcc installation nicholas
2002-05-22 15:30 ` Kelley Cook
2002-04-06 22:22 GCC Installation Rabea Husseis
2002-04-06 22:23 ` Bobby McNulty Junior
2002-01-17 11:58 gcc installation Justin R. Gortner
2002-01-17 12:14 ` Andrea 'Fyre Wyzard' Bocci
2001-06-05  9:46 Radisa Maksimovic
2001-06-05 11:05 ` Joe Buck
2001-06-06  3:26 ` Robert McNulty Junior
2000-11-13  4:34 michal
2000-11-13 20:04 ` Alexandre Oliva
2000-02-14  2:52 GCC installation Salvatore Sciortino
2000-01-08 14:42 GCC Installation Deb, A. (Anindya)
1997-08-21  6:32 f/runtime configure for x-builds? Mumit Khan
1997-08-21  8:00 ` gcc installation Thomas Weise
1997-08-19 19:00 xm-alpha.h alloca patch Richard Henderson
1997-08-19 19:08 ` gcc installation Jeffrey A Law
1997-08-19 16:06 Minor SS issue Peter Seebach
1997-08-19 17:54 ` gcc installation Thomas Weise

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).