This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the EGCS project.


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

stupid.c, rip


For your consideration, a patch to remove stupid.c.

Among the motivations:

  (1) Don't use USEs to mark function return registers.  Instead
      mark the registers live at the start of EXIT_BLOCK.  One of
      Jan's reg-stack cleanups is dependant on this, which also
      explains why we don't want to just do this if !optimize.

  (2) Stupid can't handle non-trivial control flow, and so does
      the wrong thing with Java try-finally constructs.  It's
      possible to work around the problem, but ugly.

  (3) There's zero point to having two completely separate
      register allocation passes.

So instead of stupid, we run through local-alloc and disable
virtually all of global-alloc (about all that's left is data
structure initialization for reload).  This results in code
that is not dissimilar to what -O0 produced before the change.

One thing additional that's needed by local in order to do its
job is a CFG, so we have to run flow.  Which really would 
prefer to have things tidied a bit in jump.  So:

   (A) Jump now does jump tensioning at -O0.  We do delete
       unreachable insns.

   (B) Flow is run.  We do remove unreachable blocks, but do
       not do block merging.

   (C) The needless uses are dead.

   (D) Flow does the right thing in mark_regs_live_at_end.

   (E) Nothing is done in global to restore stupid's putting
       `register' variables in registers.  I don't really see
       this as interesting to a minimal-optimization mode,
       but if we do do something, global should be the one
       to do it.



r~



	* Makefile.in (OBJS): Remove stupid.o.
	* except.c (emit_eh_context): Don't emit uses for stupid.
	* explow.c (probe_stack_range): Likewise.
	* flow.c (delete_unreachable_blocks): Don't merge blocks at -O0.
	(mark_reg): New function.
	(mark_regs_live_at_end): Mark the function return value.
	(propagate_block): Don't AUTO_INC_DEC at -O0.
	(mark_used_regs) [RETURN]: Don't duplicate mark_regs_live_at_end code.
	(print_rtl_with_bb): Ignore obey_regdecls.
	* function.c (use_variable, use_variable_after): Delete.
	(assign_parms): Don't USE regs for reg-stack.
	(expand_function_start): Don't USE parameters.  Always copy
	the static chain into a pseudo.
	(expand_function_end): Don't USE the return value.
	* global.c (global_alloc): Don't scan at -O0.
	* integrate.c (expand_inline_function): Don't ignore the
	return value USE.
	* jump.c (jump_optimize_1): Don't early out at -O0.  Disable 
	HAVE_return, and ought but jump tensioning.
	(calculate_can_reach_end): Remove checked_deleted argument.
	(delete_insn): Really delete insns at -O0.
	* rtl.h (use_variable, use_variable_after): Delete decls.
	* stmt.c (expand_value_return): Don't USE return values.
	(expand_end_bindings): Don't USE register variables.
	(expand_decl): Likewise.
	* toplev.c (rest_of_compilation): Always call flow.  Always
	call local_alloc and global_alloc.


Index: Makefile.in
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/Makefile.in,v
retrieving revision 1.267
diff -c -p -d -r1.267 Makefile.in
*** Makefile.in	1999/07/01 23:53:00	1.267
--- Makefile.in	1999/07/16 21:46:42
*************** OBJS = toplev.o version.o tree.o print-t
*** 676,682 ****
   function.o stmt.o except.o expr.o calls.o expmed.o explow.o optabs.o \
   intl.o varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o genrtl.o real.o \
   dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o gcse.o \
!  integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o varray.o \
   regclass.o regmove.o local-alloc.o global.o reload.o reload1.o caller-save.o \
   insn-peep.o reorg.o $(SCHED_PREFIX)sched.o final.o recog.o reg-stack.o \
   insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o lcm.o \
--- 676,682 ----
   function.o stmt.o except.o expr.o calls.o expmed.o explow.o optabs.o \
   intl.o varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o genrtl.o real.o \
   dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o gcse.o \
!  integrate.o jump.o cse.o loop.o unroll.o flow.o combine.o varray.o \
   regclass.o regmove.o local-alloc.o global.o reload.o reload1.o caller-save.o \
   insn-peep.o reorg.o $(SCHED_PREFIX)sched.o final.o recog.o reg-stack.o \
   insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o lcm.o \
*************** integrate.o : integrate.c $(CONFIG_H) sy
*** 1516,1523 ****
  jump.o : jump.c $(CONFIG_H) system.h $(RTL_H) flags.h hard-reg-set.h $(REGS_H) \
     insn-config.h insn-flags.h $(RECOG_H) $(EXPR_H) real.h except.h \
     toplev.h insn-attr.h
- stupid.o : stupid.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h \
-    $(BASIC_BLOCK_H) insn-config.h reload.h flags.h toplev.h
  
  cse.o : cse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
     real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h \
--- 1516,1521 ----
Index: except.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/except.c,v
retrieving revision 1.83
diff -c -p -d -r1.83 except.c
*** except.c	1999/07/01 23:52:55	1.83
--- except.c	1999/07/16 21:46:42
*************** emit_eh_context ()
*** 2295,2308 ****
  	    end_sequence ();
  
  	    emit_insns_before (insns, insn);
- 
-             /* At -O0, we must make the context register stay alive so
-                that the stupid.c register allocator doesn't get confused. */
-             if (obey_regdecls != 0)
-               {
-                 insns = gen_rtx_USE (GET_MODE (XEXP (reg,0)), XEXP (reg,0));
-                 emit_insn_before (insns, get_last_insn ());
-               }
  	  }
        }
  }
--- 2295,2300 ----
Index: explow.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/explow.c,v
retrieving revision 1.28
diff -c -p -d -r1.28 explow.c
*** explow.c	1999/04/17 17:14:48	1.28
--- explow.c	1999/07/16 21:46:42
*************** probe_stack_range (first, size)
*** 1456,1465 ****
        emit_note (NULL_PTR, NOTE_INSN_LOOP_END);
        emit_label (end_lab);
  
-       /* If will be doing stupid optimization, show test_addr is still live. */
-       if (obey_regdecls)
- 	emit_insn (gen_rtx_USE (VOIDmode, test_addr));
- 
        emit_stack_probe (last_addr);
      }
  }
--- 1456,1461 ----
Index: flow.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/flow.c,v
retrieving revision 1.125
diff -c -p -d -r1.125 flow.c
*** flow.c	1999/07/01 23:52:58	1.125
--- flow.c	1999/07/16 21:46:43
*************** Boston, MA 02111-1307, USA.  */
*** 121,126 ****
--- 121,127 ----
  #include "config.h"
  #include "system.h"
  #include "rtl.h"
+ #include "tree.h"
  #include "basic-block.h"
  #include "insn-config.h"
  #include "regs.h"
*************** static int set_noop_p			PROTO((rtx));
*** 302,307 ****
--- 303,309 ----
  static int noop_move_p			PROTO((rtx));
  static void notice_stack_pointer_modification PROTO ((rtx, rtx));
  static void record_volatile_insns	PROTO((rtx));
+ static void mark_reg			PROTO((regset, rtx));
  static void mark_regs_live_at_end	PROTO((regset));
  static void life_analysis_1		PROTO((rtx, int, int));
  static void init_regset_vector		PROTO ((regset *, int,
*************** delete_unreachable_blocks ()
*** 1570,1592 ****
       has only one successor, and the successor has only one predecessor, 
       they may be combined.  */
  
!   for (i = 0; i < n_basic_blocks; )
!     {
!       basic_block c, b = BASIC_BLOCK (i);
!       edge s;
  
!       /* A loop because chains of blocks might be combineable.  */
!       while ((s = b->succ) != NULL
! 	     && s->succ_next == NULL
! 	     && (s->flags & EDGE_EH) == 0
! 	     && (c = s->dest) != EXIT_BLOCK_PTR
! 	     && c->pred->pred_next == NULL
! 	     && merge_blocks (s, b, c))
! 	continue;
  
!       /* Don't get confused by the index shift caused by deleting blocks.  */
!       i = b->index + 1;
!     }
  
    /* If we deleted an exception handler, we may have EH region begin/end
       blocks to remove as well. */
--- 1572,1595 ----
       has only one successor, and the successor has only one predecessor, 
       they may be combined.  */
  
!   if (optimize)
!     for (i = 0; i < n_basic_blocks; )
!       {
!         basic_block c, b = BASIC_BLOCK (i);
!         edge s;
  
!         /* A loop because chains of blocks might be combineable.  */
!         while ((s = b->succ) != NULL
! 	       && s->succ_next == NULL
! 	       && (s->flags & EDGE_EH) == 0
! 	       && (c = s->dest) != EXIT_BLOCK_PTR
! 	       && c->pred->pred_next == NULL
! 	       && merge_blocks (s, b, c))
! 	  continue;
  
!         /* Don't get confused by the index shift caused by deleting blocks.  */
!         i = b->index + 1;
!       }
  
    /* If we deleted an exception handler, we may have EH region begin/end
       blocks to remove as well. */
*************** record_volatile_insns (f)
*** 2250,2255 ****
--- 2253,2276 ----
      }
  }
  
+ /* Mark a register in SET.  Hard registers get all of their component
+    registers set as well.  */
+ static void
+ mark_reg (set, reg)
+      regset set;
+      rtx reg;
+ {
+   int regno = REGNO (reg);
+ 
+   SET_REGNO_REG_SET (set, regno);
+   if (regno < FIRST_PSEUDO_REGISTER)
+     {
+       int n = HARD_REGNO_NREGS (regno, GET_MODE (reg));
+       while (--n > 0)
+ 	SET_REGNO_REG_SET (set, regno+n);
+     }
+ }
+ 
  /* Mark those regs which are needed at the end of the function as live
     at the end of the last basic block.  */
  static void
*************** mark_regs_live_at_end (set)
*** 2293,2299 ****
  	)
        SET_REGNO_REG_SET (set, i);
  
!   /* ??? Mark function return value here rather than as uses.  */
  }
  
  /* Determine which registers are live at the start of each
--- 2314,2354 ----
  	)
        SET_REGNO_REG_SET (set, i);
  
!   /* Mark function return value.  */
! 
!   {
!     rtx outgoing;
!     tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
! 
!     if (current_function_returns_struct
!         || current_function_returns_pcc_struct)
!       type = build_pointer_type (type);
! 
! #ifdef FUNCTION_OUTGOING_VALUE
!     outgoing = FUNCTION_OUTGOING_VALUE (type, current_function_decl);
! #else
!     outgoing = FUNCTION_VALUE (type, current_function_decl);
! #endif
! 
!     if (GET_CODE (outgoing) == REG)
!       mark_reg (set, outgoing);
!     else if (GET_CODE (outgoing) == PARALLEL)
!       {
! 	int len = XVECLEN (outgoing, 0);
!         /* Check for a NULL entry, used to indicate that the parameter goes
!            both on the stack and in registers.  */
! 	i = (XEXP (XVECEXP (outgoing, 0, 0), 0) ? 0 : 1);
! 
! 	for (; i < len; ++i)
! 	  {
! 	    rtx r = XVECEXP (outgoing, 0, i);
! 	    if (GET_CODE (r) == REG)
! 	      mark_reg (set, r);
! 	  }
!       }
!     else
!       abort ();
!   }
  }
  
  /* Determine which registers are live at the start of each
*************** propagate_block (old, first, last, final
*** 2749,2755 ****
  	    register rtx x = single_set (insn);
  
  	    /* Does this instruction increment or decrement a register?  */
! 	    if (!reload_completed
  		&& final && x != 0
  		&& GET_CODE (SET_DEST (x)) == REG
  		&& (GET_CODE (SET_SRC (x)) == PLUS
--- 2804,2811 ----
  	    register rtx x = single_set (insn);
  
  	    /* Does this instruction increment or decrement a register?  */
! 	    if (optimize
! 		&& !reload_completed
  		&& final && x != 0
  		&& GET_CODE (SET_DEST (x)) == REG
  		&& (GET_CODE (SET_SRC (x)) == PLUS
*************** propagate_block (old, first, last, final
*** 2862,2868 ****
  	      /* Update OLD for the registers used or set.  */
  	      AND_COMPL_REG_SET (old, dead);
  	      IOR_REG_SET (old, live);
- 
  	    }
  
  	  /* On final pass, update counts of how many insns each reg is live
--- 2918,2923 ----
*************** mark_used_regs (needed, live, x, final, 
*** 3691,3697 ****
  	invalidate_mems_from_autoinc (insn);
  
  #ifdef AUTO_INC_DEC
!       if (final)
  	find_auto_inc (needed, x, insn);
  #endif
        break;
--- 3746,3752 ----
  	invalidate_mems_from_autoinc (insn);
  
  #ifdef AUTO_INC_DEC
!       if (optimize && final)
  	find_auto_inc (needed, x, insn);
  #endif
        break;
*************** mark_used_regs (needed, live, x, final, 
*** 3874,3880 ****
  	if (GET_CODE (testreg) == MEM)
  	  {
  #ifdef AUTO_INC_DEC
! 	    if (final)
  	      find_auto_inc (needed, testreg, insn);
  #endif
  	    mark_used_regs (needed, live, XEXP (testreg, 0), final, insn);
--- 3929,3935 ----
  	if (GET_CODE (testreg) == MEM)
  	  {
  #ifdef AUTO_INC_DEC
! 	    if (optimize && final)
  	      find_auto_inc (needed, testreg, insn);
  #endif
  	    mark_used_regs (needed, live, XEXP (testreg, 0), final, insn);
*************** mark_used_regs (needed, live, x, final, 
*** 3941,3963 ****
        break;
  
      case RETURN:
!       /* If exiting needs the right stack value, consider this insn as
! 	 using the stack pointer.  In any event, consider it as using
! 	 all global registers and all registers used by return.  */
!       if (! EXIT_IGNORE_STACK
! 	  || (! FRAME_POINTER_REQUIRED
! 	      && ! current_function_calls_alloca
! 	      && flag_omit_frame_pointer)
! 	  || current_function_sp_is_unchanging)
! 	SET_REGNO_REG_SET (live, STACK_POINTER_REGNUM);
! 
!       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 	if (global_regs[i]
! #ifdef EPILOGUE_USES
! 	    || EPILOGUE_USES (i)
! #endif
! 	    )
! 	  SET_REGNO_REG_SET (live, i);
        break;
  
      case ASM_OPERANDS:
--- 3996,4004 ----
        break;
  
      case RETURN:
!       /* ??? This info should have been gotten from mark_regs_live_at_end,
! 	 as applied to the EXIT block, and propogated along the edge that
! 	 connects this block to the EXIT.  */
        break;
  
      case ASM_OPERANDS:
*************** print_rtl_with_bb (outf, rtx_first)
*** 4421,4428 ****
  
  	  if (in_bb_p[INSN_UID(tmp_rtx)] == NOT_IN_BB
  	      && GET_CODE (tmp_rtx) != NOTE
! 	      && GET_CODE (tmp_rtx) != BARRIER
! 	      && ! obey_regdecls)
  	    fprintf (outf, ";; Insn is not within a basic block\n");
  	  else if (in_bb_p[INSN_UID(tmp_rtx)] == IN_MULTIPLE_BB)
  	    fprintf (outf, ";; Insn is in multiple basic blocks\n");
--- 4462,4468 ----
  
  	  if (in_bb_p[INSN_UID(tmp_rtx)] == NOT_IN_BB
  	      && GET_CODE (tmp_rtx) != NOTE
! 	      && GET_CODE (tmp_rtx) != BARRIER)
  	    fprintf (outf, ";; Insn is not within a basic block\n");
  	  else if (in_bb_p[INSN_UID(tmp_rtx)] == IN_MULTIPLE_BB)
  	    fprintf (outf, ";; Insn is in multiple basic blocks\n");
Index: function.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.c,v
retrieving revision 1.91
diff -c -p -d -r1.91 function.c
*** function.c	1999/05/20 22:22:34	1.91
--- function.c	1999/07/16 21:46:43
*************** delete_handlers ()
*** 4117,4161 ****
      }
  }
  
- /* Output a USE for any register use in RTL.
-    This is used with -noreg to mark the extent of lifespan
-    of any registers used in a user-visible variable's DECL_RTL.  */
- 
- void
- use_variable (rtl)
-      rtx rtl;
- {
-   if (GET_CODE (rtl) == REG)
-     /* This is a register variable.  */
-     emit_insn (gen_rtx_USE (VOIDmode, rtl));
-   else if (GET_CODE (rtl) == MEM
- 	   && GET_CODE (XEXP (rtl, 0)) == REG
- 	   && (REGNO (XEXP (rtl, 0)) < FIRST_VIRTUAL_REGISTER
- 	       || REGNO (XEXP (rtl, 0)) > LAST_VIRTUAL_REGISTER)
- 	   && XEXP (rtl, 0) != current_function_internal_arg_pointer)
-     /* This is a variable-sized structure.  */
-     emit_insn (gen_rtx_USE (VOIDmode, XEXP (rtl, 0)));
- }
- 
- /* Like use_variable except that it outputs the USEs after INSN
-    instead of at the end of the insn-chain.  */
- 
- void
- use_variable_after (rtl, insn)
-      rtx rtl, insn;
- {
-   if (GET_CODE (rtl) == REG)
-     /* This is a register variable.  */
-     emit_insn_after (gen_rtx_USE (VOIDmode, rtl), insn);
-   else if (GET_CODE (rtl) == MEM
- 	   && GET_CODE (XEXP (rtl, 0)) == REG
- 	   && (REGNO (XEXP (rtl, 0)) < FIRST_VIRTUAL_REGISTER
- 	       || REGNO (XEXP (rtl, 0)) > LAST_VIRTUAL_REGISTER)
- 	   && XEXP (rtl, 0) != current_function_internal_arg_pointer)
-     /* This is a variable-sized structure.  */
-     emit_insn_after (gen_rtx_USE (VOIDmode, XEXP (rtl, 0)), insn);
- }
- 
  int
  max_parm_reg_num ()
  {
--- 4117,4122 ----
*************** assign_parms (fndecl, second_time)
*** 4647,4663 ****
  	}
  #endif /* 0 */
  
- #ifdef STACK_REGS
-       /* We need this "use" info, because the gcc-register->stack-register
- 	 converter in reg-stack.c needs to know which registers are active
- 	 at the start of the function call.  The actual parameter loading
- 	 instructions are not always available then anymore, since they might
- 	 have been optimised away.  */
- 
-       if (GET_CODE (entry_parm) == REG && !(hide_last_arg && last_named))
- 	  emit_insn (gen_rtx_USE (GET_MODE (entry_parm), entry_parm));
- #endif
- 
        /* ENTRY_PARM is an RTX for the parameter as it arrives,
  	 in the mode in which it arrives.
  	 STACK_PARM is an RTX for a stack slot where the parameter can live
--- 4608,4613 ----
*************** expand_function_start (subr, parms_have_
*** 6210,6241 ****
       as opposed to parm setup.  */
    emit_note (NULL_PTR, NOTE_INSN_FUNCTION_BEG);
  
-   /* If doing stupid allocation, mark parms as born here.  */
- 
    if (GET_CODE (get_last_insn ()) != NOTE)
      emit_note (NULL_PTR, NOTE_INSN_DELETED);
    parm_birth_insn = get_last_insn ();
  
-   if (obey_regdecls)
-     {
-       for (i = LAST_VIRTUAL_REGISTER + 1; i < max_parm_reg; i++)
- 	use_variable (regno_reg_rtx[i]);
- 
-       if (current_function_internal_arg_pointer != virtual_incoming_args_rtx)
- 	use_variable (current_function_internal_arg_pointer);
-     }
- 
    context_display = 0;
    if (current_function_needs_context)
      {
        /* Fetch static chain values for containing functions.  */
        tem = decl_function_context (current_function_decl);
!       /* If not doing stupid register allocation copy the static chain
! 	 pointer into a pseudo.  If we have small register classes, copy
! 	 the value from memory if static_chain_incoming_rtx is a REG.  If
! 	 we do stupid register allocation, we use the stack address
! 	 generated above.  */
!       if (tem && ! obey_regdecls)
  	{
  	  /* If the static chain originally came in a register, put it back
  	     there, then move it out in the next insn.  The reason for
--- 6160,6178 ----
       as opposed to parm setup.  */
    emit_note (NULL_PTR, NOTE_INSN_FUNCTION_BEG);
  
    if (GET_CODE (get_last_insn ()) != NOTE)
      emit_note (NULL_PTR, NOTE_INSN_DELETED);
    parm_birth_insn = get_last_insn ();
  
    context_display = 0;
    if (current_function_needs_context)
      {
        /* Fetch static chain values for containing functions.  */
        tem = decl_function_context (current_function_decl);
!       /* Copy the static chain pointer into a pseudo.  If we have
! 	 small register classes, copy the value from memory if
! 	 static_chain_incoming_rtx is a REG.  */
!       if (tem)
  	{
  	  /* If the static chain originally came in a register, put it back
  	     there, then move it out in the next insn.  The reason for
*************** expand_function_end (filename, line, end
*** 6435,6461 ****
       until next function's body starts.  */
    immediate_size_expand--;
  
-   /* If doing stupid register allocation,
-      mark register parms as dying here.  */
- 
-   if (obey_regdecls)
-     {
-       rtx tem;
-       for (i = LAST_VIRTUAL_REGISTER + 1; i < max_parm_reg; i++)
- 	use_variable (regno_reg_rtx[i]);
- 
-       /* Likewise for the regs of all the SAVE_EXPRs in the function.  */
- 
-       for (tem = save_expr_regs; tem; tem = XEXP (tem, 1))
- 	{
- 	  use_variable (XEXP (tem, 0));
- 	  use_variable_after (XEXP (tem, 0), parm_birth_insn);
- 	}
- 
-       if (current_function_internal_arg_pointer != virtual_incoming_args_rtx)
- 	use_variable (current_function_internal_arg_pointer);
-     }
- 
    clear_pending_stack_adjust ();
    do_pending_stack_adjust ();
  
--- 6372,6377 ----
*************** expand_function_end (filename, line, end
*** 6562,6568 ****
  		  GET_MODE (DECL_RTL (DECL_RESULT (current_function_decl))));
        emit_move_insn (real_decl_result,
  		      DECL_RTL (DECL_RESULT (current_function_decl)));
-       emit_insn (gen_rtx_USE (VOIDmode, real_decl_result));
  
        /* The delay slot scheduler assumes that current_function_return_rtx
  	 holds the hard register containing the return value, not a temporary
--- 6478,6483 ----
*************** expand_function_end (filename, line, end
*** 6596,6602 ****
        REG_FUNCTION_VALUE_P (outgoing) = 1;
  
        emit_move_insn (outgoing, value_address);
-       use_variable (outgoing);
      }
  
    /* If this is an implementation of __throw, do what's necessary to 
--- 6511,6516 ----
Index: global.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/global.c,v
retrieving revision 1.27
diff -c -p -d -r1.27 global.c
*** global.c	1999/02/25 23:45:19	1.27
--- global.c	1999/07/16 21:46:43
*************** global_alloc (file)
*** 495,501 ****
    /* If there is work to be done (at least one reg to allocate),
       perform global conflict analysis and allocate the regs.  */
  
!   if (max_allocno > 0)
      {
        /* Scan all the insns and compute the conflicts among allocnos
  	 and between allocnos and hard regs.  */
--- 495,501 ----
    /* If there is work to be done (at least one reg to allocate),
       perform global conflict analysis and allocate the regs.  */
  
!   if (optimize && max_allocno > 0)
      {
        /* Scan all the insns and compute the conflicts among allocnos
  	 and between allocnos and hard regs.  */
Index: integrate.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/integrate.c,v
retrieving revision 1.54
diff -c -p -d -r1.54 integrate.c
*** integrate.c	1999/04/25 23:35:12	1.54
--- integrate.c	1999/07/16 21:46:44
*************** expand_inline_function (fndecl, parms, t
*** 1891,1903 ****
  	  pattern = PATTERN (insn);
  	  set = single_set (insn);
  	  copy = 0;
- 	  if (GET_CODE (pattern) == USE
- 	      && GET_CODE (XEXP (pattern, 0)) == REG
- 	      && REG_FUNCTION_VALUE_P (XEXP (pattern, 0)))
- 	    /* The (USE (REG n)) at return from the function should
- 	       be ignored since we are changing (REG n) into
- 	       inline_target.  */
- 	    break;
  
  	  /* If the inline fn needs eh context, make sure that
  	     the current fn has one. */
--- 1891,1896 ----
Index: jump.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/jump.c,v
retrieving revision 1.62
diff -c -p -d -r1.62 jump.c
*** jump.c	1999/06/27 02:39:42	1.62
--- jump.c	1999/07/16 21:46:45
*************** static void delete_barrier_successors	PR
*** 114,120 ****
  static void mark_all_labels		PROTO((rtx, int));
  static rtx delete_unreferenced_labels	PROTO((rtx));
  static void delete_noop_moves		PROTO((rtx));
! static int calculate_can_reach_end	PROTO((rtx, int, int));
  static int duplicate_loop_exit_test	PROTO((rtx));
  static void find_cross_jump		PROTO((rtx, rtx, int, rtx *, rtx *));
  static void do_cross_jump		PROTO((rtx, rtx, rtx));
--- 114,120 ----
  static void mark_all_labels		PROTO((rtx, int));
  static rtx delete_unreferenced_labels	PROTO((rtx));
  static void delete_noop_moves		PROTO((rtx));
! static int calculate_can_reach_end	PROTO((rtx, int));
  static int duplicate_loop_exit_test	PROTO((rtx));
  static void find_cross_jump		PROTO((rtx, rtx, int, rtx *, rtx *));
  static void do_cross_jump		PROTO((rtx, rtx, rtx));
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 233,258 ****
  
    last_insn = delete_unreferenced_labels (f);
  
-   if (!optimize)
-     {
-       /* CAN_REACH_END is persistent for each function.  Once set it should
- 	 not be cleared.  This is especially true for the case where we
- 	 delete the NOTE_FUNCTION_END note.  CAN_REACH_END is cleared by
- 	 the front-end before compiling each function.  */
-       if (calculate_can_reach_end (last_insn, 1, 0))
- 	can_reach_end = 1;
- 
-       /* Zero the "deleted" flag of all the "deleted" insns.  */
-       for (insn = f; insn; insn = NEXT_INSN (insn))
- 	INSN_DELETED_P (insn) = 0;
- 
-       /* Show that the jump chain is not valid.  */
-       jump_chain = 0;
-       return;
-     }
- 
  #ifdef HAVE_return
!   if (HAVE_return)
      {
        /* If we fall through to the epilogue, see if we can insert a RETURN insn
  	 in front of it.  If the machine allows it at this point (we might be
--- 233,240 ----
  
    last_insn = delete_unreferenced_labels (f);
  
  #ifdef HAVE_return
!   if (optimize && HAVE_return)
      {
        /* If we fall through to the epilogue, see if we can insert a RETURN insn
  	 in front of it.  If the machine allows it at this point (we might be
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 278,284 ****
       This helps some of the optimizations below by having less insns
       being jumped around.  */
  
!   if (! reload_completed && after_regscan)
      for (insn = f; insn; insn = next)
        {
  	rtx set = single_set (insn);
--- 260,266 ----
       This helps some of the optimizations below by having less insns
       being jumped around.  */
  
!   if (optimize && ! reload_completed && after_regscan)
      for (insn = f; insn; insn = next)
        {
  	rtx set = single_set (insn);
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 396,402 ****
  
  	  /* If a jump references the end of the function, try to turn
  	     it into a RETURN insn, possibly a conditional one.  */
! 	  if (JUMP_LABEL (insn)
  	      && (next_active_insn (JUMP_LABEL (insn)) == 0
  		  || GET_CODE (PATTERN (next_active_insn (JUMP_LABEL (insn))))
  		      == RETURN))
--- 378,385 ----
  
  	  /* If a jump references the end of the function, try to turn
  	     it into a RETURN insn, possibly a conditional one.  */
! 	  if (optimize
! 	      && JUMP_LABEL (insn)
  	      && (next_active_insn (JUMP_LABEL (insn)) == 0
  		  || GET_CODE (PATTERN (next_active_insn (JUMP_LABEL (insn))))
  		      == RETURN))
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 411,416 ****
--- 394,412 ----
  	      continue;
  	    }
  
+ 	  /* Detect a jump to a jump.  */
+ 
+ 	  nlabel = follow_jumps (JUMP_LABEL (insn));
+ 	  if (nlabel != JUMP_LABEL (insn)
+ 	      && redirect_jump (insn, nlabel))
+ 	    {
+ 	      changed = 1;
+ 	      continue;
+ 	    }
+ 
+ 	  if (!optimize)
+ 	    continue;
+ 
  	  /* If we have an unconditional jump preceded by a USE, try to put
  	     the USE before the target and jump there.  This simplifies many
  	     of the optimizations below since we don't have to worry about
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 1798,1813 ****
  	    }
  	  else
  	    {
- 	      /* Detect a jump to a jump.  */
- 
- 	      nlabel = follow_jumps (JUMP_LABEL (insn));
- 	      if (nlabel != JUMP_LABEL (insn)
- 		  && redirect_jump (insn, nlabel))
- 		{
- 		  changed = 1;
- 		  next = insn;
- 		}
- 
  	      /* Look for   if (foo) bar; else break;  */
  	      /* The insns look like this:
  		 insn = condjump label1;
--- 1794,1799 ----
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 2096,2102 ****
       not be cleared.  This is especially true for the case where we
       delete the NOTE_FUNCTION_END note.  CAN_REACH_END is cleared by
       the front-end before compiling each function.  */
!   if (calculate_can_reach_end (last_insn, 0, 1))
      can_reach_end = 1;
  
    /* Show JUMP_CHAIN no longer valid.  */
--- 2082,2088 ----
       not be cleared.  This is especially true for the case where we
       delete the NOTE_FUNCTION_END note.  CAN_REACH_END is cleared by
       the front-end before compiling each function.  */
!   if (calculate_can_reach_end (last_insn, optimize != 0))
      can_reach_end = 1;
  
    /* Show JUMP_CHAIN no longer valid.  */
*************** delete_noop_moves (f)
*** 2499,2507 ****
     if we find it.  */
  
  static int
! calculate_can_reach_end (last, check_deleted, delete_final_note)
       rtx last;
-      int check_deleted;
       int delete_final_note;
  {
    rtx insn = last;
--- 2485,2492 ----
     if we find it.  */
  
  static int
! calculate_can_reach_end (last, delete_final_note)
       rtx last;
       int delete_final_note;
  {
    rtx insn = last;
*************** calculate_can_reach_end (last, check_del
*** 2539,2547 ****
    /* See if we backed up to the appropriate type of note.  */
    if (insn != NULL_RTX
        && GET_CODE (insn) == NOTE
!       && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END
!       && (check_deleted == 0
! 	  || ! INSN_DELETED_P (insn)))
      {
        if (delete_final_note)
  	delete_insn (insn);
--- 2524,2530 ----
    /* See if we backed up to the appropriate type of note.  */
    if (insn != NULL_RTX
        && GET_CODE (insn) == NOTE
!       && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END)
      {
        if (delete_final_note)
  	delete_insn (insn);
*************** delete_insn (insn)
*** 3965,3972 ****
  
    /* Don't delete user-declared labels.  Convert them to special NOTEs
       instead.  */
!   if (was_code_label && LABEL_NAME (insn) != 0
!       && optimize && ! dont_really_delete)
      {
        PUT_CODE (insn, NOTE);
        NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED_LABEL;
--- 3948,3954 ----
  
    /* Don't delete user-declared labels.  Convert them to special NOTEs
       instead.  */
!   if (was_code_label && LABEL_NAME (insn) != 0 && ! dont_really_delete)
      {
        PUT_CODE (insn, NOTE);
        NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED_LABEL;
*************** delete_insn (insn)
*** 3992,3998 ****
  
    /* Patch out INSN (and the barrier if any) */
  
!   if (optimize && ! dont_really_delete)
      {
        if (prev)
  	{
--- 3974,3980 ----
  
    /* Patch out INSN (and the barrier if any) */
  
!   if (! dont_really_delete)
      {
        if (prev)
  	{
Index: rtl.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/rtl.h,v
retrieving revision 1.105
diff -c -p -d -r1.105 rtl.h
*** rtl.h	1999/04/27 17:08:34	1.105
--- rtl.h	1999/07/16 21:46:45
*************** extern void record_excess_regs		PROTO ((
*** 1449,1460 ****
  /* In function.c */
  extern void reposition_prologue_and_epilogue_notes	PROTO ((rtx));
  extern void thread_prologue_and_epilogue_insns		PROTO ((rtx));
- extern void use_variable				PROTO ((rtx));
  extern HOST_WIDE_INT get_frame_size			PROTO ((void));
  extern void preserve_rtl_expr_result			PROTO ((rtx));
  extern void mark_temp_addr_taken			PROTO ((rtx));
  extern void update_temp_slot_address			PROTO ((rtx, rtx));
- extern void use_variable_after				PROTO ((rtx, rtx));
  extern void purge_addressof				PROTO ((rtx));
  
  /* In reload.c */
--- 1449,1458 ----
Index: stmt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/stmt.c,v
retrieving revision 1.74
diff -c -p -d -r1.74 stmt.c
*** stmt.c	1999/05/30 13:33:10	1.74
--- stmt.c	1999/07/16 21:46:46
*************** expand_value_return (val)
*** 2521,2544 ****
  #endif
  	emit_move_insn (return_reg, val);
      }
-   if (GET_CODE (return_reg) == REG
-       && REGNO (return_reg) < FIRST_PSEUDO_REGISTER)
-     emit_insn (gen_rtx_USE (VOIDmode, return_reg));
-   /* Handle calls that return values in multiple non-contiguous locations.
-      The Irix 6 ABI has examples of this.  */
-   else if (GET_CODE (return_reg) == PARALLEL)
-     {
-       int i;
- 
-       for (i = 0; i < XVECLEN (return_reg, 0); i++)
- 	{
- 	  rtx x = XEXP (XVECEXP (return_reg, 0, i), 0);
- 
- 	  if (GET_CODE (x) == REG
- 	      && REGNO (x) < FIRST_PSEUDO_REGISTER)
- 	    emit_insn (gen_rtx_USE (VOIDmode, x));
- 	}
-     }
  
    /* Does any pending block have cleanups?  */
  
--- 2521,2526 ----
*************** expand_end_bindings (vars, mark_ends, do
*** 3455,3468 ****
      /* Get rid of the beginning-mark if we don't make an end-mark.  */
      NOTE_LINE_NUMBER (thisblock->data.block.first_insn) = NOTE_INSN_DELETED;
  
-   /* If doing stupid register allocation, make sure lives of all
-      register variables declared here extend thru end of scope.  */
- 
-   if (obey_regdecls)
-     for (decl = vars; decl; decl = TREE_CHAIN (decl))
-       if (TREE_CODE (decl) == VAR_DECL && DECL_RTL (decl))
- 	use_variable (DECL_RTL (decl));
- 
    /* Restore the temporary level of TARGET_EXPRs.  */
    target_temp_slot_level = thisblock->data.block.target_temp_slot_level;
  
--- 3437,3442 ----
*************** expand_decl (decl)
*** 3647,3661 ****
    if (TREE_READONLY (decl))
      RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
  #endif
- 
-   /* If doing stupid register allocation, make sure life of any
-      register variable starts here, at the start of its scope.  */
- 
-   if (obey_regdecls)
-     use_variable (DECL_RTL (decl));
  }
- 
- 
  
  /* Emit code to perform the initialization of a declaration DECL.  */
  
--- 3621,3627 ----
Index: toplev.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/toplev.c,v
retrieving revision 1.187
diff -c -p -d -r1.187 toplev.c
*** toplev.c	1999/07/09 22:48:57	1.187
--- toplev.c	1999/07/16 21:46:47
*************** rest_of_compilation (decl)
*** 3845,3852 ****
  
    /* Dump rtl code after jump, if we are doing that.  */
  
!     if (jump_opt_dump)
!       dump_rtl (".jump", decl, print_rtl, insns);
  
    /* Perform common subexpression elimination.
       Nonzero value from `cse_main' means that jumps were simplified
