OSDN Git Service

* except.c (remove_unreachable_regions): 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   /* ??? This comment was old before the most recent rewrite.  We
1041      really ought to fix the callers at some point.  */
1042   /* For backwards compatibility, we allow callers to omit calls to
1043      begin_protect_partials for the outermost region.  So, we must
1044      explicitly do so here.  */
1045   if (!cfun->eh->protect_list)
1046     begin_protect_partials ();
1047
1048   /* Add this entry to the front of the list.  */
1049   TREE_VALUE (cfun->eh->protect_list)
1050     = tree_cons (NULL_TREE, handler, TREE_VALUE (cfun->eh->protect_list));
1051 }
1052
1053 /* End all the pending exception regions on protect_list.  */
1054
1055 void
1056 end_protect_partials ()
1057 {
1058   tree t;
1059
1060   /* ??? This comment was old before the most recent rewrite.  We
1061      really ought to fix the callers at some point.  */
1062   /* For backwards compatibility, we allow callers to omit the call to
1063      begin_protect_partials for the outermost region.  So,
1064      PROTECT_LIST may be NULL.  */
1065   if (!cfun->eh->protect_list)
1066     return;
1067
1068   /* Pop the topmost entry.  */
1069   t = TREE_VALUE (cfun->eh->protect_list);
1070   cfun->eh->protect_list = TREE_CHAIN (cfun->eh->protect_list);
1071
1072   /* End all the exception regions.  */
1073   for (; t; t = TREE_CHAIN (t))
1074     expand_eh_region_end_cleanup (TREE_VALUE (t));
1075 }
1076
1077 \f
1078 /* This section is for the exception handling specific optimization pass.  */
1079
1080 /* Random access the exception region tree.  It's just as simple to
1081    collect the regions this way as in expand_eh_region_start, but
1082    without having to realloc memory.  */
1083
1084 static void
1085 collect_eh_region_array ()
1086 {
1087   struct eh_region **array, *i;
1088
1089   i = cfun->eh->region_tree;
1090   if (! i)
1091     return;
1092
1093   array = xcalloc (cfun->eh->last_region_number + 1, sizeof (*array));
1094   cfun->eh->region_array = array;
1095
1096   while (1)
1097     {
1098       array[i->region_number] = i;
1099
1100       /* If there are sub-regions, process them.  */
1101       if (i->inner)
1102         i = i->inner;
1103       /* If there are peers, process them.  */
1104       else if (i->next_peer)
1105         i = i->next_peer;
1106       /* Otherwise, step back up the tree to the next peer.  */
1107       else
1108         {
1109           do {
1110             i = i->outer;
1111             if (i == NULL)
1112               return;
1113           } while (i->next_peer == NULL);
1114           i = i->next_peer;
1115         }
1116     }
1117 }
1118
1119 static void
1120 resolve_fixup_regions ()
1121 {
1122   int i, j, n = cfun->eh->last_region_number;
1123
1124   for (i = 1; i <= n; ++i)
1125     {
1126       struct eh_region *fixup = cfun->eh->region_array[i];
1127       struct eh_region *cleanup = 0;
1128
1129       if (! fixup || fixup->type != ERT_FIXUP)
1130         continue;
1131
1132       for (j = 1; j <= n; ++j)
1133         {
1134           cleanup = cfun->eh->region_array[j];
1135           if (cleanup->type == ERT_CLEANUP
1136               && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp)
1137             break;
1138         }
1139       if (j > n)
1140         abort ();
1141
1142       fixup->u.fixup.real_region = cleanup->outer;
1143     }
1144 }
1145
1146 /* Now that we've discovered what region actually encloses a fixup,
1147    we can shuffle pointers and remove them from the tree.  */
1148
1149 static void
1150 remove_fixup_regions ()
1151 {
1152   int i;
1153   rtx insn, note;
1154   struct eh_region *fixup;
1155
1156   /* Walk the insn chain and adjust the REG_EH_REGION numbers
1157      for instructions referencing fixup regions.  This is only
1158      strictly necessary for fixup regions with no parent, but
1159      doesn't hurt to do it for all regions.  */
1160   for (insn = get_insns(); insn ; insn = NEXT_INSN (insn))
1161     if (INSN_P (insn)
1162         && (note = find_reg_note (insn, REG_EH_REGION, NULL))
1163         && INTVAL (XEXP (note, 0)) > 0
1164         && (fixup = cfun->eh->region_array[INTVAL (XEXP (note, 0))])
1165         && fixup->type == ERT_FIXUP)
1166       {
1167         if (fixup->u.fixup.real_region)
1168           XEXP (note, 0) = GEN_INT (fixup->u.fixup.real_region->region_number);
1169         else
1170           remove_note (insn, note);
1171       }
1172
1173   /* Remove the fixup regions from the tree.  */
1174   for (i = cfun->eh->last_region_number; i > 0; --i)
1175     {
1176       fixup = cfun->eh->region_array[i];
1177       if (! fixup)
1178         continue;
1179
1180       /* Allow GC to maybe free some memory.  */
1181       if (fixup->type == ERT_CLEANUP)
1182         fixup->u.cleanup.exp = NULL_TREE;
1183
1184       if (fixup->type != ERT_FIXUP)
1185         continue;
1186
1187       if (fixup->inner)
1188         {
1189           struct eh_region *parent, *p, **pp;
1190
1191           parent = fixup->u.fixup.real_region;
1192
1193           /* Fix up the children's parent pointers; find the end of
1194              the list.  */
1195           for (p = fixup->inner; ; p = p->next_peer)
1196             {
1197               p->outer = parent;
1198               if (! p->next_peer)
1199                 break;
1200             }
1201
1202           /* In the tree of cleanups, only outer-inner ordering matters.
1203              So link the children back in anywhere at the correct level.  */
1204           if (parent)
1205             pp = &parent->inner;
1206           else
1207             pp = &cfun->eh->region_tree;
1208           p->next_peer = *pp;
1209           *pp = fixup->inner;
1210           fixup->inner = NULL;
1211         }
1212
1213       remove_eh_handler (fixup);
1214     }
1215 }
1216
1217 /* Remove all regions whose labels are not reachable from insns.  */
1218
1219 static void
1220 remove_unreachable_regions (insns)
1221      rtx insns;
1222 {
1223   int i, *uid_region_num;
1224   bool *reachable;
1225   struct eh_region *r;
1226   rtx insn;
1227
1228   uid_region_num = xcalloc (get_max_uid (), sizeof(int));
1229   reachable = xcalloc (cfun->eh->last_region_number + 1, sizeof(bool));
1230
1231   for (i = cfun->eh->last_region_number; i > 0; --i)
1232     {
1233       r = cfun->eh->region_array[i];
1234       if (!r || r->region_number != i)
1235         continue;
1236
1237       if (r->resume)
1238         {
1239           if (uid_region_num[INSN_UID (r->resume)])
1240             abort ();
1241           uid_region_num[INSN_UID (r->resume)] = i;
1242         }
1243       if (r->label)
1244         {
1245           if (uid_region_num[INSN_UID (r->label)])
1246             abort ();
1247           uid_region_num[INSN_UID (r->label)] = i;
1248         }
1249       if (r->type == ERT_TRY && r->u.try.continue_label)
1250         {
1251           if (uid_region_num[INSN_UID (r->u.try.continue_label)])
1252             abort ();
1253           uid_region_num[INSN_UID (r->u.try.continue_label)] = i;
1254         }
1255     }
1256
1257   for (insn = insns; insn; insn = NEXT_INSN (insn))
1258     reachable[uid_region_num[INSN_UID (insn)]] = true;
1259
1260   for (i = cfun->eh->last_region_number; i > 0; --i)
1261     {
1262       r = cfun->eh->region_array[i];
1263       if (r && r->region_number == i && !reachable[i])
1264         {
1265           /* Don't remove ERT_THROW regions if their outer region
1266              is reachable.  */
1267           if (r->type == ERT_THROW
1268               && r->outer
1269               && reachable[r->outer->region_number])
1270             continue;
1271
1272           remove_eh_handler (r);
1273         }
1274     }
1275
1276   free (reachable);
1277   free (uid_region_num);
1278 }
1279
1280 /* Turn NOTE_INSN_EH_REGION notes into REG_EH_REGION notes for each
1281    can_throw instruction in the region.  */
1282
1283 static void
1284 convert_from_eh_region_ranges_1 (pinsns, orig_sp, cur)
1285      rtx *pinsns;
1286      int *orig_sp;
1287      int cur;
1288 {
1289   int *sp = orig_sp;
1290   rtx insn, next;
1291
1292   for (insn = *pinsns; insn ; insn = next)
1293     {
1294       next = NEXT_INSN (insn);
1295       if (GET_CODE (insn) == NOTE)
1296         {
1297           int kind = NOTE_LINE_NUMBER (insn);
1298           if (kind == NOTE_INSN_EH_REGION_BEG
1299               || kind == NOTE_INSN_EH_REGION_END)
1300             {
1301               if (kind == NOTE_INSN_EH_REGION_BEG)
1302                 {
1303                   struct eh_region *r;
1304
1305                   *sp++ = cur;
1306                   cur = NOTE_EH_HANDLER (insn);
1307
1308                   r = cfun->eh->region_array[cur];
1309                   if (r->type == ERT_FIXUP)
1310                     {
1311                       r = r->u.fixup.real_region;
1312                       cur = r ? r->region_number : 0;
1313                     }
1314                   else if (r->type == ERT_CATCH)
1315                     {
1316                       r = r->outer;
1317                       cur = r ? r->region_number : 0;
1318                     }
1319                 }
1320               else
1321                 cur = *--sp;
1322
1323               /* Removing the first insn of a CALL_PLACEHOLDER sequence
1324                  requires extra care to adjust sequence start.  */
1325               if (insn == *pinsns)
1326                 *pinsns = next;
1327               remove_insn (insn);
1328               continue;
1329             }
1330         }
1331       else if (INSN_P (insn))
1332         {
1333           if (cur > 0
1334               && ! find_reg_note (insn, REG_EH_REGION, NULL_RTX)
1335               /* Calls can always potentially throw exceptions, unless
1336                  they have a REG_EH_REGION note with a value of 0 or less.
1337                  Which should be the only possible kind so far.  */
1338               && (GET_CODE (insn) == CALL_INSN
1339                   /* If we wanted exceptions for non-call insns, then
1340                      any may_trap_p instruction could throw.  */
1341                   || (flag_non_call_exceptions
1342                       && GET_CODE (PATTERN (insn)) != CLOBBER
1343                       && GET_CODE (PATTERN (insn)) != USE
1344                       && may_trap_p (PATTERN (insn)))))
1345             {
1346               REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (cur),
1347                                                   REG_NOTES (insn));
1348             }
1349
1350           if (GET_CODE (insn) == CALL_INSN
1351               && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
1352             {
1353               convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 0),
1354                                                sp, cur);
1355               convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 1),
1356                                                sp, cur);
1357               convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 2),
1358                                                sp, cur);
1359             }
1360         }
1361     }
1362
1363   if (sp != orig_sp)
1364     abort ();
1365 }
1366
1367 void
1368 convert_from_eh_region_ranges ()
1369 {
1370   int *stack;
1371   rtx insns;
1372
1373   collect_eh_region_array ();
1374   resolve_fixup_regions ();
1375
1376   stack = xmalloc (sizeof (int) * (cfun->eh->last_region_number + 1));
1377   insns = get_insns ();
1378   convert_from_eh_region_ranges_1 (&insns, stack, 0);
1379   free (stack);
1380
1381   remove_fixup_regions ();
1382   remove_unreachable_regions (insns);
1383 }
1384
1385 void
1386 find_exception_handler_labels ()
1387 {
1388   rtx list = NULL_RTX;
1389   int i;
1390
1391   free_EXPR_LIST_list (&exception_handler_labels);
1392
1393   if (cfun->eh->region_tree == NULL)
1394     return;
1395
1396   for (i = cfun->eh->last_region_number; i > 0; --i)
1397     {
1398       struct eh_region *region = cfun->eh->region_array[i];
1399       rtx lab;
1400
1401       if (! region || region->region_number != i)
1402         continue;
1403       if (cfun->eh->built_landing_pads)
1404         lab = region->landing_pad;
1405       else
1406         lab = region->label;
1407
1408       if (lab)
1409         list = alloc_EXPR_LIST (0, lab, list);
1410     }
1411
1412   /* For sjlj exceptions, need the return label to remain live until
1413      after landing pad generation.  */
1414   if (USING_SJLJ_EXCEPTIONS && ! cfun->eh->built_landing_pads)
1415     list = alloc_EXPR_LIST (0, return_label, list);
1416
1417   exception_handler_labels = list;
1418 }
1419
1420 \f
1421 static struct eh_region *
1422 duplicate_eh_region_1 (o, map)
1423      struct eh_region *o;
1424      struct inline_remap *map;
1425 {
1426   struct eh_region *n
1427     = (struct eh_region *) xcalloc (1, sizeof (struct eh_region));
1428
1429   n->region_number = o->region_number + cfun->eh->last_region_number;
1430   n->type = o->type;
1431
1432   switch (n->type)
1433     {
1434     case ERT_CLEANUP:
1435     case ERT_MUST_NOT_THROW:
1436       break;
1437
1438     case ERT_TRY:
1439       if (o->u.try.continue_label)
1440         n->u.try.continue_label
1441           = get_label_from_map (map,
1442                                 CODE_LABEL_NUMBER (o->u.try.continue_label));
1443       break;
1444
1445     case ERT_CATCH:
1446       n->u.catch.type_list = o->u.catch.type_list;
1447       break;
1448
1449     case ERT_ALLOWED_EXCEPTIONS:
1450       n->u.allowed.type_list = o->u.allowed.type_list;
1451       break;
1452
1453     case ERT_THROW:
1454       n->u.throw.type = o->u.throw.type;
1455
1456     default:
1457       abort ();
1458     }
1459
1460   if (o->label)
1461     n->label = get_label_from_map (map, CODE_LABEL_NUMBER (o->label));
1462   if (o->resume)
1463     {
1464       n->resume = map->insn_map[INSN_UID (o->resume)];
1465       if (n->resume == NULL)
1466         abort ();
1467     }
1468
1469   return n;
1470 }
1471
1472 static void
1473 duplicate_eh_region_2 (o, n_array)
1474      struct eh_region *o;
1475      struct eh_region **n_array;
1476 {
1477   struct eh_region *n = n_array[o->region_number];
1478
1479   switch (n->type)
1480     {
1481     case ERT_TRY:
1482       n->u.try.catch = n_array[o->u.try.catch->region_number];
1483       n->u.try.last_catch = n_array[o->u.try.last_catch->region_number];
1484       break;
1485
1486     case ERT_CATCH:
1487       if (o->u.catch.next_catch)
1488         n->u.catch.next_catch = n_array[o->u.catch.next_catch->region_number];
1489       if (o->u.catch.prev_catch)
1490         n->u.catch.prev_catch = n_array[o->u.catch.prev_catch->region_number];
1491       break;
1492
1493     default:
1494       break;
1495     }
1496
1497   if (o->outer)
1498     n->outer = n_array[o->outer->region_number];
1499   if (o->inner)
1500     n->inner = n_array[o->inner->region_number];
1501   if (o->next_peer)
1502     n->next_peer = n_array[o->next_peer->region_number];
1503 }
1504
1505 int
1506 duplicate_eh_regions (ifun, map)
1507      struct function *ifun;
1508      struct inline_remap *map;
1509 {
1510   int ifun_last_region_number = ifun->eh->last_region_number;
1511   struct eh_region **n_array, *root, *cur;
1512   int i;
1513
1514   if (ifun_last_region_number == 0)
1515     return 0;
1516
1517   n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array));
1518
1519   for (i = 1; i <= ifun_last_region_number; ++i)
1520     {
1521       cur = ifun->eh->region_array[i];
1522       if (!cur || cur->region_number != i)
1523         continue;
1524       n_array[i] = duplicate_eh_region_1 (cur, map);
1525     }
1526   for (i = 1; i <= ifun_last_region_number; ++i)
1527     {
1528       cur = ifun->eh->region_array[i];
1529       if (!cur || cur->region_number != i)
1530         continue;
1531       duplicate_eh_region_2 (cur, n_array);
1532     }
1533
1534   root = n_array[ifun->eh->region_tree->region_number];
1535   cur = cfun->eh->cur_region;
1536   if (cur)
1537     {
1538       struct eh_region *p = cur->inner;
1539       if (p)
1540         {
1541           while (p->next_peer)
1542             p = p->next_peer;
1543           p->next_peer = root;
1544         }
1545       else
1546         cur->inner = root;
1547
1548       for (i = 1; i <= ifun_last_region_number; ++i)
1549         if (n_array[i] && n_array[i]->outer == NULL)
1550           n_array[i]->outer = cur;
1551     }
1552   else
1553     {
1554       struct eh_region *p = cfun->eh->region_tree;
1555       if (p)
1556         {
1557           while (p->next_peer)
1558             p = p->next_peer;
1559           p->next_peer = root;
1560         }
1561       else
1562         cfun->eh->region_tree = root;
1563     }
1564
1565   free (n_array);
1566
1567   i = cfun->eh->last_region_number;
1568   cfun->eh->last_region_number = i + ifun_last_region_number;
1569   return i;
1570 }
1571
1572 \f
1573 static int
1574 t2r_eq (pentry, pdata)
1575      const PTR pentry;
1576      const PTR pdata;
1577 {
1578   tree entry = (tree) pentry;
1579   tree data = (tree) pdata;
1580
1581   return TREE_PURPOSE (entry) == data;
1582 }
1583
1584 static hashval_t
1585 t2r_hash (pentry)
1586      const PTR pentry;
1587 {
1588   tree entry = (tree) pentry;
1589   return TYPE_HASH (TREE_PURPOSE (entry));
1590 }
1591
1592 static int
1593 t2r_mark_1 (slot, data)
1594      PTR *slot;
1595      PTR data ATTRIBUTE_UNUSED;
1596 {
1597   tree contents = (tree) *slot;
1598   ggc_mark_tree (contents);
1599   return 1;
1600 }
1601
1602 static void
1603 t2r_mark (addr)
1604      PTR addr;
1605 {
1606   htab_traverse (*(htab_t *)addr, t2r_mark_1, NULL);
1607 }
1608
1609 static void
1610 add_type_for_runtime (type)
1611      tree type;
1612 {
1613   tree *slot;
1614
1615   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
1616                                             TYPE_HASH (type), INSERT);
1617   if (*slot == NULL)
1618     {
1619       tree runtime = (*lang_eh_runtime_type) (type);
1620       *slot = tree_cons (type, runtime, NULL_TREE);
1621     }
1622 }
1623
1624 static tree
1625 lookup_type_for_runtime (type)
1626      tree type;
1627 {
1628   tree *slot;
1629
1630   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
1631                                             TYPE_HASH (type), NO_INSERT);
1632
1633   /* We should have always inserted the data earlier.  */
1634   return TREE_VALUE (*slot);
1635 }
1636
1637 \f
1638 /* Represent an entry in @TTypes for either catch actions
1639    or exception filter actions.  */
1640 struct ttypes_filter
1641 {
1642   tree t;
1643   int filter;
1644 };
1645
1646 /* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
1647    (a tree) for a @TTypes type node we are thinking about adding.  */
1648
1649 static int
1650 ttypes_filter_eq (pentry, pdata)
1651      const PTR pentry;
1652      const PTR pdata;
1653 {
1654   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1655   tree data = (tree) pdata;
1656
1657   return entry->t == data;
1658 }
1659
1660 static hashval_t
1661 ttypes_filter_hash (pentry)
1662      const PTR pentry;
1663 {
1664   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1665   return TYPE_HASH (entry->t);
1666 }
1667
1668 /* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
1669    exception specification list we are thinking about adding.  */
1670 /* ??? Currently we use the type lists in the order given.  Someone
1671    should put these in some canonical order.  */
1672
1673 static int
1674 ehspec_filter_eq (pentry, pdata)
1675      const PTR pentry;
1676      const PTR pdata;
1677 {
1678   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1679   const struct ttypes_filter *data = (const struct ttypes_filter *) pdata;
1680
1681   return type_list_equal (entry->t, data->t);
1682 }
1683
1684 /* Hash function for exception specification lists.  */
1685
1686 static hashval_t
1687 ehspec_filter_hash (pentry)
1688      const PTR pentry;
1689 {
1690   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1691   hashval_t h = 0;
1692   tree list;
1693
1694   for (list = entry->t; list ; list = TREE_CHAIN (list))
1695     h = (h << 5) + (h >> 27) + TYPE_HASH (TREE_VALUE (list));
1696   return h;
1697 }
1698
1699 /* Add TYPE to cfun->eh->ttype_data, using TYPES_HASH to speed
1700    up the search.  Return the filter value to be used.  */
1701
1702 static int
1703 add_ttypes_entry (ttypes_hash, type)
1704      htab_t ttypes_hash;
1705      tree type;
1706 {
1707   struct ttypes_filter **slot, *n;
1708
1709   slot = (struct ttypes_filter **)
1710     htab_find_slot_with_hash (ttypes_hash, type, TYPE_HASH (type), INSERT);
1711
1712   if ((n = *slot) == NULL)
1713     {
1714       /* Filter value is a 1 based table index.  */
1715
1716       n = (struct ttypes_filter *) xmalloc (sizeof (*n));
1717       n->t = type;
1718       n->filter = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) + 1;
1719       *slot = n;
1720
1721       VARRAY_PUSH_TREE (cfun->eh->ttype_data, type);
1722     }
1723
1724   return n->filter;
1725 }
1726
1727 /* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH
1728    to speed up the search.  Return the filter value to be used.  */
1729
1730 static int
1731 add_ehspec_entry (ehspec_hash, ttypes_hash, list)
1732      htab_t ehspec_hash;
1733      htab_t ttypes_hash;
1734      tree list;
1735 {
1736   struct ttypes_filter **slot, *n;
1737   struct ttypes_filter dummy;
1738
1739   dummy.t = list;
1740   slot = (struct ttypes_filter **)
1741     htab_find_slot (ehspec_hash, &dummy, INSERT);
1742
1743   if ((n = *slot) == NULL)
1744     {
1745       /* Filter value is a -1 based byte index into a uleb128 buffer.  */
1746
1747       n = (struct ttypes_filter *) xmalloc (sizeof (*n));
1748       n->t = list;
1749       n->filter = -(VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) + 1);
1750       *slot = n;
1751
1752       /* Look up each type in the list and encode its filter
1753          value as a uleb128.  Terminate the list with 0.  */
1754       for (; list ; list = TREE_CHAIN (list))
1755         push_uleb128 (&cfun->eh->ehspec_data,
1756                       add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
1757       VARRAY_PUSH_UCHAR (cfun->eh->ehspec_data, 0);
1758     }
1759
1760   return n->filter;
1761 }
1762
1763 /* Generate the action filter values to be used for CATCH and
1764    ALLOWED_EXCEPTIONS regions.  When using dwarf2 exception regions,
1765    we use lots of landing pads, and so every type or list can share
1766    the same filter value, which saves table space.  */
1767
1768 static void
1769 assign_filter_values ()
1770 {
1771   int i;
1772   htab_t ttypes, ehspec;
1773
1774   VARRAY_TREE_INIT (cfun->eh->ttype_data, 16, "ttype_data");
1775   VARRAY_UCHAR_INIT (cfun->eh->ehspec_data, 64, "ehspec_data");
1776
1777   ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
1778   ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
1779
1780   for (i = cfun->eh->last_region_number; i > 0; --i)
1781     {
1782       struct eh_region *r = cfun->eh->region_array[i];
1783
1784       /* Mind we don't process a region more than once.  */
1785       if (!r || r->region_number != i)
1786         continue;
1787
1788       switch (r->type)
1789         {
1790         case ERT_CATCH:
1791           /* Whatever type_list is (NULL or true list), we build a list
1792              of filters for the region.  */
1793           r->u.catch.filter_list = NULL_TREE;
1794
1795           if (r->u.catch.type_list != NULL)
1796             {
1797               /* Get a filter value for each of the types caught and store
1798                  them in the region's dedicated list.  */
1799               tree tp_node = r->u.catch.type_list;
1800
1801               for (;tp_node; tp_node = TREE_CHAIN (tp_node))
1802                 {
1803                   int flt = add_ttypes_entry (ttypes, TREE_VALUE (tp_node));
1804                   tree flt_node = build_int_2 (flt, 0);
1805
1806                   r->u.catch.filter_list
1807                     = tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list);
1808                 }
1809             }
1810           else
1811             {
1812               /* Get a filter value for the NULL list also since it will need
1813                  an action record anyway.  */
1814               int flt = add_ttypes_entry (ttypes, NULL);
1815               tree flt_node = build_int_2 (flt, 0);
1816
1817               r->u.catch.filter_list
1818                 = tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list);
1819             }
1820
1821           break;
1822
1823         case ERT_ALLOWED_EXCEPTIONS:
1824           r->u.allowed.filter
1825             = add_ehspec_entry (ehspec, ttypes, r->u.allowed.type_list);
1826           break;
1827
1828         default:
1829           break;
1830         }
1831     }
1832
1833   htab_delete (ttypes);
1834   htab_delete (ehspec);
1835 }
1836
1837 static void
1838 build_post_landing_pads ()
1839 {
1840   int i;
1841
1842   for (i = cfun->eh->last_region_number; i > 0; --i)
1843     {
1844       struct eh_region *region = cfun->eh->region_array[i];
1845       rtx seq;
1846
1847       /* Mind we don't process a region more than once.  */
1848       if (!region || region->region_number != i)
1849         continue;
1850
1851       switch (region->type)
1852         {
1853         case ERT_TRY:
1854           /* ??? Collect the set of all non-overlapping catch handlers
1855                all the way up the chain until blocked by a cleanup.  */
1856           /* ??? Outer try regions can share landing pads with inner
1857              try regions if the types are completely non-overlapping,
1858              and there are no intervening cleanups.  */
1859
1860           region->post_landing_pad = gen_label_rtx ();
1861
1862           start_sequence ();
1863
1864           emit_label (region->post_landing_pad);
1865
1866           /* ??? It is mighty inconvenient to call back into the
1867              switch statement generation code in expand_end_case.
1868              Rapid prototyping sez a sequence of ifs.  */
1869           {
1870             struct eh_region *c;
1871             for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
1872               {
1873                 /* ??? _Unwind_ForcedUnwind wants no match here.  */
1874                 if (c->u.catch.type_list == NULL)
1875                   emit_jump (c->label);
1876                 else
1877                   {
1878                     /* Need for one cmp/jump per type caught. Each type
1879                        list entry has a matching entry in the filter list
1880                        (see assign_filter_values).  */
1881                     tree tp_node = c->u.catch.type_list;
1882                     tree flt_node = c->u.catch.filter_list;
1883
1884                     for (; tp_node; )
1885                       {
1886                         emit_cmp_and_jump_insns
1887                           (cfun->eh->filter,
1888                            GEN_INT (tree_low_cst (TREE_VALUE (flt_node), 0)),
1889                            EQ, NULL_RTX, word_mode, 0, c->label);
1890
1891                         tp_node = TREE_CHAIN (tp_node);
1892                         flt_node = TREE_CHAIN (flt_node);
1893                       }
1894                   }
1895               }
1896           }
1897
1898           /* We delay the generation of the _Unwind_Resume until we generate
1899              landing pads.  We emit a marker here so as to get good control
1900              flow data in the meantime.  */
1901           region->resume
1902             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1903           emit_barrier ();
1904
1905           seq = get_insns ();
1906           end_sequence ();
1907
1908           emit_insns_before (seq, region->u.try.catch->label);
1909           break;
1910
1911         case ERT_ALLOWED_EXCEPTIONS:
1912           region->post_landing_pad = gen_label_rtx ();
1913
1914           start_sequence ();
1915
1916           emit_label (region->post_landing_pad);
1917
1918           emit_cmp_and_jump_insns (cfun->eh->filter,
1919                                    GEN_INT (region->u.allowed.filter),
1920                                    EQ, NULL_RTX, word_mode, 0, region->label);
1921
1922           /* We delay the generation of the _Unwind_Resume until we generate
1923              landing pads.  We emit a marker here so as to get good control
1924              flow data in the meantime.  */
1925           region->resume
1926             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1927           emit_barrier ();
1928
1929           seq = get_insns ();
1930           end_sequence ();
1931
1932           emit_insns_before (seq, region->label);
1933           break;
1934
1935         case ERT_CLEANUP:
1936         case ERT_MUST_NOT_THROW:
1937           region->post_landing_pad = region->label;
1938           break;
1939
1940         case ERT_CATCH:
1941         case ERT_THROW:
1942           /* Nothing to do.  */
1943           break;
1944
1945         default:
1946           abort ();
1947         }
1948     }
1949 }
1950
1951 /* Replace RESX patterns with jumps to the next handler if any, or calls to
1952    _Unwind_Resume otherwise.  */
1953
1954 static void
1955 connect_post_landing_pads ()
1956 {
1957   int i;
1958
1959   for (i = cfun->eh->last_region_number; i > 0; --i)
1960     {
1961       struct eh_region *region = cfun->eh->region_array[i];
1962       struct eh_region *outer;
1963       rtx seq;
1964
1965       /* Mind we don't process a region more than once.  */
1966       if (!region || region->region_number != i)
1967         continue;
1968
1969       /* If there is no RESX, or it has been deleted by flow, there's
1970          nothing to fix up.  */
1971       if (! region->resume || INSN_DELETED_P (region->resume))
1972         continue;
1973
1974       /* Search for another landing pad in this function.  */
1975       for (outer = region->outer; outer ; outer = outer->outer)
1976         if (outer->post_landing_pad)
1977           break;
1978
1979       start_sequence ();
1980
1981       if (outer)
1982         emit_jump (outer->post_landing_pad);
1983       else
1984         emit_library_call (unwind_resume_libfunc, LCT_THROW,
1985                            VOIDmode, 1, cfun->eh->exc_ptr, Pmode);
1986
1987       seq = get_insns ();
1988       end_sequence ();
1989       emit_insns_before (seq, region->resume);
1990       delete_insn (region->resume);
1991     }
1992 }
1993
1994 \f
1995 static void
1996 dw2_build_landing_pads ()
1997 {
1998   int i;
1999   unsigned int j;
2000
2001   for (i = cfun->eh->last_region_number; i > 0; --i)
2002     {
2003       struct eh_region *region = cfun->eh->region_array[i];
2004       rtx seq;
2005       bool clobbers_hard_regs = false;
2006
2007       /* Mind we don't process a region more than once.  */
2008       if (!region || region->region_number != i)
2009         continue;
2010
2011       if (region->type != ERT_CLEANUP
2012           && region->type != ERT_TRY
2013           && region->type != ERT_ALLOWED_EXCEPTIONS)
2014         continue;
2015
2016       start_sequence ();
2017
2018       region->landing_pad = gen_label_rtx ();
2019       emit_label (region->landing_pad);
2020
2021 #ifdef HAVE_exception_receiver
2022       if (HAVE_exception_receiver)
2023         emit_insn (gen_exception_receiver ());
2024       else
2025 #endif
2026 #ifdef HAVE_nonlocal_goto_receiver
2027         if (HAVE_nonlocal_goto_receiver)
2028           emit_insn (gen_nonlocal_goto_receiver ());
2029         else
2030 #endif
2031           { /* Nothing */ }
2032
2033       /* If the eh_return data registers are call-saved, then we
2034          won't have considered them clobbered from the call that
2035          threw.  Kill them now.  */
2036       for (j = 0; ; ++j)
2037         {
2038           unsigned r = EH_RETURN_DATA_REGNO (j);
2039           if (r == INVALID_REGNUM)
2040             break;
2041           if (! call_used_regs[r])
2042             {
2043               emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, r)));
2044               clobbers_hard_regs = true;
2045             }
2046         }
2047
2048       if (clobbers_hard_regs)
2049         {
2050           /* @@@ This is a kludge.  Not all machine descriptions define a
2051              blockage insn, but we must not allow the code we just generated
2052              to be reordered by scheduling.  So emit an ASM_INPUT to act as
2053              blockage insn.  */
2054           emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
2055         }
2056
2057       emit_move_insn (cfun->eh->exc_ptr,
2058                       gen_rtx_REG (Pmode, EH_RETURN_DATA_REGNO (0)));
2059       emit_move_insn (cfun->eh->filter,
2060                       gen_rtx_REG (word_mode, EH_RETURN_DATA_REGNO (1)));
2061
2062       seq = get_insns ();
2063       end_sequence ();
2064
2065       emit_insns_before (seq, region->post_landing_pad);
2066     }
2067 }
2068
2069 \f
2070 struct sjlj_lp_info
2071 {
2072   int directly_reachable;
2073   int action_index;
2074   int dispatch_index;
2075   int call_site_index;
2076 };
2077
2078 static bool
2079 sjlj_find_directly_reachable_regions (lp_info)
2080      struct sjlj_lp_info *lp_info;
2081 {
2082   rtx insn;
2083   bool found_one = false;
2084
2085   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
2086     {
2087       struct eh_region *region;
2088       enum reachable_code rc;
2089       tree type_thrown;
2090       rtx note;
2091
2092       if (! INSN_P (insn))
2093         continue;
2094
2095       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2096       if (!note || INTVAL (XEXP (note, 0)) <= 0)
2097         continue;
2098
2099       region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2100
2101       type_thrown = NULL_TREE;
2102       if (region->type == ERT_THROW)
2103         {
2104           type_thrown = region->u.throw.type;
2105           region = region->outer;
2106         }
2107
2108       /* Find the first containing region that might handle the exception.
2109          That's the landing pad to which we will transfer control.  */
2110       rc = RNL_NOT_CAUGHT;
2111       for (; region; region = region->outer)
2112         {
2113           rc = reachable_next_level (region, type_thrown, 0);
2114           if (rc != RNL_NOT_CAUGHT)
2115             break;
2116         }
2117       if (rc == RNL_MAYBE_CAUGHT || rc == RNL_CAUGHT)
2118         {
2119           lp_info[region->region_number].directly_reachable = 1;
2120           found_one = true;
2121         }
2122     }
2123
2124   return found_one;
2125 }
2126
2127 static void
2128 sjlj_assign_call_site_values (dispatch_label, lp_info)
2129      rtx dispatch_label;
2130      struct sjlj_lp_info *lp_info;
2131 {
2132   htab_t ar_hash;
2133   int i, index;
2134
2135   /* First task: build the action table.  */
2136
2137   VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
2138   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
2139
2140   for (i = cfun->eh->last_region_number; i > 0; --i)
2141     if (lp_info[i].directly_reachable)
2142       {
2143         struct eh_region *r = cfun->eh->region_array[i];
2144         r->landing_pad = dispatch_label;
2145         lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
2146         if (lp_info[i].action_index != -1)
2147           cfun->uses_eh_lsda = 1;
2148       }
2149
2150   htab_delete (ar_hash);
2151
2152   /* Next: assign dispatch values.  In dwarf2 terms, this would be the
2153      landing pad label for the region.  For sjlj though, there is one
2154      common landing pad from which we dispatch to the post-landing pads.
2155
2156      A region receives a dispatch index if it is directly reachable
2157      and requires in-function processing.  Regions that share post-landing
2158      pads may share dispatch indices.  */
2159   /* ??? Post-landing pad sharing doesn't actually happen at the moment
2160      (see build_post_landing_pads) so we don't bother checking for it.  */
2161
2162   index = 0;
2163   for (i = cfun->eh->last_region_number; i > 0; --i)
2164     if (lp_info[i].directly_reachable)
2165       lp_info[i].dispatch_index = index++;
2166
2167   /* Finally: assign call-site values.  If dwarf2 terms, this would be
2168      the region number assigned by convert_to_eh_region_ranges, but
2169      handles no-action and must-not-throw differently.  */
2170
2171   call_site_base = 1;
2172   for (i = cfun->eh->last_region_number; i > 0; --i)
2173     if (lp_info[i].directly_reachable)
2174       {
2175         int action = lp_info[i].action_index;
2176
2177         /* Map must-not-throw to otherwise unused call-site index 0.  */
2178         if (action == -2)
2179           index = 0;
2180         /* Map no-action to otherwise unused call-site index -1.  */
2181         else if (action == -1)
2182           index = -1;
2183         /* Otherwise, look it up in the table.  */
2184         else
2185           index = add_call_site (GEN_INT (lp_info[i].dispatch_index), action);
2186
2187         lp_info[i].call_site_index = index;
2188       }
2189 }
2190
2191 static void
2192 sjlj_mark_call_sites (lp_info)
2193      struct sjlj_lp_info *lp_info;
2194 {
2195   int last_call_site = -2;
2196   rtx insn, mem;
2197
2198   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
2199     {
2200       struct eh_region *region;
2201       int this_call_site;
2202       rtx note, before, p;
2203
2204       /* Reset value tracking at extended basic block boundaries.  */
2205       if (GET_CODE (insn) == CODE_LABEL)
2206         last_call_site = -2;
2207
2208       if (! INSN_P (insn))
2209         continue;
2210
2211       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2212       if (!note)
2213         {
2214           /* Calls (and trapping insns) without notes are outside any
2215              exception handling region in this function.  Mark them as
2216              no action.  */
2217           if (GET_CODE (insn) == CALL_INSN
2218               || (flag_non_call_exceptions
2219                   && may_trap_p (PATTERN (insn))))
2220             this_call_site = -1;
2221           else
2222             continue;
2223         }
2224       else
2225         {
2226           /* Calls that are known to not throw need not be marked.  */
2227           if (INTVAL (XEXP (note, 0)) <= 0)
2228             continue;
2229
2230           region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2231           this_call_site = lp_info[region->region_number].call_site_index;
2232         }
2233
2234       if (this_call_site == last_call_site)
2235         continue;
2236
2237       /* Don't separate a call from it's argument loads.  */
2238       before = insn;
2239       if (GET_CODE (insn) == CALL_INSN)
2240          before = find_first_parameter_load (insn, NULL_RTX);
2241
2242       start_sequence ();
2243       mem = adjust_address (cfun->eh->sjlj_fc, TYPE_MODE (integer_type_node),
2244                             sjlj_fc_call_site_ofs);
2245       emit_move_insn (mem, GEN_INT (this_call_site));
2246       p = get_insns ();
2247       end_sequence ();
2248
2249       emit_insns_before (p, before);
2250       last_call_site = this_call_site;
2251     }
2252 }
2253
2254 /* Construct the SjLj_Function_Context.  */
2255
2256 static void
2257 sjlj_emit_function_enter (dispatch_label)
2258      rtx dispatch_label;
2259 {
2260   rtx fn_begin, fc, mem, seq;
2261
2262   fc = cfun->eh->sjlj_fc;
2263
2264   start_sequence ();
2265
2266   /* We're storing this libcall's address into memory instead of
2267      calling it directly.  Thus, we must call assemble_external_libcall
2268      here, as we can not depend on emit_library_call to do it for us.  */
2269   assemble_external_libcall (eh_personality_libfunc);
2270   mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
2271   emit_move_insn (mem, eh_personality_libfunc);
2272
2273   mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
2274   if (cfun->uses_eh_lsda)
2275     {
2276       char buf[20];
2277       ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", sjlj_funcdef_number);
2278       emit_move_insn (mem, gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
2279     }
2280   else
2281     emit_move_insn (mem, const0_rtx);
2282
2283 #ifdef DONT_USE_BUILTIN_SETJMP
2284   {
2285     rtx x, note;
2286     x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
2287                                  TYPE_MODE (integer_type_node), 1,
2288                                  plus_constant (XEXP (fc, 0),
2289                                                 sjlj_fc_jbuf_ofs), Pmode);
2290
2291     note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
2292     NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, x, const0_rtx);
2293
2294     emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
2295                              TYPE_MODE (integer_type_node), 0, dispatch_label);
2296   }
2297 #else
2298   expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
2299                                dispatch_label);
2300 #endif
2301
2302   emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
2303                      1, XEXP (fc, 0), Pmode);
2304
2305   seq = get_insns ();
2306   end_sequence ();
2307
2308   /* ??? Instead of doing this at the beginning of the function,
2309      do this in a block that is at loop level 0 and dominates all
2310      can_throw_internal instructions.  */
2311
2312   for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
2313     if (GET_CODE (fn_begin) == NOTE
2314         && NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
2315       break;
2316   emit_insns_after (seq, fn_begin);
2317 }
2318
2319 /* Call back from expand_function_end to know where we should put
2320    the call to unwind_sjlj_unregister_libfunc if needed.  */
2321
2322 void
2323 sjlj_emit_function_exit_after (after)
2324      rtx after;
2325 {
2326   cfun->eh->sjlj_exit_after = after;
2327 }
2328
2329 static void
2330 sjlj_emit_function_exit ()
2331 {
2332   rtx seq;
2333
2334   start_sequence ();
2335
2336   emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
2337                      1, XEXP (cfun->eh->sjlj_fc, 0), Pmode);
2338
2339   seq = get_insns ();
2340   end_sequence ();
2341
2342   /* ??? Really this can be done in any block at loop level 0 that
2343      post-dominates all can_throw_internal instructions.  This is
2344      the last possible moment.  */
2345
2346   emit_insns_after (seq, cfun->eh->sjlj_exit_after);
2347 }
2348
2349 static void
2350 sjlj_emit_dispatch_table (dispatch_label, lp_info)
2351      rtx dispatch_label;
2352      struct sjlj_lp_info *lp_info;
2353 {
2354   int i, first_reachable;
2355   rtx mem, dispatch, seq, fc;
2356
2357   fc = cfun->eh->sjlj_fc;
2358
2359   start_sequence ();
2360
2361   emit_label (dispatch_label);
2362
2363 #ifndef DONT_USE_BUILTIN_SETJMP
2364   expand_builtin_setjmp_receiver (dispatch_label);
2365 #endif
2366
2367   /* Load up dispatch index, exc_ptr and filter values from the
2368      function context.  */
2369   mem = adjust_address (fc, TYPE_MODE (integer_type_node),
2370                         sjlj_fc_call_site_ofs);
2371   dispatch = copy_to_reg (mem);
2372
2373   mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs);
2374   if (word_mode != Pmode)
2375     {
2376 #ifdef POINTERS_EXTEND_UNSIGNED
2377       mem = convert_memory_address (Pmode, mem);
2378 #else
2379       mem = convert_to_mode (Pmode, mem, 0);
2380 #endif
2381     }
2382   emit_move_insn (cfun->eh->exc_ptr, mem);
2383
2384   mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs + UNITS_PER_WORD);
2385   emit_move_insn (cfun->eh->filter, mem);
2386
2387   /* Jump to one of the directly reachable regions.  */
2388   /* ??? This really ought to be using a switch statement.  */
2389
2390   first_reachable = 0;
2391   for (i = cfun->eh->last_region_number; i > 0; --i)
2392     {
2393       if (! lp_info[i].directly_reachable)
2394         continue;
2395
2396       if (! first_reachable)
2397         {
2398           first_reachable = i;
2399           continue;
2400         }
2401
2402       emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index),
2403                                EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0,
2404                                cfun->eh->region_array[i]->post_landing_pad);
2405     }
2406
2407   seq = get_insns ();
2408   end_sequence ();
2409
2410   emit_insns_before (seq, (cfun->eh->region_array[first_reachable]
2411                            ->post_landing_pad));
2412 }
2413
2414 static void
2415 sjlj_build_landing_pads ()
2416 {
2417   struct sjlj_lp_info *lp_info;
2418
2419   lp_info = (struct sjlj_lp_info *) xcalloc (cfun->eh->last_region_number + 1,
2420                                              sizeof (struct sjlj_lp_info));
2421
2422   if (sjlj_find_directly_reachable_regions (lp_info))
2423     {
2424       rtx dispatch_label = gen_label_rtx ();
2425
2426       cfun->eh->sjlj_fc
2427         = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
2428                               int_size_in_bytes (sjlj_fc_type_node),
2429                               TYPE_ALIGN (sjlj_fc_type_node));
2430
2431       sjlj_assign_call_site_values (dispatch_label, lp_info);
2432       sjlj_mark_call_sites (lp_info);
2433
2434       sjlj_emit_function_enter (dispatch_label);
2435       sjlj_emit_dispatch_table (dispatch_label, lp_info);
2436       sjlj_emit_function_exit ();
2437     }
2438
2439   free (lp_info);
2440 }
2441
2442 void
2443 finish_eh_generation ()
2444 {
2445   /* Nothing to do if no regions created.  */
2446   if (cfun->eh->region_tree == NULL)
2447     return;
2448
2449   /* The object here is to provide find_basic_blocks with detailed
2450      information (via reachable_handlers) on how exception control
2451      flows within the function.  In this first pass, we can include
2452      type information garnered from ERT_THROW and ERT_ALLOWED_EXCEPTIONS
2453      regions, and hope that it will be useful in deleting unreachable
2454      handlers.  Subsequently, we will generate landing pads which will
2455      connect many of the handlers, and then type information will not
2456      be effective.  Still, this is a win over previous implementations.  */
2457
2458   rebuild_jump_labels (get_insns ());
2459   find_basic_blocks (get_insns (), max_reg_num (), 0);
2460   cleanup_cfg (CLEANUP_PRE_LOOP);
2461
2462   /* These registers are used by the landing pads.  Make sure they
2463      have been generated.  */
2464   get_exception_pointer (cfun);
2465   get_exception_filter (cfun);
2466
2467   /* Construct the landing pads.  */
2468
2469   assign_filter_values ();
2470   build_post_landing_pads ();
2471   connect_post_landing_pads ();
2472   if (USING_SJLJ_EXCEPTIONS)
2473     sjlj_build_landing_pads ();
2474   else
2475     dw2_build_landing_pads ();
2476
2477   cfun->eh->built_landing_pads = 1;
2478
2479   /* We've totally changed the CFG.  Start over.  */
2480   find_exception_handler_labels ();
2481   rebuild_jump_labels (get_insns ());
2482   find_basic_blocks (get_insns (), max_reg_num (), 0);
2483   cleanup_cfg (CLEANUP_PRE_LOOP);
2484 }
2485 \f
2486 /* This section handles removing dead code for flow.  */
2487
2488 /* Remove LABEL from the exception_handler_labels list.  */
2489
2490 static void
2491 remove_exception_handler_label (label)
2492      rtx label;
2493 {
2494   rtx *pl, l;
2495
2496   /* If exception_handler_labels was not built yet,
2497      there is nothing to do.  */
2498   if (exception_handler_labels == NULL)
2499     return;
2500
2501   for (pl = &exception_handler_labels, l = *pl;
2502        XEXP (l, 0) != label;
2503        pl = &XEXP (l, 1), l = *pl)
2504     continue;
2505
2506   *pl = XEXP (l, 1);
2507   free_EXPR_LIST_node (l);
2508 }
2509
2510 /* Splice REGION from the region tree etc.  */
2511
2512 static void
2513 remove_eh_handler (region)
2514      struct eh_region *region;
2515 {
2516   struct eh_region **pp, *p;
2517   rtx lab;
2518   int i;
2519
2520   /* For the benefit of efficiently handling REG_EH_REGION notes,
2521      replace this region in the region array with its containing
2522      region.  Note that previous region deletions may result in
2523      multiple copies of this region in the array, so we have to
2524      search the whole thing.  */
2525   for (i = cfun->eh->last_region_number; i > 0; --i)
2526     if (cfun->eh->region_array[i] == region)
2527       cfun->eh->region_array[i] = region->outer;
2528
2529   if (cfun->eh->built_landing_pads)
2530     lab = region->landing_pad;
2531   else
2532     lab = region->label;
2533   if (lab)
2534     remove_exception_handler_label (lab);
2535
2536   if (region->outer)
2537     pp = &region->outer->inner;
2538   else
2539     pp = &cfun->eh->region_tree;
2540   for (p = *pp; p != region; pp = &p->next_peer, p = *pp)
2541     continue;
2542
2543   if (region->inner)
2544     {
2545       for (p = region->inner; p->next_peer ; p = p->next_peer)
2546         p->outer = region->outer;
2547       p->next_peer = region->next_peer;
2548       p->outer = region->outer;
2549       *pp = region->inner;
2550     }
2551   else
2552     *pp = region->next_peer;
2553
2554   if (region->type == ERT_CATCH)
2555     {
2556       struct eh_region *try, *next, *prev;
2557
2558       for (try = region->next_peer;
2559            try->type == ERT_CATCH;
2560            try = try->next_peer)
2561         continue;
2562       if (try->type != ERT_TRY)
2563         abort ();
2564
2565       next = region->u.catch.next_catch;
2566       prev = region->u.catch.prev_catch;
2567
2568       if (next)
2569         next->u.catch.prev_catch = prev;
2570       else
2571         try->u.try.last_catch = prev;
2572       if (prev)
2573         prev->u.catch.next_catch = next;
2574       else
2575         {
2576           try->u.try.catch = next;
2577           if (! next)
2578             remove_eh_handler (try);
2579         }
2580     }
2581
2582   free (region);
2583 }
2584
2585 /* LABEL heads a basic block that is about to be deleted.  If this
2586    label corresponds to an exception region, we may be able to
2587    delete the region.  */
2588
2589 void
2590 maybe_remove_eh_handler (label)
2591      rtx label;
2592 {
2593   int i;
2594
2595   /* ??? After generating landing pads, it's not so simple to determine
2596      if the region data is completely unused.  One must examine the
2597      landing pad and the post landing pad, and whether an inner try block
2598      is referencing the catch handlers directly.  */
2599   if (cfun->eh->built_landing_pads)
2600     return;
2601
2602   for (i = cfun->eh->last_region_number; i > 0; --i)
2603     {
2604       struct eh_region *region = cfun->eh->region_array[i];
2605       if (region && region->label == label)
2606         {
2607           /* Flow will want to remove MUST_NOT_THROW regions as unreachable
2608              because there is no path to the fallback call to terminate.
2609              But the region continues to affect call-site data until there
2610              are no more contained calls, which we don't see here.  */
2611           if (region->type == ERT_MUST_NOT_THROW)
2612             {
2613               remove_exception_handler_label (region->label);
2614               region->label = NULL_RTX;
2615             }
2616           else
2617             remove_eh_handler (region);
2618           break;
2619         }
2620     }
2621 }
2622
2623 \f
2624 /* This section describes CFG exception edges for flow.  */
2625
2626 /* For communicating between calls to reachable_next_level.  */
2627 struct reachable_info
2628 {
2629   tree types_caught;
2630   tree types_allowed;
2631   rtx handlers;
2632 };
2633
2634 /* A subroutine of reachable_next_level.  Return true if TYPE, or a
2635    base class of TYPE, is in HANDLED.  */
2636
2637 static int
2638 check_handled (handled, type)
2639      tree handled, type;
2640 {
2641   tree t;
2642
2643   /* We can check for exact matches without front-end help.  */
2644   if (! lang_eh_type_covers)
2645     {
2646       for (t = handled; t ; t = TREE_CHAIN (t))
2647         if (TREE_VALUE (t) == type)
2648           return 1;
2649     }
2650   else
2651     {
2652       for (t = handled; t ; t = TREE_CHAIN (t))
2653         if ((*lang_eh_type_covers) (TREE_VALUE (t), type))
2654           return 1;
2655     }
2656
2657   return 0;
2658 }
2659
2660 /* A subroutine of reachable_next_level.  If we are collecting a list
2661    of handlers, add one.  After landing pad generation, reference
2662    it instead of the handlers themselves.  Further, the handlers are
2663    all wired together, so by referencing one, we've got them all.
2664    Before landing pad generation we reference each handler individually.
2665
2666    LP_REGION contains the landing pad; REGION is the handler.  */
2667
2668 static void
2669 add_reachable_handler (info, lp_region, region)
2670      struct reachable_info *info;
2671      struct eh_region *lp_region;
2672      struct eh_region *region;
2673 {
2674   if (! info)
2675     return;
2676
2677   if (cfun->eh->built_landing_pads)
2678     {
2679       if (! info->handlers)
2680         info->handlers = alloc_INSN_LIST (lp_region->landing_pad, NULL_RTX);
2681     }
2682   else
2683     info->handlers = alloc_INSN_LIST (region->label, info->handlers);
2684 }
2685
2686 /* Process one level of exception regions for reachability.
2687    If TYPE_THROWN is non-null, then it is the *exact* type being
2688    propagated.  If INFO is non-null, then collect handler labels
2689    and caught/allowed type information between invocations.  */
2690
2691 static enum reachable_code
2692 reachable_next_level (region, type_thrown, info)
2693      struct eh_region *region;
2694      tree type_thrown;
2695      struct reachable_info *info;
2696 {
2697   switch (region->type)
2698     {
2699     case ERT_CLEANUP:
2700       /* Before landing-pad generation, we model control flow
2701          directly to the individual handlers.  In this way we can
2702          see that catch handler types may shadow one another.  */
2703       add_reachable_handler (info, region, region);
2704       return RNL_MAYBE_CAUGHT;
2705
2706     case ERT_TRY:
2707       {
2708         struct eh_region *c;
2709         enum reachable_code ret = RNL_NOT_CAUGHT;
2710
2711         for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
2712           {
2713             /* A catch-all handler ends the search.  */
2714             /* ??? _Unwind_ForcedUnwind will want outer cleanups
2715                to be run as well.  */
2716             if (c->u.catch.type_list == NULL)
2717               {
2718                 add_reachable_handler (info, region, c);
2719                 return RNL_CAUGHT;
2720               }
2721
2722             if (type_thrown)
2723               {
2724                 /* If we have at least one type match, end the search.  */
2725                 tree tp_node = c->u.catch.type_list;
2726
2727                 for (; tp_node; tp_node = TREE_CHAIN (tp_node))
2728                   {
2729                     tree type = TREE_VALUE (tp_node);
2730
2731                     if (type == type_thrown
2732                         || (lang_eh_type_covers
2733                             && (*lang_eh_type_covers) (type, type_thrown)))
2734                       {
2735                         add_reachable_handler (info, region, c);
2736                         return RNL_CAUGHT;
2737                       }
2738                   }
2739
2740                 /* If we have definitive information of a match failure,
2741                    the catch won't trigger.  */
2742                 if (lang_eh_type_covers)
2743                   return RNL_NOT_CAUGHT;
2744               }
2745
2746             /* At this point, we either don't know what type is thrown or
2747                don't have front-end assistance to help deciding if it is
2748                covered by one of the types in the list for this region.
2749
2750                We'd then like to add this region to the list of reachable
2751                handlers since it is indeed potentially reachable based on the
2752                information we have.
2753
2754                Actually, this handler is for sure not reachable if all the
2755                types it matches have already been caught. That is, it is only
2756                potentially reachable if at least one of the types it catches
2757                has not been previously caught.  */
2758
2759             if (! info)
2760               ret = RNL_MAYBE_CAUGHT;
2761             else
2762               {
2763                 tree tp_node = c->u.catch.type_list;
2764                 bool maybe_reachable = false;
2765
2766                 /* Compute the potential reachability of this handler and
2767                    update the list of types caught at the same time.  */
2768                 for (; tp_node; tp_node = TREE_CHAIN (tp_node))
2769                   {
2770                     tree type = TREE_VALUE (tp_node);
2771
2772                     if (! check_handled (info->types_caught, type))
2773                       {
2774                         info->types_caught
2775                           = tree_cons (NULL, type, info->types_caught);
2776
2777                         maybe_reachable = true;
2778                       }
2779                   }
2780
2781                 if (maybe_reachable)
2782                   {
2783                     add_reachable_handler (info, region, c);
2784
2785                     /* ??? If the catch type is a base class of every allowed
2786                        type, then we know we can stop the search.  */
2787                     ret = RNL_MAYBE_CAUGHT;
2788                   }
2789               }
2790           }
2791
2792         return ret;
2793       }
2794
2795     case ERT_ALLOWED_EXCEPTIONS:
2796       /* An empty list of types definitely ends the search.  */
2797       if (region->u.allowed.type_list == NULL_TREE)
2798         {
2799           add_reachable_handler (info, region, region);
2800           return RNL_CAUGHT;
2801         }
2802
2803       /* Collect a list of lists of allowed types for use in detecting
2804          when a catch may be transformed into a catch-all.  */
2805       if (info)
2806         info->types_allowed = tree_cons (NULL_TREE,
2807                                          region->u.allowed.type_list,
2808                                          info->types_allowed);
2809
2810       /* If we have definitive information about the type hierarchy,
2811          then we can tell if the thrown type will pass through the
2812          filter.  */
2813       if (type_thrown && lang_eh_type_covers)
2814         {
2815           if (check_handled (region->u.allowed.type_list, type_thrown))
2816             return RNL_NOT_CAUGHT;
2817           else
2818             {
2819               add_reachable_handler (info, region, region);
2820               return RNL_CAUGHT;
2821             }
2822         }
2823
2824       add_reachable_handler (info, region, region);
2825       return RNL_MAYBE_CAUGHT;
2826
2827     case ERT_CATCH:
2828       /* Catch regions are handled by their controling try region.  */
2829       return RNL_NOT_CAUGHT;
2830
2831     case ERT_MUST_NOT_THROW:
2832       /* Here we end our search, since no exceptions may propagate.
2833          If we've touched down at some landing pad previous, then the
2834          explicit function call we generated may be used.  Otherwise
2835          the call is made by the runtime.  */
2836       if (info && info->handlers)
2837         {
2838           add_reachable_handler (info, region, region);
2839           return RNL_CAUGHT;
2840         }
2841       else
2842         return RNL_BLOCKED;
2843
2844     case ERT_THROW:
2845     case ERT_FIXUP:
2846     case ERT_UNKNOWN:
2847       /* Shouldn't see these here.  */
2848       break;
2849     }
2850
2851   abort ();
2852 }
2853
2854 /* Retrieve a list of labels of exception handlers which can be
2855    reached by a given insn.  */
2856
2857 rtx
2858 reachable_handlers (insn)
2859      rtx insn;
2860 {
2861   struct reachable_info info;
2862   struct eh_region *region;
2863   tree type_thrown;
2864   int region_number;
2865
2866   if (GET_CODE (insn) == JUMP_INSN
2867       && GET_CODE (PATTERN (insn)) == RESX)
2868     region_number = XINT (PATTERN (insn), 0);
2869   else
2870     {
2871       rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2872       if (!note || INTVAL (XEXP (note, 0)) <= 0)
2873         return NULL;
2874       region_number = INTVAL (XEXP (note, 0));
2875     }
2876
2877   memset (&info, 0, sizeof (info));
2878
2879   region = cfun->eh->region_array[region_number];
2880
2881   type_thrown = NULL_TREE;
2882   if (GET_CODE (insn) == JUMP_INSN
2883       && GET_CODE (PATTERN (insn)) == RESX)
2884     {
2885       /* A RESX leaves a region instead of entering it.  Thus the
2886          region itself may have been deleted out from under us.  */
2887       if (region == NULL)
2888         return NULL;
2889       region = region->outer;
2890     }
2891   else if (region->type == ERT_THROW)
2892     {
2893       type_thrown = region->u.throw.type;
2894       region = region->outer;
2895     }
2896
2897   for (; region; region = region->outer)
2898     if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
2899       break;
2900
2901   return info.handlers;
2902 }
2903
2904 /* Determine if the given INSN can throw an exception that is caught
2905    within the function.  */
2906
2907 bool
2908 can_throw_internal (insn)
2909      rtx insn;
2910 {
2911   struct eh_region *region;
2912   tree type_thrown;
2913   rtx note;
2914
2915   if (! INSN_P (insn))
2916     return false;
2917
2918   if (GET_CODE (insn) == INSN
2919       && GET_CODE (PATTERN (insn)) == SEQUENCE)
2920     insn = XVECEXP (PATTERN (insn), 0, 0);
2921
2922   if (GET_CODE (insn) == CALL_INSN
2923       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
2924     {
2925       int i;
2926       for (i = 0; i < 3; ++i)
2927         {
2928           rtx sub = XEXP (PATTERN (insn), i);
2929           for (; sub ; sub = NEXT_INSN (sub))
2930             if (can_throw_internal (sub))
2931               return true;
2932         }
2933       return false;
2934     }
2935
2936   /* Every insn that might throw has an EH_REGION note.  */
2937   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2938   if (!note || INTVAL (XEXP (note, 0)) <= 0)
2939     return false;
2940
2941   region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2942
2943   type_thrown = NULL_TREE;
2944   if (region->type == ERT_THROW)
2945     {
2946       type_thrown = region->u.throw.type;
2947       region = region->outer;
2948     }
2949
2950   /* If this exception is ignored by each and every containing region,
2951      then control passes straight out.  The runtime may handle some
2952      regions, which also do not require processing internally.  */
2953   for (; region; region = region->outer)
2954     {
2955       enum reachable_code how = reachable_next_level (region, type_thrown, 0);
2956       if (how == RNL_BLOCKED)
2957         return false;
2958       if (how != RNL_NOT_CAUGHT)
2959         return true;
2960     }
2961
2962   return false;
2963 }
2964
2965 /* Determine if the given INSN can throw an exception that is
2966    visible outside the function.  */
2967
2968 bool
2969 can_throw_external (insn)
2970      rtx insn;
2971 {
2972   struct eh_region *region;
2973   tree type_thrown;
2974   rtx note;
2975
2976   if (! INSN_P (insn))
2977     return false;
2978
2979   if (GET_CODE (insn) == INSN
2980       && GET_CODE (PATTERN (insn)) == SEQUENCE)
2981     insn = XVECEXP (PATTERN (insn), 0, 0);
2982
2983   if (GET_CODE (insn) == CALL_INSN
2984       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
2985     {
2986       int i;
2987       for (i = 0; i < 3; ++i)
2988         {
2989           rtx sub = XEXP (PATTERN (insn), i);
2990           for (; sub ; sub = NEXT_INSN (sub))
2991             if (can_throw_external (sub))
2992               return true;
2993         }
2994       return false;
2995     }
2996
2997   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2998   if (!note)
2999     {
3000       /* Calls (and trapping insns) without notes are outside any
3001          exception handling region in this function.  We have to
3002          assume it might throw.  Given that the front end and middle
3003          ends mark known NOTHROW functions, this isn't so wildly
3004          inaccurate.  */
3005       return (GET_CODE (insn) == CALL_INSN
3006               || (flag_non_call_exceptions
3007                   && may_trap_p (PATTERN (insn))));
3008     }
3009   if (INTVAL (XEXP (note, 0)) <= 0)
3010     return false;
3011
3012   region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
3013
3014   type_thrown = NULL_TREE;
3015   if (region->type == ERT_THROW)
3016     {
3017       type_thrown = region->u.throw.type;
3018       region = region->outer;
3019     }
3020
3021   /* If the exception is caught or blocked by any containing region,
3022      then it is not seen by any calling function.  */
3023   for (; region ; region = region->outer)
3024     if (reachable_next_level (region, type_thrown, NULL) >= RNL_CAUGHT)
3025       return false;
3026
3027   return true;
3028 }
3029
3030 /* True if nothing in this function can throw outside this function.  */
3031
3032 bool
3033 nothrow_function_p ()
3034 {
3035   rtx insn;
3036
3037   if (! flag_exceptions)
3038     return true;
3039
3040   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3041     if (can_throw_external (insn))
3042       return false;
3043   for (insn = current_function_epilogue_delay_list; insn;
3044        insn = XEXP (insn, 1))
3045     if (can_throw_external (insn))
3046       return false;
3047
3048   return true;
3049 }
3050
3051 \f
3052 /* Various hooks for unwind library.  */
3053
3054 /* Do any necessary initialization to access arbitrary stack frames.
3055    On the SPARC, this means flushing the register windows.  */
3056
3057 void
3058 expand_builtin_unwind_init ()
3059 {
3060   /* Set this so all the registers get saved in our frame; we need to be
3061      able to copy the saved values for any registers from frames we unwind.  */
3062   current_function_has_nonlocal_label = 1;
3063
3064 #ifdef SETUP_FRAME_ADDRESSES
3065   SETUP_FRAME_ADDRESSES ();
3066 #endif
3067 }
3068
3069 rtx
3070 expand_builtin_eh_return_data_regno (arglist)
3071      tree arglist;
3072 {
3073   tree which = TREE_VALUE (arglist);
3074   unsigned HOST_WIDE_INT iwhich;
3075
3076   if (TREE_CODE (which) != INTEGER_CST)
3077     {
3078       error ("argument of `__builtin_eh_return_regno' must be constant");
3079       return constm1_rtx;
3080     }
3081
3082   iwhich = tree_low_cst (which, 1);
3083   iwhich = EH_RETURN_DATA_REGNO (iwhich);
3084   if (iwhich == INVALID_REGNUM)
3085     return constm1_rtx;
3086
3087 #ifdef DWARF_FRAME_REGNUM
3088   iwhich = DWARF_FRAME_REGNUM (iwhich);
3089 #else
3090   iwhich = DBX_REGISTER_NUMBER (iwhich);
3091 #endif
3092
3093   return GEN_INT (iwhich);
3094 }
3095
3096 /* Given a value extracted from the return address register or stack slot,
3097    return the actual address encoded in that value.  */
3098
3099 rtx
3100 expand_builtin_extract_return_addr (addr_tree)
3101      tree addr_tree;
3102 {
3103   rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
3104
3105   /* First mask out any unwanted bits.  */
3106 #ifdef MASK_RETURN_ADDR
3107   expand_and (addr, MASK_RETURN_ADDR, addr);
3108 #endif
3109
3110   /* Then adjust to find the real return address.  */
3111 #if defined (RETURN_ADDR_OFFSET)
3112   addr = plus_constant (addr, RETURN_ADDR_OFFSET);
3113 #endif
3114
3115   return addr;
3116 }
3117
3118 /* Given an actual address in addr_tree, do any necessary encoding
3119    and return the value to be stored in the return address register or
3120    stack slot so the epilogue will return to that address.  */
3121
3122 rtx
3123 expand_builtin_frob_return_addr (addr_tree)
3124      tree addr_tree;
3125 {
3126   rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, 0);
3127
3128 #ifdef POINTERS_EXTEND_UNSIGNED
3129   if (GET_MODE (addr) != Pmode)
3130     addr = convert_memory_address (Pmode, addr);
3131 #endif
3132
3133 #ifdef RETURN_ADDR_OFFSET
3134   addr = force_reg (Pmode, addr);
3135   addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
3136 #endif
3137
3138   return addr;
3139 }
3140
3141 /* Set up the epilogue with the magic bits we'll need to return to the
3142    exception handler.  */
3143
3144 void
3145 expand_builtin_eh_return (stackadj_tree, handler_tree)
3146     tree stackadj_tree, handler_tree;
3147 {
3148   rtx stackadj, handler;
3149
3150   stackadj = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0);
3151   handler = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0);
3152
3153 #ifdef POINTERS_EXTEND_UNSIGNED
3154   if (GET_MODE (stackadj) != Pmode)
3155     stackadj = convert_memory_address (Pmode, stackadj);
3156
3157   if (GET_MODE (handler) != Pmode)
3158     handler = convert_memory_address (Pmode, handler);
3159 #endif
3160
3161   if (! cfun->eh->ehr_label)
3162     {
3163       cfun->eh->ehr_stackadj = copy_to_reg (stackadj);
3164       cfun->eh->ehr_handler = copy_to_reg (handler);
3165       cfun->eh->ehr_label = gen_label_rtx ();
3166     }
3167   else
3168     {
3169       if (stackadj != cfun->eh->ehr_stackadj)
3170         emit_move_insn (cfun->eh->ehr_stackadj, stackadj);
3171       if (handler != cfun->eh->ehr_handler)
3172         emit_move_insn (cfun->eh->ehr_handler, handler);
3173     }
3174
3175   emit_jump (cfun->eh->ehr_label);
3176 }
3177
3178 void
3179 expand_eh_return ()
3180 {
3181   rtx sa, ra, around_label;
3182
3183   if (! cfun->eh->ehr_label)
3184     return;
3185
3186   sa = EH_RETURN_STACKADJ_RTX;
3187   if (! sa)
3188     {
3189       error ("__builtin_eh_return not supported on this target");
3190       return;
3191     }
3192
3193   current_function_calls_eh_return = 1;
3194
3195   around_label = gen_label_rtx ();
3196   emit_move_insn (sa, const0_rtx);
3197   emit_jump (around_label);
3198
3199   emit_label (cfun->eh->ehr_label);
3200   clobber_return_register ();
3201
3202 #ifdef HAVE_eh_return
3203   if (HAVE_eh_return)
3204     emit_insn (gen_eh_return (cfun->eh->ehr_stackadj, cfun->eh->ehr_handler));
3205   else
3206 #endif
3207     {
3208       ra = EH_RETURN_HANDLER_RTX;
3209       if (! ra)
3210         {
3211           error ("__builtin_eh_return not supported on this target");
3212           ra = gen_reg_rtx (Pmode);
3213         }
3214
3215       emit_move_insn (sa, cfun->eh->ehr_stackadj);
3216       emit_move_insn (ra, cfun->eh->ehr_handler);
3217     }
3218
3219   emit_label (around_label);
3220 }
3221 \f
3222 /* In the following functions, we represent entries in the action table
3223    as 1-based indices.  Special cases are:
3224
3225          0:     null action record, non-null landing pad; implies cleanups
3226         -1:     null action record, null landing pad; implies no action
3227         -2:     no call-site entry; implies must_not_throw
3228         -3:     we have yet to process outer regions
3229
3230    Further, no special cases apply to the "next" field of the record.
3231    For next, 0 means end of list.  */
3232
3233 struct action_record
3234 {
3235   int offset;
3236   int filter;
3237   int next;
3238 };
3239
3240 static int
3241 action_record_eq (pentry, pdata)
3242      const PTR pentry;
3243      const PTR pdata;
3244 {
3245   const struct action_record *entry = (const struct action_record *) pentry;
3246   const struct action_record *data = (const struct action_record *) pdata;
3247   return entry->filter == data->filter && entry->next == data->next;
3248 }
3249
3250 static hashval_t
3251 action_record_hash (pentry)
3252      const PTR pentry;
3253 {
3254   const struct action_record *entry = (const struct action_record *) pentry;
3255   return entry->next * 1009 + entry->filter;
3256 }
3257
3258 static int
3259 add_action_record (ar_hash, filter, next)
3260      htab_t ar_hash;
3261      int filter, next;
3262 {
3263   struct action_record **slot, *new, tmp;
3264
3265   tmp.filter = filter;
3266   tmp.next = next;
3267   slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT);
3268
3269   if ((new = *slot) == NULL)
3270     {
3271       new = (struct action_record *) xmalloc (sizeof (*new));
3272       new->offset = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
3273       new->filter = filter;
3274       new->next = next;
3275       *slot = new;
3276
3277       /* The filter value goes in untouched.  The link to the next
3278          record is a "self-relative" byte offset, or zero to indicate
3279          that there is no next record.  So convert the absolute 1 based
3280          indices we've been carrying around into a displacement.  */
3281
3282       push_sleb128 (&cfun->eh->action_record_data, filter);
3283       if (next)
3284         next -= VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
3285       push_sleb128 (&cfun->eh->action_record_data, next);
3286     }
3287
3288   return new->offset;
3289 }
3290
3291 static int
3292 collect_one_action_chain (ar_hash, region)
3293      htab_t ar_hash;
3294      struct eh_region *region;
3295 {
3296   struct eh_region *c;
3297   int next;
3298
3299   /* If we've reached the top of the region chain, then we have
3300      no actions, and require no landing pad.  */
3301   if (region == NULL)
3302     return -1;
3303
3304   switch (region->type)
3305     {
3306     case ERT_CLEANUP:
3307       /* A cleanup adds a zero filter to the beginning of the chain, but
3308          there are special cases to look out for.  If there are *only*
3309          cleanups along a path, then it compresses to a zero action.
3310          Further, if there are multiple cleanups along a path, we only
3311          need to represent one of them, as that is enough to trigger
3312          entry to the landing pad at runtime.  */
3313       next = collect_one_action_chain (ar_hash, region->outer);
3314       if (next <= 0)
3315         return 0;
3316       for (c = region->outer; c ; c = c->outer)
3317         if (c->type == ERT_CLEANUP)
3318           return next;
3319       return add_action_record (ar_hash, 0, next);
3320
3321     case ERT_TRY:
3322       /* Process the associated catch regions in reverse order.
3323          If there's a catch-all handler, then we don't need to
3324          search outer regions.  Use a magic -3 value to record
3325          that we haven't done the outer search.  */
3326       next = -3;
3327       for (c = region->u.try.last_catch; c ; c = c->u.catch.prev_catch)
3328         {
3329           if (c->u.catch.type_list == NULL)
3330             {
3331               /* Retrieve the filter from the head of the filter list
3332                  where we have stored it (see assign_filter_values).  */
3333               int filter
3334                 = TREE_INT_CST_LOW (TREE_VALUE (c->u.catch.filter_list));
3335
3336               next = add_action_record (ar_hash, filter, 0);
3337             }
3338           else
3339             {
3340               /* Once the outer search is done, trigger an action record for
3341                  each filter we have.  */
3342               tree flt_node;
3343
3344               if (next == -3)
3345                 {
3346                   next = collect_one_action_chain (ar_hash, region->outer);
3347
3348                   /* If there is no next action, terminate the chain.  */
3349                   if (next == -1)
3350                     next = 0;
3351                   /* If all outer actions are cleanups or must_not_throw,
3352                      we'll have no action record for it, since we had wanted
3353                      to encode these states in the call-site record directly.
3354                      Add a cleanup action to the chain to catch these.  */
3355                   else if (next <= 0)
3356                     next = add_action_record (ar_hash, 0, 0);
3357                 }
3358
3359               flt_node = c->u.catch.filter_list;
3360               for (; flt_node; flt_node = TREE_CHAIN (flt_node))
3361                 {
3362                   int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node));
3363                   next = add_action_record (ar_hash, filter, next);
3364                 }
3365             }
3366         }
3367       return next;
3368
3369     case ERT_ALLOWED_EXCEPTIONS:
3370       /* An exception specification adds its filter to the
3371          beginning of the chain.  */
3372       next = collect_one_action_chain (ar_hash, region->outer);
3373       return add_action_record (ar_hash, region->u.allowed.filter,
3374                                 next < 0 ? 0 : next);
3375
3376     case ERT_MUST_NOT_THROW:
3377       /* A must-not-throw region with no inner handlers or cleanups
3378          requires no call-site entry.  Note that this differs from
3379          the no handler or cleanup case in that we do require an lsda
3380          to be generated.  Return a magic -2 value to record this.  */
3381       return -2;
3382
3383     case ERT_CATCH:
3384     case ERT_THROW:
3385       /* CATCH regions are handled in TRY above.  THROW regions are
3386          for optimization information only and produce no output.  */
3387       return collect_one_action_chain (ar_hash, region->outer);
3388
3389     default:
3390       abort ();
3391     }
3392 }
3393
3394 static int
3395 add_call_site (landing_pad, action)
3396      rtx landing_pad;
3397      int action;
3398 {
3399   struct call_site_record *data = cfun->eh->call_site_data;
3400   int used = cfun->eh->call_site_data_used;
3401   int size = cfun->eh->call_site_data_size;
3402
3403   if (used >= size)
3404     {
3405       size = (size ? size * 2 : 64);
3406       data = (struct call_site_record *)
3407         xrealloc (data, sizeof (*data) * size);
3408       cfun->eh->call_site_data = data;
3409       cfun->eh->call_site_data_size = size;
3410     }
3411
3412   data[used].landing_pad = landing_pad;
3413   data[used].action = action;
3414
3415   cfun->eh->call_site_data_used = used + 1;
3416
3417   return used + call_site_base;
3418 }
3419
3420 /* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
3421    The new note numbers will not refer to region numbers, but
3422    instead to call site entries.  */
3423
3424 void
3425 convert_to_eh_region_ranges ()
3426 {
3427   rtx insn, iter, note;
3428   htab_t ar_hash;
3429   int last_action = -3;
3430   rtx last_action_insn = NULL_RTX;
3431   rtx last_landing_pad = NULL_RTX;
3432   rtx first_no_action_insn = NULL_RTX;
3433   int call_site = 0;
3434
3435   if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL)
3436     return;
3437
3438   VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
3439
3440   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
3441
3442   for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
3443     if (INSN_P (iter))
3444       {
3445         struct eh_region *region;
3446         int this_action;
3447         rtx this_landing_pad;
3448
3449         insn = iter;
3450         if (GET_CODE (insn) == INSN
3451             && GET_CODE (PATTERN (insn)) == SEQUENCE)
3452           insn = XVECEXP (PATTERN (insn), 0, 0);
3453
3454         note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3455         if (!note)
3456           {
3457             if (! (GET_CODE (insn) == CALL_INSN
3458                    || (flag_non_call_exceptions
3459                        && may_trap_p (PATTERN (insn)))))
3460               continue;
3461             this_action = -1;
3462             region = NULL;
3463           }
3464         else
3465           {
3466             if (INTVAL (XEXP (note, 0)) <= 0)
3467               continue;
3468             region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
3469             this_action = collect_one_action_chain (ar_hash, region);
3470           }
3471
3472         /* Existence of catch handlers, or must-not-throw regions
3473            implies that an lsda is needed (even if empty).  */
3474         if (this_action != -1)
3475           cfun->uses_eh_lsda = 1;
3476
3477         /* Delay creation of region notes for no-action regions
3478            until we're sure that an lsda will be required.  */
3479         else if (last_action == -3)
3480           {
3481             first_no_action_insn = iter;
3482             last_action = -1;
3483           }
3484
3485         /* Cleanups and handlers may share action chains but not
3486            landing pads.  Collect the landing pad for this region.  */
3487         if (this_action >= 0)
3488           {
3489             struct eh_region *o;
3490             for (o = region; ! o->landing_pad ; o = o->outer)
3491               continue;
3492             this_landing_pad = o->landing_pad;
3493           }
3494         else
3495           this_landing_pad = NULL_RTX;
3496
3497         /* Differing actions or landing pads implies a change in call-site
3498            info, which implies some EH_REGION note should be emitted.  */
3499         if (last_action != this_action
3500             || last_landing_pad != this_landing_pad)
3501           {
3502             /* If we'd not seen a previous action (-3) or the previous
3503                action was must-not-throw (-2), then we do not need an
3504                end note.  */
3505             if (last_action >= -1)
3506               {
3507                 /* If we delayed the creation of the begin, do it now.  */
3508                 if (first_no_action_insn)
3509                   {
3510                     call_site = add_call_site (NULL_RTX, 0);
3511                     note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
3512                                              first_no_action_insn);
3513                     NOTE_EH_HANDLER (note) = call_site;
3514                     first_no_action_insn = NULL_RTX;
3515                   }
3516
3517                 note = emit_note_after (NOTE_INSN_EH_REGION_END,
3518                                         last_action_insn);
3519                 NOTE_EH_HANDLER (note) = call_site;
3520               }
3521
3522             /* If the new action is must-not-throw, then no region notes
3523                are created.  */
3524             if (this_action >= -1)
3525               {
3526                 call_site = add_call_site (this_landing_pad,
3527                                            this_action < 0 ? 0 : this_action);
3528                 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter);
3529                 NOTE_EH_HANDLER (note) = call_site;
3530               }
3531
3532             last_action = this_action;
3533             last_landing_pad = this_landing_pad;
3534           }
3535         last_action_insn = iter;
3536       }
3537
3538   if (last_action >= -1 && ! first_no_action_insn)
3539     {
3540       note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn);
3541       NOTE_EH_HANDLER (note) = call_site;
3542     }
3543
3544   htab_delete (ar_hash);
3545 }
3546
3547 \f
3548 static void
3549 push_uleb128 (data_area, value)
3550      varray_type *data_area;
3551      unsigned int value;
3552 {
3553   do
3554     {
3555       unsigned char byte = value & 0x7f;
3556       value >>= 7;
3557       if (value)
3558         byte |= 0x80;
3559       VARRAY_PUSH_UCHAR (*data_area, byte);
3560     }
3561   while (value);
3562 }
3563
3564 static void
3565 push_sleb128 (data_area, value)
3566      varray_type *data_area;
3567      int value;
3568 {
3569   unsigned char byte;
3570   int more;
3571
3572   do
3573     {
3574       byte = value & 0x7f;
3575       value >>= 7;
3576       more = ! ((value == 0 && (byte & 0x40) == 0)
3577                 || (value == -1 && (byte & 0x40) != 0));
3578       if (more)
3579         byte |= 0x80;
3580       VARRAY_PUSH_UCHAR (*data_area, byte);
3581     }
3582   while (more);
3583 }
3584
3585 \f
3586 #ifndef HAVE_AS_LEB128
3587 static int
3588 dw2_size_of_call_site_table ()
3589 {
3590   int n = cfun->eh->call_site_data_used;
3591   int size = n * (4 + 4 + 4);
3592   int i;
3593
3594   for (i = 0; i < n; ++i)
3595     {
3596       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3597       size += size_of_uleb128 (cs->action);
3598     }
3599
3600   return size;
3601 }
3602
3603 static int
3604 sjlj_size_of_call_site_table ()
3605 {
3606   int n = cfun->eh->call_site_data_used;
3607   int size = 0;
3608   int i;
3609
3610   for (i = 0; i < n; ++i)
3611     {
3612       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3613       size += size_of_uleb128 (INTVAL (cs->landing_pad));
3614       size += size_of_uleb128 (cs->action);
3615     }
3616
3617   return size;
3618 }
3619 #endif
3620
3621 static void
3622 dw2_output_call_site_table ()
3623 {
3624   const char *const function_start_lab
3625     = IDENTIFIER_POINTER (current_function_func_begin_label);
3626   int n = cfun->eh->call_site_data_used;
3627   int i;
3628
3629   for (i = 0; i < n; ++i)
3630     {
3631       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3632       char reg_start_lab[32];
3633       char reg_end_lab[32];
3634       char landing_pad_lab[32];
3635
3636       ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i);
3637       ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i);
3638
3639       if (cs->landing_pad)
3640         ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L",
3641                                      CODE_LABEL_NUMBER (cs->landing_pad));
3642
3643       /* ??? Perhaps use insn length scaling if the assembler supports
3644          generic arithmetic.  */
3645       /* ??? Perhaps use attr_length to choose data1 or data2 instead of
3646          data4 if the function is small enough.  */
3647 #ifdef HAVE_AS_LEB128
3648       dw2_asm_output_delta_uleb128 (reg_start_lab, function_start_lab,
3649                                     "region %d start", i);
3650       dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
3651                                     "length");
3652       if (cs->landing_pad)
3653         dw2_asm_output_delta_uleb128 (landing_pad_lab, function_start_lab,
3654                                       "landing pad");
3655       else
3656         dw2_asm_output_data_uleb128 (0, "landing pad");
3657 #else
3658       dw2_asm_output_delta (4, reg_start_lab, function_start_lab,
3659                             "region %d start", i);
3660       dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
3661       if (cs->landing_pad)
3662         dw2_asm_output_delta (4, landing_pad_lab, function_start_lab,
3663                               "landing pad");
3664       else
3665         dw2_asm_output_data (4, 0, "landing pad");
3666 #endif
3667       dw2_asm_output_data_uleb128 (cs->action, "action");
3668     }
3669
3670   call_site_base += n;
3671 }
3672
3673 static void
3674 sjlj_output_call_site_table ()
3675 {
3676   int n = cfun->eh->call_site_data_used;
3677   int i;
3678
3679   for (i = 0; i < n; ++i)
3680     {
3681       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3682
3683       dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
3684                                    "region %d landing pad", i);
3685       dw2_asm_output_data_uleb128 (cs->action, "action");
3686     }
3687
3688   call_site_base += n;
3689 }
3690
3691 void
3692 output_function_exception_table ()
3693 {
3694   int tt_format, cs_format, lp_format, i, n;
3695 #ifdef HAVE_AS_LEB128
3696   char ttype_label[32];
3697   char cs_after_size_label[32];
3698   char cs_end_label[32];
3699 #else
3700   int call_site_len;
3701 #endif
3702   int have_tt_data;
3703   int funcdef_number;
3704   int tt_format_size = 0;
3705
3706   /* Not all functions need anything.  */
3707   if (! cfun->uses_eh_lsda)
3708     return;
3709
3710   funcdef_number = (USING_SJLJ_EXCEPTIONS
3711                     ? sjlj_funcdef_number
3712                     : current_funcdef_number);
3713
3714 #ifdef IA64_UNWIND_INFO
3715   fputs ("\t.personality\t", asm_out_file);
3716   output_addr_const (asm_out_file, eh_personality_libfunc);
3717   fputs ("\n\t.handlerdata\n", asm_out_file);
3718   /* Note that varasm still thinks we're in the function's code section.
3719      The ".endp" directive that will immediately follow will take us back.  */
3720 #else
3721   (*targetm.asm_out.exception_section) ();
3722 #endif
3723
3724   have_tt_data = (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) > 0
3725                   || VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) > 0);
3726
3727   /* Indicate the format of the @TType entries.  */
3728   if (! have_tt_data)
3729     tt_format = DW_EH_PE_omit;
3730   else
3731     {
3732       tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3733 #ifdef HAVE_AS_LEB128
3734       ASM_GENERATE_INTERNAL_LABEL (ttype_label, "LLSDATT", funcdef_number);
3735 #endif
3736       tt_format_size = size_of_encoded_value (tt_format);
3737
3738       assemble_align (tt_format_size * BITS_PER_UNIT);
3739     }
3740
3741   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LLSDA", funcdef_number);
3742
3743   /* The LSDA header.  */
3744
3745   /* Indicate the format of the landing pad start pointer.  An omitted
3746      field implies @LPStart == @Start.  */
3747   /* Currently we always put @LPStart == @Start.  This field would
3748      be most useful in moving the landing pads completely out of
3749      line to another section, but it could also be used to minimize
3750      the size of uleb128 landing pad offsets.  */
3751   lp_format = DW_EH_PE_omit;
3752   dw2_asm_output_data (1, lp_format, "@LPStart format (%s)",
3753                        eh_data_format_name (lp_format));
3754
3755   /* @LPStart pointer would go here.  */
3756
3757   dw2_asm_output_data (1, tt_format, "@TType format (%s)",
3758                        eh_data_format_name (tt_format));
3759
3760 #ifndef HAVE_AS_LEB128
3761   if (USING_SJLJ_EXCEPTIONS)
3762     call_site_len = sjlj_size_of_call_site_table ();
3763   else
3764     call_site_len = dw2_size_of_call_site_table ();
3765 #endif
3766
3767   /* A pc-relative 4-byte displacement to the @TType data.  */
3768   if (have_tt_data)
3769     {
3770 #ifdef HAVE_AS_LEB128
3771       char ttype_after_disp_label[32];
3772       ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label, "LLSDATTD",
3773                                    funcdef_number);
3774       dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label,
3775                                     "@TType base offset");
3776       ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
3777 #else
3778       /* Ug.  Alignment queers things.  */
3779       unsigned int before_disp, after_disp, last_disp, disp;
3780
3781       before_disp = 1 + 1;
3782       after_disp = (1 + size_of_uleb128 (call_site_len)
3783                     + call_site_len
3784                     + VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data)
3785                     + (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data)
3786                        * tt_format_size));
3787
3788       disp = after_disp;
3789       do
3790         {
3791           unsigned int disp_size, pad;
3792
3793           last_disp = disp;
3794           disp_size = size_of_uleb128 (disp);
3795           pad = before_disp + disp_size + after_disp;
3796           if (pad % tt_format_size)
3797             pad = tt_format_size - (pad % tt_format_size);
3798           else
3799             pad = 0;
3800           disp = after_disp + pad;
3801         }
3802       while (disp != last_disp);
3803
3804       dw2_asm_output_data_uleb128 (disp, "@TType base offset");
3805 #endif
3806     }
3807
3808   /* Indicate the format of the call-site offsets.  */
3809 #ifdef HAVE_AS_LEB128
3810   cs_format = DW_EH_PE_uleb128;
3811 #else
3812   cs_format = DW_EH_PE_udata4;
3813 #endif
3814   dw2_asm_output_data (1, cs_format, "call-site format (%s)",
3815                        eh_data_format_name (cs_format));
3816
3817 #ifdef HAVE_AS_LEB128
3818   ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label, "LLSDACSB",
3819                                funcdef_number);
3820   ASM_GENERATE_INTERNAL_LABEL (cs_end_label, "LLSDACSE",
3821                                funcdef_number);
3822   dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label,
3823                                 "Call-site table length");
3824   ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label);
3825   if (USING_SJLJ_EXCEPTIONS)
3826     sjlj_output_call_site_table ();
3827   else
3828     dw2_output_call_site_table ();
3829   ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
3830 #else
3831   dw2_asm_output_data_uleb128 (call_site_len,"Call-site table length");
3832   if (USING_SJLJ_EXCEPTIONS)
3833     sjlj_output_call_site_table ();
3834   else
3835     dw2_output_call_site_table ();
3836 #endif
3837
3838   /* ??? Decode and interpret the data for flag_debug_asm.  */
3839   n = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data);
3840   for (i = 0; i < n; ++i)
3841     dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->action_record_data, i),
3842                          (i ? NULL : "Action record table"));
3843
3844   if (have_tt_data)
3845     assemble_align (tt_format_size * BITS_PER_UNIT);
3846
3847   i = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data);
3848   while (i-- > 0)
3849     {
3850       tree type = VARRAY_TREE (cfun->eh->ttype_data, i);
3851       rtx value;
3852
3853       if (type == NULL_TREE)
3854         type = integer_zero_node;
3855       else
3856         type = lookup_type_for_runtime (type);
3857
3858       value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
3859       if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
3860         assemble_integer (value, tt_format_size,
3861                           tt_format_size * BITS_PER_UNIT, 1);
3862       else
3863         dw2_asm_output_encoded_addr_rtx (tt_format, value, NULL);
3864     }
3865
3866 #ifdef HAVE_AS_LEB128
3867   if (have_tt_data)
3868       ASM_OUTPUT_LABEL (asm_out_file, ttype_label);
3869 #endif
3870
3871   /* ??? Decode and interpret the data for flag_debug_asm.  */
3872   n = VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data);
3873   for (i = 0; i < n; ++i)
3874     dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->ehspec_data, i),
3875                          (i ? NULL : "Exception specification table"));
3876
3877   function_section (current_function_decl);
3878
3879   if (USING_SJLJ_EXCEPTIONS)
3880     sjlj_funcdef_number += 1;
3881 }