OSDN Git Service

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