public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Call once get_dynamic_handler_chain/get_eh_context per fn
@ 1997-12-08  4:52 Teemu Torma
  0 siblings, 0 replies; only message in thread
From: Teemu Torma @ 1997-12-08  4:52 UTC (permalink / raw)
  To: egcs

I noticed that 971207 snapshot has changed the way
get_dynamic_handler_chain is called.  I have attempted to make my
MT-safe exceptions to call get_eh_context only once, and I have tried
a completely different approach, which eliminates duplicate calls also
from inlined functions.

I'd appreciate a comment from others who know gcc better than I do.
These diffs are actually against MT-safe diffs of 1.00, but the idea
should be clear.  

The idea is to emit USE insn with a new reg note REG_EH_CONTEXT once
per function, and after inlining, emit a call to get_eh_context and
set the register to that value.  I would like to know if I am doing
something fundamentally wrong here or something very
stupid/unacceptable?  Check-g++ is clean on sparc-sun-solaris2.5.1,
with both unwinding and sjlj exceptions.

Of course, if emit_library_call_value is the wrong way to emit library
calls, it can be changed like get_dynamic_handler_chain is called
nowadays. 

Teemu

1997-12-08  Teemu Torma  <tot@lev.labs.trema.com>

	* toplev.c (rest_of_compilation): Call emit_eh_context.

	* except.c (get_eh_context): For the first time in each fn, emit
	USE insn with note REG_EH_CONTEXT for the EH context register.
	(call_get_eh_context, emit_eh_context): New fns.
	* except.h (emit_eh_context): New prototype.

	* rtl.h, rtl.c: New reg_note REG_EH_CONTEXT.

Index: except.c
===================================================================
RCS file: /trema/cvs/gnu/egcs/gcc/except.c,v
retrieving revision 1.9
diff -c -c -r1.9 except.c
*** except.c	1997/12/01 12:45:55	1.9
--- except.c	1997/12/08 12:03:07
***************
*** 705,734 ****
    pop_obstacks ();
  }
  
! /* This routine is here to facilitate the porting of this code to
!    systems with threads.  One can either replace the routine we emit a
!    call for here in libgcc2.c, or one can modify this routine to work
!    with their thread system.  */
  
  rtx
  get_eh_context ()
  {
    rtx ehc;
-   rtx target, insns;
  
!   start_sequence ();
!   ehc = emit_library_call_value (get_eh_context_libfunc,
! 				 NULL_RTX, 1,
! 				 Pmode, 0);
!   RTX_UNCHANGING_P (ehc) = 1;
!   insns = get_insns ();
!   end_sequence ();
  
!   target = gen_reg_rtx (Pmode);
!   emit_libcall_block (insns, target, ehc,
! 		      gen_rtx (EXPR_LIST, VOIDmode,
! 			       get_eh_context_libfunc, 0));
!   return target;
  }
       
  /* Get a reference to the dynamic handler chain.  It points to the
--- 705,748 ----
    pop_obstacks ();
  }
  
! /* Get a reference to the EH context.
!    We will only generate a register for the current function EH context here,
!    and emit a USE insn to mark that this is a EH context register.
! 
!    Later, emit_eh_context will emit needed call to __get_eh_context
!    in libgcc2, and copy the value to the register we have generated. */
  
  rtx
  get_eh_context ()
  {
    rtx ehc;
  
!   if (current_function_ehc == 0)
!     {
!       rtx insn, insns;
!       rtx first;
! 
!       current_function_ehc = gen_reg_rtx (Pmode);
!       insn = gen_rtx (USE,
! 		      GET_MODE (current_function_ehc),
! 		      copy_rtx (current_function_ehc));
! 
!       first = get_first_nonparm_insn ();
!       if (first == 0)
! 	first = get_insns ();
! 
!       insn = emit_insn_before (insn, first);
! 
!       REG_NOTES (insn)
! 	= gen_rtx (EXPR_LIST, 
! 		   REG_EH_CONTEXT, copy_rtx (current_function_ehc),
! 		   REG_NOTES (insn));
!     }
! 
!   ehc = gen_reg_rtx (Pmode);
!   emit_move_insn (ehc, current_function_ehc);
  
!   return ehc;
  }
       
  /* Get a reference to the dynamic handler chain.  It points to the
***************
*** 1786,1791 ****
--- 1800,1862 ----
      }
      
    emit_insns_after (insns, insn);
+ }
+ 
+ /* Emit code to get EH context to current function.
+ 
+    We have to scan thru the code to find possible EH context registers.
+    Inlined functions may use it too, and thus we'll have to be able
+    to change them too. */
+ 
+ static rtx
+ call_get_eh_context ()
+ {
+   rtx ehc, reg, insns;
+   rtx before;
+ 
+   start_sequence ();
+   ehc = emit_library_call_value (get_eh_context_libfunc,
+ 				 NULL_RTX, 1, Pmode, 0);
+   reg = copy_to_reg (ehc);
+ 
+   insns = get_insns ();
+   end_sequence ();
+ 
+   before = get_first_nonparm_insn ();
+   if (before == 0)
+     before = get_insns ();
+ 
+   emit_insns_before (insns, before);
+   return reg;
+ }
+ 
+ void
+ emit_eh_context ()
+ {
+   rtx insn;
+   rtx ehc = 0;
+ 
+   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+     if (GET_CODE (insn) == INSN
+ 	&& GET_CODE (PATTERN (insn)) == USE)
+       {
+ 	rtx reg = find_reg_note (insn, REG_EH_CONTEXT, 0);
+ 	if (reg)
+ 	  {
+ 	    rtx insns;
+ 	    
+ 	    /* If this is the first use insn, emit the call here. */
+ 	    if (ehc == 0)
+ 	      ehc = call_get_eh_context ();
+ 
+ 	    start_sequence ();
+ 	    emit_move_insn (XEXP (reg, 0), ehc);
+ 	    insns = get_insns ();
+ 	    end_sequence ();
+ 
+ 	    emit_insns_before (insns, insn);
+ 	  }
+       }
  }
  
  /* Scan the current insns and build a list of handler labels. The
Index: except.h
===================================================================
RCS file: /trema/cvs/gnu/egcs/gcc/except.h,v
retrieving revision 1.5
diff -c -c -r1.5 except.h
*** except.h	1997/12/01 16:21:51	1.5
--- except.h	1997/12/08 11:53:18
***************
*** 212,217 ****
--- 212,222 ----
  
  extern void expand_leftover_cleanups		PROTO((void));
  
+ /* If necessary, emit insns to get EH context for the current
+    function. */
+ 
+ extern void emit_eh_context			PROTO((void));
+ 
  /* If necessary, emit insns for the start of per-function unwinder for
     the current function.  */
  
