OSDN Git Service

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