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


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

PATCH: find_dead_or_set_registers vs. EH



The function mark_target_regs_live is supposed to figure out which
hard registers are live at a given instruction.  The algorithm used
there is pretty obscure.  First, it scans forward from some earlier
basic block.  Then, it scans past the instruction, following jumps.
That second scan is broken because it assumes that, in the absence of
a jump, there is no control-flow change.  That's false when using
exceptions.  This patch fixes the bug.

But, there's a more global question.  Why use this obscure algorithm
when the simple:

  - Find the end of the basic block
  - Take the set of registers known to be live there
  - Work backwards, marking used registers as live, and set registers
    as dead

would seem to work just fine?  

If nobody objects, I'll probably convert this code to use the simpler
algorithm, based on Alex's code in conflict_graph_compute.  (That code
deals with pseudos, and depends on SSA form, but the basic ideas are
applicable.)

Thanks,

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2000-05-25  Mark Mitchell  <mark@codesourcery.com>

	* except.h (can_throw): Declare it.
	* except.c (can_throw): Give it external linkage.
	* resource.c (find_dead_or_set_registers): Use can_throw.
	
Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/except.c,v
retrieving revision 1.130
diff -c -p -r1.130 except.c
*** except.c	2000/05/20 19:45:33	1.130
--- except.c	2000/05/25 07:57:06
*************** static void start_dynamic_cleanup	PARAMS
*** 463,469 ****
  static void start_dynamic_handler	PARAMS ((void));
  static void expand_rethrow	PARAMS ((rtx));
  static void output_exception_table_entry	PARAMS ((FILE *, int));
- static int can_throw		PARAMS ((rtx));
  static rtx scan_region		PARAMS ((rtx, int, int *));
  static void eh_regs		PARAMS ((rtx *, rtx *, rtx *, int));
  static void set_insn_eh_region	PARAMS ((rtx *, int));
--- 463,468 ----
*************** free_eh_status (f)
*** 2643,2654 ****
  }
  
  /* This section is for the exception handling specific optimization
!    pass.  First are the internal routines, and then the main
!    optimization pass.  */
  
  /* Determine if the given INSN can throw an exception.  */
  
! static int
  can_throw (insn)
       rtx insn;
  {
--- 2642,2652 ----
  }
  
  /* This section is for the exception handling specific optimization
!    pass.  */
  
  /* Determine if the given INSN can throw an exception.  */
  
! int
  can_throw (insn)
       rtx insn;
  {
Index: except.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/except.h,v
retrieving revision 1.39
diff -c -p -r1.39 except.h
*** except.h	2000/03/19 18:25:24	1.39
--- except.h	2000/05/25 07:57:06
*************** extern struct label_node *outer_context_
*** 430,435 ****
--- 430,439 ----
  
  extern rtx exception_handler_labels;
  
+ /* Determine if the given INSN can throw an exception.  */
+ 
+ extern int can_throw                            PARAMS ((rtx));
+ 
  /* Return nonzero if nothing in this function can throw.  */
  
  extern int nothrow_function_p			PARAMS ((void));
Index: resource.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/resource.c,v
retrieving revision 1.28
diff -c -p -r1.28 resource.c
*** resource.c	2000/03/27 21:50:15	1.28
--- resource.c	2000/05/25 07:57:13
*************** find_dead_or_set_registers (target, res,
*** 422,427 ****
--- 422,435 ----
        rtx this_jump_insn = insn;
  
        next = NEXT_INSN (insn);
+ 
+       /* If this instruction can throw an exception, then we don't
+ 	 know where we might end up next.  That means that we have to
+ 	 assume that whatever we have already marked as live really is
+ 	 live.  */
+       if (can_throw (insn))
+ 	break;
+ 
        switch (GET_CODE (insn))
  	{
  	case CODE_LABEL:

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