This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Committed: patch for dwarf2 eh
- To: gcc-patches at gcc dot gnu dot org
- Subject: Committed: patch for dwarf2 eh
- From: Bernd Schmidt <bernds at cygnus dot co dot uk>
- Date: Thu, 30 Sep 1999 14:43:46 +0100 (BST)
This patch removes __builtin_dwarf_reg_size and replaces it with a new
builtin __builtin_init_dwarf_reg_sizes. This is done to get rid of some
runtime overhead when determining the size of registers in
libgcc2.c:copy_reg, we now use a lookup table to find register sizes.
I stumbled over this area in the code when the old
expand_builtin_dwarf_reg_size code aborted because a port I was working on
overflowed its (arbitrary) limit of 5 ranges.
Approved by Jason Merrill.
Bernd
* tree.h (enum built_in_function): Rename BUILT_IN_DWARF_REG_SIZE
to BUILT_IN_INIT_DWARF_REG_SIZES.
* builtins.c (expand_builtins, case BUILT_IN_INIT_DWARF_REG_SIZES):
Renamed from BUILT_IN_DWARF_REG_SIZE; call
expand_builtin_init_dwarf_reg_sizes.
* c-decl.c (init_decl_processing): Replace __builtin_dwarf_reg_size
with __builtin_init_dwarf_reg_size_table.
* dwarf2out.c (struct reg_size_range): Delete.
(expand_builtin_init_dwarf_reg_sizes): New function.
(expand_builtin_dwarf_reg_size): Delete.
* except.h (expand_builtin_init_dwarf_reg_sizes): Declare.
(expand_builtin_dwarf_reg_size): Don't declare.
* libgcc2.c (dwarf_reg_size_table_initialized): New.
(dwarf_reg_size_table): New.
(init_reg_size_table): New function.
(copy_reg): Use dwarf_reg_size_table.
(eh_context_initialize): Make sure dwarf_reg_size_table is initialized
before use.
Index: builtins.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/builtins.c,v
retrieving revision 1.15
diff -u -p -c -p -d -r1.15 builtins.c
*** builtins.c 1999/09/28 08:15:38 1.15
--- builtins.c 1999/09/29 14:18:36
*************** expand_builtin (exp, target, subtarget,
*** 2484,2491 ****
#ifdef DWARF2_UNWIND_INFO
case BUILT_IN_DWARF_FP_REGNUM:
return expand_builtin_dwarf_fp_regnum ();
! case BUILT_IN_DWARF_REG_SIZE:
! return expand_builtin_dwarf_reg_size (TREE_VALUE (arglist), target);
#endif
case BUILT_IN_FROB_RETURN_ADDR:
return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
--- 2484,2492 ----
#ifdef DWARF2_UNWIND_INFO
case BUILT_IN_DWARF_FP_REGNUM:
return expand_builtin_dwarf_fp_regnum ();
! case BUILT_IN_INIT_DWARF_REG_SIZES:
! expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
! return const0_rtx;
#endif
case BUILT_IN_FROB_RETURN_ADDR:
return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
Index: c-decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-decl.c,v
retrieving revision 1.80
diff -u -p -c -p -d -r1.80 c-decl.c
*** c-decl.c 1999/09/28 13:43:34 1.80
--- c-decl.c 1999/09/29 14:18:38
*************** init_decl_processing ()
*** 3060,3067 ****
builtin_function ("__builtin_dwarf_fp_regnum",
build_function_type (unsigned_type_node, endlink),
BUILT_IN_DWARF_FP_REGNUM, BUILT_IN_NORMAL, NULL_PTR);
! builtin_function ("__builtin_dwarf_reg_size", int_ftype_int,
! BUILT_IN_DWARF_REG_SIZE, BUILT_IN_NORMAL, NULL_PTR);
builtin_function ("__builtin_frob_return_addr", ptr_ftype_ptr,
BUILT_IN_FROB_RETURN_ADDR, BUILT_IN_NORMAL, NULL_PTR);
builtin_function ("__builtin_extract_return_addr", ptr_ftype_ptr,
--- 3060,3067 ----
builtin_function ("__builtin_dwarf_fp_regnum",
build_function_type (unsigned_type_node, endlink),
BUILT_IN_DWARF_FP_REGNUM, BUILT_IN_NORMAL, NULL_PTR);
! builtin_function ("__builtin_init_dwarf_reg_size_table", void_ftype_ptr,
! BUILT_IN_INIT_DWARF_REG_SIZES, BUILT_IN_NORMAL, NULL_PTR);
builtin_function ("__builtin_frob_return_addr", ptr_ftype_ptr,
BUILT_IN_FROB_RETURN_ADDR, BUILT_IN_NORMAL, NULL_PTR);
builtin_function ("__builtin_extract_return_addr", ptr_ftype_ptr,
Index: dwarf2out.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/dwarf2out.c,v
retrieving revision 1.117
diff -u -p -c -p -d -r1.117 dwarf2out.c
*** dwarf2out.c 1999/09/28 17:11:44 1.117
--- dwarf2out.c 1999/09/29 14:18:41
*************** reg_number (rtl)
*** 560,669 ****
return regno;
}
! struct reg_size_range
! {
! int beg;
! int end;
! int size;
! };
!
! /* Given a register number in REG_TREE, return an rtx for its size in bytes.
! We do this in kind of a roundabout way, by building up a list of
! register size ranges and seeing where our register falls in one of those
! ranges. We need to do it this way because REG_TREE is not a constant,
! and the target macros were not designed to make this task easy. */
! rtx
! expand_builtin_dwarf_reg_size (reg_tree, target)
! tree reg_tree;
! rtx target;
{
! enum machine_mode mode;
! int size;
! struct reg_size_range ranges[5];
! tree t, t2;
!
! int i = 0;
! int n_ranges = 0;
! int last_size = -1;
! for (; i < FIRST_PSEUDO_REGISTER; ++i)
{
! /* The return address is out of order on the MIPS, and we don't use
! copy_reg for it anyway, so we don't care here how large it is. */
! if (DWARF_FRAME_REGNUM (i) == DWARF_FRAME_RETURN_COLUMN)
! continue;
!
! mode = reg_raw_mode[i];
!
! /* CCmode is arbitrarily given a size of 4 bytes. It is more useful
! to use the same size as word_mode, since that reduces the number
! of ranges we need. It should not matter, since the result should
! never be used for a condition code register anyways. */
! if (GET_MODE_CLASS (mode) == MODE_CC)
! mode = word_mode;
!
! size = GET_MODE_SIZE (mode);
!
! /* If this register is not valid in the specified mode and
! we have a previous size, use that for the size of this
! register to avoid making junk tiny ranges. */
! if (! HARD_REGNO_MODE_OK (i, mode) && last_size != -1)
! size = last_size;
!
! if (size != last_size)
! {
! ranges[n_ranges].beg = i;
! ranges[n_ranges].size = last_size = size;
! ++n_ranges;
! if (n_ranges >= 5)
! abort ();
! }
! ranges[n_ranges-1].end = i;
! }
! /* The usual case: fp regs surrounded by general regs. */
! if (n_ranges == 3 && ranges[0].size == ranges[2].size)
! {
! if ((DWARF_FRAME_REGNUM (ranges[1].end)
! - DWARF_FRAME_REGNUM (ranges[1].beg))
! != ranges[1].end - ranges[1].beg)
! abort ();
! t = fold (build (GE_EXPR, integer_type_node, reg_tree,
! build_int_2 (DWARF_FRAME_REGNUM (ranges[1].beg), 0)));
! t2 = fold (build (LE_EXPR, integer_type_node, reg_tree,
! build_int_2 (DWARF_FRAME_REGNUM (ranges[1].end), 0)));
! t = fold (build (TRUTH_ANDIF_EXPR, integer_type_node, t, t2));
! t = fold (build (COND_EXPR, integer_type_node, t,
! build_int_2 (ranges[1].size, 0),
! build_int_2 (ranges[0].size, 0)));
! }
! else
! {
! /* Initialize last_end to be larger than any possible
! DWARF_FRAME_REGNUM. */
! int last_end = 0x7fffffff;
! --n_ranges;
! t = build_int_2 (ranges[n_ranges].size, 0);
! do
! {
! int beg = DWARF_FRAME_REGNUM (ranges[n_ranges].beg);
! int end = DWARF_FRAME_REGNUM (ranges[n_ranges].end);
! if (beg < 0)
! continue;
! if (end >= last_end)
! abort ();
! last_end = end;
! if (end - beg != ranges[n_ranges].end - ranges[n_ranges].beg)
! abort ();
! t2 = fold (build (LE_EXPR, integer_type_node, reg_tree,
! build_int_2 (end, 0)));
! t = fold (build (COND_EXPR, integer_type_node, t2,
! build_int_2 (ranges[n_ranges].size, 0), t));
! }
! while (--n_ranges >= 0);
}
- return expand_expr (t, target, Pmode, 0);
}
/* Convert a DWARF call frame info. operation to its string name */
--- 560,585 ----
return regno;
}
! /* Generate code to initialize the register size table. */
! void
! expand_builtin_init_dwarf_reg_sizes (address)
! tree address;
{
! int i;
! enum machine_mode mode = TYPE_MODE (char_type_node);
! rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0);
! rtx mem = gen_rtx_MEM (mode, addr);
! for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
{
! int offset = i * GET_MODE_SIZE (mode);
! int size = GET_MODE_SIZE (reg_raw_mode[i]);
! emit_move_insn (change_address (mem, mode,
! plus_constant (addr, offset)),
! GEN_INT (size));
}
}
/* Convert a DWARF call frame info. operation to its string name */
Index: except.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/except.h,v
retrieving revision 1.30
diff -u -p -c -p -d -r1.30 except.h
*** except.h 1999/08/10 16:19:14 1.30
--- except.h 1999/09/29 14:18:41
*************** rtx expand_builtin_dwarf_fp_regnum PROTO
*** 473,479 ****
#ifdef TREE_CODE
rtx expand_builtin_frob_return_addr PROTO((tree));
rtx expand_builtin_extract_return_addr PROTO((tree));
! rtx expand_builtin_dwarf_reg_size PROTO((tree, rtx));
void expand_builtin_eh_return PROTO((tree, tree, tree));
#endif
void expand_eh_return PROTO((void));
--- 473,479 ----
#ifdef TREE_CODE
rtx expand_builtin_frob_return_addr PROTO((tree));
rtx expand_builtin_extract_return_addr PROTO((tree));
! void expand_builtin_init_dwarf_reg_sizes PROTO((tree));
void expand_builtin_eh_return PROTO((tree, tree, tree));
#endif
void expand_eh_return PROTO((void));
Index: libgcc2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/libgcc2.c,v
retrieving revision 1.70
diff -u -p -c -p -d -r1.70 libgcc2.c
*** libgcc2.c 1999/09/23 13:37:49 1.70
--- libgcc2.c 1999/09/29 14:18:43
*************** __get_eh_info ()
*** 3120,3125 ****
--- 3120,3137 ----
return &eh->info;
}
+ #ifdef DWARF2_UNWIND_INFO
+ static int dwarf_reg_size_table_initialized = 0;
+ static char dwarf_reg_size_table[FIRST_PSEUDO_REGISTER];
+
+ static void
+ init_reg_size_table ()
+ {
+ __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
+ dwarf_reg_size_table_initialized = 1;
+ }
+ #endif
+
#if __GTHREADS
static void
eh_threads_initialize ()
*************** eh_context_initialize ()
*** 3152,3163 ****
--- 3164,3187 ----
/* Use static version of EH context. */
get_eh_context = &eh_context_static;
}
+ #ifdef DWARF2_UNWIND_INFO
+ {
+ static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
+ if (__gthread_once (&once_regsizes, init_reg_size_table) != 0
+ || ! dwarf_reg_size_table_initialized)
+ init_reg_size_table ();
+ }
+ #endif
#else /* no __GTHREADS */
/* Use static version of EH context. */
get_eh_context = &eh_context_static;
+ #ifdef DWARF2_UNWIND_INFO
+ init_reg_size_table ();
+ #endif
+
#endif /* no __GTHREADS */
return (*get_eh_context) ();
*************** EH_TABLE_LOOKUP
*** 3395,3401 ****
#ifdef DWARF2_UNWIND_INFO
-
/* Return the table version of an exception descriptor */
short
--- 3419,3424 ----
*************** copy_reg (unsigned reg, frame_state *uda
*** 3620,3626 ****
word_type *preg = get_reg_addr (reg, udata, NULL);
word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
! memcpy (ptreg, preg, __builtin_dwarf_reg_size (reg));
}
/* Retrieve the return address for frame UDATA. */
--- 3643,3649 ----
word_type *preg = get_reg_addr (reg, udata, NULL);
word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
! memcpy (ptreg, preg, dwarf_reg_size_table [reg]);
}
/* Retrieve the return address for frame UDATA. */
Index: tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tree.h,v
retrieving revision 1.94
diff -u -p -c -p -d -r1.94 tree.h
*** tree.h 1999/09/28 06:18:11 1.94
--- tree.h 1999/09/29 14:18:46
*************** enum built_in_function
*** 120,126 ****
BUILT_IN_UNWIND_INIT,
BUILT_IN_DWARF_CFA,
BUILT_IN_DWARF_FP_REGNUM,
! BUILT_IN_DWARF_REG_SIZE,
BUILT_IN_FROB_RETURN_ADDR,
BUILT_IN_EXTRACT_RETURN_ADDR,
BUILT_IN_EH_RETURN,
--- 120,126 ----
BUILT_IN_UNWIND_INIT,
BUILT_IN_DWARF_CFA,
BUILT_IN_DWARF_FP_REGNUM,
! BUILT_IN_INIT_DWARF_REG_SIZES,
BUILT_IN_FROB_RETURN_ADDR,
BUILT_IN_EXTRACT_RETURN_ADDR,
BUILT_IN_EH_RETURN,