--- 3845,3852 ----
  
    /* Dump rtl code after jump, if we are doing that.  */
  
!   if (jump_opt_dump)
!     dump_rtl (".jump", decl, print_rtl, insns);
  
    /* Perform common subexpression elimination.
       Nonzero value from `cse_main' means that jumps were simplified
*************** rest_of_compilation (decl)
*** 4040,4071 ****
    if (flow_dump)
      open_dump_file (".flow", decl_printable_name (decl, 2));
    
!   if (obey_regdecls)
!     {
!       TIMEVAR (flow_time,
! 	       {
! 		 regclass (insns, max_reg_num ());
! 		 stupid_life_analysis (insns, max_reg_num (),
! 				       rtl_dump_file);
! 	       });
!     }
!   else
!     {
!       /* Do control and data flow analysis,
! 	 and write some of the results to dump file.  */
  
!       TIMEVAR
! 	(flow_time,
! 	 {
! 	   find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
! 	   life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
! 	 });
  
!       if (warn_uninitialized)
! 	{
! 	  uninitialized_vars_warning (DECL_INITIAL (decl));
! 	  setjmp_args_warning ();
! 	}
      }
  
    /* Dump rtl after flow analysis.  */
--- 4040,4059 ----
    if (flow_dump)
      open_dump_file (".flow", decl_printable_name (decl, 2));
    
