OSDN Git Service

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