Merge from the pain train
[official-gcc.git] / gcc / except.c
blobb2e4188d9575829bae10c6572293a25230681f07
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
11 version.
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
16 for more details.
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
21 02111-1307, USA. */
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. ] */
50 #include "config.h"
51 #include "system.h"
52 #include "coretypes.h"
53 #include "tm.h"
54 #include "rtl.h"
55 #include "tree.h"
56 #include "flags.h"
57 #include "function.h"
58 #include "expr.h"
59 #include "libfuncs.h"
60 #include "insn-config.h"
61 #include "except.h"
62 #include "integrate.h"
63 #include "hard-reg-set.h"
64 #include "basic-block.h"
65 #include "output.h"
66 #include "dwarf2asm.h"
67 #include "dwarf2out.h"
68 #include "dwarf2.h"
69 #include "toplev.h"
70 #include "hashtab.h"
71 #include "intl.h"
72 #include "ggc.h"
73 #include "tm_p.h"
74 #include "target.h"
75 #include "langhooks.h"
76 #include "cgraph.h"
78 /* Provide defaults for stuff that may not be defined when using
79 sjlj exceptions. */
80 #ifndef EH_RETURN_DATA_REGNO
81 #define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM
82 #endif
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(())
99 rtx label;
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. */
126 int region_number;
128 /* When a region is deleted, its parents inherit the REG_EH_REGION
129 numbers already assigned. */
130 bitmap aka;
132 /* Each region does exactly one thing. */
133 enum eh_region_type
135 ERT_UNKNOWN = 0,
136 ERT_CLEANUP,
137 ERT_TRY,
138 ERT_CATCH,
139 ERT_ALLOWED_EXCEPTIONS,
140 ERT_MUST_NOT_THROW,
141 ERT_THROW,
142 ERT_FIXUP
143 } type;
145 /* Holds the action to perform based on the preceding type. */
146 union eh_region_u {
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;
153 rtx continue_label;
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;
161 tree type_list;
162 tree filter_list;
163 } GTY ((tag ("ERT_CATCH"))) catch;
165 /* A tree_list of allowed types. */
166 struct eh_region_u_allowed {
167 tree type_list;
168 int filter;
169 } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
171 /* The type given by a call to "throw foo();", or discovered
172 for a throw. */
173 struct eh_region_u_throw {
174 tree type;
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 {
180 tree exp;
181 struct eh_region *prev_try;
182 } GTY ((tag ("ERT_CLEANUP"))) cleanup;
184 /* The real region (by expression and by pointer) that fixup code
185 should live in. */
186 struct eh_region_u_fixup {
187 tree cleanup_exp;
188 struct eh_region *real_region;
189 bool resolved;
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. */
194 rtx label;
195 tree tree_label;
197 /* Entry point for this region's handler from the runtime eh library. */
198 rtx landing_pad;
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,
204 if appropriate. */
205 rtx resume;
207 /* True if something in this region may throw. */
208 unsigned may_contain_throw : 1;
211 struct call_site_record GTY(())
213 rtx landing_pad;
214 int action;
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;
232 rtx filter;
233 rtx exc_ptr;
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")))
245 call_site_data;
246 int call_site_data_used;
247 int call_site_data_size;
249 rtx ehr_stackadj;
250 rtx ehr_handler;
251 rtx ehr_label;
253 rtx sjlj_fc;
254 rtx sjlj_exit_after;
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);
276 struct sjlj_lp_info;
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. */
293 enum reachable_code
295 /* The given exception is not processed by the given region. */
296 RNL_NOT_CAUGHT,
297 /* The given exception may need processing by the given region. */
298 RNL_MAYBE_CAUGHT,
299 /* The given exception is completely processed by the given region. */
300 RNL_CAUGHT,
301 /* The given exception is completely processed by the runtime. */
302 RNL_BLOCKED
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);
320 #endif
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");
341 warned = 1;
343 return 0;
345 return 1;
349 void
350 init_eh (void)
352 if (! flag_exceptions)
353 return;
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"),
370 integer_type_node);
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),
375 tmp);
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"),
380 ptr_type_node);
381 DECL_FIELD_CONTEXT (f_per) = sjlj_fc_type_node;
383 f_lsda = build_decl (FIELD_DECL, get_identifier ("__lsda"),
384 ptr_type_node);
385 DECL_FIELD_CONTEXT (f_lsda) = sjlj_fc_type_node;
387 #ifdef DONT_USE_BUILTIN_SETJMP
388 #ifdef JMP_BUF_SIZE
389 tmp = build_int_cst (NULL_TREE, JMP_BUF_SIZE - 1);
390 #else
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);
396 #endif
397 #else
398 /* builtin_setjmp takes a pointer to 5 words. */
399 tmp = build_int_cst (NULL_TREE, 5 * BITS_PER_WORD / POINTER_SIZE - 1);
400 #endif
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;
409 #endif
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);
426 sjlj_fc_data_ofs
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);
432 sjlj_fc_lsda_ofs
433 = (tree_low_cst (DECL_FIELD_OFFSET (f_lsda), 1)
434 + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_lsda), 1) / BITS_PER_UNIT);
435 sjlj_fc_jbuf_ofs
436 = (tree_low_cst (DECL_FIELD_OFFSET (f_jbuf), 1)
437 + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_jbuf), 1) / BITS_PER_UNIT);
441 void
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));
458 #endif
460 /* Insert a new blank region as a leaf in the tree. */
461 new = ggc_alloc_cleared (sizeof (*new));
462 new->type = type;
463 new->outer = outer;
464 if (outer)
466 new->next_peer = outer->inner;
467 outer->inner = new;
469 else
471 new->next_peer = cfun->eh->region_tree;
472 cfun->eh->region_tree = new;
475 new->region_number = ++cfun->eh->last_region_number;
477 return new;
480 struct eh_region *
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;
485 return cleanup;
488 struct eh_region *
489 gen_eh_region_try (struct eh_region *outer)
491 return gen_eh_region (ERT_TRY, outer);
494 struct eh_region *
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;
503 if (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;
517 if (l)
518 l->u.catch.next_catch = c;
519 else
520 t->u.try.catch = c;
521 t->u.try.last_catch = c;
523 return c;
526 struct eh_region *
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));
535 return region;
538 struct eh_region *
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;
550 bool
551 get_eh_region_may_contain_throw (struct eh_region *region)
553 return region->may_contain_throw;
556 tree
557 get_eh_region_tree_label (struct eh_region *region)
559 return region->tree_label;
562 void
563 set_eh_region_tree_label (struct eh_region *region, tree lab)
565 region->tree_label = lab;
568 void
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));
575 emit_barrier ();
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. */
581 void
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;
591 void
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
599 within a handler. */
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;
610 return exc_ptr;
613 /* Return an rtl expression for the exception dispatch filter
614 within a handler. */
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;
625 return filter;
628 /* This section is for the exception handling specific optimization pass. */
630 /* Random access the exception region tree. */
632 void
633 collect_eh_region_array (void)
635 struct eh_region **array, *i;
637 i = cfun->eh->region_tree;
638 if (! i)
639 return;
641 array = ggc_alloc_cleared ((cfun->eh->last_region_number + 1)
642 * sizeof (*array));
643 cfun->eh->region_array = array;
645 while (1)
647 array[i->region_number] = i;
649 /* If there are sub-regions, process them. */
650 if (i->inner)
651 i = i->inner;
652 /* If there are peers, process them. */
653 else if (i->next_peer)
654 i = i->next_peer;
655 /* Otherwise, step back up the tree to the next peer. */
656 else
658 do {
659 i = i->outer;
660 if (i == NULL)
661 return;
662 } while (i->next_peer == NULL);
663 i = i->next_peer;
668 /* Remove all regions whose labels are not reachable from insns. */
670 static void
671 remove_unreachable_regions (rtx insns)
673 int i, *uid_region_num;
674 bool *reachable;
675 struct eh_region *r;
676 rtx insn;
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)
685 continue;
687 if (r->resume)
689 gcc_assert (!uid_region_num[INSN_UID (r->resume)]);
690 uid_region_num[INSN_UID (r->resume)] = i;
692 if (r->label)
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])
707 bool kill_it = true;
708 switch (r->type)
710 case ERT_THROW:
711 /* Don't remove ERT_THROW regions if their outer region
712 is reachable. */
713 if (r->outer && reachable[r->outer->region_number])
714 kill_it = false;
715 break;
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. */
721 kill_it = false;
722 break;
724 case ERT_TRY:
726 /* TRY regions are reachable if any of its CATCH regions
727 are reachable. */
728 struct eh_region *c;
729 for (c = r->u.try.catch; c ; c = c->u.catch.next_catch)
730 if (reachable[c->region_number])
732 kill_it = false;
733 break;
735 break;
738 default:
739 break;
742 if (kill_it)
743 remove_eh_handler (r);
747 free (reachable);
748 free (uid_region_num);
751 /* Set up EH labels for RTL. */
753 void
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);
773 static void
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);
793 *slot = entry;
796 void
797 find_exception_handler_labels (void)
799 int i;
801 if (cfun->eh->exception_handler_label_map)
802 htab_empty (cfun->eh->exception_handler_label_map);
803 else
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)
813 return;
815 for (i = cfun->eh->last_region_number; i > 0; --i)
817 struct eh_region *region = cfun->eh->region_array[i];
818 rtx lab;
820 if (! region || region->region_number != i)
821 continue;
822 if (cfun->eh->built_landing_pads)
823 lab = region->landing_pad;
824 else
825 lab = region->label;
827 if (lab)
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);
837 bool
838 current_function_has_exception_handlers (void)
840 int i;
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)
847 continue;
848 if (region->type != ERT_THROW)
849 return true;
852 return false;
855 static int
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;
864 static hashval_t
865 t2r_hash (const void *pentry)
867 tree entry = (tree) pentry;
868 return TREE_HASH (TREE_PURPOSE (entry));
871 static void
872 add_type_for_runtime (tree type)
874 tree *slot;
876 slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
877 TREE_HASH (type), INSERT);
878 if (*slot == NULL)
880 tree runtime = (*lang_eh_runtime_type) (type);
881 *slot = tree_cons (type, runtime, NULL_TREE);
885 static tree
886 lookup_type_for_runtime (tree type)
888 tree *slot;
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(())
902 tree t;
903 int filter;
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. */
909 static int
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;
918 static hashval_t
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. */
930 static int
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. */
941 static hashval_t
942 ehspec_filter_hash (const void *pentry)
944 const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
945 hashval_t h = 0;
946 tree list;
948 for (list = entry->t; list ; list = TREE_CHAIN (list))
949 h = (h << 5) + (h >> 27) + TREE_HASH (TREE_VALUE (list));
950 return h;
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. */
956 static int
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));
969 n->t = type;
970 n->filter = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) + 1;
971 *slot = n;
973 VARRAY_PUSH_TREE (cfun->eh->ttype_data, type);
976 return n->filter;
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. */
982 static int
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;
988 dummy.t = list;
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));
997 n->t = list;
998 n->filter = -(VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) + 1);
999 *slot = n;
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);
1009 return n->filter;
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. */
1017 static void
1018 assign_filter_values (void)
1020 int i;
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)
1035 continue;
1037 switch (r->type)
1039 case ERT_CATCH:
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);
1059 else
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);
1070 break;
1072 case ERT_ALLOWED_EXCEPTIONS:
1073 r->u.allowed.filter
1074 = add_ehspec_entry (ehspec, ttypes, r->u.allowed.type_list);
1075 break;
1077 default:
1078 break;
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
1088 produced block. */
1089 static basic_block
1090 emit_to_new_bb_before (rtx seq, rtx insn)
1092 rtx last;
1093 basic_block bb;
1094 edge e;
1095 edge_iterator ei;
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
1099 construct. */
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);
1103 else
1104 ei_next (&ei);
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;
1111 return bb;
1114 /* Generate the code to actually handle exceptions, which will follow the
1115 landing pads. */
1117 static void
1118 build_post_landing_pads (void)
1120 int i;
1122 for (i = cfun->eh->last_region_number; i > 0; --i)
1124 struct eh_region *region = cfun->eh->region_array[i];
1125 rtx seq;
1127 /* Mind we don't process a region more than once. */
1128 if (!region || region->region_number != i)
1129 continue;
1131 switch (region->type)
1133 case ERT_TRY:
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 ();
1142 start_sequence ();
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);
1155 else
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;
1163 for (; tp_node; )
1165 emit_cmp_and_jump_insns
1166 (cfun->eh->filter,
1167 GEN_INT (tree_low_cst (TREE_VALUE (flt_node), 0)),
1168 EQ, NULL_RTX,
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. */
1181 region->resume
1182 = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1183 emit_barrier ();
1185 seq = get_insns ();
1186 end_sequence ();
1188 emit_to_new_bb_before (seq, region->u.try.catch->label);
1190 break;
1192 case ERT_ALLOWED_EXCEPTIONS:
1193 region->post_landing_pad = gen_label_rtx ();
1195 start_sequence ();
1197 emit_label (region->post_landing_pad);
1199 emit_cmp_and_jump_insns (cfun->eh->filter,
1200 GEN_INT (region->u.allowed.filter),
1201 EQ, NULL_RTX,
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. */
1207 region->resume
1208 = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1209 emit_barrier ();
1211 seq = get_insns ();
1212 end_sequence ();
1214 emit_to_new_bb_before (seq, region->label);
1215 break;
1217 case ERT_CLEANUP:
1218 case ERT_MUST_NOT_THROW:
1219 region->post_landing_pad = region->label;
1220 break;
1222 case ERT_CATCH:
1223 case ERT_THROW:
1224 /* Nothing to do. */
1225 break;
1227 default:
1228 gcc_unreachable ();
1233 /* Replace RESX patterns with jumps to the next handler if any, or calls to
1234 _Unwind_Resume otherwise. */
1236 static void
1237 connect_post_landing_pads (void)
1239 int i;
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;
1245 rtx seq;
1246 rtx barrier;
1248 /* Mind we don't process a region more than once. */
1249 if (!region || region->region_number != i)
1250 continue;
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))
1255 continue;
1257 /* Search for another landing pad in this function. */
1258 for (outer = region->outer; outer ; outer = outer->outer)
1259 if (outer->post_landing_pad)
1260 break;
1262 start_sequence ();
1264 if (outer)
1266 edge e;
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;
1278 else
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
1291 the sequence. */
1292 delete_insns_since (NEXT_INSN (last_call_insn ()));
1295 seq = get_insns ();
1296 end_sequence ();
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);
1312 static void
1313 dw2_build_landing_pads (void)
1315 int i;
1316 unsigned int j;
1318 for (i = cfun->eh->last_region_number; i > 0; --i)
1320 struct eh_region *region = cfun->eh->region_array[i];
1321 rtx seq;
1322 basic_block bb;
1323 bool clobbers_hard_regs = false;
1324 edge e;
1326 /* Mind we don't process a region more than once. */
1327 if (!region || region->region_number != i)
1328 continue;
1330 if (region->type != ERT_CLEANUP
1331 && region->type != ERT_TRY
1332 && region->type != ERT_ALLOWED_EXCEPTIONS)
1333 continue;
1335 start_sequence ();
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 ());
1343 else
1344 #endif
1345 #ifdef HAVE_nonlocal_goto_receiver
1346 if (HAVE_nonlocal_goto_receiver)
1347 emit_insn (gen_nonlocal_goto_receiver ());
1348 else
1349 #endif
1350 { /* Nothing */ }
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. */
1355 for (j = 0; ; ++j)
1357 unsigned r = EH_RETURN_DATA_REGNO (j);
1358 if (r == INVALID_REGNUM)
1359 break;
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
1372 blockage insn. */
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)));
1382 seq = get_insns ();
1383 end_sequence ();
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;
1393 struct sjlj_lp_info
1395 int directly_reachable;
1396 int action_index;
1397 int dispatch_index;
1398 int call_site_index;
1401 static bool
1402 sjlj_find_directly_reachable_regions (struct sjlj_lp_info *lp_info)
1404 rtx insn;
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;
1411 tree type_thrown;
1412 rtx note;
1414 if (! INSN_P (insn))
1415 continue;
1417 note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1418 if (!note || INTVAL (XEXP (note, 0)) <= 0)
1419 continue;
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)
1437 break;
1439 if (rc == RNL_MAYBE_CAUGHT || rc == RNL_CAUGHT)
1441 lp_info[region->region_number].directly_reachable = 1;
1442 found_one = true;
1446 return found_one;
1449 static void
1450 sjlj_assign_call_site_values (rtx dispatch_label, struct sjlj_lp_info *lp_info)
1452 htab_t ar_hash;
1453 int i, index;
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. */
1482 index = 0;
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. */
1491 call_site_base = 1;
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. */
1498 if (action == -2)
1499 index = 0;
1500 /* Map no-action to otherwise unused call-site index -1. */
1501 else if (action == -1)
1502 index = -1;
1503 /* Otherwise, look it up in the table. */
1504 else
1505 index = add_call_site (GEN_INT (lp_info[i].dispatch_index), action);
1507 lp_info[i].call_site_index = index;
1511 static void
1512 sjlj_mark_call_sites (struct sjlj_lp_info *lp_info)
1514 int last_call_site = -2;
1515 rtx insn, mem;
1517 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
1519 struct eh_region *region;
1520 int this_call_site;
1521 rtx note, before, p;
1523 /* Reset value tracking at extended basic block boundaries. */
1524 if (LABEL_P (insn))
1525 last_call_site = -2;
1527 if (! INSN_P (insn))
1528 continue;
1530 note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1531 if (!note)
1533 /* Calls (and trapping insns) without notes are outside any
1534 exception handling region in this function. Mark them as
1535 no action. */
1536 if (CALL_P (insn)
1537 || (flag_non_call_exceptions
1538 && may_trap_p (PATTERN (insn))))
1539 this_call_site = -1;
1540 else
1541 continue;
1543 else
1545 /* Calls that are known to not throw need not be marked. */
1546 if (INTVAL (XEXP (note, 0)) <= 0)
1547 continue;
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)
1554 continue;
1556 /* Don't separate a call from it's argument loads. */
1557 before = insn;
1558 if (CALL_P (insn))
1559 before = find_first_parameter_load (insn, NULL_RTX);
1561 start_sequence ();
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));
1565 p = get_insns ();
1566 end_sequence ();
1568 emit_insn_before (p, before);
1569 last_call_site = this_call_site;
1573 /* Construct the SjLj_Function_Context. */
1575 static void
1576 sjlj_emit_function_enter (rtx dispatch_label)
1578 rtx fn_begin, fc, mem, seq;
1580 fc = cfun->eh->sjlj_fc;
1582 start_sequence ();
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)
1594 char buf[20];
1595 rtx sym;
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);
1602 else
1603 emit_move_insn (mem, const0_rtx);
1605 #ifdef DONT_USE_BUILTIN_SETJMP
1607 rtx x, note;
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);
1619 #else
1620 expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
1621 dispatch_label);
1622 #endif
1624 emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
1625 1, XEXP (fc, 0), Pmode);
1627 seq = get_insns ();
1628 end_sequence ();
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))
1638 break;
1639 if (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
1640 insert_insn_on_edge (seq, EDGE_SUCC (ENTRY_BLOCK_PTR, 0));
1641 else
1643 rtx last = BB_END (EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest);
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)
1648 break;
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. */
1656 void
1657 sjlj_emit_function_exit_after (rtx after)
1659 cfun->eh->sjlj_exit_after = after;
1662 static void
1663 sjlj_emit_function_exit (void)
1665 rtx seq;
1666 edge e;
1667 edge_iterator ei;
1669 start_sequence ();
1671 emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
1672 1, XEXP (cfun->eh->sjlj_fc, 0), Pmode);
1674 seq = get_insns ();
1675 end_sequence ();
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)
1683 break;
1684 if (e)
1686 rtx insn;
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)
1696 if (LABEL_P (insn))
1697 insn = NEXT_INSN (insn);
1698 emit_insn_after (seq, insn);
1699 return;
1701 if (insn == BB_END (e->src))
1702 break;
1704 insert_insn_on_edge (seq, e);
1708 static void
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;
1713 rtx before;
1714 basic_block bb;
1715 edge e;
1717 fc = cfun->eh->sjlj_fc;
1719 start_sequence ();
1721 emit_label (dispatch_label);
1723 #ifndef DONT_USE_BUILTIN_SETJMP
1724 expand_builtin_setjmp_receiver (dispatch_label);
1725 #endif
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);
1738 #else
1739 mem = convert_to_mode (ptr_mode, mem, 0);
1740 #endif
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)
1754 continue;
1756 if (! first_reachable)
1758 first_reachable = i;
1759 continue;
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);
1767 seq = get_insns ();
1768 end_sequence ();
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;
1778 static void
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 ();
1790 cfun->eh->sjlj_fc
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 ();
1803 free (lp_info);
1806 void
1807 finish_eh_generation (void)
1809 basic_block bb;
1811 /* Nothing to do if no regions created. */
1812 if (cfun->eh->region_tree == NULL)
1813 return;
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 ();
1836 else
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 ();
1846 FOR_EACH_BB (bb)
1848 edge e;
1849 edge_iterator ei;
1850 bool eh = false;
1851 for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
1853 if (e->flags & EDGE_EH)
1855 remove_edge (e);
1856 eh = true;
1858 else
1859 ei_next (&ei);
1861 if (eh)
1862 rtl_make_eh_edge (NULL, bb, BB_END (bb));
1866 static hashval_t
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;
1876 static int
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. */
1889 static void
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)
1897 return;
1899 tmp.label = label;
1900 slot = (struct ehl_map_entry **)
1901 htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
1902 gcc_assert (slot);
1904 htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot);
1907 /* Splice REGION from the region tree etc. */
1909 static void
1910 remove_eh_handler (struct eh_region *region)
1912 struct eh_region **pp, **pp_start, *p, *outer, *inner;
1913 rtx lab;
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;
1923 if (region->aka)
1925 unsigned i;
1926 bitmap_iterator bi;
1928 EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, bi)
1930 cfun->eh->region_array[i] = outer;
1934 if (outer)
1936 if (!outer->aka)
1937 outer->aka = BITMAP_GGC_ALLOC ();
1938 if (region->aka)
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;
1945 else
1946 lab = region->label;
1947 if (lab)
1948 remove_exception_handler_label (lab);
1950 if (outer)
1951 pp_start = &outer->inner;
1952 else
1953 pp_start = &cfun->eh->region_tree;
1954 for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
1955 continue;
1956 *pp = region->next_peer;
1958 inner = region->inner;
1959 if (inner)
1961 for (p = inner; p->next_peer ; p = p->next_peer)
1962 p->outer = outer;
1963 p->outer = outer;
1965 p->next_peer = *pp_start;
1966 *pp_start = inner;
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)
1976 continue;
1977 gcc_assert (try->type == ERT_TRY);
1979 next = region->u.catch.next_catch;
1980 prev = region->u.catch.prev_catch;
1982 if (next)
1983 next->u.catch.prev_catch = prev;
1984 else
1985 try->u.try.last_catch = prev;
1986 if (prev)
1987 prev->u.catch.next_catch = next;
1988 else
1990 try->u.try.catch = next;
1991 if (! 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. */
2001 void
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)
2012 return;
2014 tmp.label = label;
2015 slot = (struct ehl_map_entry **)
2016 htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
2017 if (! slot)
2018 return;
2019 region = (*slot)->region;
2020 if (! region)
2021 return;
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;
2032 else
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. */
2039 void
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);
2046 static int
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);
2053 return 1;
2056 /* Invoke CALLBACK for every exception region in the current function. */
2058 void
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];
2065 if (region)
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
2075 tree types_caught;
2076 tree types_allowed;
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)
2088 tree t;
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)
2095 return 1;
2097 else
2099 for (t = handled; t ; t = TREE_CHAIN (t))
2100 if ((*lang_eh_type_covers) (TREE_VALUE (t), type))
2101 return 1;
2104 return 0;
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. */
2115 static void
2116 add_reachable_handler (struct reachable_info *info,
2117 struct eh_region *lp_region, struct eh_region *region)
2119 if (! info)
2120 return;
2122 info->saw_any_handlers = true;
2124 if (cfun->eh->built_landing_pads)
2125 info->callback (lp_region, info->callback_data);
2126 else
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)
2141 case ERT_CLEANUP:
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;
2148 case ERT_TRY:
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);
2159 return RNL_CAUGHT;
2162 if (type_thrown)
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);
2176 return RNL_CAUGHT;
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. */
2199 if (! info)
2200 ret = RNL_MAYBE_CAUGHT;
2201 else
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))
2214 info->types_caught
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;
2232 return ret;
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);
2240 return RNL_CAUGHT;
2243 /* Collect a list of lists of allowed types for use in detecting
2244 when a catch may be transformed into a catch-all. */
2245 if (info)
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
2252 filter. */
2253 if (type_thrown && lang_eh_type_covers)
2255 if (check_handled (region->u.allowed.type_list, type_thrown))
2256 return RNL_NOT_CAUGHT;
2257 else
2259 add_reachable_handler (info, region, region);
2260 return RNL_CAUGHT;
2264 add_reachable_handler (info, region, region);
2265 return RNL_MAYBE_CAUGHT;
2267 case ERT_CATCH:
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);
2279 return RNL_CAUGHT;
2281 else
2282 return RNL_BLOCKED;
2284 case ERT_THROW:
2285 case ERT_FIXUP:
2286 case ERT_UNKNOWN:
2287 /* Shouldn't see these here. */
2288 gcc_unreachable ();
2289 break;
2290 default:
2291 gcc_unreachable ();
2295 /* Invoke CALLBACK on each region reachable from REGION_NUMBER. */
2297 void
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;
2304 tree type_thrown;
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;
2313 if (is_resx)
2315 /* A RESX leaves a region instead of entering it. Thus the
2316 region itself may have been deleted out from under us. */
2317 if (region == NULL)
2318 return;
2319 region = region->outer;
2321 else if (region->type == ERT_THROW)
2323 type_thrown = region->u.throw.type;
2324 region = region->outer;
2327 while (region)
2329 if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
2330 break;
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
2334 accurate. */
2335 if (region->type == ERT_CLEANUP)
2336 region = region->u.cleanup.prev_try;
2337 else
2338 region = region->outer;
2342 /* Retrieve a list of labels of exception handlers which can be
2343 reached by a given insn. */
2345 static void
2346 arh_to_landing_pad (struct eh_region *region, void *data)
2348 rtx *p_handlers = data;
2349 if (! *p_handlers)
2350 *p_handlers = alloc_INSN_LIST (region->landing_pad, NULL_RTX);
2353 static void
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;
2365 int region_number;
2367 if (JUMP_P (insn)
2368 && GET_CODE (PATTERN (insn)) == RESX)
2370 region_number = XINT (PATTERN (insn), 0);
2371 is_resx = true;
2373 else
2375 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2376 if (!note || INTVAL (XEXP (note, 0)) <= 0)
2377 return NULL;
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
2384 : arh_to_label),
2385 &handlers);
2387 return handlers;
2390 /* Determine if the given INSN can throw an exception that is caught
2391 within the function. */
2393 bool
2394 can_throw_internal_1 (int region_number)
2396 struct eh_region *region;
2397 tree type_thrown;
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)
2415 return false;
2416 if (how != RNL_NOT_CAUGHT)
2417 return true;
2420 return false;
2423 bool
2424 can_throw_internal (rtx insn)
2426 rtx note;
2428 if (! INSN_P (insn))
2429 return false;
2431 if (JUMP_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)
2443 return false;
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. */
2451 bool
2452 can_throw_external_1 (int region_number)
2454 struct eh_region *region;
2455 tree type_thrown;
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)
2470 return false;
2472 return true;
2475 bool
2476 can_throw_external (rtx insn)
2478 rtx note;
2480 if (! INSN_P (insn))
2481 return false;
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);
2488 if (!note)
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
2494 inaccurate. */
2495 return (CALL_P (insn)
2496 || (flag_non_call_exceptions
2497 && may_trap_p (PATTERN (insn))));
2499 if (INTVAL (XEXP (note, 0)) <= 0)
2500 return false;
2502 return can_throw_external_1 (INTVAL (XEXP (note, 0)));
2505 /* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */
2507 void
2508 set_nothrow_function_flags (void)
2510 rtx insn;
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
2518 is optimistic. */
2520 cfun->all_throwers_are_sibcalls = 1;
2522 if (! flag_exceptions)
2523 return;
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;
2533 return;
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;
2546 return;
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. */
2557 void
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 ();
2566 #endif
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");
2578 return constm1_rtx;
2581 iwhich = tree_low_cst (which, 1);
2582 iwhich = EH_RETURN_DATA_REGNO (iwhich);
2583 if (iwhich == INVALID_REGNUM)
2584 return constm1_rtx;
2586 #ifdef DWARF_FRAME_REGNUM
2587 iwhich = DWARF_FRAME_REGNUM (iwhich);
2588 #else
2589 iwhich = DBX_REGISTER_NUMBER (iwhich);
2590 #endif
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);
2608 #else
2609 addr = convert_to_mode (Pmode, addr, 0);
2610 #endif
2613 /* First mask out any unwanted bits. */
2614 #ifdef MASK_RETURN_ADDR
2615 expand_and (Pmode, addr, MASK_RETURN_ADDR, addr);
2616 #endif
2618 /* Then adjust to find the real return address. */
2619 #if defined (RETURN_ADDR_OFFSET)
2620 addr = plus_constant (addr, RETURN_ADDR_OFFSET);
2621 #endif
2623 return addr;
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);
2640 #endif
2642 return addr;
2645 /* Set up the epilogue with the magic bits we'll need to return to the
2646 exception handler. */
2648 void
2649 expand_builtin_eh_return (tree stackadj_tree ATTRIBUTE_UNUSED,
2650 tree handler_tree)
2652 rtx tmp;
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);
2661 #endif
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);
2675 void
2676 expand_eh_return (void)
2678 rtx around_label;
2680 if (! cfun->eh->ehr_label)
2681 return;
2683 current_function_calls_eh_return = 1;
2685 #ifdef EH_RETURN_STACKADJ_RTX
2686 emit_move_insn (EH_RETURN_STACKADJ_RTX, const0_rtx);
2687 #endif
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);
2697 #endif
2699 #ifdef HAVE_eh_return
2700 if (HAVE_eh_return)
2701 emit_insn (gen_eh_return (cfun->eh->ehr_handler));
2702 else
2703 #endif
2705 #ifdef EH_RETURN_HANDLER_RTX
2706 emit_move_insn (EH_RETURN_HANDLER_RTX, cfun->eh->ehr_handler);
2707 #else
2708 error ("__builtin_eh_return not supported on this target");
2709 #endif
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);
2722 int extend;
2724 #ifdef POINTERS_EXTEND_UNSIGNED
2725 extend = POINTERS_EXTEND_UNSIGNED;
2726 #else
2727 /* The previous EH code did an unsigned extend by default, so we do this also
2728 for consistency. */
2729 extend = 1;
2730 #endif
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
2748 int offset;
2749 int filter;
2750 int next;
2753 static int
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;
2761 static hashval_t
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;
2768 static int
2769 add_action_record (htab_t ar_hash, int filter, int next)
2771 struct action_record **slot, *new, tmp;
2773 tmp.filter = filter;
2774 tmp.next = next;
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;
2782 new->next = next;
2783 *slot = new;
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);
2791 if (next)
2792 next -= VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
2793 push_sleb128 (&cfun->eh->action_record_data, next);
2796 return new->offset;
2799 static int
2800 collect_one_action_chain (htab_t ar_hash, struct eh_region *region)
2802 struct eh_region *c;
2803 int next;
2805 /* If we've reached the top of the region chain, then we have
2806 no actions, and require no landing pad. */
2807 if (region == NULL)
2808 return -1;
2810 switch (region->type)
2812 case ERT_CLEANUP:
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);
2820 if (next <= 0)
2821 return 0;
2822 for (c = region->outer; c ; c = c->outer)
2823 if (c->type == ERT_CLEANUP)
2824 return next;
2825 return add_action_record (ar_hash, 0, next);
2827 case ERT_TRY:
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. */
2832 next = -3;
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). */
2839 int filter
2840 = TREE_INT_CST_LOW (TREE_VALUE (c->u.catch.filter_list));
2842 next = add_action_record (ar_hash, filter, 0);
2844 else
2846 /* Once the outer search is done, trigger an action record for
2847 each filter we have. */
2848 tree flt_node;
2850 if (next == -3)
2852 next = collect_one_action_chain (ar_hash, region->outer);
2854 /* If there is no next action, terminate the chain. */
2855 if (next == -1)
2856 next = 0;
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. */
2861 else if (next <= 0)
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);
2873 return 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. */
2881 if (next == -1)
2882 next = 0;
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. */
2887 else if (next <= 0)
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. */
2897 return -2;
2899 case ERT_CATCH:
2900 case ERT_THROW:
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);
2905 default:
2906 gcc_unreachable ();
2910 static int
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;
2917 if (used >= 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. */
2937 void
2938 convert_to_eh_region_ranges (void)
2940 rtx insn, iter, note;
2941 htab_t ar_hash;
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;
2946 int call_site = 0;
2948 if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL)
2949 return;
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))
2956 if (INSN_P (iter))
2958 struct eh_region *region;
2959 int this_action;
2960 rtx this_landing_pad;
2962 insn = iter;
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);
2968 if (!note)
2970 if (! (CALL_P (insn)
2971 || (flag_non_call_exceptions
2972 && may_trap_p (PATTERN (insn)))))
2973 continue;
2974 this_action = -1;
2975 region = NULL;
2977 else
2979 if (INTVAL (XEXP (note, 0)) <= 0)
2980 continue;
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;
2995 last_action = -1;
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)
3004 continue;
3005 this_landing_pad = o->landing_pad;
3007 else
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
3017 end note. */
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,
3031 last_action_insn);
3032 NOTE_EH_HANDLER (note) = call_site;
3035 /* If the new action is must-not-throw, then no region notes
3036 are created. */
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);
3061 static void
3062 push_uleb128 (varray_type *data_area, unsigned int value)
3066 unsigned char byte = value & 0x7f;
3067 value >>= 7;
3068 if (value)
3069 byte |= 0x80;
3070 VARRAY_PUSH_UCHAR (*data_area, byte);
3072 while (value);
3075 static void
3076 push_sleb128 (varray_type *data_area, int value)
3078 unsigned char byte;
3079 int more;
3083 byte = value & 0x7f;
3084 value >>= 7;
3085 more = ! ((value == 0 && (byte & 0x40) == 0)
3086 || (value == -1 && (byte & 0x40) != 0));
3087 if (more)
3088 byte |= 0x80;
3089 VARRAY_PUSH_UCHAR (*data_area, byte);
3091 while (more);
3095 #ifndef HAVE_AS_LEB128
3096 static int
3097 dw2_size_of_call_site_table (void)
3099 int n = cfun->eh->call_site_data_used;
3100 int size = n * (4 + 4 + 4);
3101 int i;
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);
3109 return size;
3112 static int
3113 sjlj_size_of_call_site_table (void)
3115 int n = cfun->eh->call_site_data_used;
3116 int size = 0;
3117 int i;
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);
3126 return size;
3128 #endif
3130 static void
3131 dw2_output_call_site_table (void)
3133 int n = cfun->eh->call_site_data_used;
3134 int i;
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,
3159 "length");
3160 if (cs->landing_pad)
3161 dw2_asm_output_delta_uleb128 (landing_pad_lab,
3162 current_function_func_begin_label,
3163 "landing pad");
3164 else
3165 dw2_asm_output_data_uleb128 (0, "landing pad");
3166 #else
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,
3174 "landing pad");
3175 else
3176 dw2_asm_output_data (4, 0, "landing pad");
3177 #endif
3178 dw2_asm_output_data_uleb128 (cs->action, "action");
3181 call_site_base += n;
3184 static void
3185 sjlj_output_call_site_table (void)
3187 int n = cfun->eh->call_site_data_used;
3188 int i;
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
3203 table. */
3205 void
3206 default_exception_section (void)
3208 if (targetm.have_named_sections)
3210 int flags;
3212 if (EH_TABLES_CAN_BE_READ_ONLY)
3214 int tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3216 flags = (! flag_pic
3217 || ((tt_format & 0x70) != DW_EH_PE_absptr
3218 && (tt_format & 0x70) != DW_EH_PE_aligned))
3219 ? 0 : SECTION_WRITE;
3221 else
3222 flags = SECTION_WRITE;
3223 named_section_flags (".gcc_except_table", flags);
3225 else if (flag_pic)
3226 data_section ();
3227 else
3228 readonly_data_section ();
3231 void
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];
3239 #else
3240 int call_site_len;
3241 #endif
3242 int have_tt_data;
3243 int tt_format_size = 0;
3245 /* Not all functions need anything. */
3246 if (! cfun->uses_eh_lsda)
3247 return;
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. */
3257 #else
3258 targetm.asm_out.exception_section ();
3259 #endif
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. */
3265 if (! have_tt_data)
3266 tt_format = DW_EH_PE_omit;
3267 else
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);
3273 #endif
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 ();
3302 else
3303 call_site_len = dw2_size_of_call_site_table ();
3304 #endif
3306 /* A pc-relative 4-byte displacement to the @TType data. */
3307 if (have_tt_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);
3316 #else
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)
3322 + call_site_len
3323 + VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data)
3324 + (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data)
3325 * tt_format_size));
3327 disp = after_disp;
3330 unsigned int disp_size, pad;
3332 last_disp = disp;
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);
3337 else
3338 pad = 0;
3339 disp = after_disp + pad;
3341 while (disp != last_disp);
3343 dw2_asm_output_data_uleb128 (disp, "@TType base offset");
3344 #endif
3347 /* Indicate the format of the call-site offsets. */
3348 #ifdef HAVE_AS_LEB128
3349 cs_format = DW_EH_PE_uleb128;
3350 #else
3351 cs_format = DW_EH_PE_udata4;
3352 #endif
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 ();
3366 else
3367 dw2_output_call_site_table ();
3368 ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
3369 #else
3370 dw2_asm_output_data_uleb128 (call_site_len,"Call-site table length");
3371 if (USING_SJLJ_EXCEPTIONS)
3372 sjlj_output_call_site_table ();
3373 else
3374 dw2_output_call_site_table ();
3375 #endif
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"));
3383 if (have_tt_data)
3384 assemble_align (tt_format_size * BITS_PER_UNIT);
3386 i = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data);
3387 while (i-- > 0)
3389 tree type = VARRAY_TREE (cfun->eh->ttype_data, i);
3390 rtx value;
3392 if (type == NULL_TREE)
3393 value = const0_rtx;
3394 else
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. */
3404 STRIP_NOPS (type);
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);
3411 if (node)
3412 cgraph_varpool_mark_needed_node (node);
3415 else
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);
3422 else
3423 dw2_asm_output_encoded_addr_rtx (tt_format, value, NULL);
3426 #ifdef HAVE_AS_LEB128
3427 if (have_tt_data)
3428 ASM_OUTPUT_LABEL (asm_out_file, ttype_label);
3429 #endif
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 function_section (current_function_decl);
3440 #include "gt-except.h"