!   /* Do control and data flow analysis, and write some of the results
!      to dump file.  */
  
!   TIMEVAR
!     (flow_time,
!      {
!        find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
!        life_analysis (insns, max_reg_num (), rtl_dump_file, optimize != 0);
!      });
  
!   if (warn_uninitialized)
!     {
!       uninitialized_vars_warning (DECL_INITIAL (decl));
!       setjmp_args_warning ();
      }
  
    /* Dump rtl after flow analysis.  */
*************** rest_of_compilation (decl)
*** 4143,4163 ****
       epilogue thus changing register elimination offsets.  */
    current_function_is_leaf = leaf_function_p ();
  
!   /* Unless we did stupid register allocation,
!      allocate pseudo-regs that are used only within 1 basic block. 
  
       RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
       jump optimizer after register allocation and reloading are finished.  */
  
!   if (!obey_regdecls)
!     TIMEVAR (local_alloc_time,
! 	     {
! 	       recompute_reg_usage (insns, ! optimize_size);
! 	       regclass (insns, max_reg_num ());
! 	       rebuild_label_notes_after_reload = local_alloc ();
! 	     });
!   else
!     rebuild_label_notes_after_reload = 0;
  
    /* Dump rtl code after allocating regs within basic blocks.  */
  
--- 4131,4147 ----
       epilogue thus changing register elimination offsets.  */
    current_function_is_leaf = leaf_function_p ();
  
