1 /* Implements exception handling.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Mike Stump <mrs@cygnus.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 /* An exception is an event that can be signaled from within a
25 function. This event can then be "caught" or "trapped" by the
26 callers of this function. This potentially allows program flow to
27 be transferred to any arbitrary code associated with a function call
28 several levels up the stack.
30 The intended use for this mechanism is for signaling "exceptional
31 events" in an out-of-band fashion, hence its name. The C++ language
32 (and many other OO-styled or functional languages) practically
33 requires such a mechanism, as otherwise it becomes very difficult
34 or even impossible to signal failure conditions in complex
35 situations. The traditional C++ example is when an error occurs in
36 the process of constructing an object; without such a mechanism, it
37 is impossible to signal that the error occurs without adding global
38 state variables and error checks around every object construction.
40 The act of causing this event to occur is referred to as "throwing
41 an exception". (Alternate terms include "raising an exception" or
42 "signaling an exception".) The term "throw" is used because control
43 is returned to the callers of the function that is signaling the
44 exception, and thus there is the concept of "throwing" the
45 exception up the call stack.
47 [ Add updated documentation on how to use this. ] */
52 #include "coretypes.h"
60 #include "insn-config.h"
62 #include "integrate.h"
63 #include "hard-reg-set.h"
64 #include "basic-block.h"
66 #include "dwarf2asm.h"
67 #include "dwarf2out.h"
75 #include "langhooks.h"
78 /* Provide defaults for stuff that may not be defined when using
80 #ifndef EH_RETURN_DATA_REGNO
81 #define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM
85 /* Protect cleanup actions with must-not-throw regions, with a call
86 to the given failure handler. */
87 tree (*lang_protect_cleanup_actions
) (void);
89 /* Return true if type A catches type B. */
90 int (*lang_eh_type_covers
) (tree a
, tree b
);
92 /* Map a type to a runtime object to match type. */
93 tree (*lang_eh_runtime_type
) (tree
);
95 /* A hash table of label to region number. */
97 struct ehl_map_entry
GTY(())
100 struct eh_region
*region
;
103 static GTY(()) int call_site_base
;
104 static GTY ((param_is (union tree_node
)))
105 htab_t type_to_runtime_map
;
107 /* Describe the SjLj_Function_Context structure. */
108 static GTY(()) tree sjlj_fc_type_node
;
109 static int sjlj_fc_call_site_ofs
;
110 static int sjlj_fc_data_ofs
;
111 static int sjlj_fc_personality_ofs
;
112 static int sjlj_fc_lsda_ofs
;
113 static int sjlj_fc_jbuf_ofs
;
115 /* Describes one exception region. */
116 struct eh_region
GTY(())
118 /* The immediately surrounding region. */
119 struct eh_region
*outer
;
121 /* The list of immediately contained regions. */
122 struct eh_region
*inner
;
123 struct eh_region
*next_peer
;
125 /* An identifier for this region. */
128 /* When a region is deleted, its parents inherit the REG_EH_REGION
129 numbers already assigned. */
132 /* Each region does exactly one thing. */
139 ERT_ALLOWED_EXCEPTIONS
,
145 /* Holds the action to perform based on the preceding type. */
147 /* A list of catch blocks, a surrounding try block,
148 and the label for continuing after a catch. */
149 struct eh_region_u_try
{
150 struct eh_region
*catch;
151 struct eh_region
*last_catch
;
152 struct eh_region
*prev_try
;
154 } GTY ((tag ("ERT_TRY"))) try;
156 /* The list through the catch handlers, the list of type objects
157 matched, and the list of associated filters. */
158 struct eh_region_u_catch
{
159 struct eh_region
*next_catch
;
160 struct eh_region
*prev_catch
;
163 } GTY ((tag ("ERT_CATCH"))) catch;
165 /* A tree_list of allowed types. */
166 struct eh_region_u_allowed
{
169 } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed
;
171 /* The type given by a call to "throw foo();", or discovered
173 struct eh_region_u_throw
{
175 } GTY ((tag ("ERT_THROW"))) throw;
177 /* Retain the cleanup expression even after expansion so that
178 we can match up fixup regions. */
179 struct eh_region_u_cleanup
{
181 struct eh_region
*prev_try
;
182 } GTY ((tag ("ERT_CLEANUP"))) cleanup
;
184 /* The real region (by expression and by pointer) that fixup code
186 struct eh_region_u_fixup
{
188 struct eh_region
*real_region
;
190 } GTY ((tag ("ERT_FIXUP"))) fixup
;
191 } GTY ((desc ("%0.type"))) u
;
193 /* Entry point for this region's handler before landing pads are built. */
197 /* Entry point for this region's handler from the runtime eh library. */
200 /* Entry point for this region's handler from an inner region. */
201 rtx post_landing_pad
;
203 /* The RESX insn for handing off control to the next outermost handler,
207 /* True if something in this region may throw. */
208 unsigned may_contain_throw
: 1;
211 struct call_site_record
GTY(())
217 /* Used to save exception status for each function. */
218 struct eh_status
GTY(())
220 /* The tree of all regions for this function. */
221 struct eh_region
*region_tree
;
223 /* The same information as an indexable array. */
224 struct eh_region
** GTY ((length ("%h.last_region_number"))) region_array
;
226 /* The most recently open region. */
227 struct eh_region
*cur_region
;
229 /* This is the region for which we are processing catch blocks. */
230 struct eh_region
*try_region
;
235 int built_landing_pads
;
236 int last_region_number
;
238 varray_type ttype_data
;
239 varray_type ehspec_data
;
240 varray_type action_record_data
;
242 htab_t
GTY ((param_is (struct ehl_map_entry
))) exception_handler_label_map
;
244 struct call_site_record
* GTY ((length ("%h.call_site_data_used")))
246 int call_site_data_used
;
247 int call_site_data_size
;
258 static int t2r_eq (const void *, const void *);
259 static hashval_t
t2r_hash (const void *);
260 static void add_type_for_runtime (tree
);
261 static tree
lookup_type_for_runtime (tree
);
263 static void remove_unreachable_regions (rtx
);
265 static int ttypes_filter_eq (const void *, const void *);
266 static hashval_t
ttypes_filter_hash (const void *);
267 static int ehspec_filter_eq (const void *, const void *);
268 static hashval_t
ehspec_filter_hash (const void *);
269 static int add_ttypes_entry (htab_t
, tree
);
270 static int add_ehspec_entry (htab_t
, htab_t
, tree
);
271 static void assign_filter_values (void);
272 static void build_post_landing_pads (void);
273 static void connect_post_landing_pads (void);
274 static void dw2_build_landing_pads (void);
277 static bool sjlj_find_directly_reachable_regions (struct sjlj_lp_info
*);
278 static void sjlj_assign_call_site_values (rtx
, struct sjlj_lp_info
*);
279 static void sjlj_mark_call_sites (struct sjlj_lp_info
*);
280 static void sjlj_emit_function_enter (rtx
);
281 static void sjlj_emit_function_exit (void);
282 static void sjlj_emit_dispatch_table (rtx
, struct sjlj_lp_info
*);
283 static void sjlj_build_landing_pads (void);
285 static hashval_t
ehl_hash (const void *);
286 static int ehl_eq (const void *, const void *);
287 static void add_ehl_entry (rtx
, struct eh_region
*);
288 static void remove_exception_handler_label (rtx
);
289 static void remove_eh_handler (struct eh_region
*);
290 static int for_each_eh_label_1 (void **, void *);
292 /* The return value of reachable_next_level. */
295 /* The given exception is not processed by the given region. */
297 /* The given exception may need processing by the given region. */
299 /* The given exception is completely processed by the given region. */
301 /* The given exception is completely processed by the runtime. */
305 struct reachable_info
;
306 static enum reachable_code
reachable_next_level (struct eh_region
*, tree
,
307 struct reachable_info
*);
309 static int action_record_eq (const void *, const void *);
310 static hashval_t
action_record_hash (const void *);
311 static int add_action_record (htab_t
, int, int);
312 static int collect_one_action_chain (htab_t
, struct eh_region
*);
313 static int add_call_site (rtx
, int);
315 static void push_uleb128 (varray_type
*, unsigned int);
316 static void push_sleb128 (varray_type
*, int);
317 #ifndef HAVE_AS_LEB128
318 static int dw2_size_of_call_site_table (void);
319 static int sjlj_size_of_call_site_table (void);
321 static void dw2_output_call_site_table (void);
322 static void sjlj_output_call_site_table (void);
325 /* Routine to see if exception handling is turned on.
326 DO_WARN is nonzero if we want to inform the user that exception
327 handling is turned off.
329 This is used to ensure that -fexceptions has been specified if the
330 compiler tries to use any exception-specific functions. */
333 doing_eh (int do_warn
)
335 if (! flag_exceptions
)
337 static int warned
= 0;
338 if (! warned
&& do_warn
)
340 error ("exception handling disabled, use -fexceptions to enable");
352 if (! flag_exceptions
)
355 type_to_runtime_map
= htab_create_ggc (31, t2r_hash
, t2r_eq
, NULL
);
357 /* Create the SjLj_Function_Context structure. This should match
358 the definition in unwind-sjlj.c. */
359 if (USING_SJLJ_EXCEPTIONS
)
361 tree f_jbuf
, f_per
, f_lsda
, f_prev
, f_cs
, f_data
, tmp
;
363 sjlj_fc_type_node
= lang_hooks
.types
.make_type (RECORD_TYPE
);
365 f_prev
= build_decl (FIELD_DECL
, get_identifier ("__prev"),
366 build_pointer_type (sjlj_fc_type_node
));
367 DECL_FIELD_CONTEXT (f_prev
) = sjlj_fc_type_node
;
369 f_cs
= build_decl (FIELD_DECL
, get_identifier ("__call_site"),
371 DECL_FIELD_CONTEXT (f_cs
) = sjlj_fc_type_node
;
373 tmp
= build_index_type (build_int_cst (NULL_TREE
, 4 - 1));
374 tmp
= build_array_type (lang_hooks
.types
.type_for_mode (word_mode
, 1),
376 f_data
= build_decl (FIELD_DECL
, get_identifier ("__data"), tmp
);
377 DECL_FIELD_CONTEXT (f_data
) = sjlj_fc_type_node
;
379 f_per
= build_decl (FIELD_DECL
, get_identifier ("__personality"),
381 DECL_FIELD_CONTEXT (f_per
) = sjlj_fc_type_node
;
383 f_lsda
= build_decl (FIELD_DECL
, get_identifier ("__lsda"),
385 DECL_FIELD_CONTEXT (f_lsda
) = sjlj_fc_type_node
;
387 #ifdef DONT_USE_BUILTIN_SETJMP
389 tmp
= build_int_cst (NULL_TREE
, JMP_BUF_SIZE
- 1);
391 /* Should be large enough for most systems, if it is not,
392 JMP_BUF_SIZE should be defined with the proper value. It will
393 also tend to be larger than necessary for most systems, a more
394 optimal port will define JMP_BUF_SIZE. */
395 tmp
= build_int_cst (NULL_TREE
, FIRST_PSEUDO_REGISTER
+ 2 - 1);
398 /* builtin_setjmp takes a pointer to 5 words. */
399 tmp
= build_int_cst (NULL_TREE
, 5 * BITS_PER_WORD
/ POINTER_SIZE
- 1);
401 tmp
= build_index_type (tmp
);
402 tmp
= build_array_type (ptr_type_node
, tmp
);
403 f_jbuf
= build_decl (FIELD_DECL
, get_identifier ("__jbuf"), tmp
);
404 #ifdef DONT_USE_BUILTIN_SETJMP
405 /* We don't know what the alignment requirements of the
406 runtime's jmp_buf has. Overestimate. */
407 DECL_ALIGN (f_jbuf
) = BIGGEST_ALIGNMENT
;
408 DECL_USER_ALIGN (f_jbuf
) = 1;
410 DECL_FIELD_CONTEXT (f_jbuf
) = sjlj_fc_type_node
;
412 TYPE_FIELDS (sjlj_fc_type_node
) = f_prev
;
413 TREE_CHAIN (f_prev
) = f_cs
;
414 TREE_CHAIN (f_cs
) = f_data
;
415 TREE_CHAIN (f_data
) = f_per
;
416 TREE_CHAIN (f_per
) = f_lsda
;
417 TREE_CHAIN (f_lsda
) = f_jbuf
;
419 layout_type (sjlj_fc_type_node
);
421 /* Cache the interesting field offsets so that we have
422 easy access from rtl. */
423 sjlj_fc_call_site_ofs
424 = (tree_low_cst (DECL_FIELD_OFFSET (f_cs
), 1)
425 + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_cs
), 1) / BITS_PER_UNIT
);
427 = (tree_low_cst (DECL_FIELD_OFFSET (f_data
), 1)
428 + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_data
), 1) / BITS_PER_UNIT
);
429 sjlj_fc_personality_ofs
430 = (tree_low_cst (DECL_FIELD_OFFSET (f_per
), 1)
431 + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_per
), 1) / BITS_PER_UNIT
);
433 = (tree_low_cst (DECL_FIELD_OFFSET (f_lsda
), 1)
434 + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_lsda
), 1) / BITS_PER_UNIT
);
436 = (tree_low_cst (DECL_FIELD_OFFSET (f_jbuf
), 1)
437 + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_jbuf
), 1) / BITS_PER_UNIT
);
442 init_eh_for_function (void)
444 cfun
->eh
= ggc_alloc_cleared (sizeof (struct eh_status
));
447 /* Routines to generate the exception tree somewhat directly.
448 These are used from tree-eh.c when processing exception related
449 nodes during tree optimization. */
451 static struct eh_region
*
452 gen_eh_region (enum eh_region_type type
, struct eh_region
*outer
)
454 struct eh_region
*new;
456 #ifdef ENABLE_CHECKING
457 gcc_assert (doing_eh (0));
460 /* Insert a new blank region as a leaf in the tree. */
461 new = ggc_alloc_cleared (sizeof (*new));
466 new->next_peer
= outer
->inner
;
471 new->next_peer
= cfun
->eh
->region_tree
;
472 cfun
->eh
->region_tree
= new;
475 new->region_number
= ++cfun
->eh
->last_region_number
;
481 gen_eh_region_cleanup (struct eh_region
*outer
, struct eh_region
*prev_try
)
483 struct eh_region
*cleanup
= gen_eh_region (ERT_CLEANUP
, outer
);
484 cleanup
->u
.cleanup
.prev_try
= prev_try
;
489 gen_eh_region_try (struct eh_region
*outer
)
491 return gen_eh_region (ERT_TRY
, outer
);
495 gen_eh_region_catch (struct eh_region
*t
, tree type_or_list
)
497 struct eh_region
*c
, *l
;
498 tree type_list
, type_node
;
500 /* Ensure to always end up with a type list to normalize further
501 processing, then register each type against the runtime types map. */
502 type_list
= type_or_list
;
505 if (TREE_CODE (type_or_list
) != TREE_LIST
)
506 type_list
= tree_cons (NULL_TREE
, type_or_list
, NULL_TREE
);
508 type_node
= type_list
;
509 for (; type_node
; type_node
= TREE_CHAIN (type_node
))
510 add_type_for_runtime (TREE_VALUE (type_node
));
513 c
= gen_eh_region (ERT_CATCH
, t
->outer
);
514 c
->u
.catch.type_list
= type_list
;
515 l
= t
->u
.try.last_catch
;
516 c
->u
.catch.prev_catch
= l
;
518 l
->u
.catch.next_catch
= c
;
521 t
->u
.try.last_catch
= c
;
527 gen_eh_region_allowed (struct eh_region
*outer
, tree allowed
)
529 struct eh_region
*region
= gen_eh_region (ERT_ALLOWED_EXCEPTIONS
, outer
);
530 region
->u
.allowed
.type_list
= allowed
;
532 for (; allowed
; allowed
= TREE_CHAIN (allowed
))
533 add_type_for_runtime (TREE_VALUE (allowed
));
539 gen_eh_region_must_not_throw (struct eh_region
*outer
)
541 return gen_eh_region (ERT_MUST_NOT_THROW
, outer
);
545 get_eh_region_number (struct eh_region
*region
)
547 return region
->region_number
;
551 get_eh_region_may_contain_throw (struct eh_region
*region
)
553 return region
->may_contain_throw
;
557 get_eh_region_tree_label (struct eh_region
*region
)
559 return region
->tree_label
;
563 set_eh_region_tree_label (struct eh_region
*region
, tree lab
)
565 region
->tree_label
= lab
;
569 expand_resx_expr (tree exp
)
571 int region_nr
= TREE_INT_CST_LOW (TREE_OPERAND (exp
, 0));
572 struct eh_region
*reg
= cfun
->eh
->region_array
[region_nr
];
574 reg
->resume
= emit_jump_insn (gen_rtx_RESX (VOIDmode
, region_nr
));
578 /* Note that the current EH region (if any) may contain a throw, or a
579 call to a function which itself may contain a throw. */
582 note_eh_region_may_contain_throw (struct eh_region
*region
)
584 while (region
&& !region
->may_contain_throw
)
586 region
->may_contain_throw
= 1;
587 region
= region
->outer
;
592 note_current_region_may_contain_throw (void)
594 note_eh_region_may_contain_throw (cfun
->eh
->cur_region
);
598 /* Return an rtl expression for a pointer to the exception object
602 get_exception_pointer (struct function
*fun
)
604 rtx exc_ptr
= fun
->eh
->exc_ptr
;
605 if (fun
== cfun
&& ! exc_ptr
)
607 exc_ptr
= gen_reg_rtx (ptr_mode
);
608 fun
->eh
->exc_ptr
= exc_ptr
;
613 /* Return an rtl expression for the exception dispatch filter
617 get_exception_filter (struct function
*fun
)
619 rtx filter
= fun
->eh
->filter
;
620 if (fun
== cfun
&& ! filter
)
622 filter
= gen_reg_rtx (targetm
.eh_return_filter_mode ());
623 fun
->eh
->filter
= filter
;
628 /* This section is for the exception handling specific optimization pass. */
630 /* Random access the exception region tree. */
633 collect_eh_region_array (void)
635 struct eh_region
**array
, *i
;
637 i
= cfun
->eh
->region_tree
;
641 array
= ggc_alloc_cleared ((cfun
->eh
->last_region_number
+ 1)
643 cfun
->eh
->region_array
= array
;
647 array
[i
->region_number
] = i
;
649 /* If there are sub-regions, process them. */
652 /* If there are peers, process them. */
653 else if (i
->next_peer
)
655 /* Otherwise, step back up the tree to the next peer. */
662 } while (i
->next_peer
== NULL
);
668 /* Remove all regions whose labels are not reachable from insns. */
671 remove_unreachable_regions (rtx insns
)
673 int i
, *uid_region_num
;
678 uid_region_num
= xcalloc (get_max_uid (), sizeof(int));
679 reachable
= xcalloc (cfun
->eh
->last_region_number
+ 1, sizeof(bool));
681 for (i
= cfun
->eh
->last_region_number
; i
> 0; --i
)
683 r
= cfun
->eh
->region_array
[i
];
684 if (!r
|| r
->region_number
!= i
)
689 gcc_assert (!uid_region_num
[INSN_UID (r
->resume
)]);
690 uid_region_num
[INSN_UID (r
->resume
)] = i
;
694 gcc_assert (!uid_region_num
[INSN_UID (r
->label
)]);
695 uid_region_num
[INSN_UID (r
->label
)] = i
;
699 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
700 reachable
[uid_region_num
[INSN_UID (insn
)]] = true;
702 for (i
= cfun
->eh
->last_region_number
; i
> 0; --i
)
704 r
= cfun
->eh
->region_array
[i
];
705 if (r
&& r
->region_number
== i
&& !reachable
[i
])
711 /* Don't remove ERT_THROW regions if their outer region
713 if (r
->outer
&& reachable
[r
->outer
->region_number
])
717 case ERT_MUST_NOT_THROW
:
718 /* MUST_NOT_THROW regions are implementable solely in the
719 runtime, but their existence continues to affect calls
720 within that region. Never delete them here. */
726 /* TRY regions are reachable if any of its CATCH regions
729 for (c
= r
->u
.try.catch; c
; c
= c
->u
.catch.next_catch
)
730 if (reachable
[c
->region_number
])
743 remove_eh_handler (r
);
748 free (uid_region_num
);
751 /* Set up EH labels for RTL. */
754 convert_from_eh_region_ranges (void)
756 rtx insns
= get_insns ();
757 int i
, n
= cfun
->eh
->last_region_number
;
759 /* Most of the work is already done at the tree level. All we need to
760 do is collect the rtl labels that correspond to the tree labels that
761 collect the rtl labels that correspond to the tree labels
762 we allocated earlier. */
763 for (i
= 1; i
<= n
; ++i
)
765 struct eh_region
*region
= cfun
->eh
->region_array
[i
];
766 if (region
&& region
->tree_label
)
767 region
->label
= DECL_RTL_IF_SET (region
->tree_label
);
770 remove_unreachable_regions (insns
);
774 add_ehl_entry (rtx label
, struct eh_region
*region
)
776 struct ehl_map_entry
**slot
, *entry
;
778 LABEL_PRESERVE_P (label
) = 1;
780 entry
= ggc_alloc (sizeof (*entry
));
781 entry
->label
= label
;
782 entry
->region
= region
;
784 slot
= (struct ehl_map_entry
**)
785 htab_find_slot (cfun
->eh
->exception_handler_label_map
, entry
, INSERT
);
787 /* Before landing pad creation, each exception handler has its own
788 label. After landing pad creation, the exception handlers may
789 share landing pads. This is ok, since maybe_remove_eh_handler
790 only requires the 1-1 mapping before landing pad creation. */
791 gcc_assert (!*slot
|| cfun
->eh
->built_landing_pads
);
797 find_exception_handler_labels (void)
801 if (cfun
->eh
->exception_handler_label_map
)
802 htab_empty (cfun
->eh
->exception_handler_label_map
);
805 /* ??? The expansion factor here (3/2) must be greater than the htab
806 occupancy factor (4/3) to avoid unnecessary resizing. */
807 cfun
->eh
->exception_handler_label_map
808 = htab_create_ggc (cfun
->eh
->last_region_number
* 3 / 2,
809 ehl_hash
, ehl_eq
, NULL
);
812 if (cfun
->eh
->region_tree
== NULL
)
815 for (i
= cfun
->eh
->last_region_number
; i
> 0; --i
)
817 struct eh_region
*region
= cfun
->eh
->region_array
[i
];
820 if (! region
|| region
->region_number
!= i
)
822 if (cfun
->eh
->built_landing_pads
)
823 lab
= region
->landing_pad
;
828 add_ehl_entry (lab
, region
);
831 /* For sjlj exceptions, need the return label to remain live until
832 after landing pad generation. */
833 if (USING_SJLJ_EXCEPTIONS
&& ! cfun
->eh
->built_landing_pads
)
834 add_ehl_entry (return_label
, NULL
);
838 current_function_has_exception_handlers (void)
842 for (i
= cfun
->eh
->last_region_number
; i
> 0; --i
)
844 struct eh_region
*region
= cfun
->eh
->region_array
[i
];
846 if (! region
|| region
->region_number
!= i
)
848 if (region
->type
!= ERT_THROW
)
856 t2r_eq (const void *pentry
, const void *pdata
)
858 tree entry
= (tree
) pentry
;
859 tree data
= (tree
) pdata
;
861 return TREE_PURPOSE (entry
) == data
;
865 t2r_hash (const void *pentry
)
867 tree entry
= (tree
) pentry
;
868 return TREE_HASH (TREE_PURPOSE (entry
));
872 add_type_for_runtime (tree type
)
876 slot
= (tree
*) htab_find_slot_with_hash (type_to_runtime_map
, type
,
877 TREE_HASH (type
), INSERT
);
880 tree runtime
= (*lang_eh_runtime_type
) (type
);
881 *slot
= tree_cons (type
, runtime
, NULL_TREE
);
886 lookup_type_for_runtime (tree type
)
890 slot
= (tree
*) htab_find_slot_with_hash (type_to_runtime_map
, type
,
891 TREE_HASH (type
), NO_INSERT
);
893 /* We should have always inserted the data earlier. */
894 return TREE_VALUE (*slot
);
898 /* Represent an entry in @TTypes for either catch actions
899 or exception filter actions. */
900 struct ttypes_filter
GTY(())
906 /* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
907 (a tree) for a @TTypes type node we are thinking about adding. */
910 ttypes_filter_eq (const void *pentry
, const void *pdata
)
912 const struct ttypes_filter
*entry
= (const struct ttypes_filter
*) pentry
;
913 tree data
= (tree
) pdata
;
915 return entry
->t
== data
;
919 ttypes_filter_hash (const void *pentry
)
921 const struct ttypes_filter
*entry
= (const struct ttypes_filter
*) pentry
;
922 return TREE_HASH (entry
->t
);
925 /* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
926 exception specification list we are thinking about adding. */
927 /* ??? Currently we use the type lists in the order given. Someone
928 should put these in some canonical order. */
931 ehspec_filter_eq (const void *pentry
, const void *pdata
)
933 const struct ttypes_filter
*entry
= (const struct ttypes_filter
*) pentry
;
934 const struct ttypes_filter
*data
= (const struct ttypes_filter
*) pdata
;
936 return type_list_equal (entry
->t
, data
->t
);
939 /* Hash function for exception specification lists. */
942 ehspec_filter_hash (const void *pentry
)
944 const struct ttypes_filter
*entry
= (const struct ttypes_filter
*) pentry
;
948 for (list
= entry
->t
; list
; list
= TREE_CHAIN (list
))
949 h
= (h
<< 5) + (h
>> 27) + TREE_HASH (TREE_VALUE (list
));
953 /* Add TYPE (which may be NULL) to cfun->eh->ttype_data, using TYPES_HASH
954 to speed up the search. Return the filter value to be used. */
957 add_ttypes_entry (htab_t ttypes_hash
, tree type
)
959 struct ttypes_filter
**slot
, *n
;
961 slot
= (struct ttypes_filter
**)
962 htab_find_slot_with_hash (ttypes_hash
, type
, TREE_HASH (type
), INSERT
);
964 if ((n
= *slot
) == NULL
)
966 /* Filter value is a 1 based table index. */
968 n
= xmalloc (sizeof (*n
));
970 n
->filter
= VARRAY_ACTIVE_SIZE (cfun
->eh
->ttype_data
) + 1;
973 VARRAY_PUSH_TREE (cfun
->eh
->ttype_data
, type
);
979 /* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH
980 to speed up the search. Return the filter value to be used. */
983 add_ehspec_entry (htab_t ehspec_hash
, htab_t ttypes_hash
, tree list
)
985 struct ttypes_filter
**slot
, *n
;
986 struct ttypes_filter dummy
;
989 slot
= (struct ttypes_filter
**)
990 htab_find_slot (ehspec_hash
, &dummy
, INSERT
);
992 if ((n
= *slot
) == NULL
)
994 /* Filter value is a -1 based byte index into a uleb128 buffer. */
996 n
= xmalloc (sizeof (*n
));
998 n
->filter
= -(VARRAY_ACTIVE_SIZE (cfun
->eh
->ehspec_data
) + 1);
1001 /* Look up each type in the list and encode its filter
1002 value as a uleb128. Terminate the list with 0. */
1003 for (; list
; list
= TREE_CHAIN (list
))
1004 push_uleb128 (&cfun
->eh
->ehspec_data
,
1005 add_ttypes_entry (ttypes_hash
, TREE_VALUE (list
)));
1006 VARRAY_PUSH_UCHAR (cfun
->eh
->ehspec_data
, 0);
1012 /* Generate the action filter values to be used for CATCH and
1013 ALLOWED_EXCEPTIONS regions. When using dwarf2 exception regions,
1014 we use lots of landing pads, and so every type or list can share
1015 the same filter value, which saves table space. */
1018 assign_filter_values (void)
1021 htab_t ttypes
, ehspec
;
1023 VARRAY_TREE_INIT (cfun
->eh
->ttype_data
, 16, "ttype_data");
1024 VARRAY_UCHAR_INIT (cfun
->eh
->ehspec_data
, 64, "ehspec_data");
1026 ttypes
= htab_create (31, ttypes_filter_hash
, ttypes_filter_eq
, free
);
1027 ehspec
= htab_create (31, ehspec_filter_hash
, ehspec_filter_eq
, free
);
1029 for (i
= cfun
->eh
->last_region_number
; i
> 0; --i
)
1031 struct eh_region
*r
= cfun
->eh
->region_array
[i
];
1033 /* Mind we don't process a region more than once. */
1034 if (!r
|| r
->region_number
!= i
)
1040 /* Whatever type_list is (NULL or true list), we build a list
1041 of filters for the region. */
1042 r
->u
.catch.filter_list
= NULL_TREE
;
1044 if (r
->u
.catch.type_list
!= NULL
)
1046 /* Get a filter value for each of the types caught and store
1047 them in the region's dedicated list. */
1048 tree tp_node
= r
->u
.catch.type_list
;
1050 for (;tp_node
; tp_node
= TREE_CHAIN (tp_node
))
1052 int flt
= add_ttypes_entry (ttypes
, TREE_VALUE (tp_node
));
1053 tree flt_node
= build_int_cst (NULL_TREE
, flt
);
1055 r
->u
.catch.filter_list
1056 = tree_cons (NULL_TREE
, flt_node
, r
->u
.catch.filter_list
);
1061 /* Get a filter value for the NULL list also since it will need
1062 an action record anyway. */
1063 int flt
= add_ttypes_entry (ttypes
, NULL
);
1064 tree flt_node
= build_int_cst (NULL_TREE
, flt
);
1066 r
->u
.catch.filter_list
1067 = tree_cons (NULL_TREE
, flt_node
, r
->u
.catch.filter_list
);
1072 case ERT_ALLOWED_EXCEPTIONS
:
1074 = add_ehspec_entry (ehspec
, ttypes
, r
->u
.allowed
.type_list
);
1082 htab_delete (ttypes
);
1083 htab_delete (ehspec
);
1086 /* Emit SEQ into basic block just before INSN (that is assumed to be
1087 first instruction of some existing BB and return the newly
1090 emit_to_new_bb_before (rtx seq
, rtx insn
)
1097 /* If there happens to be a fallthru edge (possibly created by cleanup_cfg
1098 call), we don't want it to go into newly created landing pad or other EH
1100 for (ei
= ei_start (BLOCK_FOR_INSN (insn
)->preds
); (e
= ei_safe_edge (ei
)); )
1101 if (e
->flags
& EDGE_FALLTHRU
)
1102 force_nonfallthru (e
);
1105 last
= emit_insn_before (seq
, insn
);
1106 if (BARRIER_P (last
))
1107 last
= PREV_INSN (last
);
1108 bb
= create_basic_block (seq
, last
, BLOCK_FOR_INSN (insn
)->prev_bb
);
1109 update_bb_for_insn (bb
);
1110 bb
->flags
|= BB_SUPERBLOCK
;
1114 /* Generate the code to actually handle exceptions, which will follow the
1118 build_post_landing_pads (void)
1122 for (i
= cfun
->eh
->last_region_number
; i
> 0; --i
)
1124 struct eh_region
*region
= cfun
->eh
->region_array
[i
];
1127 /* Mind we don't process a region more than once. */
1128 if (!region
|| region
->region_number
!= i
)
1131 switch (region
->type
)
1134 /* ??? Collect the set of all non-overlapping catch handlers
1135 all the way up the chain until blocked by a cleanup. */
1136 /* ??? Outer try regions can share landing pads with inner
1137 try regions if the types are completely non-overlapping,
1138 and there are no intervening cleanups. */
1140 region
->post_landing_pad
= gen_label_rtx ();
1144 emit_label (region
->post_landing_pad
);
1146 /* ??? It is mighty inconvenient to call back into the
1147 switch statement generation code in expand_end_case.
1148 Rapid prototyping sez a sequence of ifs. */
1150 struct eh_region
*c
;
1151 for (c
= region
->u
.try.catch; c
; c
= c
->u
.catch.next_catch
)
1153 if (c
->u
.catch.type_list
== NULL
)
1154 emit_jump (c
->label
);
1157 /* Need for one cmp/jump per type caught. Each type
1158 list entry has a matching entry in the filter list
1159 (see assign_filter_values). */
1160 tree tp_node
= c
->u
.catch.type_list
;
1161 tree flt_node
= c
->u
.catch.filter_list
;
1165 emit_cmp_and_jump_insns
1167 GEN_INT (tree_low_cst (TREE_VALUE (flt_node
), 0)),
1169 targetm
.eh_return_filter_mode (), 0, c
->label
);
1171 tp_node
= TREE_CHAIN (tp_node
);
1172 flt_node
= TREE_CHAIN (flt_node
);
1178 /* We delay the generation of the _Unwind_Resume until we generate
1179 landing pads. We emit a marker here so as to get good control
1180 flow data in the meantime. */
1182 = emit_jump_insn (gen_rtx_RESX (VOIDmode
, region
->region_number
));
1188 emit_to_new_bb_before (seq
, region
->u
.try.catch->label
);
1192 case ERT_ALLOWED_EXCEPTIONS
:
1193 region
->post_landing_pad
= gen_label_rtx ();
1197 emit_label (region
->post_landing_pad
);
1199 emit_cmp_and_jump_insns (cfun
->eh
->filter
,
1200 GEN_INT (region
->u
.allowed
.filter
),
1202 targetm
.eh_return_filter_mode (), 0, region
->label
);
1204 /* We delay the generation of the _Unwind_Resume until we generate
1205 landing pads. We emit a marker here so as to get good control
1206 flow data in the meantime. */
1208 = emit_jump_insn (gen_rtx_RESX (VOIDmode
, region
->region_number
));
1214 emit_to_new_bb_before (seq
, region
->label
);
1218 case ERT_MUST_NOT_THROW
:
1219 region
->post_landing_pad
= region
->label
;
1224 /* Nothing to do. */
1233 /* Replace RESX patterns with jumps to the next handler if any, or calls to
1234 _Unwind_Resume otherwise. */
1237 connect_post_landing_pads (void)
1241 for (i
= cfun
->eh
->last_region_number
; i
> 0; --i
)
1243 struct eh_region
*region
= cfun
->eh
->region_array
[i
];
1244 struct eh_region
*outer
;
1248 /* Mind we don't process a region more than once. */
1249 if (!region
|| region
->region_number
!= i
)
1252 /* If there is no RESX, or it has been deleted by flow, there's
1253 nothing to fix up. */
1254 if (! region
->resume
|| INSN_DELETED_P (region
->resume
))
1257 /* Search for another landing pad in this function. */
1258 for (outer
= region
->outer
; outer
; outer
= outer
->outer
)
1259 if (outer
->post_landing_pad
)
1267 basic_block src
, dest
;
1269 emit_jump (outer
->post_landing_pad
);
1270 src
= BLOCK_FOR_INSN (region
->resume
);
1271 dest
= BLOCK_FOR_INSN (outer
->post_landing_pad
);
1272 while (EDGE_COUNT (src
->succs
) > 0)
1273 remove_edge (EDGE_SUCC (src
, 0));
1274 e
= make_edge (src
, dest
, 0);
1275 e
->probability
= REG_BR_PROB_BASE
;
1276 e
->count
= src
->count
;
1280 emit_library_call (unwind_resume_libfunc
, LCT_THROW
,
1281 VOIDmode
, 1, cfun
->eh
->exc_ptr
, ptr_mode
);
1283 /* What we just emitted was a throwing libcall, so it got a
1284 barrier automatically added after it. If the last insn in
1285 the libcall sequence isn't the barrier, it's because the
1286 target emits multiple insns for a call, and there are insns
1287 after the actual call insn (which are redundant and would be
1288 optimized away). The barrier is inserted exactly after the
1289 call insn, so let's go get that and delete the insns after
1290 it, because below we need the barrier to be the last insn in
1292 delete_insns_since (NEXT_INSN (last_call_insn ()));
1297 barrier
= emit_insn_before (seq
, region
->resume
);
1298 /* Avoid duplicate barrier. */
1299 gcc_assert (BARRIER_P (barrier
));
1300 delete_insn (barrier
);
1301 delete_insn (region
->resume
);
1303 /* ??? From tree-ssa we can wind up with catch regions whose
1304 label is not instantiated, but whose resx is present. Now
1305 that we've dealt with the resx, kill the region. */
1306 if (region
->label
== NULL
&& region
->type
== ERT_CLEANUP
)
1307 remove_eh_handler (region
);
1313 dw2_build_landing_pads (void)
1318 for (i
= cfun
->eh
->last_region_number
; i
> 0; --i
)
1320 struct eh_region
*region
= cfun
->eh
->region_array
[i
];
1323 bool clobbers_hard_regs
= false;
1326 /* Mind we don't process a region more than once. */
1327 if (!region
|| region
->region_number
!= i
)
1330 if (region
->type
!= ERT_CLEANUP
1331 && region
->type
!= ERT_TRY
1332 && region
->type
!= ERT_ALLOWED_EXCEPTIONS
)
1337 region
->landing_pad
= gen_label_rtx ();
1338 emit_label (region
->landing_pad
);
1340 #ifdef HAVE_exception_receiver
1341 if (HAVE_exception_receiver
)
1342 emit_insn (gen_exception_receiver ());
1345 #ifdef HAVE_nonlocal_goto_receiver
1346 if (HAVE_nonlocal_goto_receiver
)
1347 emit_insn (gen_nonlocal_goto_receiver ());
1352 /* If the eh_return data registers are call-saved, then we
1353 won't have considered them clobbered from the call that
1354 threw. Kill them now. */
1357 unsigned r
= EH_RETURN_DATA_REGNO (j
);
1358 if (r
== INVALID_REGNUM
)
1360 if (! call_used_regs
[r
])
1362 emit_insn (gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, r
)));
1363 clobbers_hard_regs
= true;
1367 if (clobbers_hard_regs
)
1369 /* @@@ This is a kludge. Not all machine descriptions define a
1370 blockage insn, but we must not allow the code we just generated
1371 to be reordered by scheduling. So emit an ASM_INPUT to act as
1373 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
1376 emit_move_insn (cfun
->eh
->exc_ptr
,
1377 gen_rtx_REG (ptr_mode
, EH_RETURN_DATA_REGNO (0)));
1378 emit_move_insn (cfun
->eh
->filter
,
1379 gen_rtx_REG (targetm
.eh_return_filter_mode (),
1380 EH_RETURN_DATA_REGNO (1)));
1385 bb
= emit_to_new_bb_before (seq
, region
->post_landing_pad
);
1386 e
= make_edge (bb
, bb
->next_bb
, EDGE_FALLTHRU
);
1387 e
->count
= bb
->count
;
1388 e
->probability
= REG_BR_PROB_BASE
;
1395 int directly_reachable
;
1398 int call_site_index
;
1402 sjlj_find_directly_reachable_regions (struct sjlj_lp_info
*lp_info
)
1405 bool found_one
= false;
1407 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
1409 struct eh_region
*region
;
1410 enum reachable_code rc
;
1414 if (! INSN_P (insn
))
1417 note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
1418 if (!note
|| INTVAL (XEXP (note
, 0)) <= 0)
1421 region
= cfun
->eh
->region_array
[INTVAL (XEXP (note
, 0))];
1423 type_thrown
= NULL_TREE
;
1424 if (region
->type
== ERT_THROW
)
1426 type_thrown
= region
->u
.throw.type
;
1427 region
= region
->outer
;
1430 /* Find the first containing region that might handle the exception.
1431 That's the landing pad to which we will transfer control. */
1432 rc
= RNL_NOT_CAUGHT
;
1433 for (; region
; region
= region
->outer
)
1435 rc
= reachable_next_level (region
, type_thrown
, NULL
);
1436 if (rc
!= RNL_NOT_CAUGHT
)
1439 if (rc
== RNL_MAYBE_CAUGHT
|| rc
== RNL_CAUGHT
)
1441 lp_info
[region
->region_number
].directly_reachable
= 1;
1450 sjlj_assign_call_site_values (rtx dispatch_label
, struct sjlj_lp_info
*lp_info
)
1455 /* First task: build the action table. */
1457 VARRAY_UCHAR_INIT (cfun
->eh
->action_record_data
, 64, "action_record_data");
1458 ar_hash
= htab_create (31, action_record_hash
, action_record_eq
, free
);
1460 for (i
= cfun
->eh
->last_region_number
; i
> 0; --i
)
1461 if (lp_info
[i
].directly_reachable
)
1463 struct eh_region
*r
= cfun
->eh
->region_array
[i
];
1464 r
->landing_pad
= dispatch_label
;
1465 lp_info
[i
].action_index
= collect_one_action_chain (ar_hash
, r
);
1466 if (lp_info
[i
].action_index
!= -1)
1467 cfun
->uses_eh_lsda
= 1;
1470 htab_delete (ar_hash
);
1472 /* Next: assign dispatch values. In dwarf2 terms, this would be the
1473 landing pad label for the region. For sjlj though, there is one
1474 common landing pad from which we dispatch to the post-landing pads.
1476 A region receives a dispatch index if it is directly reachable
1477 and requires in-function processing. Regions that share post-landing
1478 pads may share dispatch indices. */
1479 /* ??? Post-landing pad sharing doesn't actually happen at the moment
1480 (see build_post_landing_pads) so we don't bother checking for it. */
1483 for (i
= cfun
->eh
->last_region_number
; i
> 0; --i
)
1484 if (lp_info
[i
].directly_reachable
)
1485 lp_info
[i
].dispatch_index
= index
++;
1487 /* Finally: assign call-site values. If dwarf2 terms, this would be
1488 the region number assigned by convert_to_eh_region_ranges, but
1489 handles no-action and must-not-throw differently. */
1492 for (i
= cfun
->eh
->last_region_number
; i
> 0; --i
)
1493 if (lp_info
[i
].directly_reachable
)
1495 int action
= lp_info
[i
].action_index
;
1497 /* Map must-not-throw to otherwise unused call-site index 0. */
1500 /* Map no-action to otherwise unused call-site index -1. */
1501 else if (action
== -1)
1503 /* Otherwise, look it up in the table. */
1505 index
= add_call_site (GEN_INT (lp_info
[i
].dispatch_index
), action
);
1507 lp_info
[i
].call_site_index
= index
;
1512 sjlj_mark_call_sites (struct sjlj_lp_info
*lp_info
)
1514 int last_call_site
= -2;
1517 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
1519 struct eh_region
*region
;
1521 rtx note
, before
, p
;
1523 /* Reset value tracking at extended basic block boundaries. */
1525 last_call_site
= -2;
1527 if (! INSN_P (insn
))
1530 note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
1533 /* Calls (and trapping insns) without notes are outside any
1534 exception handling region in this function. Mark them as
1537 || (flag_non_call_exceptions
1538 && may_trap_p (PATTERN (insn
))))
1539 this_call_site
= -1;
1545 /* Calls that are known to not throw need not be marked. */
1546 if (INTVAL (XEXP (note
, 0)) <= 0)
1549 region
= cfun
->eh
->region_array
[INTVAL (XEXP (note
, 0))];
1550 this_call_site
= lp_info
[region
->region_number
].call_site_index
;
1553 if (this_call_site
== last_call_site
)
1556 /* Don't separate a call from it's argument loads. */
1559 before
= find_first_parameter_load (insn
, NULL_RTX
);
1562 mem
= adjust_address (cfun
->eh
->sjlj_fc
, TYPE_MODE (integer_type_node
),
1563 sjlj_fc_call_site_ofs
);
1564 emit_move_insn (mem
, GEN_INT (this_call_site
));
1568 emit_insn_before (p
, before
);
1569 last_call_site
= this_call_site
;
1573 /* Construct the SjLj_Function_Context. */
1576 sjlj_emit_function_enter (rtx dispatch_label
)
1578 rtx fn_begin
, fc
, mem
, seq
;
1580 fc
= cfun
->eh
->sjlj_fc
;
1584 /* We're storing this libcall's address into memory instead of
1585 calling it directly. Thus, we must call assemble_external_libcall
1586 here, as we can not depend on emit_library_call to do it for us. */
1587 assemble_external_libcall (eh_personality_libfunc
);
1588 mem
= adjust_address (fc
, Pmode
, sjlj_fc_personality_ofs
);
1589 emit_move_insn (mem
, eh_personality_libfunc
);
1591 mem
= adjust_address (fc
, Pmode
, sjlj_fc_lsda_ofs
);
1592 if (cfun
->uses_eh_lsda
)
1597 ASM_GENERATE_INTERNAL_LABEL (buf
, "LLSDA", current_function_funcdef_no
);
1598 sym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
1599 SYMBOL_REF_FLAGS (sym
) = SYMBOL_FLAG_LOCAL
;
1600 emit_move_insn (mem
, sym
);
1603 emit_move_insn (mem
, const0_rtx
);
1605 #ifdef DONT_USE_BUILTIN_SETJMP
1608 x
= emit_library_call_value (setjmp_libfunc
, NULL_RTX
, LCT_RETURNS_TWICE
,
1609 TYPE_MODE (integer_type_node
), 1,
1610 plus_constant (XEXP (fc
, 0),
1611 sjlj_fc_jbuf_ofs
), Pmode
);
1613 note
= emit_note (NOTE_INSN_EXPECTED_VALUE
);
1614 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, x
, const0_rtx
);
1616 emit_cmp_and_jump_insns (x
, const0_rtx
, NE
, 0,
1617 TYPE_MODE (integer_type_node
), 0, dispatch_label
);
1620 expand_builtin_setjmp_setup (plus_constant (XEXP (fc
, 0), sjlj_fc_jbuf_ofs
),
1624 emit_library_call (unwind_sjlj_register_libfunc
, LCT_NORMAL
, VOIDmode
,
1625 1, XEXP (fc
, 0), Pmode
);
1630 /* ??? Instead of doing this at the beginning of the function,
1631 do this in a block that is at loop level 0 and dominates all
1632 can_throw_internal instructions. */
1634 for (fn_begin
= get_insns (); ; fn_begin
= NEXT_INSN (fn_begin
))
1635 if (NOTE_P (fn_begin
)
1636 && (NOTE_LINE_NUMBER (fn_begin
) == NOTE_INSN_FUNCTION_BEG
1637 || NOTE_LINE_NUMBER (fn_begin
) == NOTE_INSN_BASIC_BLOCK
))
1639 if (NOTE_LINE_NUMBER (fn_begin
) == NOTE_INSN_FUNCTION_BEG
)
1640 insert_insn_on_edge (seq
, single_succ_edge (ENTRY_BLOCK_PTR
));
1643 rtx last
= BB_END (single_succ (ENTRY_BLOCK_PTR
));
1644 for (; ; fn_begin
= NEXT_INSN (fn_begin
))
1645 if ((NOTE_P (fn_begin
)
1646 && NOTE_LINE_NUMBER (fn_begin
) == NOTE_INSN_FUNCTION_BEG
)
1647 || fn_begin
== last
)
1649 emit_insn_after (seq
, fn_begin
);
1653 /* Call back from expand_function_end to know where we should put
1654 the call to unwind_sjlj_unregister_libfunc if needed. */
1657 sjlj_emit_function_exit_after (rtx after
)
1659 cfun
->eh
->sjlj_exit_after
= after
;
1663 sjlj_emit_function_exit (void)
1671 emit_library_call (unwind_sjlj_unregister_libfunc
, LCT_NORMAL
, VOIDmode
,
1672 1, XEXP (cfun
->eh
->sjlj_fc
, 0), Pmode
);
1677 /* ??? Really this can be done in any block at loop level 0 that
1678 post-dominates all can_throw_internal instructions. This is
1679 the last possible moment. */
1681 FOR_EACH_EDGE (e
, ei
, EXIT_BLOCK_PTR
->preds
)
1682 if (e
->flags
& EDGE_FALLTHRU
)
1688 /* Figure out whether the place we are supposed to insert libcall
1689 is inside the last basic block or after it. In the other case
1690 we need to emit to edge. */
1691 gcc_assert (e
->src
->next_bb
== EXIT_BLOCK_PTR
);
1692 for (insn
= BB_HEAD (e
->src
); ; insn
= NEXT_INSN (insn
))
1694 if (insn
== cfun
->eh
->sjlj_exit_after
)
1697 insn
= NEXT_INSN (insn
);
1698 emit_insn_after (seq
, insn
);
1701 if (insn
== BB_END (e
->src
))
1704 insert_insn_on_edge (seq
, e
);
1709 sjlj_emit_dispatch_table (rtx dispatch_label
, struct sjlj_lp_info
*lp_info
)
1711 int i
, first_reachable
;
1712 rtx mem
, dispatch
, seq
, fc
;
1717 fc
= cfun
->eh
->sjlj_fc
;
1721 emit_label (dispatch_label
);
1723 #ifndef DONT_USE_BUILTIN_SETJMP
1724 expand_builtin_setjmp_receiver (dispatch_label
);
1727 /* Load up dispatch index, exc_ptr and filter values from the
1728 function context. */
1729 mem
= adjust_address (fc
, TYPE_MODE (integer_type_node
),
1730 sjlj_fc_call_site_ofs
);
1731 dispatch
= copy_to_reg (mem
);
1733 mem
= adjust_address (fc
, word_mode
, sjlj_fc_data_ofs
);
1734 if (word_mode
!= ptr_mode
)
1736 #ifdef POINTERS_EXTEND_UNSIGNED
1737 mem
= convert_memory_address (ptr_mode
, mem
);
1739 mem
= convert_to_mode (ptr_mode
, mem
, 0);
1742 emit_move_insn (cfun
->eh
->exc_ptr
, mem
);
1744 mem
= adjust_address (fc
, word_mode
, sjlj_fc_data_ofs
+ UNITS_PER_WORD
);
1745 emit_move_insn (cfun
->eh
->filter
, mem
);
1747 /* Jump to one of the directly reachable regions. */
1748 /* ??? This really ought to be using a switch statement. */
1750 first_reachable
= 0;
1751 for (i
= cfun
->eh
->last_region_number
; i
> 0; --i
)
1753 if (! lp_info
[i
].directly_reachable
)
1756 if (! first_reachable
)
1758 first_reachable
= i
;
1762 emit_cmp_and_jump_insns (dispatch
, GEN_INT (lp_info
[i
].dispatch_index
),
1763 EQ
, NULL_RTX
, TYPE_MODE (integer_type_node
), 0,
1764 cfun
->eh
->region_array
[i
]->post_landing_pad
);
1770 before
= cfun
->eh
->region_array
[first_reachable
]->post_landing_pad
;
1772 bb
= emit_to_new_bb_before (seq
, before
);
1773 e
= make_edge (bb
, bb
->next_bb
, EDGE_FALLTHRU
);
1774 e
->count
= bb
->count
;
1775 e
->probability
= REG_BR_PROB_BASE
;
1779 sjlj_build_landing_pads (void)
1781 struct sjlj_lp_info
*lp_info
;
1783 lp_info
= xcalloc (cfun
->eh
->last_region_number
+ 1,
1784 sizeof (struct sjlj_lp_info
));
1786 if (sjlj_find_directly_reachable_regions (lp_info
))
1788 rtx dispatch_label
= gen_label_rtx ();
1791 = assign_stack_local (TYPE_MODE (sjlj_fc_type_node
),
1792 int_size_in_bytes (sjlj_fc_type_node
),
1793 TYPE_ALIGN (sjlj_fc_type_node
));
1795 sjlj_assign_call_site_values (dispatch_label
, lp_info
);
1796 sjlj_mark_call_sites (lp_info
);
1798 sjlj_emit_function_enter (dispatch_label
);
1799 sjlj_emit_dispatch_table (dispatch_label
, lp_info
);
1800 sjlj_emit_function_exit ();
1807 finish_eh_generation (void)
1811 /* Nothing to do if no regions created. */
1812 if (cfun
->eh
->region_tree
== NULL
)
1815 /* The object here is to provide find_basic_blocks with detailed
1816 information (via reachable_handlers) on how exception control
1817 flows within the function. In this first pass, we can include
1818 type information garnered from ERT_THROW and ERT_ALLOWED_EXCEPTIONS
1819 regions, and hope that it will be useful in deleting unreachable
1820 handlers. Subsequently, we will generate landing pads which will
1821 connect many of the handlers, and then type information will not
1822 be effective. Still, this is a win over previous implementations. */
1824 /* These registers are used by the landing pads. Make sure they
1825 have been generated. */
1826 get_exception_pointer (cfun
);
1827 get_exception_filter (cfun
);
1829 /* Construct the landing pads. */
1831 assign_filter_values ();
1832 build_post_landing_pads ();
1833 connect_post_landing_pads ();
1834 if (USING_SJLJ_EXCEPTIONS
)
1835 sjlj_build_landing_pads ();
1837 dw2_build_landing_pads ();
1839 cfun
->eh
->built_landing_pads
= 1;
1841 /* We've totally changed the CFG. Start over. */
1842 find_exception_handler_labels ();
1843 break_superblocks ();
1844 if (USING_SJLJ_EXCEPTIONS
)
1845 commit_edge_insertions ();
1851 for (ei
= ei_start (bb
->succs
); (e
= ei_safe_edge (ei
)); )
1853 if (e
->flags
& EDGE_EH
)
1862 rtl_make_eh_edge (NULL
, bb
, BB_END (bb
));
1867 ehl_hash (const void *pentry
)
1869 struct ehl_map_entry
*entry
= (struct ehl_map_entry
*) pentry
;
1871 /* 2^32 * ((sqrt(5) - 1) / 2) */
1872 const hashval_t scaled_golden_ratio
= 0x9e3779b9;
1873 return CODE_LABEL_NUMBER (entry
->label
) * scaled_golden_ratio
;
1877 ehl_eq (const void *pentry
, const void *pdata
)
1879 struct ehl_map_entry
*entry
= (struct ehl_map_entry
*) pentry
;
1880 struct ehl_map_entry
*data
= (struct ehl_map_entry
*) pdata
;
1882 return entry
->label
== data
->label
;
1885 /* This section handles removing dead code for flow. */
1887 /* Remove LABEL from exception_handler_label_map. */
1890 remove_exception_handler_label (rtx label
)
1892 struct ehl_map_entry
**slot
, tmp
;
1894 /* If exception_handler_label_map was not built yet,
1895 there is nothing to do. */
1896 if (cfun
->eh
->exception_handler_label_map
== NULL
)
1900 slot
= (struct ehl_map_entry
**)
1901 htab_find_slot (cfun
->eh
->exception_handler_label_map
, &tmp
, NO_INSERT
);
1904 htab_clear_slot (cfun
->eh
->exception_handler_label_map
, (void **) slot
);
1907 /* Splice REGION from the region tree etc. */
1910 remove_eh_handler (struct eh_region
*region
)
1912 struct eh_region
**pp
, **pp_start
, *p
, *outer
, *inner
;
1915 /* For the benefit of efficiently handling REG_EH_REGION notes,
1916 replace this region in the region array with its containing
1917 region. Note that previous region deletions may result in
1918 multiple copies of this region in the array, so we have a
1919 list of alternate numbers by which we are known. */
1921 outer
= region
->outer
;
1922 cfun
->eh
->region_array
[region
->region_number
] = outer
;
1928 EXECUTE_IF_SET_IN_BITMAP (region
->aka
, 0, i
, bi
)
1930 cfun
->eh
->region_array
[i
] = outer
;
1937 outer
->aka
= BITMAP_GGC_ALLOC ();
1939 bitmap_ior_into (outer
->aka
, region
->aka
);
1940 bitmap_set_bit (outer
->aka
, region
->region_number
);
1943 if (cfun
->eh
->built_landing_pads
)
1944 lab
= region
->landing_pad
;
1946 lab
= region
->label
;
1948 remove_exception_handler_label (lab
);
1951 pp_start
= &outer
->inner
;
1953 pp_start
= &cfun
->eh
->region_tree
;
1954 for (pp
= pp_start
, p
= *pp
; p
!= region
; pp
= &p
->next_peer
, p
= *pp
)
1956 *pp
= region
->next_peer
;
1958 inner
= region
->inner
;
1961 for (p
= inner
; p
->next_peer
; p
= p
->next_peer
)
1965 p
->next_peer
= *pp_start
;
1969 if (region
->type
== ERT_CATCH
)
1971 struct eh_region
*try, *next
, *prev
;
1973 for (try = region
->next_peer
;
1974 try->type
== ERT_CATCH
;
1975 try = try->next_peer
)
1977 gcc_assert (try->type
== ERT_TRY
);
1979 next
= region
->u
.catch.next_catch
;
1980 prev
= region
->u
.catch.prev_catch
;
1983 next
->u
.catch.prev_catch
= prev
;
1985 try->u
.try.last_catch
= prev
;
1987 prev
->u
.catch.next_catch
= next
;
1990 try->u
.try.catch = next
;
1992 remove_eh_handler (try);
1997 /* LABEL heads a basic block that is about to be deleted. If this
1998 label corresponds to an exception region, we may be able to
1999 delete the region. */
2002 maybe_remove_eh_handler (rtx label
)
2004 struct ehl_map_entry
**slot
, tmp
;
2005 struct eh_region
*region
;
2007 /* ??? After generating landing pads, it's not so simple to determine
2008 if the region data is completely unused. One must examine the
2009 landing pad and the post landing pad, and whether an inner try block
2010 is referencing the catch handlers directly. */
2011 if (cfun
->eh
->built_landing_pads
)
2015 slot
= (struct ehl_map_entry
**)
2016 htab_find_slot (cfun
->eh
->exception_handler_label_map
, &tmp
, NO_INSERT
);
2019 region
= (*slot
)->region
;
2023 /* Flow will want to remove MUST_NOT_THROW regions as unreachable
2024 because there is no path to the fallback call to terminate.
2025 But the region continues to affect call-site data until there
2026 are no more contained calls, which we don't see here. */
2027 if (region
->type
== ERT_MUST_NOT_THROW
)
2029 htab_clear_slot (cfun
->eh
->exception_handler_label_map
, (void **) slot
);
2030 region
->label
= NULL_RTX
;
2033 remove_eh_handler (region
);
2036 /* Invokes CALLBACK for every exception handler label. Only used by old
2037 loop hackery; should not be used by new code. */
2040 for_each_eh_label (void (*callback
) (rtx
))
2042 htab_traverse (cfun
->eh
->exception_handler_label_map
, for_each_eh_label_1
,
2043 (void *) &callback
);
2047 for_each_eh_label_1 (void **pentry
, void *data
)
2049 struct ehl_map_entry
*entry
= *(struct ehl_map_entry
**)pentry
;
2050 void (*callback
) (rtx
) = *(void (**) (rtx
)) data
;
2052 (*callback
) (entry
->label
);
2056 /* Invoke CALLBACK for every exception region in the current function. */
2059 for_each_eh_region (void (*callback
) (struct eh_region
*))
2061 int i
, n
= cfun
->eh
->last_region_number
;
2062 for (i
= 1; i
<= n
; ++i
)
2064 struct eh_region
*region
= cfun
->eh
->region_array
[i
];
2066 (*callback
) (region
);
2070 /* This section describes CFG exception edges for flow. */
2072 /* For communicating between calls to reachable_next_level. */
2073 struct reachable_info
2077 void (*callback
) (struct eh_region
*, void *);
2078 void *callback_data
;
2079 bool saw_any_handlers
;
2082 /* A subroutine of reachable_next_level. Return true if TYPE, or a
2083 base class of TYPE, is in HANDLED. */
2086 check_handled (tree handled
, tree type
)
2090 /* We can check for exact matches without front-end help. */
2091 if (! lang_eh_type_covers
)
2093 for (t
= handled
; t
; t
= TREE_CHAIN (t
))
2094 if (TREE_VALUE (t
) == type
)
2099 for (t
= handled
; t
; t
= TREE_CHAIN (t
))
2100 if ((*lang_eh_type_covers
) (TREE_VALUE (t
), type
))
2107 /* A subroutine of reachable_next_level. If we are collecting a list
2108 of handlers, add one. After landing pad generation, reference
2109 it instead of the handlers themselves. Further, the handlers are
2110 all wired together, so by referencing one, we've got them all.
2111 Before landing pad generation we reference each handler individually.
2113 LP_REGION contains the landing pad; REGION is the handler. */
2116 add_reachable_handler (struct reachable_info
*info
,
2117 struct eh_region
*lp_region
, struct eh_region
*region
)
2122 info
->saw_any_handlers
= true;
2124 if (cfun
->eh
->built_landing_pads
)
2125 info
->callback (lp_region
, info
->callback_data
);
2127 info
->callback (region
, info
->callback_data
);
2130 /* Process one level of exception regions for reachability.
2131 If TYPE_THROWN is non-null, then it is the *exact* type being
2132 propagated. If INFO is non-null, then collect handler labels
2133 and caught/allowed type information between invocations. */
2135 static enum reachable_code
2136 reachable_next_level (struct eh_region
*region
, tree type_thrown
,
2137 struct reachable_info
*info
)
2139 switch (region
->type
)
2142 /* Before landing-pad generation, we model control flow
2143 directly to the individual handlers. In this way we can
2144 see that catch handler types may shadow one another. */
2145 add_reachable_handler (info
, region
, region
);
2146 return RNL_MAYBE_CAUGHT
;
2150 struct eh_region
*c
;
2151 enum reachable_code ret
= RNL_NOT_CAUGHT
;
2153 for (c
= region
->u
.try.catch; c
; c
= c
->u
.catch.next_catch
)
2155 /* A catch-all handler ends the search. */
2156 if (c
->u
.catch.type_list
== NULL
)
2158 add_reachable_handler (info
, region
, c
);
2164 /* If we have at least one type match, end the search. */
2165 tree tp_node
= c
->u
.catch.type_list
;
2167 for (; tp_node
; tp_node
= TREE_CHAIN (tp_node
))
2169 tree type
= TREE_VALUE (tp_node
);
2171 if (type
== type_thrown
2172 || (lang_eh_type_covers
2173 && (*lang_eh_type_covers
) (type
, type_thrown
)))
2175 add_reachable_handler (info
, region
, c
);
2180 /* If we have definitive information of a match failure,
2181 the catch won't trigger. */
2182 if (lang_eh_type_covers
)
2183 return RNL_NOT_CAUGHT
;
2186 /* At this point, we either don't know what type is thrown or
2187 don't have front-end assistance to help deciding if it is
2188 covered by one of the types in the list for this region.
2190 We'd then like to add this region to the list of reachable
2191 handlers since it is indeed potentially reachable based on the
2192 information we have.
2194 Actually, this handler is for sure not reachable if all the
2195 types it matches have already been caught. That is, it is only
2196 potentially reachable if at least one of the types it catches
2197 has not been previously caught. */
2200 ret
= RNL_MAYBE_CAUGHT
;
2203 tree tp_node
= c
->u
.catch.type_list
;
2204 bool maybe_reachable
= false;
2206 /* Compute the potential reachability of this handler and
2207 update the list of types caught at the same time. */
2208 for (; tp_node
; tp_node
= TREE_CHAIN (tp_node
))
2210 tree type
= TREE_VALUE (tp_node
);
2212 if (! check_handled (info
->types_caught
, type
))
2215 = tree_cons (NULL
, type
, info
->types_caught
);
2217 maybe_reachable
= true;
2221 if (maybe_reachable
)
2223 add_reachable_handler (info
, region
, c
);
2225 /* ??? If the catch type is a base class of every allowed
2226 type, then we know we can stop the search. */
2227 ret
= RNL_MAYBE_CAUGHT
;
2235 case ERT_ALLOWED_EXCEPTIONS
:
2236 /* An empty list of types definitely ends the search. */
2237 if (region
->u
.allowed
.type_list
== NULL_TREE
)
2239 add_reachable_handler (info
, region
, region
);
2243 /* Collect a list of lists of allowed types for use in detecting
2244 when a catch may be transformed into a catch-all. */
2246 info
->types_allowed
= tree_cons (NULL_TREE
,
2247 region
->u
.allowed
.type_list
,
2248 info
->types_allowed
);
2250 /* If we have definitive information about the type hierarchy,
2251 then we can tell if the thrown type will pass through the
2253 if (type_thrown
&& lang_eh_type_covers
)
2255 if (check_handled (region
->u
.allowed
.type_list
, type_thrown
))
2256 return RNL_NOT_CAUGHT
;
2259 add_reachable_handler (info
, region
, region
);
2264 add_reachable_handler (info
, region
, region
);
2265 return RNL_MAYBE_CAUGHT
;
2268 /* Catch regions are handled by their controlling try region. */
2269 return RNL_NOT_CAUGHT
;
2271 case ERT_MUST_NOT_THROW
:
2272 /* Here we end our search, since no exceptions may propagate.
2273 If we've touched down at some landing pad previous, then the
2274 explicit function call we generated may be used. Otherwise
2275 the call is made by the runtime. */
2276 if (info
&& info
->saw_any_handlers
)
2278 add_reachable_handler (info
, region
, region
);
2287 /* Shouldn't see these here. */
2295 /* Invoke CALLBACK on each region reachable from REGION_NUMBER. */
2298 foreach_reachable_handler (int region_number
, bool is_resx
,
2299 void (*callback
) (struct eh_region
*, void *),
2300 void *callback_data
)
2302 struct reachable_info info
;
2303 struct eh_region
*region
;
2306 memset (&info
, 0, sizeof (info
));
2307 info
.callback
= callback
;
2308 info
.callback_data
= callback_data
;
2310 region
= cfun
->eh
->region_array
[region_number
];
2312 type_thrown
= NULL_TREE
;
2315 /* A RESX leaves a region instead of entering it. Thus the
2316 region itself may have been deleted out from under us. */
2319 region
= region
->outer
;
2321 else if (region
->type
== ERT_THROW
)
2323 type_thrown
= region
->u
.throw.type
;
2324 region
= region
->outer
;
2329 if (reachable_next_level (region
, type_thrown
, &info
) >= RNL_CAUGHT
)
2331 /* If we have processed one cleanup, there is no point in
2332 processing any more of them. Each cleanup will have an edge
2333 to the next outer cleanup region, so the flow graph will be
2335 if (region
->type
== ERT_CLEANUP
)
2336 region
= region
->u
.cleanup
.prev_try
;
2338 region
= region
->outer
;
2342 /* Retrieve a list of labels of exception handlers which can be
2343 reached by a given insn. */
2346 arh_to_landing_pad (struct eh_region
*region
, void *data
)
2348 rtx
*p_handlers
= data
;
2350 *p_handlers
= alloc_INSN_LIST (region
->landing_pad
, NULL_RTX
);
2354 arh_to_label (struct eh_region
*region
, void *data
)
2356 rtx
*p_handlers
= data
;
2357 *p_handlers
= alloc_INSN_LIST (region
->label
, *p_handlers
);
2361 reachable_handlers (rtx insn
)
2363 bool is_resx
= false;
2364 rtx handlers
= NULL
;
2368 && GET_CODE (PATTERN (insn
)) == RESX
)
2370 region_number
= XINT (PATTERN (insn
), 0);
2375 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
2376 if (!note
|| INTVAL (XEXP (note
, 0)) <= 0)
2378 region_number
= INTVAL (XEXP (note
, 0));
2381 foreach_reachable_handler (region_number
, is_resx
,
2382 (cfun
->eh
->built_landing_pads
2383 ? arh_to_landing_pad
2390 /* Determine if the given INSN can throw an exception that is caught
2391 within the function. */
2394 can_throw_internal_1 (int region_number
)
2396 struct eh_region
*region
;
2399 region
= cfun
->eh
->region_array
[region_number
];
2401 type_thrown
= NULL_TREE
;
2402 if (region
->type
== ERT_THROW
)
2404 type_thrown
= region
->u
.throw.type
;
2405 region
= region
->outer
;
2408 /* If this exception is ignored by each and every containing region,
2409 then control passes straight out. The runtime may handle some
2410 regions, which also do not require processing internally. */
2411 for (; region
; region
= region
->outer
)
2413 enum reachable_code how
= reachable_next_level (region
, type_thrown
, 0);
2414 if (how
== RNL_BLOCKED
)
2416 if (how
!= RNL_NOT_CAUGHT
)
2424 can_throw_internal (rtx insn
)
2428 if (! INSN_P (insn
))
2432 && GET_CODE (PATTERN (insn
)) == RESX
2433 && XINT (PATTERN (insn
), 0) > 0)
2434 return can_throw_internal_1 (XINT (PATTERN (insn
), 0));
2436 if (NONJUMP_INSN_P (insn
)
2437 && GET_CODE (PATTERN (insn
)) == SEQUENCE
)
2438 insn
= XVECEXP (PATTERN (insn
), 0, 0);
2440 /* Every insn that might throw has an EH_REGION note. */
2441 note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
2442 if (!note
|| INTVAL (XEXP (note
, 0)) <= 0)
2445 return can_throw_internal_1 (INTVAL (XEXP (note
, 0)));
2448 /* Determine if the given INSN can throw an exception that is
2449 visible outside the function. */
2452 can_throw_external_1 (int region_number
)
2454 struct eh_region
*region
;
2457 region
= cfun
->eh
->region_array
[region_number
];
2459 type_thrown
= NULL_TREE
;
2460 if (region
->type
== ERT_THROW
)
2462 type_thrown
= region
->u
.throw.type
;
2463 region
= region
->outer
;
2466 /* If the exception is caught or blocked by any containing region,
2467 then it is not seen by any calling function. */
2468 for (; region
; region
= region
->outer
)
2469 if (reachable_next_level (region
, type_thrown
, NULL
) >= RNL_CAUGHT
)
2476 can_throw_external (rtx insn
)
2480 if (! INSN_P (insn
))
2483 if (NONJUMP_INSN_P (insn
)
2484 && GET_CODE (PATTERN (insn
)) == SEQUENCE
)
2485 insn
= XVECEXP (PATTERN (insn
), 0, 0);
2487 note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
2490 /* Calls (and trapping insns) without notes are outside any
2491 exception handling region in this function. We have to
2492 assume it might throw. Given that the front end and middle
2493 ends mark known NOTHROW functions, this isn't so wildly
2495 return (CALL_P (insn
)
2496 || (flag_non_call_exceptions
2497 && may_trap_p (PATTERN (insn
))));
2499 if (INTVAL (XEXP (note
, 0)) <= 0)
2502 return can_throw_external_1 (INTVAL (XEXP (note
, 0)));
2505 /* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */
2508 set_nothrow_function_flags (void)
2512 TREE_NOTHROW (current_function_decl
) = 1;
2514 /* Assume cfun->all_throwers_are_sibcalls until we encounter
2515 something that can throw an exception. We specifically exempt
2516 CALL_INSNs that are SIBLING_CALL_P, as these are really jumps,
2517 and can't throw. Most CALL_INSNs are not SIBLING_CALL_P, so this
2520 cfun
->all_throwers_are_sibcalls
= 1;
2522 if (! flag_exceptions
)
2525 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
2526 if (can_throw_external (insn
))
2528 TREE_NOTHROW (current_function_decl
) = 0;
2530 if (!CALL_P (insn
) || !SIBLING_CALL_P (insn
))
2532 cfun
->all_throwers_are_sibcalls
= 0;
2537 for (insn
= current_function_epilogue_delay_list
; insn
;
2538 insn
= XEXP (insn
, 1))
2539 if (can_throw_external (insn
))
2541 TREE_NOTHROW (current_function_decl
) = 0;
2543 if (!CALL_P (insn
) || !SIBLING_CALL_P (insn
))
2545 cfun
->all_throwers_are_sibcalls
= 0;
2552 /* Various hooks for unwind library. */
2554 /* Do any necessary initialization to access arbitrary stack frames.
2555 On the SPARC, this means flushing the register windows. */
2558 expand_builtin_unwind_init (void)
2560 /* Set this so all the registers get saved in our frame; we need to be
2561 able to copy the saved values for any registers from frames we unwind. */
2562 current_function_has_nonlocal_label
= 1;
2564 #ifdef SETUP_FRAME_ADDRESSES
2565 SETUP_FRAME_ADDRESSES ();
2570 expand_builtin_eh_return_data_regno (tree arglist
)
2572 tree which
= TREE_VALUE (arglist
);
2573 unsigned HOST_WIDE_INT iwhich
;
2575 if (TREE_CODE (which
) != INTEGER_CST
)
2577 error ("argument of %<__builtin_eh_return_regno%> must be constant");
2581 iwhich
= tree_low_cst (which
, 1);
2582 iwhich
= EH_RETURN_DATA_REGNO (iwhich
);
2583 if (iwhich
== INVALID_REGNUM
)
2586 #ifdef DWARF_FRAME_REGNUM
2587 iwhich
= DWARF_FRAME_REGNUM (iwhich
);
2589 iwhich
= DBX_REGISTER_NUMBER (iwhich
);
2592 return GEN_INT (iwhich
);
2595 /* Given a value extracted from the return address register or stack slot,
2596 return the actual address encoded in that value. */
2599 expand_builtin_extract_return_addr (tree addr_tree
)
2601 rtx addr
= expand_expr (addr_tree
, NULL_RTX
, Pmode
, 0);
2603 if (GET_MODE (addr
) != Pmode
2604 && GET_MODE (addr
) != VOIDmode
)
2606 #ifdef POINTERS_EXTEND_UNSIGNED
2607 addr
= convert_memory_address (Pmode
, addr
);
2609 addr
= convert_to_mode (Pmode
, addr
, 0);
2613 /* First mask out any unwanted bits. */
2614 #ifdef MASK_RETURN_ADDR
2615 expand_and (Pmode
, addr
, MASK_RETURN_ADDR
, addr
);
2618 /* Then adjust to find the real return address. */
2619 #if defined (RETURN_ADDR_OFFSET)
2620 addr
= plus_constant (addr
, RETURN_ADDR_OFFSET
);
2626 /* Given an actual address in addr_tree, do any necessary encoding
2627 and return the value to be stored in the return address register or
2628 stack slot so the epilogue will return to that address. */
2631 expand_builtin_frob_return_addr (tree addr_tree
)
2633 rtx addr
= expand_expr (addr_tree
, NULL_RTX
, ptr_mode
, 0);
2635 addr
= convert_memory_address (Pmode
, addr
);
2637 #ifdef RETURN_ADDR_OFFSET
2638 addr
= force_reg (Pmode
, addr
);
2639 addr
= plus_constant (addr
, -RETURN_ADDR_OFFSET
);
2645 /* Set up the epilogue with the magic bits we'll need to return to the
2646 exception handler. */
2649 expand_builtin_eh_return (tree stackadj_tree ATTRIBUTE_UNUSED
,
2654 #ifdef EH_RETURN_STACKADJ_RTX
2655 tmp
= expand_expr (stackadj_tree
, cfun
->eh
->ehr_stackadj
, VOIDmode
, 0);
2656 tmp
= convert_memory_address (Pmode
, tmp
);
2657 if (!cfun
->eh
->ehr_stackadj
)
2658 cfun
->eh
->ehr_stackadj
= copy_to_reg (tmp
);
2659 else if (tmp
!= cfun
->eh
->ehr_stackadj
)
2660 emit_move_insn (cfun
->eh
->ehr_stackadj
, tmp
);
2663 tmp
= expand_expr (handler_tree
, cfun
->eh
->ehr_handler
, VOIDmode
, 0);
2664 tmp
= convert_memory_address (Pmode
, tmp
);
2665 if (!cfun
->eh
->ehr_handler
)
2666 cfun
->eh
->ehr_handler
= copy_to_reg (tmp
);
2667 else if (tmp
!= cfun
->eh
->ehr_handler
)
2668 emit_move_insn (cfun
->eh
->ehr_handler
, tmp
);
2670 if (!cfun
->eh
->ehr_label
)
2671 cfun
->eh
->ehr_label
= gen_label_rtx ();
2672 emit_jump (cfun
->eh
->ehr_label
);
2676 expand_eh_return (void)
2680 if (! cfun
->eh
->ehr_label
)
2683 current_function_calls_eh_return
= 1;
2685 #ifdef EH_RETURN_STACKADJ_RTX
2686 emit_move_insn (EH_RETURN_STACKADJ_RTX
, const0_rtx
);
2689 around_label
= gen_label_rtx ();
2690 emit_jump (around_label
);
2692 emit_label (cfun
->eh
->ehr_label
);
2693 clobber_return_register ();
2695 #ifdef EH_RETURN_STACKADJ_RTX
2696 emit_move_insn (EH_RETURN_STACKADJ_RTX
, cfun
->eh
->ehr_stackadj
);
2699 #ifdef HAVE_eh_return
2701 emit_insn (gen_eh_return (cfun
->eh
->ehr_handler
));
2705 #ifdef EH_RETURN_HANDLER_RTX
2706 emit_move_insn (EH_RETURN_HANDLER_RTX
, cfun
->eh
->ehr_handler
);
2708 error ("__builtin_eh_return not supported on this target");
2712 emit_label (around_label
);
2715 /* Convert a ptr_mode address ADDR_TREE to a Pmode address controlled by
2716 POINTERS_EXTEND_UNSIGNED and return it. */
2719 expand_builtin_extend_pointer (tree addr_tree
)
2721 rtx addr
= expand_expr (addr_tree
, NULL_RTX
, ptr_mode
, 0);
2724 #ifdef POINTERS_EXTEND_UNSIGNED
2725 extend
= POINTERS_EXTEND_UNSIGNED
;
2727 /* The previous EH code did an unsigned extend by default, so we do this also
2732 return convert_modes (word_mode
, ptr_mode
, addr
, extend
);
2735 /* In the following functions, we represent entries in the action table
2736 as 1-based indices. Special cases are:
2738 0: null action record, non-null landing pad; implies cleanups
2739 -1: null action record, null landing pad; implies no action
2740 -2: no call-site entry; implies must_not_throw
2741 -3: we have yet to process outer regions
2743 Further, no special cases apply to the "next" field of the record.
2744 For next, 0 means end of list. */
2746 struct action_record
2754 action_record_eq (const void *pentry
, const void *pdata
)
2756 const struct action_record
*entry
= (const struct action_record
*) pentry
;
2757 const struct action_record
*data
= (const struct action_record
*) pdata
;
2758 return entry
->filter
== data
->filter
&& entry
->next
== data
->next
;
2762 action_record_hash (const void *pentry
)
2764 const struct action_record
*entry
= (const struct action_record
*) pentry
;
2765 return entry
->next
* 1009 + entry
->filter
;
2769 add_action_record (htab_t ar_hash
, int filter
, int next
)
2771 struct action_record
**slot
, *new, tmp
;
2773 tmp
.filter
= filter
;
2775 slot
= (struct action_record
**) htab_find_slot (ar_hash
, &tmp
, INSERT
);
2777 if ((new = *slot
) == NULL
)
2779 new = xmalloc (sizeof (*new));
2780 new->offset
= VARRAY_ACTIVE_SIZE (cfun
->eh
->action_record_data
) + 1;
2781 new->filter
= filter
;
2785 /* The filter value goes in untouched. The link to the next
2786 record is a "self-relative" byte offset, or zero to indicate
2787 that there is no next record. So convert the absolute 1 based
2788 indices we've been carrying around into a displacement. */
2790 push_sleb128 (&cfun
->eh
->action_record_data
, filter
);
2792 next
-= VARRAY_ACTIVE_SIZE (cfun
->eh
->action_record_data
) + 1;
2793 push_sleb128 (&cfun
->eh
->action_record_data
, next
);
2800 collect_one_action_chain (htab_t ar_hash
, struct eh_region
*region
)
2802 struct eh_region
*c
;
2805 /* If we've reached the top of the region chain, then we have
2806 no actions, and require no landing pad. */
2810 switch (region
->type
)
2813 /* A cleanup adds a zero filter to the beginning of the chain, but
2814 there are special cases to look out for. If there are *only*
2815 cleanups along a path, then it compresses to a zero action.
2816 Further, if there are multiple cleanups along a path, we only
2817 need to represent one of them, as that is enough to trigger
2818 entry to the landing pad at runtime. */
2819 next
= collect_one_action_chain (ar_hash
, region
->outer
);
2822 for (c
= region
->outer
; c
; c
= c
->outer
)
2823 if (c
->type
== ERT_CLEANUP
)
2825 return add_action_record (ar_hash
, 0, next
);
2828 /* Process the associated catch regions in reverse order.
2829 If there's a catch-all handler, then we don't need to
2830 search outer regions. Use a magic -3 value to record
2831 that we haven't done the outer search. */
2833 for (c
= region
->u
.try.last_catch
; c
; c
= c
->u
.catch.prev_catch
)
2835 if (c
->u
.catch.type_list
== NULL
)
2837 /* Retrieve the filter from the head of the filter list
2838 where we have stored it (see assign_filter_values). */
2840 = TREE_INT_CST_LOW (TREE_VALUE (c
->u
.catch.filter_list
));
2842 next
= add_action_record (ar_hash
, filter
, 0);
2846 /* Once the outer search is done, trigger an action record for
2847 each filter we have. */
2852 next
= collect_one_action_chain (ar_hash
, region
->outer
);
2854 /* If there is no next action, terminate the chain. */
2857 /* If all outer actions are cleanups or must_not_throw,
2858 we'll have no action record for it, since we had wanted
2859 to encode these states in the call-site record directly.
2860 Add a cleanup action to the chain to catch these. */
2862 next
= add_action_record (ar_hash
, 0, 0);
2865 flt_node
= c
->u
.catch.filter_list
;
2866 for (; flt_node
; flt_node
= TREE_CHAIN (flt_node
))
2868 int filter
= TREE_INT_CST_LOW (TREE_VALUE (flt_node
));
2869 next
= add_action_record (ar_hash
, filter
, next
);
2875 case ERT_ALLOWED_EXCEPTIONS
:
2876 /* An exception specification adds its filter to the
2877 beginning of the chain. */
2878 next
= collect_one_action_chain (ar_hash
, region
->outer
);
2880 /* If there is no next action, terminate the chain. */
2883 /* If all outer actions are cleanups or must_not_throw,
2884 we'll have no action record for it, since we had wanted
2885 to encode these states in the call-site record directly.
2886 Add a cleanup action to the chain to catch these. */
2888 next
= add_action_record (ar_hash
, 0, 0);
2890 return add_action_record (ar_hash
, region
->u
.allowed
.filter
, next
);
2892 case ERT_MUST_NOT_THROW
:
2893 /* A must-not-throw region with no inner handlers or cleanups
2894 requires no call-site entry. Note that this differs from
2895 the no handler or cleanup case in that we do require an lsda
2896 to be generated. Return a magic -2 value to record this. */
2901 /* CATCH regions are handled in TRY above. THROW regions are
2902 for optimization information only and produce no output. */
2903 return collect_one_action_chain (ar_hash
, region
->outer
);
2911 add_call_site (rtx landing_pad
, int action
)
2913 struct call_site_record
*data
= cfun
->eh
->call_site_data
;
2914 int used
= cfun
->eh
->call_site_data_used
;
2915 int size
= cfun
->eh
->call_site_data_size
;
2919 size
= (size
? size
* 2 : 64);
2920 data
= ggc_realloc (data
, sizeof (*data
) * size
);
2921 cfun
->eh
->call_site_data
= data
;
2922 cfun
->eh
->call_site_data_size
= size
;
2925 data
[used
].landing_pad
= landing_pad
;
2926 data
[used
].action
= action
;
2928 cfun
->eh
->call_site_data_used
= used
+ 1;
2930 return used
+ call_site_base
;
2933 /* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
2934 The new note numbers will not refer to region numbers, but
2935 instead to call site entries. */
2938 convert_to_eh_region_ranges (void)
2940 rtx insn
, iter
, note
;
2942 int last_action
= -3;
2943 rtx last_action_insn
= NULL_RTX
;
2944 rtx last_landing_pad
= NULL_RTX
;
2945 rtx first_no_action_insn
= NULL_RTX
;
2948 if (USING_SJLJ_EXCEPTIONS
|| cfun
->eh
->region_tree
== NULL
)
2951 VARRAY_UCHAR_INIT (cfun
->eh
->action_record_data
, 64, "action_record_data");
2953 ar_hash
= htab_create (31, action_record_hash
, action_record_eq
, free
);
2955 for (iter
= get_insns (); iter
; iter
= NEXT_INSN (iter
))
2958 struct eh_region
*region
;
2960 rtx this_landing_pad
;
2963 if (NONJUMP_INSN_P (insn
)
2964 && GET_CODE (PATTERN (insn
)) == SEQUENCE
)
2965 insn
= XVECEXP (PATTERN (insn
), 0, 0);
2967 note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
2970 if (! (CALL_P (insn
)
2971 || (flag_non_call_exceptions
2972 && may_trap_p (PATTERN (insn
)))))
2979 if (INTVAL (XEXP (note
, 0)) <= 0)
2981 region
= cfun
->eh
->region_array
[INTVAL (XEXP (note
, 0))];
2982 this_action
= collect_one_action_chain (ar_hash
, region
);
2985 /* Existence of catch handlers, or must-not-throw regions
2986 implies that an lsda is needed (even if empty). */
2987 if (this_action
!= -1)
2988 cfun
->uses_eh_lsda
= 1;
2990 /* Delay creation of region notes for no-action regions
2991 until we're sure that an lsda will be required. */
2992 else if (last_action
== -3)
2994 first_no_action_insn
= iter
;
2998 /* Cleanups and handlers may share action chains but not
2999 landing pads. Collect the landing pad for this region. */
3000 if (this_action
>= 0)
3002 struct eh_region
*o
;
3003 for (o
= region
; ! o
->landing_pad
; o
= o
->outer
)
3005 this_landing_pad
= o
->landing_pad
;
3008 this_landing_pad
= NULL_RTX
;
3010 /* Differing actions or landing pads implies a change in call-site
3011 info, which implies some EH_REGION note should be emitted. */
3012 if (last_action
!= this_action
3013 || last_landing_pad
!= this_landing_pad
)
3015 /* If we'd not seen a previous action (-3) or the previous
3016 action was must-not-throw (-2), then we do not need an
3018 if (last_action
>= -1)
3020 /* If we delayed the creation of the begin, do it now. */
3021 if (first_no_action_insn
)
3023 call_site
= add_call_site (NULL_RTX
, 0);
3024 note
= emit_note_before (NOTE_INSN_EH_REGION_BEG
,
3025 first_no_action_insn
);
3026 NOTE_EH_HANDLER (note
) = call_site
;
3027 first_no_action_insn
= NULL_RTX
;
3030 note
= emit_note_after (NOTE_INSN_EH_REGION_END
,
3032 NOTE_EH_HANDLER (note
) = call_site
;
3035 /* If the new action is must-not-throw, then no region notes
3037 if (this_action
>= -1)
3039 call_site
= add_call_site (this_landing_pad
,
3040 this_action
< 0 ? 0 : this_action
);
3041 note
= emit_note_before (NOTE_INSN_EH_REGION_BEG
, iter
);
3042 NOTE_EH_HANDLER (note
) = call_site
;
3045 last_action
= this_action
;
3046 last_landing_pad
= this_landing_pad
;
3048 last_action_insn
= iter
;
3051 if (last_action
>= -1 && ! first_no_action_insn
)
3053 note
= emit_note_after (NOTE_INSN_EH_REGION_END
, last_action_insn
);
3054 NOTE_EH_HANDLER (note
) = call_site
;
3057 htab_delete (ar_hash
);
3062 push_uleb128 (varray_type
*data_area
, unsigned int value
)
3066 unsigned char byte
= value
& 0x7f;
3070 VARRAY_PUSH_UCHAR (*data_area
, byte
);
3076 push_sleb128 (varray_type
*data_area
, int value
)
3083 byte
= value
& 0x7f;
3085 more
= ! ((value
== 0 && (byte
& 0x40) == 0)
3086 || (value
== -1 && (byte
& 0x40) != 0));
3089 VARRAY_PUSH_UCHAR (*data_area
, byte
);
3095 #ifndef HAVE_AS_LEB128
3097 dw2_size_of_call_site_table (void)
3099 int n
= cfun
->eh
->call_site_data_used
;
3100 int size
= n
* (4 + 4 + 4);
3103 for (i
= 0; i
< n
; ++i
)
3105 struct call_site_record
*cs
= &cfun
->eh
->call_site_data
[i
];
3106 size
+= size_of_uleb128 (cs
->action
);
3113 sjlj_size_of_call_site_table (void)
3115 int n
= cfun
->eh
->call_site_data_used
;
3119 for (i
= 0; i
< n
; ++i
)
3121 struct call_site_record
*cs
= &cfun
->eh
->call_site_data
[i
];
3122 size
+= size_of_uleb128 (INTVAL (cs
->landing_pad
));
3123 size
+= size_of_uleb128 (cs
->action
);
3131 dw2_output_call_site_table (void)
3133 int n
= cfun
->eh
->call_site_data_used
;
3136 for (i
= 0; i
< n
; ++i
)
3138 struct call_site_record
*cs
= &cfun
->eh
->call_site_data
[i
];
3139 char reg_start_lab
[32];
3140 char reg_end_lab
[32];
3141 char landing_pad_lab
[32];
3143 ASM_GENERATE_INTERNAL_LABEL (reg_start_lab
, "LEHB", call_site_base
+ i
);
3144 ASM_GENERATE_INTERNAL_LABEL (reg_end_lab
, "LEHE", call_site_base
+ i
);
3146 if (cs
->landing_pad
)
3147 ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab
, "L",
3148 CODE_LABEL_NUMBER (cs
->landing_pad
));
3150 /* ??? Perhaps use insn length scaling if the assembler supports
3151 generic arithmetic. */
3152 /* ??? Perhaps use attr_length to choose data1 or data2 instead of
3153 data4 if the function is small enough. */
3154 #ifdef HAVE_AS_LEB128
3155 dw2_asm_output_delta_uleb128 (reg_start_lab
,
3156 current_function_func_begin_label
,
3157 "region %d start", i
);
3158 dw2_asm_output_delta_uleb128 (reg_end_lab
, reg_start_lab
,
3160 if (cs
->landing_pad
)
3161 dw2_asm_output_delta_uleb128 (landing_pad_lab
,
3162 current_function_func_begin_label
,
3165 dw2_asm_output_data_uleb128 (0, "landing pad");
3167 dw2_asm_output_delta (4, reg_start_lab
,
3168 current_function_func_begin_label
,
3169 "region %d start", i
);
3170 dw2_asm_output_delta (4, reg_end_lab
, reg_start_lab
, "length");
3171 if (cs
->landing_pad
)
3172 dw2_asm_output_delta (4, landing_pad_lab
,
3173 current_function_func_begin_label
,
3176 dw2_asm_output_data (4, 0, "landing pad");
3178 dw2_asm_output_data_uleb128 (cs
->action
, "action");
3181 call_site_base
+= n
;
3185 sjlj_output_call_site_table (void)
3187 int n
= cfun
->eh
->call_site_data_used
;
3190 for (i
= 0; i
< n
; ++i
)
3192 struct call_site_record
*cs
= &cfun
->eh
->call_site_data
[i
];
3194 dw2_asm_output_data_uleb128 (INTVAL (cs
->landing_pad
),
3195 "region %d landing pad", i
);
3196 dw2_asm_output_data_uleb128 (cs
->action
, "action");
3199 call_site_base
+= n
;
3202 /* Tell assembler to switch to the section for the exception handling
3206 default_exception_section (void)
3208 if (targetm
.have_named_sections
)
3212 if (EH_TABLES_CAN_BE_READ_ONLY
)
3214 int tt_format
= ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3217 || ((tt_format
& 0x70) != DW_EH_PE_absptr
3218 && (tt_format
& 0x70) != DW_EH_PE_aligned
))
3219 ? 0 : SECTION_WRITE
;
3222 flags
= SECTION_WRITE
;
3223 named_section_flags (".gcc_except_table", flags
);
3228 readonly_data_section ();
3232 output_function_exception_table (void)
3234 int tt_format
, cs_format
, lp_format
, i
, n
;
3235 #ifdef HAVE_AS_LEB128
3236 char ttype_label
[32];
3237 char cs_after_size_label
[32];
3238 char cs_end_label
[32];
3243 int tt_format_size
= 0;
3245 /* Not all functions need anything. */
3246 if (! cfun
->uses_eh_lsda
)
3249 #ifdef TARGET_UNWIND_INFO
3250 /* TODO: Move this into target file. */
3251 assemble_external_libcall (eh_personality_libfunc
);
3252 fputs ("\t.personality\t", asm_out_file
);
3253 output_addr_const (asm_out_file
, eh_personality_libfunc
);
3254 fputs ("\n\t.handlerdata\n", asm_out_file
);
3255 /* Note that varasm still thinks we're in the function's code section.
3256 The ".endp" directive that will immediately follow will take us back. */
3258 targetm
.asm_out
.exception_section ();
3261 have_tt_data
= (VARRAY_ACTIVE_SIZE (cfun
->eh
->ttype_data
) > 0
3262 || VARRAY_ACTIVE_SIZE (cfun
->eh
->ehspec_data
) > 0);
3264 /* Indicate the format of the @TType entries. */
3266 tt_format
= DW_EH_PE_omit
;
3269 tt_format
= ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3270 #ifdef HAVE_AS_LEB128
3271 ASM_GENERATE_INTERNAL_LABEL (ttype_label
, "LLSDATT",
3272 current_function_funcdef_no
);
3274 tt_format_size
= size_of_encoded_value (tt_format
);
3276 assemble_align (tt_format_size
* BITS_PER_UNIT
);
3279 targetm
.asm_out
.internal_label (asm_out_file
, "LLSDA",
3280 current_function_funcdef_no
);
3282 /* The LSDA header. */
3284 /* Indicate the format of the landing pad start pointer. An omitted
3285 field implies @LPStart == @Start. */
3286 /* Currently we always put @LPStart == @Start. This field would
3287 be most useful in moving the landing pads completely out of
3288 line to another section, but it could also be used to minimize
3289 the size of uleb128 landing pad offsets. */
3290 lp_format
= DW_EH_PE_omit
;
3291 dw2_asm_output_data (1, lp_format
, "@LPStart format (%s)",
3292 eh_data_format_name (lp_format
));
3294 /* @LPStart pointer would go here. */
3296 dw2_asm_output_data (1, tt_format
, "@TType format (%s)",
3297 eh_data_format_name (tt_format
));
3299 #ifndef HAVE_AS_LEB128
3300 if (USING_SJLJ_EXCEPTIONS
)
3301 call_site_len
= sjlj_size_of_call_site_table ();
3303 call_site_len
= dw2_size_of_call_site_table ();
3306 /* A pc-relative 4-byte displacement to the @TType data. */
3309 #ifdef HAVE_AS_LEB128
3310 char ttype_after_disp_label
[32];
3311 ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label
, "LLSDATTD",
3312 current_function_funcdef_no
);
3313 dw2_asm_output_delta_uleb128 (ttype_label
, ttype_after_disp_label
,
3314 "@TType base offset");
3315 ASM_OUTPUT_LABEL (asm_out_file
, ttype_after_disp_label
);
3317 /* Ug. Alignment queers things. */
3318 unsigned int before_disp
, after_disp
, last_disp
, disp
;
3320 before_disp
= 1 + 1;
3321 after_disp
= (1 + size_of_uleb128 (call_site_len
)
3323 + VARRAY_ACTIVE_SIZE (cfun
->eh
->action_record_data
)
3324 + (VARRAY_ACTIVE_SIZE (cfun
->eh
->ttype_data
)
3330 unsigned int disp_size
, pad
;
3333 disp_size
= size_of_uleb128 (disp
);
3334 pad
= before_disp
+ disp_size
+ after_disp
;
3335 if (pad
% tt_format_size
)
3336 pad
= tt_format_size
- (pad
% tt_format_size
);
3339 disp
= after_disp
+ pad
;
3341 while (disp
!= last_disp
);
3343 dw2_asm_output_data_uleb128 (disp
, "@TType base offset");
3347 /* Indicate the format of the call-site offsets. */
3348 #ifdef HAVE_AS_LEB128
3349 cs_format
= DW_EH_PE_uleb128
;
3351 cs_format
= DW_EH_PE_udata4
;
3353 dw2_asm_output_data (1, cs_format
, "call-site format (%s)",
3354 eh_data_format_name (cs_format
));
3356 #ifdef HAVE_AS_LEB128
3357 ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label
, "LLSDACSB",
3358 current_function_funcdef_no
);
3359 ASM_GENERATE_INTERNAL_LABEL (cs_end_label
, "LLSDACSE",
3360 current_function_funcdef_no
);
3361 dw2_asm_output_delta_uleb128 (cs_end_label
, cs_after_size_label
,
3362 "Call-site table length");
3363 ASM_OUTPUT_LABEL (asm_out_file
, cs_after_size_label
);
3364 if (USING_SJLJ_EXCEPTIONS
)
3365 sjlj_output_call_site_table ();
3367 dw2_output_call_site_table ();
3368 ASM_OUTPUT_LABEL (asm_out_file
, cs_end_label
);
3370 dw2_asm_output_data_uleb128 (call_site_len
,"Call-site table length");
3371 if (USING_SJLJ_EXCEPTIONS
)
3372 sjlj_output_call_site_table ();
3374 dw2_output_call_site_table ();
3377 /* ??? Decode and interpret the data for flag_debug_asm. */
3378 n
= VARRAY_ACTIVE_SIZE (cfun
->eh
->action_record_data
);
3379 for (i
= 0; i
< n
; ++i
)
3380 dw2_asm_output_data (1, VARRAY_UCHAR (cfun
->eh
->action_record_data
, i
),
3381 (i
? NULL
: "Action record table"));
3384 assemble_align (tt_format_size
* BITS_PER_UNIT
);
3386 i
= VARRAY_ACTIVE_SIZE (cfun
->eh
->ttype_data
);
3389 tree type
= VARRAY_TREE (cfun
->eh
->ttype_data
, i
);
3392 if (type
== NULL_TREE
)
3396 struct cgraph_varpool_node
*node
;
3398 type
= lookup_type_for_runtime (type
);
3399 value
= expand_expr (type
, NULL_RTX
, VOIDmode
, EXPAND_INITIALIZER
);
3401 /* Let cgraph know that the rtti decl is used. Not all of the
3402 paths below go through assemble_integer, which would take
3403 care of this for us. */
3405 if (TREE_CODE (type
) == ADDR_EXPR
)
3407 type
= TREE_OPERAND (type
, 0);
3408 if (TREE_CODE (type
) == VAR_DECL
)
3410 node
= cgraph_varpool_node (type
);
3412 cgraph_varpool_mark_needed_node (node
);
3416 gcc_assert (TREE_CODE (type
) == INTEGER_CST
);
3419 if (tt_format
== DW_EH_PE_absptr
|| tt_format
== DW_EH_PE_aligned
)
3420 assemble_integer (value
, tt_format_size
,
3421 tt_format_size
* BITS_PER_UNIT
, 1);
3423 dw2_asm_output_encoded_addr_rtx (tt_format
, value
, NULL
);
3426 #ifdef HAVE_AS_LEB128
3428 ASM_OUTPUT_LABEL (asm_out_file
, ttype_label
);
3431 /* ??? Decode and interpret the data for flag_debug_asm. */
3432 n
= VARRAY_ACTIVE_SIZE (cfun
->eh
->ehspec_data
);
3433 for (i
= 0; i
< n
; ++i
)
3434 dw2_asm_output_data (1, VARRAY_UCHAR (cfun
->eh
->ehspec_data
, i
),
3435 (i
? NULL
: "Exception specification table"));
3437 current_function_section (current_function_decl
);
3440 #include "gt-except.h"