cfganal.c (set_edge_can_fallthru_flag): Clear the EDGE_CAN_FALLTHRU flag before setti...
[gcc.git] / gcc / except.c
1 /* Implements exception handling.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 Contributed by Mike Stump <mrs@cygnus.com>.
5
6 This file is part of GCC.
7
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.
12
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.
17
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. */
22
23
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.
29
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.
39
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.
46
47 [ Add updated documentation on how to use this. ] */
48
49
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
77 /* Provide defaults for stuff that may not be defined when using
78 sjlj exceptions. */
79 #ifndef EH_RETURN_STACKADJ_RTX
80 #define EH_RETURN_STACKADJ_RTX 0
81 #endif
82 #ifndef EH_RETURN_HANDLER_RTX
83 #define EH_RETURN_HANDLER_RTX 0
84 #endif
85 #ifndef EH_RETURN_DATA_REGNO
86 #define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM
87 #endif
88
89
90 /* Nonzero means enable synchronous exceptions for non-call instructions. */
91 int flag_non_call_exceptions;
92
93 /* Protect cleanup actions with must-not-throw regions, with a call
94 to the given failure handler. */
95 tree (*lang_protect_cleanup_actions) PARAMS ((void));
96
97 /* Return true if type A catches type B. */
98 int (*lang_eh_type_covers) PARAMS ((tree a, tree b));
99
100 /* Map a type to a runtime object to match type. */
101 tree (*lang_eh_runtime_type) PARAMS ((tree));
102
103 /* A hash table of label to region number. */
104
105 struct ehl_map_entry GTY(())
106 {
107 rtx label;
108 struct eh_region *region;
109 };
110
111 static int call_site_base;
112 static GTY ((param_is (union tree_node)))
113 htab_t type_to_runtime_map;
114
115 /* Describe the SjLj_Function_Context structure. */
116 static GTY(()) tree sjlj_fc_type_node;
117 static int sjlj_fc_call_site_ofs;
118 static int sjlj_fc_data_ofs;
119 static int sjlj_fc_personality_ofs;
120 static int sjlj_fc_lsda_ofs;
121 static int sjlj_fc_jbuf_ofs;
122 \f
123 /* Describes one exception region. */
124 struct eh_region GTY(())
125 {
126 /* The immediately surrounding region. */
127 struct eh_region *outer;
128
129 /* The list of immediately contained regions. */
130 struct eh_region *inner;
131 struct eh_region *next_peer;
132
133 /* An identifier for this region. */
134 int region_number;
135
136 /* When a region is deleted, its parents inherit the REG_EH_REGION
137 numbers already assigned. */
138 bitmap aka;
139
140 /* Each region does exactly one thing. */
141 enum eh_region_type
142 {
143 ERT_UNKNOWN = 0,
144 ERT_CLEANUP,
145 ERT_TRY,
146 ERT_CATCH,
147 ERT_ALLOWED_EXCEPTIONS,
148 ERT_MUST_NOT_THROW,
149 ERT_THROW,
150 ERT_FIXUP
151 } type;
152
153 /* Holds the action to perform based on the preceding type. */
154 union eh_region_u {
155 /* A list of catch blocks, a surrounding try block,
156 and the label for continuing after a catch. */
157 struct eh_region_u_try {
158 struct eh_region *catch;
159 struct eh_region *last_catch;
160 struct eh_region *prev_try;
161 rtx continue_label;
162 } GTY ((tag ("ERT_TRY"))) try;
163
164 /* The list through the catch handlers, the list of type objects
165 matched, and the list of associated filters. */
166 struct eh_region_u_catch {
167 struct eh_region *next_catch;
168 struct eh_region *prev_catch;
169 tree type_list;
170 tree filter_list;
171 } GTY ((tag ("ERT_CATCH"))) catch;
172
173 /* A tree_list of allowed types. */
174 struct eh_region_u_allowed {
175 tree type_list;
176 int filter;
177 } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
178
179 /* The type given by a call to "throw foo();", or discovered
180 for a throw. */
181 struct eh_region_u_throw {
182 tree type;
183 } GTY ((tag ("ERT_THROW"))) throw;
184
185 /* Retain the cleanup expression even after expansion so that
186 we can match up fixup regions. */
187 struct eh_region_u_cleanup {
188 tree exp;
189 } GTY ((tag ("ERT_CLEANUP"))) cleanup;
190
191 /* The real region (by expression and by pointer) that fixup code
192 should live in. */
193 struct eh_region_u_fixup {
194 tree cleanup_exp;
195 struct eh_region *real_region;
196 } GTY ((tag ("ERT_FIXUP"))) fixup;
197 } GTY ((desc ("%0.type"))) u;
198
199 /* Entry point for this region's handler before landing pads are built. */
200 rtx label;
201
202 /* Entry point for this region's handler from the runtime eh library. */
203 rtx landing_pad;
204
205 /* Entry point for this region's handler from an inner region. */
206 rtx post_landing_pad;
207
208 /* The RESX insn for handing off control to the next outermost handler,
209 if appropriate. */
210 rtx resume;
211 };
212
213 struct call_site_record GTY(())
214 {
215 rtx landing_pad;
216 int action;
217 };
218
219 /* Used to save exception status for each function. */
220 struct eh_status GTY(())
221 {
222 /* The tree of all regions for this function. */
223 struct eh_region *region_tree;
224
225 /* The same information as an indexable array. */
226 struct eh_region ** GTY ((length ("%h.last_region_number"))) region_array;
227
228 /* The most recently open region. */
229 struct eh_region *cur_region;
230
231 /* This is the region for which we are processing catch blocks. */
232 struct eh_region *try_region;
233
234 rtx filter;
235 rtx exc_ptr;
236
237 int built_landing_pads;
238 int last_region_number;
239
240 varray_type ttype_data;
241 varray_type ehspec_data;
242 varray_type action_record_data;
243
244 htab_t GTY ((param_is (struct ehl_map_entry))) exception_handler_label_map;
245
246 struct call_site_record * GTY ((length ("%h.call_site_data_used")))
247 call_site_data;
248 int call_site_data_used;
249 int call_site_data_size;
250
251 rtx ehr_stackadj;
252 rtx ehr_handler;
253 rtx ehr_label;
254
255 rtx sjlj_fc;
256 rtx sjlj_exit_after;
257 };
258
259 \f
260 static int t2r_eq PARAMS ((const PTR,
261 const PTR));
262 static hashval_t t2r_hash PARAMS ((const PTR));
263 static void add_type_for_runtime PARAMS ((tree));
264 static tree lookup_type_for_runtime PARAMS ((tree));
265
266 static struct eh_region *expand_eh_region_end PARAMS ((void));
267
268 static rtx get_exception_filter PARAMS ((struct function *));
269
270 static void collect_eh_region_array PARAMS ((void));
271 static void resolve_fixup_regions PARAMS ((void));
272 static void remove_fixup_regions PARAMS ((void));
273 static void remove_unreachable_regions PARAMS ((rtx));
274 static void convert_from_eh_region_ranges_1 PARAMS ((rtx *, int *, int));
275
276 static struct eh_region *duplicate_eh_region_1 PARAMS ((struct eh_region *,
277 struct inline_remap *));
278 static void duplicate_eh_region_2 PARAMS ((struct eh_region *,
279 struct eh_region **));
280 static int ttypes_filter_eq PARAMS ((const PTR,
281 const PTR));
282 static hashval_t ttypes_filter_hash PARAMS ((const PTR));
283 static int ehspec_filter_eq PARAMS ((const PTR,
284 const PTR));
285 static hashval_t ehspec_filter_hash PARAMS ((const PTR));
286 static int add_ttypes_entry PARAMS ((htab_t, tree));
287 static int add_ehspec_entry PARAMS ((htab_t, htab_t,
288 tree));
289 static void assign_filter_values PARAMS ((void));
290 static void build_post_landing_pads PARAMS ((void));
291 static void connect_post_landing_pads PARAMS ((void));
292 static void dw2_build_landing_pads PARAMS ((void));
293
294 struct sjlj_lp_info;
295 static bool sjlj_find_directly_reachable_regions
296 PARAMS ((struct sjlj_lp_info *));
297 static void sjlj_assign_call_site_values
298 PARAMS ((rtx, struct sjlj_lp_info *));
299 static void sjlj_mark_call_sites
300 PARAMS ((struct sjlj_lp_info *));
301 static void sjlj_emit_function_enter PARAMS ((rtx));
302 static void sjlj_emit_function_exit PARAMS ((void));
303 static void sjlj_emit_dispatch_table
304 PARAMS ((rtx, struct sjlj_lp_info *));
305 static void sjlj_build_landing_pads PARAMS ((void));
306
307 static hashval_t ehl_hash PARAMS ((const PTR));
308 static int ehl_eq PARAMS ((const PTR,
309 const PTR));
310 static void add_ehl_entry PARAMS ((rtx,
311 struct eh_region *));
312 static void remove_exception_handler_label PARAMS ((rtx));
313 static void remove_eh_handler PARAMS ((struct eh_region *));
314 static int for_each_eh_label_1 PARAMS ((PTR *, PTR));
315
316 struct reachable_info;
317
318 /* The return value of reachable_next_level. */
319 enum reachable_code
320 {
321 /* The given exception is not processed by the given region. */
322 RNL_NOT_CAUGHT,
323 /* The given exception may need processing by the given region. */
324 RNL_MAYBE_CAUGHT,
325 /* The given exception is completely processed by the given region. */
326 RNL_CAUGHT,
327 /* The given exception is completely processed by the runtime. */
328 RNL_BLOCKED
329 };
330
331 static int check_handled PARAMS ((tree, tree));
332 static void add_reachable_handler
333 PARAMS ((struct reachable_info *, struct eh_region *,
334 struct eh_region *));
335 static enum reachable_code reachable_next_level
336 PARAMS ((struct eh_region *, tree, struct reachable_info *));
337
338 static int action_record_eq PARAMS ((const PTR,
339 const PTR));
340 static hashval_t action_record_hash PARAMS ((const PTR));
341 static int add_action_record PARAMS ((htab_t, int, int));
342 static int collect_one_action_chain PARAMS ((htab_t,
343 struct eh_region *));
344 static int add_call_site PARAMS ((rtx, int));
345
346 static void push_uleb128 PARAMS ((varray_type *,
347 unsigned int));
348 static void push_sleb128 PARAMS ((varray_type *, int));
349 #ifndef HAVE_AS_LEB128
350 static int dw2_size_of_call_site_table PARAMS ((void));
351 static int sjlj_size_of_call_site_table PARAMS ((void));
352 #endif
353 static void dw2_output_call_site_table PARAMS ((void));
354 static void sjlj_output_call_site_table PARAMS ((void));
355
356 \f
357 /* Routine to see if exception handling is turned on.
358 DO_WARN is nonzero if we want to inform the user that exception
359 handling is turned off.
360
361 This is used to ensure that -fexceptions has been specified if the
362 compiler tries to use any exception-specific functions. */
363
364 int
365 doing_eh (do_warn)
366 int do_warn;
367 {
368 if (! flag_exceptions)
369 {
370 static int warned = 0;
371 if (! warned && do_warn)
372 {
373 error ("exception handling disabled, use -fexceptions to enable");
374 warned = 1;
375 }
376 return 0;
377 }
378 return 1;
379 }
380
381 \f
382 void
383 init_eh ()
384 {
385 if (! flag_exceptions)
386 return;
387
388 type_to_runtime_map = htab_create_ggc (31, t2r_hash, t2r_eq, NULL);
389
390 /* Create the SjLj_Function_Context structure. This should match
391 the definition in unwind-sjlj.c. */
392 if (USING_SJLJ_EXCEPTIONS)
393 {
394 tree f_jbuf, f_per, f_lsda, f_prev, f_cs, f_data, tmp;
395
396 sjlj_fc_type_node = (*lang_hooks.types.make_type) (RECORD_TYPE);
397
398 f_prev = build_decl (FIELD_DECL, get_identifier ("__prev"),
399 build_pointer_type (sjlj_fc_type_node));
400 DECL_FIELD_CONTEXT (f_prev) = sjlj_fc_type_node;
401
402 f_cs = build_decl (FIELD_DECL, get_identifier ("__call_site"),
403 integer_type_node);
404 DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
405
406 tmp = build_index_type (build_int_2 (4 - 1, 0));
407 tmp = build_array_type ((*lang_hooks.types.type_for_mode) (word_mode, 1),
408 tmp);
409 f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp);
410 DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node;
411
412 f_per = build_decl (FIELD_DECL, get_identifier ("__personality"),
413 ptr_type_node);
414 DECL_FIELD_CONTEXT (f_per) = sjlj_fc_type_node;
415
416 f_lsda = build_decl (FIELD_DECL, get_identifier ("__lsda"),
417 ptr_type_node);
418 DECL_FIELD_CONTEXT (f_lsda) = sjlj_fc_type_node;
419
420 #ifdef DONT_USE_BUILTIN_SETJMP
421 #ifdef JMP_BUF_SIZE
422 tmp = build_int_2 (JMP_BUF_SIZE - 1, 0);
423 #else
424 /* Should be large enough for most systems, if it is not,
425 JMP_BUF_SIZE should be defined with the proper value. It will
426 also tend to be larger than necessary for most systems, a more
427 optimal port will define JMP_BUF_SIZE. */
428 tmp = build_int_2 (FIRST_PSEUDO_REGISTER + 2 - 1, 0);
429 #endif
430 #else
431 /* This is 2 for builtin_setjmp, plus whatever the target requires
432 via STACK_SAVEAREA_MODE (SAVE_NONLOCAL). */
433 tmp = build_int_2 ((GET_MODE_SIZE (STACK_SAVEAREA_MODE (SAVE_NONLOCAL))
434 / GET_MODE_SIZE (Pmode)) + 2 - 1, 0);
435 #endif
436 tmp = build_index_type (tmp);
437 tmp = build_array_type (ptr_type_node, tmp);
438 f_jbuf = build_decl (FIELD_DECL, get_identifier ("__jbuf"), tmp);
439 #ifdef DONT_USE_BUILTIN_SETJMP
440 /* We don't know what the alignment requirements of the
441 runtime's jmp_buf has. Overestimate. */
442 DECL_ALIGN (f_jbuf) = BIGGEST_ALIGNMENT;
443 DECL_USER_ALIGN (f_jbuf) = 1;
444 #endif
445 DECL_FIELD_CONTEXT (f_jbuf) = sjlj_fc_type_node;
446
447 TYPE_FIELDS (sjlj_fc_type_node) = f_prev;
448 TREE_CHAIN (f_prev) = f_cs;
449 TREE_CHAIN (f_cs) = f_data;
450 TREE_CHAIN (f_data) = f_per;
451 TREE_CHAIN (f_per) = f_lsda;
452 TREE_CHAIN (f_lsda) = f_jbuf;
453
454 layout_type (sjlj_fc_type_node);
455
456 /* Cache the interesting field offsets so that we have
457 easy access from rtl. */
458 sjlj_fc_call_site_ofs
459 = (tree_low_cst (DECL_FIELD_OFFSET (f_cs), 1)
460 + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_cs), 1) / BITS_PER_UNIT);
461 sjlj_fc_data_ofs
462 = (tree_low_cst (DECL_FIELD_OFFSET (f_data), 1)
463 + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_data), 1) / BITS_PER_UNIT);
464 sjlj_fc_personality_ofs
465 = (tree_low_cst (DECL_FIELD_OFFSET (f_per), 1)
466 + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_per), 1) / BITS_PER_UNIT);
467 sjlj_fc_lsda_ofs
468 = (tree_low_cst (DECL_FIELD_OFFSET (f_lsda), 1)
469 + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_lsda), 1) / BITS_PER_UNIT);
470 sjlj_fc_jbuf_ofs
471 = (tree_low_cst (DECL_FIELD_OFFSET (f_jbuf), 1)
472 + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_jbuf), 1) / BITS_PER_UNIT);
473 }
474 }
475
476 void
477 init_eh_for_function ()
478 {
479 cfun->eh = (struct eh_status *)
480 ggc_alloc_cleared (sizeof (struct eh_status));
481 }
482 \f
483 /* Start an exception handling region. All instructions emitted
484 after this point are considered to be part of the region until
485 expand_eh_region_end is invoked. */
486
487 void
488 expand_eh_region_start ()
489 {
490 struct eh_region *new_region;
491 struct eh_region *cur_region;
492 rtx note;
493
494 if (! doing_eh (0))
495 return;
496
497 /* Insert a new blank region as a leaf in the tree. */
498 new_region = (struct eh_region *) ggc_alloc_cleared (sizeof (*new_region));
499 cur_region = cfun->eh->cur_region;
500 new_region->outer = cur_region;
501 if (cur_region)
502 {
503 new_region->next_peer = cur_region->inner;
504 cur_region->inner = new_region;
505 }
506 else
507 {
508 new_region->next_peer = cfun->eh->region_tree;
509 cfun->eh->region_tree = new_region;
510 }
511 cfun->eh->cur_region = new_region;
512
513 /* Create a note marking the start of this region. */
514 new_region->region_number = ++cfun->eh->last_region_number;
515 note = emit_note (NULL, NOTE_INSN_EH_REGION_BEG);
516 NOTE_EH_HANDLER (note) = new_region->region_number;
517 }
518
519 /* Common code to end a region. Returns the region just ended. */
520
521 static struct eh_region *
522 expand_eh_region_end ()
523 {
524 struct eh_region *cur_region = cfun->eh->cur_region;
525 rtx note;
526
527 /* Create a note marking the end of this region. */
528 note = emit_note (NULL, NOTE_INSN_EH_REGION_END);
529 NOTE_EH_HANDLER (note) = cur_region->region_number;
530
531 /* Pop. */
532 cfun->eh->cur_region = cur_region->outer;
533
534 return cur_region;
535 }
536
537 /* End an exception handling region for a cleanup. HANDLER is an
538 expression to expand for the cleanup. */
539
540 void
541 expand_eh_region_end_cleanup (handler)
542 tree handler;
543 {
544 struct eh_region *region;
545 tree protect_cleanup_actions;
546 rtx around_label;
547 rtx data_save[2];
548
549 if (! doing_eh (0))
550 return;
551
552 region = expand_eh_region_end ();
553 region->type = ERT_CLEANUP;
554 region->label = gen_label_rtx ();
555 region->u.cleanup.exp = handler;
556
557 around_label = gen_label_rtx ();
558 emit_jump (around_label);
559
560 emit_label (region->label);
561
562 /* Give the language a chance to specify an action to be taken if an
563 exception is thrown that would propagate out of the HANDLER. */
564 protect_cleanup_actions
565 = (lang_protect_cleanup_actions
566 ? (*lang_protect_cleanup_actions) ()
567 : NULL_TREE);
568
569 if (protect_cleanup_actions)
570 expand_eh_region_start ();
571
572 /* In case this cleanup involves an inline destructor with a try block in
573 it, we need to save the EH return data registers around it. */
574 data_save[0] = gen_reg_rtx (ptr_mode);
575 emit_move_insn (data_save[0], get_exception_pointer (cfun));
576 data_save[1] = gen_reg_rtx (word_mode);
577 emit_move_insn (data_save[1], get_exception_filter (cfun));
578
579 expand_expr (handler, const0_rtx, VOIDmode, 0);
580
581 emit_move_insn (cfun->eh->exc_ptr, data_save[0]);
582 emit_move_insn (cfun->eh->filter, data_save[1]);
583
584 if (protect_cleanup_actions)
585 expand_eh_region_end_must_not_throw (protect_cleanup_actions);
586
587 /* We need any stack adjustment complete before the around_label. */
588 do_pending_stack_adjust ();
589
590 /* We delay the generation of the _Unwind_Resume until we generate
591 landing pads. We emit a marker here so as to get good control
592 flow data in the meantime. */
593 region->resume
594 = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
595 emit_barrier ();
596
597 emit_label (around_label);
598 }
599
600 /* End an exception handling region for a try block, and prepares
601 for subsequent calls to expand_start_catch. */
602
603 void
604 expand_start_all_catch ()
605 {
606 struct eh_region *region;
607
608 if (! doing_eh (1))
609 return;
610
611 region = expand_eh_region_end ();
612 region->type = ERT_TRY;
613 region->u.try.prev_try = cfun->eh->try_region;
614 region->u.try.continue_label = gen_label_rtx ();
615
616 cfun->eh->try_region = region;
617
618 emit_jump (region->u.try.continue_label);
619 }
620
621 /* Begin a catch clause. TYPE is the type caught, a list of such types, or
622 null if this is a catch-all clause. Providing a type list enables to
623 associate the catch region with potentially several exception types, which
624 is useful e.g. for Ada. */
625
626 void
627 expand_start_catch (type_or_list)
628 tree type_or_list;
629 {
630 struct eh_region *t, *c, *l;
631 tree type_list;
632
633 if (! doing_eh (0))
634 return;
635
636 type_list = type_or_list;
637
638 if (type_or_list)
639 {
640 /* Ensure to always end up with a type list to normalize further
641 processing, then register each type against the runtime types
642 map. */
643 tree type_node;
644
645 if (TREE_CODE (type_or_list) != TREE_LIST)
646 type_list = tree_cons (NULL_TREE, type_or_list, NULL_TREE);
647
648 type_node = type_list;
649 for (; type_node; type_node = TREE_CHAIN (type_node))
650 add_type_for_runtime (TREE_VALUE (type_node));
651 }
652
653 expand_eh_region_start ();
654
655 t = cfun->eh->try_region;
656 c = cfun->eh->cur_region;
657 c->type = ERT_CATCH;
658 c->u.catch.type_list = type_list;
659 c->label = gen_label_rtx ();
660
661 l = t->u.try.last_catch;
662 c->u.catch.prev_catch = l;
663 if (l)
664 l->u.catch.next_catch = c;
665 else
666 t->u.try.catch = c;
667 t->u.try.last_catch = c;
668
669 emit_label (c->label);
670 }
671
672 /* End a catch clause. Control will resume after the try/catch block. */
673
674 void
675 expand_end_catch ()
676 {
677 struct eh_region *try_region;
678
679 if (! doing_eh (0))
680 return;
681
682 expand_eh_region_end ();
683 try_region = cfun->eh->try_region;
684
685 emit_jump (try_region->u.try.continue_label);
686 }
687
688 /* End a sequence of catch handlers for a try block. */
689
690 void
691 expand_end_all_catch ()
692 {
693 struct eh_region *try_region;
694
695 if (! doing_eh (0))
696 return;
697
698 try_region = cfun->eh->try_region;
699 cfun->eh->try_region = try_region->u.try.prev_try;
700
701 emit_label (try_region->u.try.continue_label);
702 }
703
704 /* End an exception region for an exception type filter. ALLOWED is a
705 TREE_LIST of types to be matched by the runtime. FAILURE is an
706 expression to invoke if a mismatch occurs.
707
708 ??? We could use these semantics for calls to rethrow, too; if we can
709 see the surrounding catch clause, we know that the exception we're
710 rethrowing satisfies the "filter" of the catch type. */
711
712 void
713 expand_eh_region_end_allowed (allowed, failure)
714 tree allowed, failure;
715 {
716 struct eh_region *region;
717 rtx around_label;
718
719 if (! doing_eh (0))
720 return;
721
722 region = expand_eh_region_end ();
723 region->type = ERT_ALLOWED_EXCEPTIONS;
724 region->u.allowed.type_list = allowed;
725 region->label = gen_label_rtx ();
726
727 for (; allowed ; allowed = TREE_CHAIN (allowed))
728 add_type_for_runtime (TREE_VALUE (allowed));
729
730 /* We must emit the call to FAILURE here, so that if this function
731 throws a different exception, that it will be processed by the
732 correct region. */
733
734 around_label = gen_label_rtx ();
735 emit_jump (around_label);
736
737 emit_label (region->label);
738 expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL);
739 /* We must adjust the stack before we reach the AROUND_LABEL because
740 the call to FAILURE does not occur on all paths to the
741 AROUND_LABEL. */
742 do_pending_stack_adjust ();
743
744 emit_label (around_label);
745 }
746
747 /* End an exception region for a must-not-throw filter. FAILURE is an
748 expression invoke if an uncaught exception propagates this far.
749
750 This is conceptually identical to expand_eh_region_end_allowed with
751 an empty allowed list (if you passed "std::terminate" instead of
752 "__cxa_call_unexpected"), but they are represented differently in
753 the C++ LSDA. */
754
755 void
756 expand_eh_region_end_must_not_throw (failure)
757 tree failure;
758 {
759 struct eh_region *region;
760 rtx around_label;
761
762 if (! doing_eh (0))
763 return;
764
765 region = expand_eh_region_end ();
766 region->type = ERT_MUST_NOT_THROW;
767 region->label = gen_label_rtx ();
768
769 /* We must emit the call to FAILURE here, so that if this function
770 throws a different exception, that it will be processed by the
771 correct region. */
772
773 around_label = gen_label_rtx ();
774 emit_jump (around_label);
775
776 emit_label (region->label);
777 expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL);
778
779 emit_label (around_label);
780 }
781
782 /* End an exception region for a throw. No handling goes on here,
783 but it's the easiest way for the front-end to indicate what type
784 is being thrown. */
785
786 void
787 expand_eh_region_end_throw (type)
788 tree type;
789 {
790 struct eh_region *region;
791
792 if (! doing_eh (0))
793 return;
794
795 region = expand_eh_region_end ();
796 region->type = ERT_THROW;
797 region->u.throw.type = type;
798 }
799
800 /* End a fixup region. Within this region the cleanups for the immediately
801 enclosing region are _not_ run. This is used for goto cleanup to avoid
802 destroying an object twice.
803
804 This would be an extraordinarily simple prospect, were it not for the
805 fact that we don't actually know what the immediately enclosing region
806 is. This surprising fact is because expand_cleanups is currently
807 generating a sequence that it will insert somewhere else. We collect
808 the proper notion of "enclosing" in convert_from_eh_region_ranges. */
809
810 void
811 expand_eh_region_end_fixup (handler)
812 tree handler;
813 {
814 struct eh_region *fixup;
815
816 if (! doing_eh (0))
817 return;
818
819 fixup = expand_eh_region_end ();
820 fixup->type = ERT_FIXUP;
821 fixup->u.fixup.cleanup_exp = handler;
822 }
823
824 /* Return an rtl expression for a pointer to the exception object
825 within a handler. */
826
827 rtx
828 get_exception_pointer (fun)
829 struct function *fun;
830 {
831 rtx exc_ptr = fun->eh->exc_ptr;
832 if (fun == cfun && ! exc_ptr)
833 {
834 exc_ptr = gen_reg_rtx (ptr_mode);
835 fun->eh->exc_ptr = exc_ptr;
836 }
837 return exc_ptr;
838 }
839
840 /* Return an rtl expression for the exception dispatch filter
841 within a handler. */
842
843 static rtx
844 get_exception_filter (fun)
845 struct function *fun;
846 {
847 rtx filter = fun->eh->filter;
848 if (fun == cfun && ! filter)
849 {
850 filter = gen_reg_rtx (word_mode);
851 fun->eh->filter = filter;
852 }
853 return filter;
854 }
855 \f
856 /* This section is for the exception handling specific optimization pass. */
857
858 /* Random access the exception region tree. It's just as simple to
859 collect the regions this way as in expand_eh_region_start, but
860 without having to realloc memory. */
861
862 static void
863 collect_eh_region_array ()
864 {
865 struct eh_region **array, *i;
866
867 i = cfun->eh->region_tree;
868 if (! i)
869 return;
870
871 array = ggc_alloc_cleared ((cfun->eh->last_region_number + 1)
872 * sizeof (*array));
873 cfun->eh->region_array = array;
874
875 while (1)
876 {
877 array[i->region_number] = i;
878
879 /* If there are sub-regions, process them. */
880 if (i->inner)
881 i = i->inner;
882 /* If there are peers, process them. */
883 else if (i->next_peer)
884 i = i->next_peer;
885 /* Otherwise, step back up the tree to the next peer. */
886 else
887 {
888 do {
889 i = i->outer;
890 if (i == NULL)
891 return;
892 } while (i->next_peer == NULL);
893 i = i->next_peer;
894 }
895 }
896 }
897
898 static void
899 resolve_fixup_regions ()
900 {
901 int i, j, n = cfun->eh->last_region_number;
902
903 for (i = 1; i <= n; ++i)
904 {
905 struct eh_region *fixup = cfun->eh->region_array[i];
906 struct eh_region *cleanup = 0;
907
908 if (! fixup || fixup->type != ERT_FIXUP)
909 continue;
910
911 for (j = 1; j <= n; ++j)
912 {
913 cleanup = cfun->eh->region_array[j];
914 if (cleanup->type == ERT_CLEANUP
915 && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp)
916 break;
917 }
918 if (j > n)
919 abort ();
920
921 fixup->u.fixup.real_region = cleanup->outer;
922 }
923 }
924
925 /* Now that we've discovered what region actually encloses a fixup,
926 we can shuffle pointers and remove them from the tree. */
927
928 static void
929 remove_fixup_regions ()
930 {
931 int i;
932 rtx insn, note;
933 struct eh_region *fixup;
934
935 /* Walk the insn chain and adjust the REG_EH_REGION numbers
936 for instructions referencing fixup regions. This is only
937 strictly necessary for fixup regions with no parent, but
938 doesn't hurt to do it for all regions. */
939 for (insn = get_insns(); insn ; insn = NEXT_INSN (insn))
940 if (INSN_P (insn)
941 && (note = find_reg_note (insn, REG_EH_REGION, NULL))
942 && INTVAL (XEXP (note, 0)) > 0
943 && (fixup = cfun->eh->region_array[INTVAL (XEXP (note, 0))])
944 && fixup->type == ERT_FIXUP)
945 {
946 if (fixup->u.fixup.real_region)
947 XEXP (note, 0) = GEN_INT (fixup->u.fixup.real_region->region_number);
948 else
949 remove_note (insn, note);
950 }
951
952 /* Remove the fixup regions from the tree. */
953 for (i = cfun->eh->last_region_number; i > 0; --i)
954 {
955 fixup = cfun->eh->region_array[i];
956 if (! fixup)
957 continue;
958
959 /* Allow GC to maybe free some memory. */
960 if (fixup->type == ERT_CLEANUP)
961 fixup->u.cleanup.exp = NULL_TREE;
962
963 if (fixup->type != ERT_FIXUP)
964 continue;
965
966 if (fixup->inner)
967 {
968 struct eh_region *parent, *p, **pp;
969
970 parent = fixup->u.fixup.real_region;
971
972 /* Fix up the children's parent pointers; find the end of
973 the list. */
974 for (p = fixup->inner; ; p = p->next_peer)
975 {
976 p->outer = parent;
977 if (! p->next_peer)
978 break;
979 }
980
981 /* In the tree of cleanups, only outer-inner ordering matters.
982 So link the children back in anywhere at the correct level. */
983 if (parent)
984 pp = &parent->inner;
985 else
986 pp = &cfun->eh->region_tree;
987 p->next_peer = *pp;
988 *pp = fixup->inner;
989 fixup->inner = NULL;
990 }
991
992 remove_eh_handler (fixup);
993 }
994 }
995
996 /* Remove all regions whose labels are not reachable from insns. */
997
998 static void
999 remove_unreachable_regions (insns)
1000 rtx insns;
1001 {
1002 int i, *uid_region_num;
1003 bool *reachable;
1004 struct eh_region *r;
1005 rtx insn;
1006
1007 uid_region_num = xcalloc (get_max_uid (), sizeof(int));
1008 reachable = xcalloc (cfun->eh->last_region_number + 1, sizeof(bool));
1009
1010 for (i = cfun->eh->last_region_number; i > 0; --i)
1011 {
1012 r = cfun->eh->region_array[i];
1013 if (!r || r->region_number != i)
1014 continue;
1015
1016 if (r->resume)
1017 {
1018 if (uid_region_num[INSN_UID (r->resume)])
1019 abort ();
1020 uid_region_num[INSN_UID (r->resume)] = i;
1021 }
1022 if (r->label)
1023 {
1024 if (uid_region_num[INSN_UID (r->label)])
1025 abort ();
1026 uid_region_num[INSN_UID (r->label)] = i;
1027 }
1028 if (r->type == ERT_TRY && r->u.try.continue_label)
1029 {
1030 if (uid_region_num[INSN_UID (r->u.try.continue_label)])
1031 abort ();
1032 uid_region_num[INSN_UID (r->u.try.continue_label)] = i;
1033 }
1034 }
1035
1036 for (insn = insns; insn; insn = NEXT_INSN (insn))
1037 reachable[uid_region_num[INSN_UID (insn)]] = true;
1038
1039 for (i = cfun->eh->last_region_number; i > 0; --i)
1040 {
1041 r = cfun->eh->region_array[i];
1042 if (r && r->region_number == i && !reachable[i])
1043 {
1044 /* Don't remove ERT_THROW regions if their outer region
1045 is reachable. */
1046 if (r->type == ERT_THROW
1047 && r->outer
1048 && reachable[r->outer->region_number])
1049 continue;
1050
1051 remove_eh_handler (r);
1052 }
1053 }
1054
1055 free (reachable);
1056 free (uid_region_num);
1057 }
1058
1059 /* Turn NOTE_INSN_EH_REGION notes into REG_EH_REGION notes for each
1060 can_throw instruction in the region. */
1061
1062 static void
1063 convert_from_eh_region_ranges_1 (pinsns, orig_sp, cur)
1064 rtx *pinsns;
1065 int *orig_sp;
1066 int cur;
1067 {
1068 int *sp = orig_sp;
1069 rtx insn, next;
1070
1071 for (insn = *pinsns; insn ; insn = next)
1072 {
1073 next = NEXT_INSN (insn);
1074 if (GET_CODE (insn) == NOTE)
1075 {
1076 int kind = NOTE_LINE_NUMBER (insn);
1077 if (kind == NOTE_INSN_EH_REGION_BEG
1078 || kind == NOTE_INSN_EH_REGION_END)
1079 {
1080 if (kind == NOTE_INSN_EH_REGION_BEG)
1081 {
1082 struct eh_region *r;
1083
1084 *sp++ = cur;
1085 cur = NOTE_EH_HANDLER (insn);
1086
1087 r = cfun->eh->region_array[cur];
1088 if (r->type == ERT_FIXUP)
1089 {
1090 r = r->u.fixup.real_region;
1091 cur = r ? r->region_number : 0;
1092 }
1093 else if (r->type == ERT_CATCH)
1094 {
1095 r = r->outer;
1096 cur = r ? r->region_number : 0;
1097 }
1098 }
1099 else
1100 cur = *--sp;
1101
1102 /* Removing the first insn of a CALL_PLACEHOLDER sequence
1103 requires extra care to adjust sequence start. */
1104 if (insn == *pinsns)
1105 *pinsns = next;
1106 remove_insn (insn);
1107 continue;
1108 }
1109 }
1110 else if (INSN_P (insn))
1111 {
1112 if (cur > 0
1113 && ! find_reg_note (insn, REG_EH_REGION, NULL_RTX)
1114 /* Calls can always potentially throw exceptions, unless
1115 they have a REG_EH_REGION note with a value of 0 or less.
1116 Which should be the only possible kind so far. */
1117 && (GET_CODE (insn) == CALL_INSN
1118 /* If we wanted exceptions for non-call insns, then
1119 any may_trap_p instruction could throw. */
1120 || (flag_non_call_exceptions
1121 && GET_CODE (PATTERN (insn)) != CLOBBER
1122 && GET_CODE (PATTERN (insn)) != USE
1123 && may_trap_p (PATTERN (insn)))))
1124 {
1125 REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (cur),
1126 REG_NOTES (insn));
1127 }
1128
1129 if (GET_CODE (insn) == CALL_INSN
1130 && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
1131 {
1132 convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 0),
1133 sp, cur);
1134 convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 1),
1135 sp, cur);
1136 convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 2),
1137 sp, cur);
1138 }
1139 }
1140 }
1141
1142 if (sp != orig_sp)
1143 abort ();
1144 }
1145
1146 void
1147 convert_from_eh_region_ranges ()
1148 {
1149 int *stack;
1150 rtx insns;
1151
1152 collect_eh_region_array ();
1153 resolve_fixup_regions ();
1154
1155 stack = xmalloc (sizeof (int) * (cfun->eh->last_region_number + 1));
1156 insns = get_insns ();
1157 convert_from_eh_region_ranges_1 (&insns, stack, 0);
1158 free (stack);
1159
1160 remove_fixup_regions ();
1161 remove_unreachable_regions (insns);
1162 }
1163
1164 static void
1165 add_ehl_entry (label, region)
1166 rtx label;
1167 struct eh_region *region;
1168 {
1169 struct ehl_map_entry **slot, *entry;
1170
1171 LABEL_PRESERVE_P (label) = 1;
1172
1173 entry = (struct ehl_map_entry *) ggc_alloc (sizeof (*entry));
1174 entry->label = label;
1175 entry->region = region;
1176
1177 slot = (struct ehl_map_entry **)
1178 htab_find_slot (cfun->eh->exception_handler_label_map, entry, INSERT);
1179
1180 /* Before landing pad creation, each exception handler has its own
1181 label. After landing pad creation, the exception handlers may
1182 share landing pads. This is ok, since maybe_remove_eh_handler
1183 only requires the 1-1 mapping before landing pad creation. */
1184 if (*slot && !cfun->eh->built_landing_pads)
1185 abort ();
1186
1187 *slot = entry;
1188 }
1189
1190 void
1191 find_exception_handler_labels ()
1192 {
1193 int i;
1194
1195 if (cfun->eh->exception_handler_label_map)
1196 htab_empty (cfun->eh->exception_handler_label_map);
1197 else
1198 {
1199 /* ??? The expansion factor here (3/2) must be greater than the htab
1200 occupancy factor (4/3) to avoid unnecessary resizing. */
1201 cfun->eh->exception_handler_label_map
1202 = htab_create_ggc (cfun->eh->last_region_number * 3 / 2,
1203 ehl_hash, ehl_eq, NULL);
1204 }
1205
1206 if (cfun->eh->region_tree == NULL)
1207 return;
1208
1209 for (i = cfun->eh->last_region_number; i > 0; --i)
1210 {
1211 struct eh_region *region = cfun->eh->region_array[i];
1212 rtx lab;
1213
1214 if (! region || region->region_number != i)
1215 continue;
1216 if (cfun->eh->built_landing_pads)
1217 lab = region->landing_pad;
1218 else
1219 lab = region->label;
1220
1221 if (lab)
1222 add_ehl_entry (lab, region);
1223 }
1224
1225 /* For sjlj exceptions, need the return label to remain live until
1226 after landing pad generation. */
1227 if (USING_SJLJ_EXCEPTIONS && ! cfun->eh->built_landing_pads)
1228 add_ehl_entry (return_label, NULL);
1229 }
1230
1231 bool
1232 current_function_has_exception_handlers ()
1233 {
1234 int i;
1235
1236 for (i = cfun->eh->last_region_number; i > 0; --i)
1237 {
1238 struct eh_region *region = cfun->eh->region_array[i];
1239
1240 if (! region || region->region_number != i)
1241 continue;
1242 if (region->type != ERT_THROW)
1243 return true;
1244 }
1245
1246 return false;
1247 }
1248 \f
1249 static struct eh_region *
1250 duplicate_eh_region_1 (o, map)
1251 struct eh_region *o;
1252 struct inline_remap *map;
1253 {
1254 struct eh_region *n
1255 = (struct eh_region *) ggc_alloc_cleared (sizeof (struct eh_region));
1256
1257 n->region_number = o->region_number + cfun->eh->last_region_number;
1258 n->type = o->type;
1259
1260 switch (n->type)
1261 {
1262 case ERT_CLEANUP:
1263 case ERT_MUST_NOT_THROW:
1264 break;
1265
1266 case ERT_TRY:
1267 if (o->u.try.continue_label)
1268 n->u.try.continue_label
1269 = get_label_from_map (map,
1270 CODE_LABEL_NUMBER (o->u.try.continue_label));
1271 break;
1272
1273 case ERT_CATCH:
1274 n->u.catch.type_list = o->u.catch.type_list;
1275 break;
1276
1277 case ERT_ALLOWED_EXCEPTIONS:
1278 n->u.allowed.type_list = o->u.allowed.type_list;
1279 break;
1280
1281 case ERT_THROW:
1282 n->u.throw.type = o->u.throw.type;
1283
1284 default:
1285 abort ();
1286 }
1287
1288 if (o->label)
1289 n->label = get_label_from_map (map, CODE_LABEL_NUMBER (o->label));
1290 if (o->resume)
1291 {
1292 n->resume = map->insn_map[INSN_UID (o->resume)];
1293 if (n->resume == NULL)
1294 abort ();
1295 }
1296
1297 return n;
1298 }
1299
1300 static void
1301 duplicate_eh_region_2 (o, n_array)
1302 struct eh_region *o;
1303 struct eh_region **n_array;
1304 {
1305 struct eh_region *n = n_array[o->region_number];
1306
1307 switch (n->type)
1308 {
1309 case ERT_TRY:
1310 n->u.try.catch = n_array[o->u.try.catch->region_number];
1311 n->u.try.last_catch = n_array[o->u.try.last_catch->region_number];
1312 break;
1313
1314 case ERT_CATCH:
1315 if (o->u.catch.next_catch)
1316 n->u.catch.next_catch = n_array[o->u.catch.next_catch->region_number];
1317 if (o->u.catch.prev_catch)
1318 n->u.catch.prev_catch = n_array[o->u.catch.prev_catch->region_number];
1319 break;
1320
1321 default:
1322 break;
1323 }
1324
1325 if (o->outer)
1326 n->outer = n_array[o->outer->region_number];
1327 if (o->inner)
1328 n->inner = n_array[o->inner->region_number];
1329 if (o->next_peer)
1330 n->next_peer = n_array[o->next_peer->region_number];
1331 }
1332
1333 int
1334 duplicate_eh_regions (ifun, map)
1335 struct function *ifun;
1336 struct inline_remap *map;
1337 {
1338 int ifun_last_region_number = ifun->eh->last_region_number;
1339 struct eh_region **n_array, *root, *cur;
1340 int i;
1341
1342 if (ifun_last_region_number == 0)
1343 return 0;
1344
1345 n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array));
1346
1347 for (i = 1; i <= ifun_last_region_number; ++i)
1348 {
1349 cur = ifun->eh->region_array[i];
1350 if (!cur || cur->region_number != i)
1351 continue;
1352 n_array[i] = duplicate_eh_region_1 (cur, map);
1353 }
1354 for (i = 1; i <= ifun_last_region_number; ++i)
1355 {
1356 cur = ifun->eh->region_array[i];
1357 if (!cur || cur->region_number != i)
1358 continue;
1359 duplicate_eh_region_2 (cur, n_array);
1360 }
1361
1362 root = n_array[ifun->eh->region_tree->region_number];
1363 cur = cfun->eh->cur_region;
1364 if (cur)
1365 {
1366 struct eh_region *p = cur->inner;
1367 if (p)
1368 {
1369 while (p->next_peer)
1370 p = p->next_peer;
1371 p->next_peer = root;
1372 }
1373 else
1374 cur->inner = root;
1375
1376 for (i = 1; i <= ifun_last_region_number; ++i)
1377 if (n_array[i] && n_array[i]->outer == NULL)
1378 n_array[i]->outer = cur;
1379 }
1380 else
1381 {
1382 struct eh_region *p = cfun->eh->region_tree;
1383 if (p)
1384 {
1385 while (p->next_peer)
1386 p = p->next_peer;
1387 p->next_peer = root;
1388 }
1389 else
1390 cfun->eh->region_tree = root;
1391 }
1392
1393 free (n_array);
1394
1395 i = cfun->eh->last_region_number;
1396 cfun->eh->last_region_number = i + ifun_last_region_number;
1397 return i;
1398 }
1399
1400 \f
1401 static int
1402 t2r_eq (pentry, pdata)
1403 const PTR pentry;
1404 const PTR pdata;
1405 {
1406 tree entry = (tree) pentry;
1407 tree data = (tree) pdata;
1408
1409 return TREE_PURPOSE (entry) == data;
1410 }
1411
1412 static hashval_t
1413 t2r_hash (pentry)
1414 const PTR pentry;
1415 {
1416 tree entry = (tree) pentry;
1417 return TYPE_HASH (TREE_PURPOSE (entry));
1418 }
1419
1420 static void
1421 add_type_for_runtime (type)
1422 tree type;
1423 {
1424 tree *slot;
1425
1426 slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
1427 TYPE_HASH (type), INSERT);
1428 if (*slot == NULL)
1429 {
1430 tree runtime = (*lang_eh_runtime_type) (type);
1431 *slot = tree_cons (type, runtime, NULL_TREE);
1432 }
1433 }
1434
1435 static tree
1436 lookup_type_for_runtime (type)
1437 tree type;
1438 {
1439 tree *slot;
1440
1441 slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
1442 TYPE_HASH (type), NO_INSERT);
1443
1444 /* We should have always inserted the data earlier. */
1445 return TREE_VALUE (*slot);
1446 }
1447
1448 \f
1449 /* Represent an entry in @TTypes for either catch actions
1450 or exception filter actions. */
1451 struct ttypes_filter GTY(())
1452 {
1453 tree t;
1454 int filter;
1455 };
1456
1457 /* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
1458 (a tree) for a @TTypes type node we are thinking about adding. */
1459
1460 static int
1461 ttypes_filter_eq (pentry, pdata)
1462 const PTR pentry;
1463 const PTR pdata;
1464 {
1465 const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1466 tree data = (tree) pdata;
1467
1468 return entry->t == data;
1469 }
1470
1471 static hashval_t
1472 ttypes_filter_hash (pentry)
1473 const PTR pentry;
1474 {
1475 const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1476 return TYPE_HASH (entry->t);
1477 }
1478
1479 /* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
1480 exception specification list we are thinking about adding. */
1481 /* ??? Currently we use the type lists in the order given. Someone
1482 should put these in some canonical order. */
1483
1484 static int
1485 ehspec_filter_eq (pentry, pdata)
1486 const PTR pentry;
1487 const PTR pdata;
1488 {
1489 const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1490 const struct ttypes_filter *data = (const struct ttypes_filter *) pdata;
1491
1492 return type_list_equal (entry->t, data->t);
1493 }
1494
1495 /* Hash function for exception specification lists. */
1496
1497 static hashval_t
1498 ehspec_filter_hash (pentry)
1499 const PTR pentry;
1500 {
1501 const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1502 hashval_t h = 0;
1503 tree list;
1504
1505 for (list = entry->t; list ; list = TREE_CHAIN (list))
1506 h = (h << 5) + (h >> 27) + TYPE_HASH (TREE_VALUE (list));
1507 return h;
1508 }
1509
1510 /* Add TYPE to cfun->eh->ttype_data, using TYPES_HASH to speed
1511 up the search. Return the filter value to be used. */
1512
1513 static int
1514 add_ttypes_entry (ttypes_hash, type)
1515 htab_t ttypes_hash;
1516 tree type;
1517 {
1518 struct ttypes_filter **slot, *n;
1519
1520 slot = (struct ttypes_filter **)
1521 htab_find_slot_with_hash (ttypes_hash, type, TYPE_HASH (type), INSERT);
1522
1523 if ((n = *slot) == NULL)
1524 {
1525 /* Filter value is a 1 based table index. */
1526
1527 n = (struct ttypes_filter *) xmalloc (sizeof (*n));
1528 n->t = type;
1529 n->filter = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) + 1;
1530 *slot = n;
1531
1532 VARRAY_PUSH_TREE (cfun->eh->ttype_data, type);
1533 }
1534
1535 return n->filter;
1536 }
1537
1538 /* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH
1539 to speed up the search. Return the filter value to be used. */
1540
1541 static int
1542 add_ehspec_entry (ehspec_hash, ttypes_hash, list)
1543 htab_t ehspec_hash;
1544 htab_t ttypes_hash;
1545 tree list;
1546 {
1547 struct ttypes_filter **slot, *n;
1548 struct ttypes_filter dummy;
1549
1550 dummy.t = list;
1551 slot = (struct ttypes_filter **)
1552 htab_find_slot (ehspec_hash, &dummy, INSERT);
1553
1554 if ((n = *slot) == NULL)
1555 {
1556 /* Filter value is a -1 based byte index into a uleb128 buffer. */
1557
1558 n = (struct ttypes_filter *) xmalloc (sizeof (*n));
1559 n->t = list;
1560 n->filter = -(VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) + 1);
1561 *slot = n;
1562
1563 /* Look up each type in the list and encode its filter
1564 value as a uleb128. Terminate the list with 0. */
1565 for (; list ; list = TREE_CHAIN (list))
1566 push_uleb128 (&cfun->eh->ehspec_data,
1567 add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
1568 VARRAY_PUSH_UCHAR (cfun->eh->ehspec_data, 0);
1569 }
1570
1571 return n->filter;
1572 }
1573
1574 /* Generate the action filter values to be used for CATCH and
1575 ALLOWED_EXCEPTIONS regions. When using dwarf2 exception regions,
1576 we use lots of landing pads, and so every type or list can share
1577 the same filter value, which saves table space. */
1578
1579 static void
1580 assign_filter_values ()
1581 {
1582 int i;
1583 htab_t ttypes, ehspec;
1584
1585 VARRAY_TREE_INIT (cfun->eh->ttype_data, 16, "ttype_data");
1586 VARRAY_UCHAR_INIT (cfun->eh->ehspec_data, 64, "ehspec_data");
1587
1588 ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
1589 ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
1590
1591 for (i = cfun->eh->last_region_number; i > 0; --i)
1592 {
1593 struct eh_region *r = cfun->eh->region_array[i];
1594
1595 /* Mind we don't process a region more than once. */
1596 if (!r || r->region_number != i)
1597 continue;
1598
1599 switch (r->type)
1600 {
1601 case ERT_CATCH:
1602 /* Whatever type_list is (NULL or true list), we build a list
1603 of filters for the region. */
1604 r->u.catch.filter_list = NULL_TREE;
1605
1606 if (r->u.catch.type_list != NULL)
1607 {
1608 /* Get a filter value for each of the types caught and store
1609 them in the region's dedicated list. */
1610 tree tp_node = r->u.catch.type_list;
1611
1612 for (;tp_node; tp_node = TREE_CHAIN (tp_node))
1613 {
1614 int flt = add_ttypes_entry (ttypes, TREE_VALUE (tp_node));
1615 tree flt_node = build_int_2 (flt, 0);
1616
1617 r->u.catch.filter_list
1618 = tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list);
1619 }
1620 }
1621 else
1622 {
1623 /* Get a filter value for the NULL list also since it will need
1624 an action record anyway. */
1625 int flt = add_ttypes_entry (ttypes, NULL);
1626 tree flt_node = build_int_2 (flt, 0);
1627
1628 r->u.catch.filter_list
1629 = tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list);
1630 }
1631
1632 break;
1633
1634 case ERT_ALLOWED_EXCEPTIONS:
1635 r->u.allowed.filter
1636 = add_ehspec_entry (ehspec, ttypes, r->u.allowed.type_list);
1637 break;
1638
1639 default:
1640 break;
1641 }
1642 }
1643
1644 htab_delete (ttypes);
1645 htab_delete (ehspec);
1646 }
1647
1648 static void
1649 build_post_landing_pads ()
1650 {
1651 int i;
1652
1653 for (i = cfun->eh->last_region_number; i > 0; --i)
1654 {
1655 struct eh_region *region = cfun->eh->region_array[i];
1656 rtx seq;
1657
1658 /* Mind we don't process a region more than once. */
1659 if (!region || region->region_number != i)
1660 continue;
1661
1662 switch (region->type)
1663 {
1664 case ERT_TRY:
1665 /* ??? Collect the set of all non-overlapping catch handlers
1666 all the way up the chain until blocked by a cleanup. */
1667 /* ??? Outer try regions can share landing pads with inner
1668 try regions if the types are completely non-overlapping,
1669 and there are no intervening cleanups. */
1670
1671 region->post_landing_pad = gen_label_rtx ();
1672
1673 start_sequence ();
1674
1675 emit_label (region->post_landing_pad);
1676
1677 /* ??? It is mighty inconvenient to call back into the
1678 switch statement generation code in expand_end_case.
1679 Rapid prototyping sez a sequence of ifs. */
1680 {
1681 struct eh_region *c;
1682 for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
1683 {
1684 /* ??? _Unwind_ForcedUnwind wants no match here. */
1685 if (c->u.catch.type_list == NULL)
1686 emit_jump (c->label);
1687 else
1688 {
1689 /* Need for one cmp/jump per type caught. Each type
1690 list entry has a matching entry in the filter list
1691 (see assign_filter_values). */
1692 tree tp_node = c->u.catch.type_list;
1693 tree flt_node = c->u.catch.filter_list;
1694
1695 for (; tp_node; )
1696 {
1697 emit_cmp_and_jump_insns
1698 (cfun->eh->filter,
1699 GEN_INT (tree_low_cst (TREE_VALUE (flt_node), 0)),
1700 EQ, NULL_RTX, word_mode, 0, c->label);
1701
1702 tp_node = TREE_CHAIN (tp_node);
1703 flt_node = TREE_CHAIN (flt_node);
1704 }
1705 }
1706 }
1707 }
1708
1709 /* We delay the generation of the _Unwind_Resume until we generate
1710 landing pads. We emit a marker here so as to get good control
1711 flow data in the meantime. */
1712 region->resume
1713 = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1714 emit_barrier ();
1715
1716 seq = get_insns ();
1717 end_sequence ();
1718
1719 emit_insn_before (seq, region->u.try.catch->label);
1720 break;
1721
1722 case ERT_ALLOWED_EXCEPTIONS:
1723 region->post_landing_pad = gen_label_rtx ();
1724
1725 start_sequence ();
1726
1727 emit_label (region->post_landing_pad);
1728
1729 emit_cmp_and_jump_insns (cfun->eh->filter,
1730 GEN_INT (region->u.allowed.filter),
1731 EQ, NULL_RTX, word_mode, 0, region->label);
1732
1733 /* We delay the generation of the _Unwind_Resume until we generate
1734 landing pads. We emit a marker here so as to get good control
1735 flow data in the meantime. */
1736 region->resume
1737 = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1738 emit_barrier ();
1739
1740 seq = get_insns ();
1741 end_sequence ();
1742
1743 emit_insn_before (seq, region->label);
1744 break;
1745
1746 case ERT_CLEANUP:
1747 case ERT_MUST_NOT_THROW:
1748 region->post_landing_pad = region->label;
1749 break;
1750
1751 case ERT_CATCH:
1752 case ERT_THROW:
1753 /* Nothing to do. */
1754 break;
1755
1756 default:
1757 abort ();
1758 }
1759 }
1760 }
1761
1762 /* Replace RESX patterns with jumps to the next handler if any, or calls to
1763 _Unwind_Resume otherwise. */
1764
1765 static void
1766 connect_post_landing_pads ()
1767 {
1768 int i;
1769
1770 for (i = cfun->eh->last_region_number; i > 0; --i)
1771 {
1772 struct eh_region *region = cfun->eh->region_array[i];
1773 struct eh_region *outer;
1774 rtx seq;
1775
1776 /* Mind we don't process a region more than once. */
1777 if (!region || region->region_number != i)
1778 continue;
1779
1780 /* If there is no RESX, or it has been deleted by flow, there's
1781 nothing to fix up. */
1782 if (! region->resume || INSN_DELETED_P (region->resume))
1783 continue;
1784
1785 /* Search for another landing pad in this function. */
1786 for (outer = region->outer; outer ; outer = outer->outer)
1787 if (outer->post_landing_pad)
1788 break;
1789
1790 start_sequence ();
1791
1792 if (outer)
1793 emit_jump (outer->post_landing_pad);
1794 else
1795 emit_library_call (unwind_resume_libfunc, LCT_THROW,
1796 VOIDmode, 1, cfun->eh->exc_ptr, ptr_mode);
1797
1798 seq = get_insns ();
1799 end_sequence ();
1800 emit_insn_before (seq, region->resume);
1801 delete_insn (region->resume);
1802 }
1803 }
1804
1805 \f
1806 static void
1807 dw2_build_landing_pads ()
1808 {
1809 int i;
1810 unsigned int j;
1811
1812 for (i = cfun->eh->last_region_number; i > 0; --i)
1813 {
1814 struct eh_region *region = cfun->eh->region_array[i];
1815 rtx seq;
1816 bool clobbers_hard_regs = false;
1817
1818 /* Mind we don't process a region more than once. */
1819 if (!region || region->region_number != i)
1820 continue;
1821
1822 if (region->type != ERT_CLEANUP
1823 && region->type != ERT_TRY
1824 && region->type != ERT_ALLOWED_EXCEPTIONS)
1825 continue;
1826
1827 start_sequence ();
1828
1829 region->landing_pad = gen_label_rtx ();
1830 emit_label (region->landing_pad);
1831
1832 #ifdef HAVE_exception_receiver
1833 if (HAVE_exception_receiver)
1834 emit_insn (gen_exception_receiver ());
1835 else
1836 #endif
1837 #ifdef HAVE_nonlocal_goto_receiver
1838 if (HAVE_nonlocal_goto_receiver)
1839 emit_insn (gen_nonlocal_goto_receiver ());
1840 else
1841 #endif
1842 { /* Nothing */ }
1843
1844 /* If the eh_return data registers are call-saved, then we
1845 won't have considered them clobbered from the call that
1846 threw. Kill them now. */
1847 for (j = 0; ; ++j)
1848 {
1849 unsigned r = EH_RETURN_DATA_REGNO (j);
1850 if (r == INVALID_REGNUM)
1851 break;
1852 if (! call_used_regs[r])
1853 {
1854 emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, r)));
1855 clobbers_hard_regs = true;
1856 }
1857 }
1858
1859 if (clobbers_hard_regs)
1860 {
1861 /* @@@ This is a kludge. Not all machine descriptions define a
1862 blockage insn, but we must not allow the code we just generated
1863 to be reordered by scheduling. So emit an ASM_INPUT to act as
1864 blockage insn. */
1865 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
1866 }
1867
1868 emit_move_insn (cfun->eh->exc_ptr,
1869 gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
1870 emit_move_insn (cfun->eh->filter,
1871 gen_rtx_REG (word_mode, EH_RETURN_DATA_REGNO (1)));
1872
1873 seq = get_insns ();
1874 end_sequence ();
1875
1876 emit_insn_before (seq, region->post_landing_pad);
1877 }
1878 }
1879
1880 \f
1881 struct sjlj_lp_info
1882 {
1883 int directly_reachable;
1884 int action_index;
1885 int dispatch_index;
1886 int call_site_index;
1887 };
1888
1889 static bool
1890 sjlj_find_directly_reachable_regions (lp_info)
1891 struct sjlj_lp_info *lp_info;
1892 {
1893 rtx insn;
1894 bool found_one = false;
1895
1896 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
1897 {
1898 struct eh_region *region;
1899 enum reachable_code rc;
1900 tree type_thrown;
1901 rtx note;
1902
1903 if (! INSN_P (insn))
1904 continue;
1905
1906 note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1907 if (!note || INTVAL (XEXP (note, 0)) <= 0)
1908 continue;
1909
1910 region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
1911
1912 type_thrown = NULL_TREE;
1913 if (region->type == ERT_THROW)
1914 {
1915 type_thrown = region->u.throw.type;
1916 region = region->outer;
1917 }
1918
1919 /* Find the first containing region that might handle the exception.
1920 That's the landing pad to which we will transfer control. */
1921 rc = RNL_NOT_CAUGHT;
1922 for (; region; region = region->outer)
1923 {
1924 rc = reachable_next_level (region, type_thrown, 0);
1925 if (rc != RNL_NOT_CAUGHT)
1926 break;
1927 }
1928 if (rc == RNL_MAYBE_CAUGHT || rc == RNL_CAUGHT)
1929 {
1930 lp_info[region->region_number].directly_reachable = 1;
1931 found_one = true;
1932 }
1933 }
1934
1935 return found_one;
1936 }
1937
1938 static void
1939 sjlj_assign_call_site_values (dispatch_label, lp_info)
1940 rtx dispatch_label;
1941 struct sjlj_lp_info *lp_info;
1942 {
1943 htab_t ar_hash;
1944 int i, index;
1945
1946 /* First task: build the action table. */
1947
1948 VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
1949 ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
1950
1951 for (i = cfun->eh->last_region_number; i > 0; --i)
1952 if (lp_info[i].directly_reachable)
1953 {
1954 struct eh_region *r = cfun->eh->region_array[i];
1955 r->landing_pad = dispatch_label;
1956 lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
1957 if (lp_info[i].action_index != -1)
1958 cfun->uses_eh_lsda = 1;
1959 }
1960
1961 htab_delete (ar_hash);
1962
1963 /* Next: assign dispatch values. In dwarf2 terms, this would be the
1964 landing pad label for the region. For sjlj though, there is one
1965 common landing pad from which we dispatch to the post-landing pads.
1966
1967 A region receives a dispatch index if it is directly reachable
1968 and requires in-function processing. Regions that share post-landing
1969 pads may share dispatch indices. */
1970 /* ??? Post-landing pad sharing doesn't actually happen at the moment
1971 (see build_post_landing_pads) so we don't bother checking for it. */
1972
1973 index = 0;
1974 for (i = cfun->eh->last_region_number; i > 0; --i)
1975 if (lp_info[i].directly_reachable)
1976 lp_info[i].dispatch_index = index++;
1977
1978 /* Finally: assign call-site values. If dwarf2 terms, this would be
1979 the region number assigned by convert_to_eh_region_ranges, but
1980 handles no-action and must-not-throw differently. */
1981
1982 call_site_base = 1;
1983 for (i = cfun->eh->last_region_number; i > 0; --i)
1984 if (lp_info[i].directly_reachable)
1985 {
1986 int action = lp_info[i].action_index;
1987
1988 /* Map must-not-throw to otherwise unused call-site index 0. */
1989 if (action == -2)
1990 index = 0;
1991 /* Map no-action to otherwise unused call-site index -1. */
1992 else if (action == -1)
1993 index = -1;
1994 /* Otherwise, look it up in the table. */
1995 else
1996 index = add_call_site (GEN_INT (lp_info[i].dispatch_index), action);
1997
1998 lp_info[i].call_site_index = index;
1999 }
2000 }
2001
2002 static void
2003 sjlj_mark_call_sites (lp_info)
2004 struct sjlj_lp_info *lp_info;
2005 {
2006 int last_call_site = -2;
2007 rtx insn, mem;
2008
2009 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
2010 {
2011 struct eh_region *region;
2012 int this_call_site;
2013 rtx note, before, p;
2014
2015 /* Reset value tracking at extended basic block boundaries. */
2016 if (GET_CODE (insn) == CODE_LABEL)
2017 last_call_site = -2;
2018
2019 if (! INSN_P (insn))
2020 continue;
2021
2022 note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2023 if (!note)
2024 {
2025 /* Calls (and trapping insns) without notes are outside any
2026 exception handling region in this function. Mark them as
2027 no action. */
2028 if (GET_CODE (insn) == CALL_INSN
2029 || (flag_non_call_exceptions
2030 && may_trap_p (PATTERN (insn))))
2031 this_call_site = -1;
2032 else
2033 continue;
2034 }
2035 else
2036 {
2037 /* Calls that are known to not throw need not be marked. */
2038 if (INTVAL (XEXP (note, 0)) <= 0)
2039 continue;
2040
2041 region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2042 this_call_site = lp_info[region->region_number].call_site_index;
2043 }
2044
2045 if (this_call_site == last_call_site)
2046 continue;
2047
2048 /* Don't separate a call from it's argument loads. */
2049 before = insn;
2050 if (GET_CODE (insn) == CALL_INSN)
2051 before = find_first_parameter_load (insn, NULL_RTX);
2052
2053 start_sequence ();
2054 mem = adjust_address (cfun->eh->sjlj_fc, TYPE_MODE (integer_type_node),
2055 sjlj_fc_call_site_ofs);
2056 emit_move_insn (mem, GEN_INT (this_call_site));
2057 p = get_insns ();
2058 end_sequence ();
2059
2060 emit_insn_before (p, before);
2061 last_call_site = this_call_site;
2062 }
2063 }
2064
2065 /* Construct the SjLj_Function_Context. */
2066
2067 static void
2068 sjlj_emit_function_enter (dispatch_label)
2069 rtx dispatch_label;
2070 {
2071 rtx fn_begin, fc, mem, seq;
2072
2073 fc = cfun->eh->sjlj_fc;
2074
2075 start_sequence ();
2076
2077 /* We're storing this libcall's address into memory instead of
2078 calling it directly. Thus, we must call assemble_external_libcall
2079 here, as we can not depend on emit_library_call to do it for us. */
2080 assemble_external_libcall (eh_personality_libfunc);
2081 mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
2082 emit_move_insn (mem, eh_personality_libfunc);
2083
2084 mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
2085 if (cfun->uses_eh_lsda)
2086 {
2087 char buf[20];
2088 ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", current_function_funcdef_no);
2089 emit_move_insn (mem, gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
2090 }
2091 else
2092 emit_move_insn (mem, const0_rtx);
2093
2094 #ifdef DONT_USE_BUILTIN_SETJMP
2095 {
2096 rtx x, note;
2097 x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
2098 TYPE_MODE (integer_type_node), 1,
2099 plus_constant (XEXP (fc, 0),
2100 sjlj_fc_jbuf_ofs), Pmode);
2101
2102 note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
2103 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, x, const0_rtx);
2104
2105 emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
2106 TYPE_MODE (integer_type_node), 0, dispatch_label);
2107 }
2108 #else
2109 expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
2110 dispatch_label);
2111 #endif
2112
2113 emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
2114 1, XEXP (fc, 0), Pmode);
2115
2116 seq = get_insns ();
2117 end_sequence ();
2118
2119 /* ??? Instead of doing this at the beginning of the function,
2120 do this in a block that is at loop level 0 and dominates all
2121 can_throw_internal instructions. */
2122
2123 for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
2124 if (GET_CODE (fn_begin) == NOTE
2125 && NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
2126 break;
2127 emit_insn_after (seq, fn_begin);
2128 }
2129
2130 /* Call back from expand_function_end to know where we should put
2131 the call to unwind_sjlj_unregister_libfunc if needed. */
2132
2133 void
2134 sjlj_emit_function_exit_after (after)
2135 rtx after;
2136 {
2137 cfun->eh->sjlj_exit_after = after;
2138 }
2139
2140 static void
2141 sjlj_emit_function_exit ()
2142 {
2143 rtx seq;
2144
2145 start_sequence ();
2146
2147 emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
2148 1, XEXP (cfun->eh->sjlj_fc, 0), Pmode);
2149
2150 seq = get_insns ();
2151 end_sequence ();
2152
2153 /* ??? Really this can be done in any block at loop level 0 that
2154 post-dominates all can_throw_internal instructions. This is
2155 the last possible moment. */
2156
2157 emit_insn_after (seq, cfun->eh->sjlj_exit_after);
2158 }
2159
2160 static void
2161 sjlj_emit_dispatch_table (dispatch_label, lp_info)
2162 rtx dispatch_label;
2163 struct sjlj_lp_info *lp_info;
2164 {
2165 int i, first_reachable;
2166 rtx mem, dispatch, seq, fc;
2167
2168 fc = cfun->eh->sjlj_fc;
2169
2170 start_sequence ();
2171
2172 emit_label (dispatch_label);
2173
2174 #ifndef DONT_USE_BUILTIN_SETJMP
2175 expand_builtin_setjmp_receiver (dispatch_label);
2176 #endif
2177
2178 /* Load up dispatch index, exc_ptr and filter values from the
2179 function context. */
2180 mem = adjust_address (fc, TYPE_MODE (integer_type_node),
2181 sjlj_fc_call_site_ofs);
2182 dispatch = copy_to_reg (mem);
2183
2184 mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs);
2185 if (word_mode != Pmode)
2186 {
2187 #ifdef POINTERS_EXTEND_UNSIGNED
2188 mem = convert_memory_address (Pmode, mem);
2189 #else
2190 mem = convert_to_mode (Pmode, mem, 0);
2191 #endif
2192 }
2193 emit_move_insn (cfun->eh->exc_ptr, mem);
2194
2195 mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs + UNITS_PER_WORD);
2196 emit_move_insn (cfun->eh->filter, mem);
2197
2198 /* Jump to one of the directly reachable regions. */
2199 /* ??? This really ought to be using a switch statement. */
2200
2201 first_reachable = 0;
2202 for (i = cfun->eh->last_region_number; i > 0; --i)
2203 {
2204 if (! lp_info[i].directly_reachable)
2205 continue;
2206
2207 if (! first_reachable)
2208 {
2209 first_reachable = i;
2210 continue;
2211 }
2212
2213 emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index),
2214 EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0,
2215 cfun->eh->region_array[i]->post_landing_pad);
2216 }
2217
2218 seq = get_insns ();
2219 end_sequence ();
2220
2221 emit_insn_before (seq, (cfun->eh->region_array[first_reachable]
2222 ->post_landing_pad));
2223 }
2224
2225 static void
2226 sjlj_build_landing_pads ()
2227 {
2228 struct sjlj_lp_info *lp_info;
2229
2230 lp_info = (struct sjlj_lp_info *) xcalloc (cfun->eh->last_region_number + 1,
2231 sizeof (struct sjlj_lp_info));
2232
2233 if (sjlj_find_directly_reachable_regions (lp_info))
2234 {
2235 rtx dispatch_label = gen_label_rtx ();
2236
2237 cfun->eh->sjlj_fc
2238 = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
2239 int_size_in_bytes (sjlj_fc_type_node),
2240 TYPE_ALIGN (sjlj_fc_type_node));
2241
2242 sjlj_assign_call_site_values (dispatch_label, lp_info);
2243 sjlj_mark_call_sites (lp_info);
2244
2245 sjlj_emit_function_enter (dispatch_label);
2246 sjlj_emit_dispatch_table (dispatch_label, lp_info);
2247 sjlj_emit_function_exit ();
2248 }
2249
2250 free (lp_info);
2251 }
2252
2253 void
2254 finish_eh_generation ()
2255 {
2256 /* Nothing to do if no regions created. */
2257 if (cfun->eh->region_tree == NULL)
2258 return;
2259
2260 /* The object here is to provide find_basic_blocks with detailed
2261 information (via reachable_handlers) on how exception control
2262 flows within the function. In this first pass, we can include
2263 type information garnered from ERT_THROW and ERT_ALLOWED_EXCEPTIONS
2264 regions, and hope that it will be useful in deleting unreachable
2265 handlers. Subsequently, we will generate landing pads which will
2266 connect many of the handlers, and then type information will not
2267 be effective. Still, this is a win over previous implementations. */
2268
2269 cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL);
2270
2271 /* These registers are used by the landing pads. Make sure they
2272 have been generated. */
2273 get_exception_pointer (cfun);
2274 get_exception_filter (cfun);
2275
2276 /* Construct the landing pads. */
2277
2278 assign_filter_values ();
2279 build_post_landing_pads ();
2280 connect_post_landing_pads ();
2281 if (USING_SJLJ_EXCEPTIONS)
2282 sjlj_build_landing_pads ();
2283 else
2284 dw2_build_landing_pads ();
2285
2286 cfun->eh->built_landing_pads = 1;
2287
2288 /* We've totally changed the CFG. Start over. */
2289 find_exception_handler_labels ();
2290 rebuild_jump_labels (get_insns ());
2291 find_basic_blocks (get_insns (), max_reg_num (), 0);
2292 cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL);
2293 }
2294 \f
2295 static hashval_t
2296 ehl_hash (pentry)
2297 const PTR pentry;
2298 {
2299 struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry;
2300
2301 /* 2^32 * ((sqrt(5) - 1) / 2) */
2302 const hashval_t scaled_golden_ratio = 0x9e3779b9;
2303 return CODE_LABEL_NUMBER (entry->label) * scaled_golden_ratio;
2304 }
2305
2306 static int
2307 ehl_eq (pentry, pdata)
2308 const PTR pentry;
2309 const PTR pdata;
2310 {
2311 struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry;
2312 struct ehl_map_entry *data = (struct ehl_map_entry *) pdata;
2313
2314 return entry->label == data->label;
2315 }
2316
2317 /* This section handles removing dead code for flow. */
2318
2319 /* Remove LABEL from exception_handler_label_map. */
2320
2321 static void
2322 remove_exception_handler_label (label)
2323 rtx label;
2324 {
2325 struct ehl_map_entry **slot, tmp;
2326
2327 /* If exception_handler_label_map was not built yet,
2328 there is nothing to do. */
2329 if (cfun->eh->exception_handler_label_map == NULL)
2330 return;
2331
2332 tmp.label = label;
2333 slot = (struct ehl_map_entry **)
2334 htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
2335 if (! slot)
2336 abort ();
2337
2338 htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot);
2339 }
2340
2341 /* Splice REGION from the region tree etc. */
2342
2343 static void
2344 remove_eh_handler (region)
2345 struct eh_region *region;
2346 {
2347 struct eh_region **pp, **pp_start, *p, *outer, *inner;
2348 rtx lab;
2349
2350 /* For the benefit of efficiently handling REG_EH_REGION notes,
2351 replace this region in the region array with its containing
2352 region. Note that previous region deletions may result in
2353 multiple copies of this region in the array, so we have a
2354 list of alternate numbers by which we are known. */
2355
2356 outer = region->outer;
2357 cfun->eh->region_array[region->region_number] = outer;
2358 if (region->aka)
2359 {
2360 int i;
2361 EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i,
2362 { cfun->eh->region_array[i] = outer; });
2363 }
2364
2365 if (outer)
2366 {
2367 if (!outer->aka)
2368 outer->aka = BITMAP_GGC_ALLOC ();
2369 if (region->aka)
2370 bitmap_a_or_b (outer->aka, outer->aka, region->aka);
2371 bitmap_set_bit (outer->aka, region->region_number);
2372 }
2373
2374 if (cfun->eh->built_landing_pads)
2375 lab = region->landing_pad;
2376 else
2377 lab = region->label;
2378 if (lab)
2379 remove_exception_handler_label (lab);
2380
2381 if (outer)
2382 pp_start = &outer->inner;
2383 else
2384 pp_start = &cfun->eh->region_tree;
2385 for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
2386 continue;
2387 *pp = region->next_peer;
2388
2389 inner = region->inner;
2390 if (inner)
2391 {
2392 for (p = inner; p->next_peer ; p = p->next_peer)
2393 p->outer = outer;
2394 p->outer = outer;
2395
2396 p->next_peer = *pp_start;
2397 *pp_start = inner;
2398 }
2399
2400 if (region->type == ERT_CATCH)
2401 {
2402 struct eh_region *try, *next, *prev;
2403
2404 for (try = region->next_peer;
2405 try->type == ERT_CATCH;
2406 try = try->next_peer)
2407 continue;
2408 if (try->type != ERT_TRY)
2409 abort ();
2410
2411 next = region->u.catch.next_catch;
2412 prev = region->u.catch.prev_catch;
2413
2414 if (next)
2415 next->u.catch.prev_catch = prev;
2416 else
2417 try->u.try.last_catch = prev;
2418 if (prev)
2419 prev->u.catch.next_catch = next;
2420 else
2421 {
2422 try->u.try.catch = next;
2423 if (! next)
2424 remove_eh_handler (try);
2425 }
2426 }
2427 }
2428
2429 /* LABEL heads a basic block that is about to be deleted. If this
2430 label corresponds to an exception region, we may be able to
2431 delete the region. */
2432
2433 void
2434 maybe_remove_eh_handler (label)
2435 rtx label;
2436 {
2437 struct ehl_map_entry **slot, tmp;
2438 struct eh_region *region;
2439
2440 /* ??? After generating landing pads, it's not so simple to determine
2441 if the region data is completely unused. One must examine the
2442 landing pad and the post landing pad, and whether an inner try block
2443 is referencing the catch handlers directly. */
2444 if (cfun->eh->built_landing_pads)
2445 return;
2446
2447 tmp.label = label;
2448 slot = (struct ehl_map_entry **)
2449 htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
2450 if (! slot)
2451 return;
2452 region = (*slot)->region;
2453 if (! region)
2454 return;
2455
2456 /* Flow will want to remove MUST_NOT_THROW regions as unreachable
2457 because there is no path to the fallback call to terminate.
2458 But the region continues to affect call-site data until there
2459 are no more contained calls, which we don't see here. */
2460 if (region->type == ERT_MUST_NOT_THROW)
2461 {
2462 htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot);
2463 region->label = NULL_RTX;
2464 }
2465 else
2466 remove_eh_handler (region);
2467 }
2468
2469 /* Invokes CALLBACK for every exception handler label. Only used by old
2470 loop hackery; should not be used by new code. */
2471
2472 void
2473 for_each_eh_label (callback)
2474 void (*callback) PARAMS ((rtx));
2475 {
2476 htab_traverse (cfun->eh->exception_handler_label_map, for_each_eh_label_1,
2477 (void *)callback);
2478 }
2479
2480 static int
2481 for_each_eh_label_1 (pentry, data)
2482 PTR *pentry;
2483 PTR data;
2484 {
2485 struct ehl_map_entry *entry = *(struct ehl_map_entry **)pentry;
2486 void (*callback) PARAMS ((rtx)) = (void (*) PARAMS ((rtx))) data;
2487
2488 (*callback) (entry->label);
2489 return 1;
2490 }
2491 \f
2492 /* This section describes CFG exception edges for flow. */
2493
2494 /* For communicating between calls to reachable_next_level. */
2495 struct reachable_info GTY(())
2496 {
2497 tree types_caught;
2498 tree types_allowed;
2499 rtx handlers;
2500 };
2501
2502 /* A subroutine of reachable_next_level. Return true if TYPE, or a
2503 base class of TYPE, is in HANDLED. */
2504
2505 static int
2506 check_handled (handled, type)
2507 tree handled, type;
2508 {
2509 tree t;
2510
2511 /* We can check for exact matches without front-end help. */
2512 if (! lang_eh_type_covers)
2513 {
2514 for (t = handled; t ; t = TREE_CHAIN (t))
2515 if (TREE_VALUE (t) == type)
2516 return 1;
2517 }
2518 else
2519 {
2520 for (t = handled; t ; t = TREE_CHAIN (t))
2521 if ((*lang_eh_type_covers) (TREE_VALUE (t), type))
2522 return 1;
2523 }
2524
2525 return 0;
2526 }
2527
2528 /* A subroutine of reachable_next_level. If we are collecting a list
2529 of handlers, add one. After landing pad generation, reference
2530 it instead of the handlers themselves. Further, the handlers are
2531 all wired together, so by referencing one, we've got them all.
2532 Before landing pad generation we reference each handler individually.
2533
2534 LP_REGION contains the landing pad; REGION is the handler. */
2535
2536 static void
2537 add_reachable_handler (info, lp_region, region)
2538 struct reachable_info *info;
2539 struct eh_region *lp_region;
2540 struct eh_region *region;
2541 {
2542 if (! info)
2543 return;
2544
2545 if (cfun->eh->built_landing_pads)
2546 {
2547 if (! info->handlers)
2548 info->handlers = alloc_INSN_LIST (lp_region->landing_pad, NULL_RTX);
2549 }
2550 else
2551 info->handlers = alloc_INSN_LIST (region->label, info->handlers);
2552 }
2553
2554 /* Process one level of exception regions for reachability.
2555 If TYPE_THROWN is non-null, then it is the *exact* type being
2556 propagated. If INFO is non-null, then collect handler labels
2557 and caught/allowed type information between invocations. */
2558
2559 static enum reachable_code
2560 reachable_next_level (region, type_thrown, info)
2561 struct eh_region *region;
2562 tree type_thrown;
2563 struct reachable_info *info;
2564 {
2565 switch (region->type)
2566 {
2567 case ERT_CLEANUP:
2568 /* Before landing-pad generation, we model control flow
2569 directly to the individual handlers. In this way we can
2570 see that catch handler types may shadow one another. */
2571 add_reachable_handler (info, region, region);
2572 return RNL_MAYBE_CAUGHT;
2573
2574 case ERT_TRY:
2575 {
2576 struct eh_region *c;
2577 enum reachable_code ret = RNL_NOT_CAUGHT;
2578
2579 for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
2580 {
2581 /* A catch-all handler ends the search. */
2582 /* ??? _Unwind_ForcedUnwind will want outer cleanups
2583 to be run as well. */
2584 if (c->u.catch.type_list == NULL)
2585 {
2586 add_reachable_handler (info, region, c);
2587 return RNL_CAUGHT;
2588 }
2589
2590 if (type_thrown)
2591 {
2592 /* If we have at least one type match, end the search. */
2593 tree tp_node = c->u.catch.type_list;
2594
2595 for (; tp_node; tp_node = TREE_CHAIN (tp_node))
2596 {
2597 tree type = TREE_VALUE (tp_node);
2598
2599 if (type == type_thrown
2600 || (lang_eh_type_covers
2601 && (*lang_eh_type_covers) (type, type_thrown)))
2602 {
2603 add_reachable_handler (info, region, c);
2604 return RNL_CAUGHT;
2605 }
2606 }
2607
2608 /* If we have definitive information of a match failure,
2609 the catch won't trigger. */
2610 if (lang_eh_type_covers)
2611 return RNL_NOT_CAUGHT;
2612 }
2613
2614 /* At this point, we either don't know what type is thrown or
2615 don't have front-end assistance to help deciding if it is
2616 covered by one of the types in the list for this region.
2617
2618 We'd then like to add this region to the list of reachable
2619 handlers since it is indeed potentially reachable based on the
2620 information we have.
2621
2622 Actually, this handler is for sure not reachable if all the
2623 types it matches have already been caught. That is, it is only
2624 potentially reachable if at least one of the types it catches
2625 has not been previously caught. */
2626
2627 if (! info)
2628 ret = RNL_MAYBE_CAUGHT;
2629 else
2630 {
2631 tree tp_node = c->u.catch.type_list;
2632 bool maybe_reachable = false;
2633
2634 /* Compute the potential reachability of this handler and
2635 update the list of types caught at the same time. */
2636 for (; tp_node; tp_node = TREE_CHAIN (tp_node))
2637 {
2638 tree type = TREE_VALUE (tp_node);
2639
2640 if (! check_handled (info->types_caught, type))
2641 {
2642 info->types_caught
2643 = tree_cons (NULL, type, info->types_caught);
2644
2645 maybe_reachable = true;
2646 }
2647 }
2648
2649 if (maybe_reachable)
2650 {
2651 add_reachable_handler (info, region, c);
2652
2653 /* ??? If the catch type is a base class of every allowed
2654 type, then we know we can stop the search. */
2655 ret = RNL_MAYBE_CAUGHT;
2656 }
2657 }
2658 }
2659
2660 return ret;
2661 }
2662
2663 case ERT_ALLOWED_EXCEPTIONS:
2664 /* An empty list of types definitely ends the search. */
2665 if (region->u.allowed.type_list == NULL_TREE)
2666 {
2667 add_reachable_handler (info, region, region);
2668 return RNL_CAUGHT;
2669 }
2670
2671 /* Collect a list of lists of allowed types for use in detecting
2672 when a catch may be transformed into a catch-all. */
2673 if (info)
2674 info->types_allowed = tree_cons (NULL_TREE,
2675 region->u.allowed.type_list,
2676 info->types_allowed);
2677
2678 /* If we have definitive information about the type hierarchy,
2679 then we can tell if the thrown type will pass through the
2680 filter. */
2681 if (type_thrown && lang_eh_type_covers)
2682 {
2683 if (check_handled (region->u.allowed.type_list, type_thrown))
2684 return RNL_NOT_CAUGHT;
2685 else
2686 {
2687 add_reachable_handler (info, region, region);
2688 return RNL_CAUGHT;
2689 }
2690 }
2691
2692 add_reachable_handler (info, region, region);
2693 return RNL_MAYBE_CAUGHT;
2694
2695 case ERT_CATCH:
2696 /* Catch regions are handled by their controling try region. */
2697 return RNL_NOT_CAUGHT;
2698
2699 case ERT_MUST_NOT_THROW:
2700 /* Here we end our search, since no exceptions may propagate.
2701 If we've touched down at some landing pad previous, then the
2702 explicit function call we generated may be used. Otherwise
2703 the call is made by the runtime. */
2704 if (info && info->handlers)
2705 {
2706 add_reachable_handler (info, region, region);
2707 return RNL_CAUGHT;
2708 }
2709 else
2710 return RNL_BLOCKED;
2711
2712 case ERT_THROW:
2713 case ERT_FIXUP:
2714 case ERT_UNKNOWN:
2715 /* Shouldn't see these here. */
2716 break;
2717 }
2718
2719 abort ();
2720 }
2721
2722 /* Retrieve a list of labels of exception handlers which can be
2723 reached by a given insn. */
2724
2725 rtx
2726 reachable_handlers (insn)
2727 rtx insn;
2728 {
2729 struct reachable_info info;
2730 struct eh_region *region;
2731 tree type_thrown;
2732 int region_number;
2733
2734 if (GET_CODE (insn) == JUMP_INSN
2735 && GET_CODE (PATTERN (insn)) == RESX)
2736 region_number = XINT (PATTERN (insn), 0);
2737 else
2738 {
2739 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2740 if (!note || INTVAL (XEXP (note, 0)) <= 0)
2741 return NULL;
2742 region_number = INTVAL (XEXP (note, 0));
2743 }
2744
2745 memset (&info, 0, sizeof (info));
2746
2747 region = cfun->eh->region_array[region_number];
2748
2749 type_thrown = NULL_TREE;
2750 if (GET_CODE (insn) == JUMP_INSN
2751 && GET_CODE (PATTERN (insn)) == RESX)
2752 {
2753 /* A RESX leaves a region instead of entering it. Thus the
2754 region itself may have been deleted out from under us. */
2755 if (region == NULL)
2756 return NULL;
2757 region = region->outer;
2758 }
2759 else if (region->type == ERT_THROW)
2760 {
2761 type_thrown = region->u.throw.type;
2762 region = region->outer;
2763 }
2764
2765 for (; region; region = region->outer)
2766 if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
2767 break;
2768
2769 return info.handlers;
2770 }
2771
2772 /* Determine if the given INSN can throw an exception that is caught
2773 within the function. */
2774
2775 bool
2776 can_throw_internal (insn)
2777 rtx insn;
2778 {
2779 struct eh_region *region;
2780 tree type_thrown;
2781 rtx note;
2782
2783 if (! INSN_P (insn))
2784 return false;
2785
2786 if (GET_CODE (insn) == INSN
2787 && GET_CODE (PATTERN (insn)) == SEQUENCE)
2788 insn = XVECEXP (PATTERN (insn), 0, 0);
2789
2790 if (GET_CODE (insn) == CALL_INSN
2791 && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
2792 {
2793 int i;
2794 for (i = 0; i < 3; ++i)
2795 {
2796 rtx sub = XEXP (PATTERN (insn), i);
2797 for (; sub ; sub = NEXT_INSN (sub))
2798 if (can_throw_internal (sub))
2799 return true;
2800 }
2801 return false;
2802 }
2803
2804 /* Every insn that might throw has an EH_REGION note. */
2805 note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2806 if (!note || INTVAL (XEXP (note, 0)) <= 0)
2807 return false;
2808
2809 region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2810
2811 type_thrown = NULL_TREE;
2812 if (region->type == ERT_THROW)
2813 {
2814 type_thrown = region->u.throw.type;
2815 region = region->outer;
2816 }
2817
2818 /* If this exception is ignored by each and every containing region,
2819 then control passes straight out. The runtime may handle some
2820 regions, which also do not require processing internally. */
2821 for (; region; region = region->outer)
2822 {
2823 enum reachable_code how = reachable_next_level (region, type_thrown, 0);
2824 if (how == RNL_BLOCKED)
2825 return false;
2826 if (how != RNL_NOT_CAUGHT)
2827 return true;
2828 }
2829
2830 return false;
2831 }
2832
2833 /* Determine if the given INSN can throw an exception that is
2834 visible outside the function. */
2835
2836 bool
2837 can_throw_external (insn)
2838 rtx insn;
2839 {
2840 struct eh_region *region;
2841 tree type_thrown;
2842 rtx note;
2843
2844 if (! INSN_P (insn))
2845 return false;
2846
2847 if (GET_CODE (insn) == INSN
2848 && GET_CODE (PATTERN (insn)) == SEQUENCE)
2849 insn = XVECEXP (PATTERN (insn), 0, 0);
2850
2851 if (GET_CODE (insn) == CALL_INSN
2852 && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
2853 {
2854 int i;
2855 for (i = 0; i < 3; ++i)
2856 {
2857 rtx sub = XEXP (PATTERN (insn), i);
2858 for (; sub ; sub = NEXT_INSN (sub))
2859 if (can_throw_external (sub))
2860 return true;
2861 }
2862 return false;
2863 }
2864
2865 note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2866 if (!note)
2867 {
2868 /* Calls (and trapping insns) without notes are outside any
2869 exception handling region in this function. We have to
2870 assume it might throw. Given that the front end and middle
2871 ends mark known NOTHROW functions, this isn't so wildly
2872 inaccurate. */
2873 return (GET_CODE (insn) == CALL_INSN
2874 || (flag_non_call_exceptions
2875 && may_trap_p (PATTERN (insn))));
2876 }
2877 if (INTVAL (XEXP (note, 0)) <= 0)
2878 return false;
2879
2880 region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2881
2882 type_thrown = NULL_TREE;
2883 if (region->type == ERT_THROW)
2884 {
2885 type_thrown = region->u.throw.type;
2886 region = region->outer;
2887 }
2888
2889 /* If the exception is caught or blocked by any containing region,
2890 then it is not seen by any calling function. */
2891 for (; region ; region = region->outer)
2892 if (reachable_next_level (region, type_thrown, NULL) >= RNL_CAUGHT)
2893 return false;
2894
2895 return true;
2896 }
2897
2898 /* Set current_function_nothrow and cfun->all_throwers_are_sibcalls. */
2899
2900 void
2901 set_nothrow_function_flags ()
2902 {
2903 rtx insn;
2904
2905 current_function_nothrow = 1;
2906
2907 /* Assume cfun->all_throwers_are_sibcalls until we encounter
2908 something that can throw an exception. We specifically exempt
2909 CALL_INSNs that are SIBLING_CALL_P, as these are really jumps,
2910 and can't throw. Most CALL_INSNs are not SIBLING_CALL_P, so this
2911 is optimistic. */
2912
2913 cfun->all_throwers_are_sibcalls = 1;
2914
2915 if (! flag_exceptions)
2916 return;
2917
2918 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2919 if (can_throw_external (insn))
2920 {
2921 current_function_nothrow = 0;
2922
2923 if (GET_CODE (insn) != CALL_INSN || !SIBLING_CALL_P (insn))
2924 {
2925 cfun->all_throwers_are_sibcalls = 0;
2926 return;
2927 }
2928 }
2929
2930 for (insn = current_function_epilogue_delay_list; insn;
2931 insn = XEXP (insn, 1))
2932 if (can_throw_external (insn))
2933 {
2934 current_function_nothrow = 0;
2935
2936 if (GET_CODE (insn) != CALL_INSN || !SIBLING_CALL_P (insn))
2937 {
2938 cfun->all_throwers_are_sibcalls = 0;
2939 return;
2940 }
2941 }
2942 }
2943
2944 \f
2945 /* Various hooks for unwind library. */
2946
2947 /* Do any necessary initialization to access arbitrary stack frames.
2948 On the SPARC, this means flushing the register windows. */
2949
2950 void
2951 expand_builtin_unwind_init ()
2952 {
2953 /* Set this so all the registers get saved in our frame; we need to be
2954 able to copy the saved values for any registers from frames we unwind. */
2955 current_function_has_nonlocal_label = 1;
2956
2957 #ifdef SETUP_FRAME_ADDRESSES
2958 SETUP_FRAME_ADDRESSES ();
2959 #endif
2960 }
2961
2962 rtx
2963 expand_builtin_eh_return_data_regno (arglist)
2964 tree arglist;
2965 {
2966 tree which = TREE_VALUE (arglist);
2967 unsigned HOST_WIDE_INT iwhich;
2968
2969 if (TREE_CODE (which) != INTEGER_CST)
2970 {
2971 error ("argument of `__builtin_eh_return_regno' must be constant");
2972 return constm1_rtx;
2973 }
2974
2975 iwhich = tree_low_cst (which, 1);
2976 iwhich = EH_RETURN_DATA_REGNO (iwhich);
2977 if (iwhich == INVALID_REGNUM)
2978 return constm1_rtx;
2979
2980 #ifdef DWARF_FRAME_REGNUM
2981 iwhich = DWARF_FRAME_REGNUM (iwhich);
2982 #else
2983 iwhich = DBX_REGISTER_NUMBER (iwhich);
2984 #endif
2985
2986 return GEN_INT (iwhich);
2987 }
2988
2989 /* Given a value extracted from the return address register or stack slot,
2990 return the actual address encoded in that value. */
2991
2992 rtx
2993 expand_builtin_extract_return_addr (addr_tree)
2994 tree addr_tree;
2995 {
2996 rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
2997
2998 if (GET_MODE (addr) != Pmode
2999 && GET_MODE (addr) != VOIDmode)
3000 {
3001 #ifdef POINTERS_EXTEND_UNSIGNED
3002 addr = convert_memory_address (Pmode, addr);
3003 #else
3004 addr = convert_to_mode (Pmode, addr, 0);
3005 #endif
3006 }
3007
3008 /* First mask out any unwanted bits. */
3009 #ifdef MASK_RETURN_ADDR
3010 expand_and (Pmode, addr, MASK_RETURN_ADDR, addr);
3011 #endif
3012
3013 /* Then adjust to find the real return address. */
3014 #if defined (RETURN_ADDR_OFFSET)
3015 addr = plus_constant (addr, RETURN_ADDR_OFFSET);
3016 #endif
3017
3018 return addr;
3019 }
3020
3021 /* Given an actual address in addr_tree, do any necessary encoding
3022 and return the value to be stored in the return address register or
3023 stack slot so the epilogue will return to that address. */
3024
3025 rtx
3026 expand_builtin_frob_return_addr (addr_tree)
3027 tree addr_tree;
3028 {
3029 rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, 0);
3030
3031 #ifdef POINTERS_EXTEND_UNSIGNED
3032 if (GET_MODE (addr) != Pmode)
3033 addr = convert_memory_address (Pmode, addr);
3034 #endif
3035
3036 #ifdef RETURN_ADDR_OFFSET
3037 addr = force_reg (Pmode, addr);
3038 addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
3039 #endif
3040
3041 return addr;
3042 }
3043
3044 /* Set up the epilogue with the magic bits we'll need to return to the
3045 exception handler. */
3046
3047 void
3048 expand_builtin_eh_return (stackadj_tree, handler_tree)
3049 tree stackadj_tree, handler_tree;
3050 {
3051 rtx stackadj, handler;
3052
3053 stackadj = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0);
3054 handler = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0);
3055
3056 #ifdef POINTERS_EXTEND_UNSIGNED
3057 if (GET_MODE (stackadj) != Pmode)
3058 stackadj = convert_memory_address (Pmode, stackadj);
3059
3060 if (GET_MODE (handler) != Pmode)
3061 handler = convert_memory_address (Pmode, handler);
3062 #endif
3063
3064 if (! cfun->eh->ehr_label)
3065 {
3066 cfun->eh->ehr_stackadj = copy_to_reg (stackadj);
3067 cfun->eh->ehr_handler = copy_to_reg (handler);
3068 cfun->eh->ehr_label = gen_label_rtx ();
3069 }
3070 else
3071 {
3072 if (stackadj != cfun->eh->ehr_stackadj)
3073 emit_move_insn (cfun->eh->ehr_stackadj, stackadj);
3074 if (handler != cfun->eh->ehr_handler)
3075 emit_move_insn (cfun->eh->ehr_handler, handler);
3076 }
3077
3078 emit_jump (cfun->eh->ehr_label);
3079 }
3080
3081 void
3082 expand_eh_return ()
3083 {
3084 rtx sa, ra, around_label;
3085
3086 if (! cfun->eh->ehr_label)
3087 return;
3088
3089 sa = EH_RETURN_STACKADJ_RTX;
3090 if (! sa)
3091 {
3092 error ("__builtin_eh_return not supported on this target");
3093 return;
3094 }
3095
3096 current_function_calls_eh_return = 1;
3097
3098 around_label = gen_label_rtx ();
3099 emit_move_insn (sa, const0_rtx);
3100 emit_jump (around_label);
3101
3102 emit_label (cfun->eh->ehr_label);
3103 clobber_return_register ();
3104
3105 #ifdef HAVE_eh_return
3106 if (HAVE_eh_return)
3107 emit_insn (gen_eh_return (cfun->eh->ehr_stackadj, cfun->eh->ehr_handler));
3108 else
3109 #endif
3110 {
3111 ra = EH_RETURN_HANDLER_RTX;
3112 if (! ra)
3113 {
3114 error ("__builtin_eh_return not supported on this target");
3115 ra = gen_reg_rtx (Pmode);
3116 }
3117
3118 emit_move_insn (sa, cfun->eh->ehr_stackadj);
3119 emit_move_insn (ra, cfun->eh->ehr_handler);
3120 }
3121
3122 emit_label (around_label);
3123 }
3124 \f
3125 /* In the following functions, we represent entries in the action table
3126 as 1-based indices. Special cases are:
3127
3128 0: null action record, non-null landing pad; implies cleanups
3129 -1: null action record, null landing pad; implies no action
3130 -2: no call-site entry; implies must_not_throw
3131 -3: we have yet to process outer regions
3132
3133 Further, no special cases apply to the "next" field of the record.
3134 For next, 0 means end of list. */
3135
3136 struct action_record
3137 {
3138 int offset;
3139 int filter;
3140 int next;
3141 };
3142
3143 static int
3144 action_record_eq (pentry, pdata)
3145 const PTR pentry;
3146 const PTR pdata;
3147 {
3148 const struct action_record *entry = (const struct action_record *) pentry;
3149 const struct action_record *data = (const struct action_record *) pdata;
3150 return entry->filter == data->filter && entry->next == data->next;
3151 }
3152
3153 static hashval_t
3154 action_record_hash (pentry)
3155 const PTR pentry;
3156 {
3157 const struct action_record *entry = (const struct action_record *) pentry;
3158 return entry->next * 1009 + entry->filter;
3159 }
3160
3161 static int
3162 add_action_record (ar_hash, filter, next)
3163 htab_t ar_hash;
3164 int filter, next;
3165 {
3166 struct action_record **slot, *new, tmp;
3167
3168 tmp.filter = filter;
3169 tmp.next = next;
3170 slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT);
3171
3172 if ((new = *slot) == NULL)
3173 {
3174 new = (struct action_record *) xmalloc (sizeof (*new));
3175 new->offset = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
3176 new->filter = filter;
3177 new->next = next;
3178 *slot = new;
3179
3180 /* The filter value goes in untouched. The link to the next
3181 record is a "self-relative" byte offset, or zero to indicate
3182 that there is no next record. So convert the absolute 1 based
3183 indices we've been carrying around into a displacement. */
3184
3185 push_sleb128 (&cfun->eh->action_record_data, filter);
3186 if (next)
3187 next -= VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
3188 push_sleb128 (&cfun->eh->action_record_data, next);
3189 }
3190
3191 return new->offset;
3192 }
3193
3194 static int
3195 collect_one_action_chain (ar_hash, region)
3196 htab_t ar_hash;
3197 struct eh_region *region;
3198 {
3199 struct eh_region *c;
3200 int next;
3201
3202 /* If we've reached the top of the region chain, then we have
3203 no actions, and require no landing pad. */
3204 if (region == NULL)
3205 return -1;
3206
3207 switch (region->type)
3208 {
3209 case ERT_CLEANUP:
3210 /* A cleanup adds a zero filter to the beginning of the chain, but
3211 there are special cases to look out for. If there are *only*
3212 cleanups along a path, then it compresses to a zero action.
3213 Further, if there are multiple cleanups along a path, we only
3214 need to represent one of them, as that is enough to trigger
3215 entry to the landing pad at runtime. */
3216 next = collect_one_action_chain (ar_hash, region->outer);
3217 if (next <= 0)
3218 return 0;
3219 for (c = region->outer; c ; c = c->outer)
3220 if (c->type == ERT_CLEANUP)
3221 return next;
3222 return add_action_record (ar_hash, 0, next);
3223
3224 case ERT_TRY:
3225 /* Process the associated catch regions in reverse order.
3226 If there's a catch-all handler, then we don't need to
3227 search outer regions. Use a magic -3 value to record
3228 that we haven't done the outer search. */
3229 next = -3;
3230 for (c = region->u.try.last_catch; c ; c = c->u.catch.prev_catch)
3231 {
3232 if (c->u.catch.type_list == NULL)
3233 {
3234 /* Retrieve the filter from the head of the filter list
3235 where we have stored it (see assign_filter_values). */
3236 int filter
3237 = TREE_INT_CST_LOW (TREE_VALUE (c->u.catch.filter_list));
3238
3239 next = add_action_record (ar_hash, filter, 0);
3240 }
3241 else
3242 {
3243 /* Once the outer search is done, trigger an action record for
3244 each filter we have. */
3245 tree flt_node;
3246
3247 if (next == -3)
3248 {
3249 next = collect_one_action_chain (ar_hash, region->outer);
3250
3251 /* If there is no next action, terminate the chain. */
3252 if (next == -1)
3253 next = 0;
3254 /* If all outer actions are cleanups or must_not_throw,
3255 we'll have no action record for it, since we had wanted
3256 to encode these states in the call-site record directly.
3257 Add a cleanup action to the chain to catch these. */
3258 else if (next <= 0)
3259 next = add_action_record (ar_hash, 0, 0);
3260 }
3261
3262 flt_node = c->u.catch.filter_list;
3263 for (; flt_node; flt_node = TREE_CHAIN (flt_node))
3264 {
3265 int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node));
3266 next = add_action_record (ar_hash, filter, next);
3267 }
3268 }
3269 }
3270 return next;
3271
3272 case ERT_ALLOWED_EXCEPTIONS:
3273 /* An exception specification adds its filter to the
3274 beginning of the chain. */
3275 next = collect_one_action_chain (ar_hash, region->outer);
3276 return add_action_record (ar_hash, region->u.allowed.filter,
3277 next < 0 ? 0 : next);
3278
3279 case ERT_MUST_NOT_THROW:
3280 /* A must-not-throw region with no inner handlers or cleanups
3281 requires no call-site entry. Note that this differs from
3282 the no handler or cleanup case in that we do require an lsda
3283 to be generated. Return a magic -2 value to record this. */
3284 return -2;
3285
3286 case ERT_CATCH:
3287 case ERT_THROW:
3288 /* CATCH regions are handled in TRY above. THROW regions are
3289 for optimization information only and produce no output. */
3290 return collect_one_action_chain (ar_hash, region->outer);
3291
3292 default:
3293 abort ();
3294 }
3295 }
3296
3297 static int
3298 add_call_site (landing_pad, action)
3299 rtx landing_pad;
3300 int action;
3301 {
3302 struct call_site_record *data = cfun->eh->call_site_data;
3303 int used = cfun->eh->call_site_data_used;
3304 int size = cfun->eh->call_site_data_size;
3305
3306 if (used >= size)
3307 {
3308 size = (size ? size * 2 : 64);
3309 data = (struct call_site_record *)
3310 ggc_realloc (data, sizeof (*data) * size);
3311 cfun->eh->call_site_data = data;
3312 cfun->eh->call_site_data_size = size;
3313 }
3314
3315 data[used].landing_pad = landing_pad;
3316 data[used].action = action;
3317
3318 cfun->eh->call_site_data_used = used + 1;
3319
3320 return used + call_site_base;
3321 }
3322
3323 /* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
3324 The new note numbers will not refer to region numbers, but
3325 instead to call site entries. */
3326
3327 void
3328 convert_to_eh_region_ranges ()
3329 {
3330 rtx insn, iter, note;
3331 htab_t ar_hash;
3332 int last_action = -3;
3333 rtx last_action_insn = NULL_RTX;
3334 rtx last_landing_pad = NULL_RTX;
3335 rtx first_no_action_insn = NULL_RTX;
3336 int call_site = 0;
3337
3338 if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL)
3339 return;
3340
3341 VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
3342
3343 ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
3344
3345 for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
3346 if (INSN_P (iter))
3347 {
3348 struct eh_region *region;
3349 int this_action;
3350 rtx this_landing_pad;
3351
3352 insn = iter;
3353 if (GET_CODE (insn) == INSN
3354 && GET_CODE (PATTERN (insn)) == SEQUENCE)
3355 insn = XVECEXP (PATTERN (insn), 0, 0);
3356
3357 note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3358 if (!note)
3359 {
3360 if (! (GET_CODE (insn) == CALL_INSN
3361 || (flag_non_call_exceptions
3362 && may_trap_p (PATTERN (insn)))))
3363 continue;
3364 this_action = -1;
3365 region = NULL;
3366 }
3367 else
3368 {
3369 if (INTVAL (XEXP (note, 0)) <= 0)
3370 continue;
3371 region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
3372 this_action = collect_one_action_chain (ar_hash, region);
3373 }
3374
3375 /* Existence of catch handlers, or must-not-throw regions
3376 implies that an lsda is needed (even if empty). */
3377 if (this_action != -1)
3378 cfun->uses_eh_lsda = 1;
3379
3380 /* Delay creation of region notes for no-action regions
3381 until we're sure that an lsda will be required. */
3382 else if (last_action == -3)
3383 {
3384 first_no_action_insn = iter;
3385 last_action = -1;
3386 }
3387
3388 /* Cleanups and handlers may share action chains but not
3389 landing pads. Collect the landing pad for this region. */
3390 if (this_action >= 0)
3391 {
3392 struct eh_region *o;
3393 for (o = region; ! o->landing_pad ; o = o->outer)
3394 continue;
3395 this_landing_pad = o->landing_pad;
3396 }
3397 else
3398 this_landing_pad = NULL_RTX;
3399
3400 /* Differing actions or landing pads implies a change in call-site
3401 info, which implies some EH_REGION note should be emitted. */
3402 if (last_action != this_action
3403 || last_landing_pad != this_landing_pad)
3404 {
3405 /* If we'd not seen a previous action (-3) or the previous
3406 action was must-not-throw (-2), then we do not need an
3407 end note. */
3408 if (last_action >= -1)
3409 {
3410 /* If we delayed the creation of the begin, do it now. */
3411 if (first_no_action_insn)
3412 {
3413 call_site = add_call_site (NULL_RTX, 0);
3414 note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
3415 first_no_action_insn);
3416 NOTE_EH_HANDLER (note) = call_site;
3417 first_no_action_insn = NULL_RTX;
3418 }
3419
3420 note = emit_note_after (NOTE_INSN_EH_REGION_END,
3421 last_action_insn);
3422 NOTE_EH_HANDLER (note) = call_site;
3423 }
3424
3425 /* If the new action is must-not-throw, then no region notes
3426 are created. */
3427 if (this_action >= -1)
3428 {
3429 call_site = add_call_site (this_landing_pad,
3430 this_action < 0 ? 0 : this_action);
3431 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter);
3432 NOTE_EH_HANDLER (note) = call_site;
3433 }
3434
3435 last_action = this_action;
3436 last_landing_pad = this_landing_pad;
3437 }
3438 last_action_insn = iter;
3439 }
3440
3441 if (last_action >= -1 && ! first_no_action_insn)
3442 {
3443 note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn);
3444 NOTE_EH_HANDLER (note) = call_site;
3445 }
3446
3447 htab_delete (ar_hash);
3448 }
3449
3450 \f
3451 static void
3452 push_uleb128 (data_area, value)
3453 varray_type *data_area;
3454 unsigned int value;
3455 {
3456 do
3457 {
3458 unsigned char byte = value & 0x7f;
3459 value >>= 7;
3460 if (value)
3461 byte |= 0x80;
3462 VARRAY_PUSH_UCHAR (*data_area, byte);
3463 }
3464 while (value);
3465 }
3466
3467 static void
3468 push_sleb128 (data_area, value)
3469 varray_type *data_area;
3470 int value;
3471 {
3472 unsigned char byte;
3473 int more;
3474
3475 do
3476 {
3477 byte = value & 0x7f;
3478 value >>= 7;
3479 more = ! ((value == 0 && (byte & 0x40) == 0)
3480 || (value == -1 && (byte & 0x40) != 0));
3481 if (more)
3482 byte |= 0x80;
3483 VARRAY_PUSH_UCHAR (*data_area, byte);
3484 }
3485 while (more);
3486 }
3487
3488 \f
3489 #ifndef HAVE_AS_LEB128
3490 static int
3491 dw2_size_of_call_site_table ()
3492 {
3493 int n = cfun->eh->call_site_data_used;
3494 int size = n * (4 + 4 + 4);
3495 int i;
3496
3497 for (i = 0; i < n; ++i)
3498 {
3499 struct call_site_record *cs = &cfun->eh->call_site_data[i];
3500 size += size_of_uleb128 (cs->action);
3501 }
3502
3503 return size;
3504 }
3505
3506 static int
3507 sjlj_size_of_call_site_table ()
3508 {
3509 int n = cfun->eh->call_site_data_used;
3510 int size = 0;
3511 int i;
3512
3513 for (i = 0; i < n; ++i)
3514 {
3515 struct call_site_record *cs = &cfun->eh->call_site_data[i];
3516 size += size_of_uleb128 (INTVAL (cs->landing_pad));
3517 size += size_of_uleb128 (cs->action);
3518 }
3519
3520 return size;
3521 }
3522 #endif
3523
3524 static void
3525 dw2_output_call_site_table ()
3526 {
3527 const char *const function_start_lab
3528 = IDENTIFIER_POINTER (current_function_func_begin_label);
3529 int n = cfun->eh->call_site_data_used;
3530 int i;
3531
3532 for (i = 0; i < n; ++i)
3533 {
3534 struct call_site_record *cs = &cfun->eh->call_site_data[i];
3535 char reg_start_lab[32];
3536 char reg_end_lab[32];
3537 char landing_pad_lab[32];
3538
3539 ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i);
3540 ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i);
3541
3542 if (cs->landing_pad)
3543 ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L",
3544 CODE_LABEL_NUMBER (cs->landing_pad));
3545
3546 /* ??? Perhaps use insn length scaling if the assembler supports
3547 generic arithmetic. */
3548 /* ??? Perhaps use attr_length to choose data1 or data2 instead of
3549 data4 if the function is small enough. */
3550 #ifdef HAVE_AS_LEB128
3551 dw2_asm_output_delta_uleb128 (reg_start_lab, function_start_lab,
3552 "region %d start", i);
3553 dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
3554 "length");
3555 if (cs->landing_pad)
3556 dw2_asm_output_delta_uleb128 (landing_pad_lab, function_start_lab,
3557 "landing pad");
3558 else
3559 dw2_asm_output_data_uleb128 (0, "landing pad");
3560 #else
3561 dw2_asm_output_delta (4, reg_start_lab, function_start_lab,
3562 "region %d start", i);
3563 dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
3564 if (cs->landing_pad)
3565 dw2_asm_output_delta (4, landing_pad_lab, function_start_lab,
3566 "landing pad");
3567 else
3568 dw2_asm_output_data (4, 0, "landing pad");
3569 #endif
3570 dw2_asm_output_data_uleb128 (cs->action, "action");
3571 }
3572
3573 call_site_base += n;
3574 }
3575
3576 static void
3577 sjlj_output_call_site_table ()
3578 {
3579 int n = cfun->eh->call_site_data_used;
3580 int i;
3581
3582 for (i = 0; i < n; ++i)
3583 {
3584 struct call_site_record *cs = &cfun->eh->call_site_data[i];
3585
3586 dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
3587 "region %d landing pad", i);
3588 dw2_asm_output_data_uleb128 (cs->action, "action");
3589 }
3590
3591 call_site_base += n;
3592 }
3593
3594 /* Tell assembler to switch to the section for the exception handling
3595 table. */
3596
3597 void
3598 default_exception_section ()
3599 {
3600 if (targetm.have_named_sections)
3601 {
3602 int flags;
3603 #ifdef HAVE_LD_RO_RW_SECTION_MIXING
3604 int tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3605
3606 flags = (! flag_pic
3607 || ((tt_format & 0x70) != DW_EH_PE_absptr
3608 && (tt_format & 0x70) != DW_EH_PE_aligned))
3609 ? 0 : SECTION_WRITE;
3610 #else
3611 flags = SECTION_WRITE;
3612 #endif
3613 named_section_flags (".gcc_except_table", flags);
3614 }
3615 else if (flag_pic)
3616 data_section ();
3617 else
3618 readonly_data_section ();
3619 }
3620
3621 void
3622 output_function_exception_table ()
3623 {
3624 int tt_format, cs_format, lp_format, i, n;
3625 #ifdef HAVE_AS_LEB128
3626 char ttype_label[32];
3627 char cs_after_size_label[32];
3628 char cs_end_label[32];
3629 #else
3630 int call_site_len;
3631 #endif
3632 int have_tt_data;
3633 int tt_format_size = 0;
3634
3635 /* Not all functions need anything. */
3636 if (! cfun->uses_eh_lsda)
3637 return;
3638
3639 #ifdef IA64_UNWIND_INFO
3640 fputs ("\t.personality\t", asm_out_file);
3641 output_addr_const (asm_out_file, eh_personality_libfunc);
3642 fputs ("\n\t.handlerdata\n", asm_out_file);
3643 /* Note that varasm still thinks we're in the function's code section.
3644 The ".endp" directive that will immediately follow will take us back. */
3645 #else
3646 (*targetm.asm_out.exception_section) ();
3647 #endif
3648
3649 have_tt_data = (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) > 0
3650 || VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) > 0);
3651
3652 /* Indicate the format of the @TType entries. */
3653 if (! have_tt_data)
3654 tt_format = DW_EH_PE_omit;
3655 else
3656 {
3657 tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3658 #ifdef HAVE_AS_LEB128
3659 ASM_GENERATE_INTERNAL_LABEL (ttype_label, "LLSDATT",
3660 current_function_funcdef_no);
3661 #endif
3662 tt_format_size = size_of_encoded_value (tt_format);
3663
3664 assemble_align (tt_format_size * BITS_PER_UNIT);
3665 }
3666
3667 (*targetm.asm_out.internal_label) (asm_out_file, "LLSDA",
3668 current_function_funcdef_no);
3669
3670 /* The LSDA header. */
3671
3672 /* Indicate the format of the landing pad start pointer. An omitted
3673 field implies @LPStart == @Start. */
3674 /* Currently we always put @LPStart == @Start. This field would
3675 be most useful in moving the landing pads completely out of
3676 line to another section, but it could also be used to minimize
3677 the size of uleb128 landing pad offsets. */
3678 lp_format = DW_EH_PE_omit;
3679 dw2_asm_output_data (1, lp_format, "@LPStart format (%s)",
3680 eh_data_format_name (lp_format));
3681
3682 /* @LPStart pointer would go here. */
3683
3684 dw2_asm_output_data (1, tt_format, "@TType format (%s)",
3685 eh_data_format_name (tt_format));
3686
3687 #ifndef HAVE_AS_LEB128
3688 if (USING_SJLJ_EXCEPTIONS)
3689 call_site_len = sjlj_size_of_call_site_table ();
3690 else
3691 call_site_len = dw2_size_of_call_site_table ();
3692 #endif
3693
3694 /* A pc-relative 4-byte displacement to the @TType data. */
3695 if (have_tt_data)
3696 {
3697 #ifdef HAVE_AS_LEB128
3698 char ttype_after_disp_label[32];
3699 ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label, "LLSDATTD",
3700 current_function_funcdef_no);
3701 dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label,
3702 "@TType base offset");
3703 ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
3704 #else
3705 /* Ug. Alignment queers things. */
3706 unsigned int before_disp, after_disp, last_disp, disp;
3707
3708 before_disp = 1 + 1;
3709 after_disp = (1 + size_of_uleb128 (call_site_len)
3710 + call_site_len
3711 + VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data)
3712 + (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data)
3713 * tt_format_size));
3714
3715 disp = after_disp;
3716 do
3717 {
3718 unsigned int disp_size, pad;
3719
3720 last_disp = disp;
3721 disp_size = size_of_uleb128 (disp);
3722 pad = before_disp + disp_size + after_disp;
3723 if (pad % tt_format_size)
3724 pad = tt_format_size - (pad % tt_format_size);
3725 else
3726 pad = 0;
3727 disp = after_disp + pad;
3728 }
3729 while (disp != last_disp);
3730
3731 dw2_asm_output_data_uleb128 (disp, "@TType base offset");
3732 #endif
3733 }
3734
3735 /* Indicate the format of the call-site offsets. */
3736 #ifdef HAVE_AS_LEB128
3737 cs_format = DW_EH_PE_uleb128;
3738 #else
3739 cs_format = DW_EH_PE_udata4;
3740 #endif
3741 dw2_asm_output_data (1, cs_format, "call-site format (%s)",
3742 eh_data_format_name (cs_format));
3743
3744 #ifdef HAVE_AS_LEB128
3745 ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label, "LLSDACSB",
3746 current_function_funcdef_no);
3747 ASM_GENERATE_INTERNAL_LABEL (cs_end_label, "LLSDACSE",
3748 current_function_funcdef_no);
3749 dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label,
3750 "Call-site table length");
3751 ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label);
3752 if (USING_SJLJ_EXCEPTIONS)
3753 sjlj_output_call_site_table ();
3754 else
3755 dw2_output_call_site_table ();
3756 ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
3757 #else
3758 dw2_asm_output_data_uleb128 (call_site_len,"Call-site table length");
3759 if (USING_SJLJ_EXCEPTIONS)
3760 sjlj_output_call_site_table ();
3761 else
3762 dw2_output_call_site_table ();
3763 #endif
3764
3765 /* ??? Decode and interpret the data for flag_debug_asm. */
3766 n = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data);
3767 for (i = 0; i < n; ++i)
3768 dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->action_record_data, i),
3769 (i ? NULL : "Action record table"));
3770
3771 if (have_tt_data)
3772 assemble_align (tt_format_size * BITS_PER_UNIT);
3773
3774 i = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data);
3775 while (i-- > 0)
3776 {
3777 tree type = VARRAY_TREE (cfun->eh->ttype_data, i);
3778 rtx value;
3779
3780 if (type == NULL_TREE)
3781 type = integer_zero_node;
3782 else
3783 type = lookup_type_for_runtime (type);
3784
3785 value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
3786 if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
3787 assemble_integer (value, tt_format_size,
3788 tt_format_size * BITS_PER_UNIT, 1);
3789 else
3790 dw2_asm_output_encoded_addr_rtx (tt_format, value, NULL);
3791 }
3792
3793 #ifdef HAVE_AS_LEB128
3794 if (have_tt_data)
3795 ASM_OUTPUT_LABEL (asm_out_file, ttype_label);
3796 #endif
3797
3798 /* ??? Decode and interpret the data for flag_debug_asm. */
3799 n = VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data);
3800 for (i = 0; i < n; ++i)
3801 dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->ehspec_data, i),
3802 (i ? NULL : "Exception specification table"));
3803
3804 function_section (current_function_decl);
3805 }
3806
3807 #include "gt-except.h"