!   /* Allocate pseudo-regs that are used only within 1 basic block. 
  
       RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
       jump optimizer after register allocation and reloading are finished.  */
  
!   TIMEVAR (local_alloc_time,
! 	   {
! 	     recompute_reg_usage (insns, ! optimize_size);
! 	     regclass (insns, max_reg_num ());
! 	     rebuild_label_notes_after_reload = local_alloc ();
! 	   });
  
    /* Dump rtl code after allocating regs within basic blocks.  */
  
*************** rest_of_compilation (decl)
*** 4176,4194 ****
    if (global_reg_dump)
      open_dump_file (".greg", decl_printable_name (decl, 2));
  
!   /* Unless we did stupid register allocation,
!      allocate remaining pseudo-regs, then do the reload pass
       fixing up any insns that are invalid.  */
  
    TIMEVAR (global_alloc_time,
  	   {
! 	     if (!obey_regdecls)
! 	       failure = global_alloc (rtl_dump_file);
! 	     else
! 	       failure = reload (insns, 0, rtl_dump_file);
  	   });
  
- 
    if (failure)
      goto exit_rest_of_compilation;
  
--- 4160,4173 ----
    if (global_reg_dump)
      open_dump_file (".greg", decl_printable_name (decl, 2));
  
!   /* If optimizing, allocate remaining pseudo-regs.  Do the reload pass
       fixing up any insns that are invalid.  */
  
    TIMEVAR (global_alloc_time,
  	   {
! 	     failure = global_alloc (rtl_dump_file);
  	   });
  
    if (failure)
      goto exit_rest_of_compilation;
  
*************** rest_of_compilation (decl)
*** 4293,4302 ****
      = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
  #endif
  
!   /* One more attempt to remove jumps to .+1
!      left by dead-store-elimination.
!      Also do cross-jumping this time
!      and delete no-op move insns.  */
  
    if (optimize > 0)
      {
--- 4272,4279 ----
      = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
  #endif
  
!   /* One more attempt to remove jumps to .+1 left by dead-store-elimination.
!      Also do cross-jumping this time and delete no-op move insns.  */
  
    if (optimize > 0)
      {

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