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