Index: rtl.c
===================================================================
RCS file: /trema/cvs/gnu/egcs/gcc/rtl.c,v
retrieving revision 1.1.1.1
diff -c -c -r1.1.1.1 rtl.c
*** rtl.c	1997/09/26 09:57:08	1.1.1.1
--- rtl.c	1997/12/08 09:36:19
***************
*** 182,188 ****
  			  "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
  			  "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
  			  "REG_EXEC_COUNT", "REG_NOALIAS", "REG_SAVE_AREA",
! 			  "REG_BR_PRED" };
  
  /* Allocate an rtx vector of N elements.
     Store the length, and initialize all elements to zero.  */
--- 182,188 ----
  			  "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
  			  "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
  			  "REG_EXEC_COUNT", "REG_NOALIAS", "REG_SAVE_AREA",
! 			  "REG_BR_PRED", "REG_EH_CONTEXT" };
  
  /* Allocate an rtx vector of N elements.
     Store the length, and initialize all elements to zero.  */
Index: rtl.h
===================================================================
RCS file: /trema/cvs/gnu/egcs/gcc/rtl.h,v
retrieving revision 1.1.1.1
diff -c -c -r1.1.1.1 rtl.h
*** rtl.h	1997/09/26 09:57:08	1.1.1.1
--- rtl.h	1997/12/08 09:33:18
***************
*** 323,329 ****
  		REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13,
  		REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15, REG_BR_PROB = 16,
  		REG_EXEC_COUNT = 17, REG_NOALIAS = 18, REG_SAVE_AREA = 19,
! 		REG_BR_PRED = 20 };
  /* The base value for branch probability notes.  */
  #define REG_BR_PROB_BASE  10000
  
--- 323,329 ----
  		REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13,
  		REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15, REG_BR_PROB = 16,
  		REG_EXEC_COUNT = 17, REG_NOALIAS = 18, REG_SAVE_AREA = 19,
! 		REG_BR_PRED = 20, REG_EH_CONTEXT = 21 };
  /* The base value for branch probability notes.  */
  #define REG_BR_PROB_BASE  10000
  
Index: toplev.c
===================================================================
RCS file: /trema/cvs/gnu/egcs/gcc/toplev.c,v
retrieving revision 1.1.1.6
diff -c -c -r1.1.1.6 toplev.c
*** toplev.c	1997/11/28 08:06:54	1.1.1.6
--- toplev.c	1997/12/08 12:23:53
***************
*** 3156,3163 ****
        goto exit_rest_of_compilation;
      }
  
!   /* Add an unwinder for exception handling, if needed.
       This must be done before we finalize PIC code.  */
    emit_unwinder ();
  
  #ifdef FINALIZE_PIC
--- 3156,3164 ----
        goto exit_rest_of_compilation;
      }
  
!   /* Add an EH context and unwinder for exception handling, if needed.
       This must be done before we finalize PIC code.  */
+   emit_eh_context ();
    emit_unwinder ();
  
  #ifdef FINALIZE_PIC


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~1997-12-08  4:52 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-12-08  4:52 Call once get_dynamic_handler_chain/get_eh_context per fn Teemu Torma

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).