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