OSDN Git Service

* except.c (sjlj_find_directly_reachable_regions): Be ready for removed toplevel
[pf3gnuchains/gcc-fork.git] / gcc / except.c
1 /* Implements exception handling.
2    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4    Free Software Foundation, Inc.
5    Contributed by Mike Stump <mrs@cygnus.com>.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23
24 /* An exception is an event that can be signaled from within a
25    function. This event can then be "caught" or "trapped" by the
26    callers of this function. This potentially allows program flow to
27    be transferred to any arbitrary code associated with a function call
28    several levels up the stack.
29
30    The intended use for this mechanism is for signaling "exceptional
31    events" in an out-of-band fashion, hence its name. The C++ language
32    (and many other OO-styled or functional languages) practically
33    requires such a mechanism, as otherwise it becomes very difficult
34    or even impossible to signal failure conditions in complex
35    situations.  The traditional C++ example is when an error occurs in
36    the process of constructing an object; without such a mechanism, it
37    is impossible to signal that the error occurs without adding global
38    state variables and error checks around every object construction.
39
40    The act of causing this event to occur is referred to as "throwing
41    an exception". (Alternate terms include "raising an exception" or
42    "signaling an exception".) The term "throw" is used because control
43    is returned to the callers of the function that is signaling the
44    exception, and thus there is the concept of "throwing" the
45    exception up the call stack.
46
47    [ Add updated documentation on how to use this.  ]  */
48
49
50 #include "config.h"
51 #include "system.h"
52 #include "coretypes.h"
53 #include "tm.h"
54 #include "rtl.h"
55 #include "tree.h"
56 #include "flags.h"
57 #include "function.h"
58 #include "expr.h"
59 #include "libfuncs.h"
60 #include "insn-config.h"
61 #include "except.h"
62 #include "integrate.h"
63 #include "hard-reg-set.h"
64 #include "basic-block.h"
65 #include "output.h"
66 #include "dwarf2asm.h"
67 #include "dwarf2out.h"
68 #include "dwarf2.h"
69 #include "toplev.h"
70 #include "hashtab.h"
71 #include "intl.h"
72 #include "ggc.h"
73 #include "tm_p.h"
74 #include "target.h"
75 #include "langhooks.h"
76 #include "cgraph.h"
77 #include "diagnostic.h"
78 #include "tree-pass.h"
79 #include "timevar.h"
80
81 /* Provide defaults for stuff that may not be defined when using
82    sjlj exceptions.  */
83 #ifndef EH_RETURN_DATA_REGNO
84 #define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM
85 #endif
86
87 /* Protect cleanup actions with must-not-throw regions, with a call
88    to the given failure handler.  */
89 gimple (*lang_protect_cleanup_actions) (void);
90
91 /* Return true if type A catches type B.  */
92 int (*lang_eh_type_covers) (tree a, tree b);
93
94 /* Map a type to a runtime object to match type.  */
95 tree (*lang_eh_runtime_type) (tree);
96
97 /* A hash table of label to region number.  */
98
99 struct ehl_map_entry GTY(())
100 {
101   rtx label;
102   struct eh_region *region;
103 };
104
105 static GTY(()) int call_site_base;
106 static GTY ((param_is (union tree_node)))
107   htab_t type_to_runtime_map;
108
109 /* Describe the SjLj_Function_Context structure.  */
110 static GTY(()) tree sjlj_fc_type_node;
111 static int sjlj_fc_call_site_ofs;
112 static int sjlj_fc_data_ofs;
113 static int sjlj_fc_personality_ofs;
114 static int sjlj_fc_lsda_ofs;
115 static int sjlj_fc_jbuf_ofs;
116 \f
117 /* Describes one exception region.  */
118 struct eh_region GTY(())
119 {
120   /* The immediately surrounding region.  */
121   struct eh_region *outer;
122
123   /* The list of immediately contained regions.  */
124   struct eh_region *inner;
125   struct eh_region *next_peer;
126
127   /* An identifier for this region.  */
128   int region_number;
129
130   /* When a region is deleted, its parents inherit the REG_EH_REGION
131      numbers already assigned.  */
132   bitmap aka;
133
134   /* Each region does exactly one thing.  */
135   enum eh_region_type
136   {
137     ERT_UNKNOWN = 0,
138     ERT_CLEANUP,
139     ERT_TRY,
140     ERT_CATCH,
141     ERT_ALLOWED_EXCEPTIONS,
142     ERT_MUST_NOT_THROW,
143     ERT_THROW
144   } type;
145
146   /* Holds the action to perform based on the preceding type.  */
147   union eh_region_u {
148     /* A list of catch blocks, a surrounding try block,
149        and the label for continuing after a catch.  */
150     struct eh_region_u_try {
151       struct eh_region *eh_catch;
152       struct eh_region *last_catch;
153     } GTY ((tag ("ERT_TRY"))) eh_try;
154
155     /* The list through the catch handlers, the list of type objects
156        matched, and the list of associated filters.  */
157     struct eh_region_u_catch {
158       struct eh_region *next_catch;
159       struct eh_region *prev_catch;
160       tree type_list;
161       tree filter_list;
162     } GTY ((tag ("ERT_CATCH"))) eh_catch;
163
164     /* A tree_list of allowed types.  */
165     struct eh_region_u_allowed {
166       tree type_list;
167       int filter;
168     } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
169
170     /* The type given by a call to "throw foo();", or discovered
171        for a throw.  */
172     struct eh_region_u_throw {
173       tree type;
174     } GTY ((tag ("ERT_THROW"))) eh_throw;
175
176     /* Retain the cleanup expression even after expansion so that
177        we can match up fixup regions.  */
178     struct eh_region_u_cleanup {
179       struct eh_region *prev_try;
180     } GTY ((tag ("ERT_CLEANUP"))) cleanup;
181   } GTY ((desc ("%0.type"))) u;
182
183   /* Entry point for this region's handler before landing pads are built.  */
184   rtx label;
185   tree tree_label;
186
187   /* Entry point for this region's handler from the runtime eh library.  */
188   rtx landing_pad;
189
190   /* Entry point for this region's handler from an inner region.  */
191   rtx post_landing_pad;
192
193   /* The RESX insn for handing off control to the next outermost handler,
194      if appropriate.  */
195   rtx resume;
196
197   /* True if something in this region may throw.  */
198   unsigned may_contain_throw : 1;
199 };
200
201 typedef struct eh_region *eh_region;
202
203 struct call_site_record GTY(())
204 {
205   rtx landing_pad;
206   int action;
207 };
208
209 DEF_VEC_P(eh_region);
210 DEF_VEC_ALLOC_P(eh_region, gc);
211 DEF_VEC_ALLOC_P(eh_region, heap);
212
213 /* Used to save exception status for each function.  */
214 struct eh_status GTY(())
215 {
216   /* The tree of all regions for this function.  */
217   struct eh_region *region_tree;
218
219   /* The same information as an indexable array.  */
220   VEC(eh_region,gc) *region_array;
221   int last_region_number;
222
223   htab_t GTY((param_is (struct throw_stmt_node))) throw_stmt_table;
224 };
225 \f
226 static int t2r_eq (const void *, const void *);
227 static hashval_t t2r_hash (const void *);
228 static void add_type_for_runtime (tree);
229 static tree lookup_type_for_runtime (tree);
230
231 static int ttypes_filter_eq (const void *, const void *);
232 static hashval_t ttypes_filter_hash (const void *);
233 static int ehspec_filter_eq (const void *, const void *);
234 static hashval_t ehspec_filter_hash (const void *);
235 static int add_ttypes_entry (htab_t, tree);
236 static int add_ehspec_entry (htab_t, htab_t, tree);
237 static void assign_filter_values (void);
238 static void build_post_landing_pads (void);
239 static void connect_post_landing_pads (void);
240 static void dw2_build_landing_pads (void);
241
242 struct sjlj_lp_info;
243 static bool sjlj_find_directly_reachable_regions (struct sjlj_lp_info *);
244 static void sjlj_assign_call_site_values (rtx, struct sjlj_lp_info *);
245 static void sjlj_mark_call_sites (struct sjlj_lp_info *);
246 static void sjlj_emit_function_enter (rtx);
247 static void sjlj_emit_function_exit (void);
248 static void sjlj_emit_dispatch_table (rtx, struct sjlj_lp_info *);
249 static void sjlj_build_landing_pads (void);
250
251 static hashval_t ehl_hash (const void *);
252 static int ehl_eq (const void *, const void *);
253 static void add_ehl_entry (rtx, struct eh_region *);
254 static void remove_exception_handler_label (rtx);
255 static void remove_eh_handler (struct eh_region *);
256 static void remove_eh_handler_and_replace (struct eh_region *,
257                                            struct eh_region *);
258 static int for_each_eh_label_1 (void **, void *);
259
260 /* The return value of reachable_next_level.  */
261 enum reachable_code
262 {
263   /* The given exception is not processed by the given region.  */
264   RNL_NOT_CAUGHT,
265   /* The given exception may need processing by the given region.  */
266   RNL_MAYBE_CAUGHT,
267   /* The given exception is completely processed by the given region.  */
268   RNL_CAUGHT,
269   /* The given exception is completely processed by the runtime.  */
270   RNL_BLOCKED
271 };
272
273 struct reachable_info;
274 static enum reachable_code reachable_next_level (struct eh_region *, tree,
275                                                  struct reachable_info *, bool);
276
277 static int action_record_eq (const void *, const void *);
278 static hashval_t action_record_hash (const void *);
279 static int add_action_record (htab_t, int, int);
280 static int collect_one_action_chain (htab_t, struct eh_region *);
281 static int add_call_site (rtx, int);
282
283 static void push_uleb128 (varray_type *, unsigned int);
284 static void push_sleb128 (varray_type *, int);
285 #ifndef HAVE_AS_LEB128
286 static int dw2_size_of_call_site_table (void);
287 static int sjlj_size_of_call_site_table (void);
288 #endif
289 static void dw2_output_call_site_table (void);
290 static void sjlj_output_call_site_table (void);
291
292 \f
293 /* Routine to see if exception handling is turned on.
294    DO_WARN is nonzero if we want to inform the user that exception
295    handling is turned off.
296
297    This is used to ensure that -fexceptions has been specified if the
298    compiler tries to use any exception-specific functions.  */
299
300 int
301 doing_eh (int do_warn)
302 {
303   if (! flag_exceptions)
304     {
305       static int warned = 0;
306       if (! warned && do_warn)
307         {
308           error ("exception handling disabled, use -fexceptions to enable");
309           warned = 1;
310         }
311       return 0;
312     }
313   return 1;
314 }
315
316 \f
317 void
318 init_eh (void)
319 {
320   if (! flag_exceptions)
321     return;
322
323   type_to_runtime_map = htab_create_ggc (31, t2r_hash, t2r_eq, NULL);
324
325   /* Create the SjLj_Function_Context structure.  This should match
326      the definition in unwind-sjlj.c.  */
327   if (USING_SJLJ_EXCEPTIONS)
328     {
329       tree f_jbuf, f_per, f_lsda, f_prev, f_cs, f_data, tmp;
330
331       sjlj_fc_type_node = lang_hooks.types.make_type (RECORD_TYPE);
332
333       f_prev = build_decl (FIELD_DECL, get_identifier ("__prev"),
334                            build_pointer_type (sjlj_fc_type_node));
335       DECL_FIELD_CONTEXT (f_prev) = sjlj_fc_type_node;
336
337       f_cs = build_decl (FIELD_DECL, get_identifier ("__call_site"),
338                          integer_type_node);
339       DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
340
341       tmp = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
342       tmp = build_array_type (lang_hooks.types.type_for_mode
343                                 (targetm.unwind_word_mode (), 1),
344                               tmp);
345       f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp);
346       DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node;
347
348       f_per = build_decl (FIELD_DECL, get_identifier ("__personality"),
349                           ptr_type_node);
350       DECL_FIELD_CONTEXT (f_per) = sjlj_fc_type_node;
351
352       f_lsda = build_decl (FIELD_DECL, get_identifier ("__lsda"),
353                            ptr_type_node);
354       DECL_FIELD_CONTEXT (f_lsda) = sjlj_fc_type_node;
355
356 #ifdef DONT_USE_BUILTIN_SETJMP
357 #ifdef JMP_BUF_SIZE
358       tmp = build_int_cst (NULL_TREE, JMP_BUF_SIZE - 1);
359 #else
360       /* Should be large enough for most systems, if it is not,
361          JMP_BUF_SIZE should be defined with the proper value.  It will
362          also tend to be larger than necessary for most systems, a more
363          optimal port will define JMP_BUF_SIZE.  */
364       tmp = build_int_cst (NULL_TREE, FIRST_PSEUDO_REGISTER + 2 - 1);
365 #endif
366 #else
367       /* builtin_setjmp takes a pointer to 5 words.  */
368       tmp = build_int_cst (NULL_TREE, 5 * BITS_PER_WORD / POINTER_SIZE - 1);
369 #endif
370       tmp = build_index_type (tmp);
371       tmp = build_array_type (ptr_type_node, tmp);
372       f_jbuf = build_decl (FIELD_DECL, get_identifier ("__jbuf"), tmp);
373 #ifdef DONT_USE_BUILTIN_SETJMP
374       /* We don't know what the alignment requirements of the
375          runtime's jmp_buf has.  Overestimate.  */
376       DECL_ALIGN (f_jbuf) = BIGGEST_ALIGNMENT;
377       DECL_USER_ALIGN (f_jbuf) = 1;
378 #endif
379       DECL_FIELD_CONTEXT (f_jbuf) = sjlj_fc_type_node;
380
381       TYPE_FIELDS (sjlj_fc_type_node) = f_prev;
382       TREE_CHAIN (f_prev) = f_cs;
383       TREE_CHAIN (f_cs) = f_data;
384       TREE_CHAIN (f_data) = f_per;
385       TREE_CHAIN (f_per) = f_lsda;
386       TREE_CHAIN (f_lsda) = f_jbuf;
387
388       layout_type (sjlj_fc_type_node);
389
390       /* Cache the interesting field offsets so that we have
391          easy access from rtl.  */
392       sjlj_fc_call_site_ofs
393         = (tree_low_cst (DECL_FIELD_OFFSET (f_cs), 1)
394            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_cs), 1) / BITS_PER_UNIT);
395       sjlj_fc_data_ofs
396         = (tree_low_cst (DECL_FIELD_OFFSET (f_data), 1)
397            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_data), 1) / BITS_PER_UNIT);
398       sjlj_fc_personality_ofs
399         = (tree_low_cst (DECL_FIELD_OFFSET (f_per), 1)
400            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_per), 1) / BITS_PER_UNIT);
401       sjlj_fc_lsda_ofs
402         = (tree_low_cst (DECL_FIELD_OFFSET (f_lsda), 1)
403            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_lsda), 1) / BITS_PER_UNIT);
404       sjlj_fc_jbuf_ofs
405         = (tree_low_cst (DECL_FIELD_OFFSET (f_jbuf), 1)
406            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_jbuf), 1) / BITS_PER_UNIT);
407     }
408 }
409
410 void
411 init_eh_for_function (void)
412 {
413   cfun->eh = GGC_CNEW (struct eh_status);
414 }
415 \f
416 /* Routines to generate the exception tree somewhat directly.
417    These are used from tree-eh.c when processing exception related
418    nodes during tree optimization.  */
419
420 static struct eh_region *
421 gen_eh_region (enum eh_region_type type, struct eh_region *outer)
422 {
423   struct eh_region *new_eh;
424
425 #ifdef ENABLE_CHECKING
426   gcc_assert (doing_eh (0));
427 #endif
428
429   /* Insert a new blank region as a leaf in the tree.  */
430   new_eh = GGC_CNEW (struct eh_region);
431   new_eh->type = type;
432   new_eh->outer = outer;
433   if (outer)
434     {
435       new_eh->next_peer = outer->inner;
436       outer->inner = new_eh;
437     }
438   else
439     {
440       new_eh->next_peer = cfun->eh->region_tree;
441       cfun->eh->region_tree = new_eh;
442     }
443
444   new_eh->region_number = ++cfun->eh->last_region_number;
445
446   return new_eh;
447 }
448
449 struct eh_region *
450 gen_eh_region_cleanup (struct eh_region *outer, struct eh_region *prev_try)
451 {
452   struct eh_region *cleanup = gen_eh_region (ERT_CLEANUP, outer);
453   cleanup->u.cleanup.prev_try = prev_try;
454   return cleanup;
455 }
456
457 struct eh_region *
458 gen_eh_region_try (struct eh_region *outer)
459 {
460   return gen_eh_region (ERT_TRY, outer);
461 }
462
463 struct eh_region *
464 gen_eh_region_catch (struct eh_region *t, tree type_or_list)
465 {
466   struct eh_region *c, *l;
467   tree type_list, type_node;
468
469   /* Ensure to always end up with a type list to normalize further
470      processing, then register each type against the runtime types map.  */
471   type_list = type_or_list;
472   if (type_or_list)
473     {
474       if (TREE_CODE (type_or_list) != TREE_LIST)
475         type_list = tree_cons (NULL_TREE, type_or_list, NULL_TREE);
476
477       type_node = type_list;
478       for (; type_node; type_node = TREE_CHAIN (type_node))
479         add_type_for_runtime (TREE_VALUE (type_node));
480     }
481
482   c = gen_eh_region (ERT_CATCH, t->outer);
483   c->u.eh_catch.type_list = type_list;
484   l = t->u.eh_try.last_catch;
485   c->u.eh_catch.prev_catch = l;
486   if (l)
487     l->u.eh_catch.next_catch = c;
488   else
489     t->u.eh_try.eh_catch = c;
490   t->u.eh_try.last_catch = c;
491
492   return c;
493 }
494
495 struct eh_region *
496 gen_eh_region_allowed (struct eh_region *outer, tree allowed)
497 {
498   struct eh_region *region = gen_eh_region (ERT_ALLOWED_EXCEPTIONS, outer);
499   region->u.allowed.type_list = allowed;
500
501   for (; allowed ; allowed = TREE_CHAIN (allowed))
502     add_type_for_runtime (TREE_VALUE (allowed));
503
504   return region;
505 }
506
507 struct eh_region *
508 gen_eh_region_must_not_throw (struct eh_region *outer)
509 {
510   return gen_eh_region (ERT_MUST_NOT_THROW, outer);
511 }
512
513 int
514 get_eh_region_number (struct eh_region *region)
515 {
516   return region->region_number;
517 }
518
519 bool
520 get_eh_region_may_contain_throw (struct eh_region *region)
521 {
522   return region->may_contain_throw;
523 }
524
525 tree
526 get_eh_region_tree_label (struct eh_region *region)
527 {
528   return region->tree_label;
529 }
530
531 tree
532 get_eh_region_no_tree_label (int region)
533 {
534   return VEC_index (eh_region, cfun->eh->region_array, region)->tree_label;
535 }
536
537 void
538 set_eh_region_tree_label (struct eh_region *region, tree lab)
539 {
540   region->tree_label = lab;
541 }
542 \f
543 void
544 expand_resx_expr (tree exp)
545 {
546   int region_nr = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0));
547   struct eh_region *reg = VEC_index (eh_region,
548                                      cfun->eh->region_array, region_nr);
549
550   gcc_assert (!reg->resume);
551   do_pending_stack_adjust ();
552   reg->resume = emit_jump_insn (gen_rtx_RESX (VOIDmode, region_nr));
553   emit_barrier ();
554 }
555
556 /* Note that the current EH region (if any) may contain a throw, or a
557    call to a function which itself may contain a throw.  */
558
559 void
560 note_eh_region_may_contain_throw (struct eh_region *region)
561 {
562   while (region && !region->may_contain_throw)
563     {
564       region->may_contain_throw = 1;
565       region = region->outer;
566     }
567 }
568
569
570 /* Return an rtl expression for a pointer to the exception object
571    within a handler.  */
572
573 rtx
574 get_exception_pointer (void)
575 {
576   if (! crtl->eh.exc_ptr)
577     crtl->eh.exc_ptr = gen_reg_rtx (ptr_mode);
578   return crtl->eh.exc_ptr;
579 }
580
581 /* Return an rtl expression for the exception dispatch filter
582    within a handler.  */
583
584 rtx
585 get_exception_filter (void)
586 {
587   if (! crtl->eh.filter)
588     crtl->eh.filter = gen_reg_rtx (targetm.eh_return_filter_mode ());
589   return crtl->eh.filter;
590 }
591 \f
592 /* This section is for the exception handling specific optimization pass.  */
593
594 /* Random access the exception region tree.  */
595
596 void
597 collect_eh_region_array (void)
598 {
599   struct eh_region *i;
600
601   i = cfun->eh->region_tree;
602   if (! i)
603     return;
604
605   VEC_safe_grow (eh_region, gc, cfun->eh->region_array,
606                  cfun->eh->last_region_number + 1);
607   VEC_replace (eh_region, cfun->eh->region_array, 0, 0);
608
609   while (1)
610     {
611       VEC_replace (eh_region, cfun->eh->region_array, i->region_number, i);
612
613       /* If there are sub-regions, process them.  */
614       if (i->inner)
615         i = i->inner;
616       /* If there are peers, process them.  */
617       else if (i->next_peer)
618         i = i->next_peer;
619       /* Otherwise, step back up the tree to the next peer.  */
620       else
621         {
622           do {
623             i = i->outer;
624             if (i == NULL)
625               return;
626           } while (i->next_peer == NULL);
627           i = i->next_peer;
628         }
629     }
630 }
631
632 /* R is MUST_NOT_THROW region that is not reachable via local
633    RESX instructions.  It still must be kept in the tree in case runtime
634    can unwind through it, or we will eliminate out terminate call
635    runtime would do otherwise.  Return TRUE if R contains throwing statements
636    or some of the exceptions in inner regions can be unwound up to R. 
637    
638    CONTAINS_STMT is bitmap of all regions that contains some throwing
639    statements.  
640    
641    Function looks O(^3) at first sight.  In fact the function is called at most
642    once for every MUST_NOT_THROW in EH tree from remove_unreachable_regions
643    Because the outer loop walking subregions does not dive in MUST_NOT_THROW,
644    the outer loop examines every region at most once.  The inner loop
645    is doing unwinding from the throwing statement same way as we do during
646    CFG construction, so it is O(^2) in size of EH tree, but O(n) in size
647    of CFG.  In practice Eh trees are wide, not deep, so this is not
648    a problem.  */
649
650 static bool
651 can_be_reached_by_runtime (sbitmap contains_stmt, struct eh_region *r)
652 {
653   struct eh_region *i = r->inner;
654   unsigned n;
655   bitmap_iterator bi;
656
657   if (TEST_BIT (contains_stmt, r->region_number))
658     return true;
659   if (r->aka)
660     EXECUTE_IF_SET_IN_BITMAP (r->aka, 0, n, bi)
661       if (TEST_BIT (contains_stmt, n))
662       return true;
663   if (!i)
664     return false;
665   while (1)
666     {
667       /* It is pointless to look into MUST_NOT_THROW
668          or dive into subregions.  They never unwind up.  */
669       if (i->type != ERT_MUST_NOT_THROW)
670         {
671           bool found = TEST_BIT (contains_stmt, i->region_number);
672           if (!found)
673             EXECUTE_IF_SET_IN_BITMAP (i->aka, 0, n, bi)
674               if (TEST_BIT (contains_stmt, n))
675               {
676                 found = true;
677                 break;
678               }
679           /* We have nested region that contains throwing statement.
680              See if resuming might lead up to the resx or we get locally
681              caught sooner.  If we get locally caught sooner, we either
682              know region R is not reachable or it would have direct edge
683              from the EH resx and thus consider region reachable at
684              firest place.  */
685           if (found)
686             {
687               struct eh_region *i1 = i;
688               tree type_thrown = NULL_TREE;
689
690               if (i1->type == ERT_THROW)
691                 {
692                   type_thrown = i1->u.eh_throw.type;
693                   i1 = i1->outer;
694                 }
695               for (; i1 != r; i1 = i1->outer)
696                 if (reachable_next_level (i1, type_thrown, NULL,
697                                           false) >= RNL_CAUGHT)
698                   break;
699               if (i1 == r)
700                 return true;
701             }
702         }
703       /* If there are sub-regions, process them.  */
704       if (i->type != ERT_MUST_NOT_THROW && i->inner)
705         i = i->inner;
706       /* If there are peers, process them.  */
707       else if (i->next_peer)
708         i = i->next_peer;
709       /* Otherwise, step back up the tree to the next peer.  */
710       else
711         {
712           do
713             {
714               i = i->outer;
715               if (i == r)
716                 return false;
717             }
718           while (i->next_peer == NULL);
719           i = i->next_peer;
720         }
721     }
722 }
723
724 /* Bring region R to the root of tree.  */
725
726 static void
727 bring_to_root (struct eh_region *r)
728 {
729   struct eh_region **pp;
730   struct eh_region *outer = r->outer;
731   if (!r->outer)
732     return;
733   for (pp = &outer->inner; *pp != r; pp = &(*pp)->next_peer)
734     continue;
735   *pp = r->next_peer;
736   r->outer = NULL;
737   r->next_peer = cfun->eh->region_tree;
738   cfun->eh->region_tree = r;
739 }
740
741 /* Remove all regions whose labels are not reachable.
742    REACHABLE is bitmap of all regions that are used by the function
743    CONTAINS_STMT is bitmap of all regions that contains stmt (or NULL). */
744
745 void
746 remove_unreachable_regions (sbitmap reachable, sbitmap contains_stmt)
747 {
748   int i;
749   struct eh_region *r;
750   VEC(eh_region,heap) *must_not_throws = VEC_alloc (eh_region, heap, 16);
751   struct eh_region *local_must_not_throw = NULL;
752   struct eh_region *first_must_not_throw = NULL;
753
754   for (i = cfun->eh->last_region_number; i > 0; --i)
755     {
756       r = VEC_index (eh_region, cfun->eh->region_array, i);
757       if (!r || r->region_number != i)
758         continue;
759       if (!TEST_BIT (reachable, i) && !r->resume)
760         {
761           bool kill_it = true;
762
763           r->tree_label = NULL;
764           switch (r->type)
765             {
766             case ERT_THROW:
767               /* Don't remove ERT_THROW regions if their outer region
768                  is reachable.  */
769               if (r->outer && TEST_BIT (reachable, r->outer->region_number))
770                 kill_it = false;
771               break;
772             case ERT_MUST_NOT_THROW:
773               /* MUST_NOT_THROW regions are implementable solely in the
774                  runtime, but we need them when inlining function.
775
776                  Keep them if outer region is not MUST_NOT_THROW a well
777                  and if they contain some statement that might unwind through
778                  them.  */
779               if ((!r->outer || r->outer->type != ERT_MUST_NOT_THROW)
780                   && (!contains_stmt
781                       || can_be_reached_by_runtime (contains_stmt, r)))
782                 kill_it = false;
783               break;
784             case ERT_TRY:
785               {
786                 /* TRY regions are reachable if any of its CATCH regions
787                    are reachable.  */
788                 struct eh_region *c;
789                 for (c = r->u.eh_try.eh_catch; c;
790                      c = c->u.eh_catch.next_catch)
791                   if (TEST_BIT (reachable, c->region_number))
792                     {
793                       kill_it = false;
794                       break;
795                     }
796                 break;
797               }
798
799             default:
800               break;
801             }
802
803           if (kill_it)
804             {
805               if (dump_file)
806                 fprintf (dump_file, "Removing unreachable eh region %i\n",
807                          r->region_number);
808               remove_eh_handler (r);
809             }
810           else if (r->type == ERT_MUST_NOT_THROW)
811             {
812               if (!first_must_not_throw)
813                 first_must_not_throw = r;
814               VEC_safe_push (eh_region, heap, must_not_throws, r);
815             }
816         }
817       else
818         if (r->type == ERT_MUST_NOT_THROW)
819           {
820             if (!local_must_not_throw)
821               local_must_not_throw = r;
822             if (r->outer)
823               VEC_safe_push (eh_region, heap, must_not_throws, r);
824           }
825     }
826
827   /* MUST_NOT_THROW regions without local handler are all the same; they
828      trigger terminate call in runtime.
829      MUST_NOT_THROW handled locally can differ in debug info associated
830      to std::terminate () call or if one is coming from Java and other
831      from C++ whether they call terminate or abort.  
832
833      We merge all MUST_NOT_THROW regions handled by the run-time into one.
834      We alsobring all local MUST_NOT_THROW regions to the roots of EH tree
835      (since unwinding never continues to the outer region anyway).
836      If MUST_NOT_THROW with local handler is present in the tree, we use
837      that region to merge into, since it will remain in tree anyway;
838      otherwise we use first MUST_NOT_THROW.
839
840      Merging of locally handled regions needs changes to the CFG.  Crossjumping
841      should take care of this, by looking at the actual code and
842      ensuring that the cleanup actions are really the same.  */
843
844   if (local_must_not_throw)
845     first_must_not_throw = local_must_not_throw;
846
847   for (i = 0; VEC_iterate (eh_region, must_not_throws, i, r); i++)
848     {
849       if (!r->label && !r->tree_label && r != first_must_not_throw)
850         {
851           if (dump_file)
852             fprintf (dump_file, "Replacing MUST_NOT_THROW region %i by %i\n",
853                      r->region_number,
854                      first_must_not_throw->region_number);
855           remove_eh_handler_and_replace (r, first_must_not_throw);
856         }
857       else
858         bring_to_root (r);
859     }
860 #ifdef ENABLE_CHECKING
861   verify_eh_tree (cfun);
862 #endif
863   VEC_free (eh_region, heap, must_not_throws);
864 }
865
866 /* Return array mapping LABEL_DECL_UID to region such that region's tree_label
867    is identical to label.  */
868
869 VEC(int,heap) *
870 label_to_region_map (void)
871 {
872   VEC(int,heap) * label_to_region = NULL;
873   int i;
874
875   VEC_safe_grow_cleared (int, heap, label_to_region,
876                          cfun->cfg->last_label_uid + 1);
877   for (i = cfun->eh->last_region_number; i > 0; --i)
878     {
879       struct eh_region *r = VEC_index (eh_region, cfun->eh->region_array, i);
880       if (r && r->region_number == i
881           && r->tree_label && LABEL_DECL_UID (r->tree_label) >= 0)
882         {
883           VEC_replace (int, label_to_region, LABEL_DECL_UID (r->tree_label),
884                        i);
885         }
886     }
887   return label_to_region;
888 }
889
890 /* Return number of EH regions.  */
891 int
892 num_eh_regions (void)
893 {
894   return cfun->eh->last_region_number + 1;
895 }
896
897 /* Remove all regions whose labels are not reachable from insns.  */
898
899 static void
900 rtl_remove_unreachable_regions (rtx insns)
901 {
902   int i, *uid_region_num;
903   sbitmap reachable;
904   struct eh_region *r;
905   rtx insn;
906
907   uid_region_num = XCNEWVEC (int, get_max_uid ());
908   reachable = sbitmap_alloc (cfun->eh->last_region_number + 1);
909   sbitmap_zero (reachable);
910
911   for (i = cfun->eh->last_region_number; i > 0; --i)
912     {
913       r = VEC_index (eh_region, cfun->eh->region_array, i);
914       if (!r || r->region_number != i)
915         continue;
916
917       if (r->resume)
918         {
919           gcc_assert (!uid_region_num[INSN_UID (r->resume)]);
920           uid_region_num[INSN_UID (r->resume)] = i;
921         }
922       if (r->label)
923         {
924           gcc_assert (!uid_region_num[INSN_UID (r->label)]);
925           uid_region_num[INSN_UID (r->label)] = i;
926         }
927     }
928
929   for (insn = insns; insn; insn = NEXT_INSN (insn))
930     SET_BIT (reachable, uid_region_num[INSN_UID (insn)]);
931
932   remove_unreachable_regions (reachable, NULL);
933
934   sbitmap_free (reachable);
935   free (uid_region_num);
936 }
937
938 /* Set up EH labels for RTL.  */
939
940 void
941 convert_from_eh_region_ranges (void)
942 {
943   rtx insns = get_insns ();
944   int i, n = cfun->eh->last_region_number;
945
946   /* Most of the work is already done at the tree level.  All we need to
947      do is collect the rtl labels that correspond to the tree labels that
948      collect the rtl labels that correspond to the tree labels
949      we allocated earlier.  */
950   for (i = 1; i <= n; ++i)
951     {
952       struct eh_region *region;
953
954       region = VEC_index (eh_region, cfun->eh->region_array, i);
955       if (region && region->tree_label)
956         region->label = DECL_RTL_IF_SET (region->tree_label);
957     }
958
959   rtl_remove_unreachable_regions (insns);
960 }
961
962 static void
963 add_ehl_entry (rtx label, struct eh_region *region)
964 {
965   struct ehl_map_entry **slot, *entry;
966
967   LABEL_PRESERVE_P (label) = 1;
968
969   entry = GGC_NEW (struct ehl_map_entry);
970   entry->label = label;
971   entry->region = region;
972
973   slot = (struct ehl_map_entry **)
974     htab_find_slot (crtl->eh.exception_handler_label_map, entry, INSERT);
975
976   /* Before landing pad creation, each exception handler has its own
977      label.  After landing pad creation, the exception handlers may
978      share landing pads.  This is ok, since maybe_remove_eh_handler
979      only requires the 1-1 mapping before landing pad creation.  */
980   gcc_assert (!*slot || crtl->eh.built_landing_pads);
981
982   *slot = entry;
983 }
984
985 void
986 find_exception_handler_labels (void)
987 {
988   int i;
989
990   if (crtl->eh.exception_handler_label_map)
991     htab_empty (crtl->eh.exception_handler_label_map);
992   else
993     {
994       /* ??? The expansion factor here (3/2) must be greater than the htab
995          occupancy factor (4/3) to avoid unnecessary resizing.  */
996       crtl->eh.exception_handler_label_map
997         = htab_create_ggc (cfun->eh->last_region_number * 3 / 2,
998                            ehl_hash, ehl_eq, NULL);
999     }
1000
1001   if (cfun->eh->region_tree == NULL)
1002     return;
1003
1004   for (i = cfun->eh->last_region_number; i > 0; --i)
1005     {
1006       struct eh_region *region;
1007       rtx lab;
1008
1009       region = VEC_index (eh_region, cfun->eh->region_array, i);
1010       if (! region || region->region_number != i)
1011         continue;
1012       if (crtl->eh.built_landing_pads)
1013         lab = region->landing_pad;
1014       else
1015         lab = region->label;
1016
1017       if (lab)
1018         add_ehl_entry (lab, region);
1019     }
1020
1021   /* For sjlj exceptions, need the return label to remain live until
1022      after landing pad generation.  */
1023   if (USING_SJLJ_EXCEPTIONS && ! crtl->eh.built_landing_pads)
1024     add_ehl_entry (return_label, NULL);
1025 }
1026
1027 /* Returns true if the current function has exception handling regions.  */
1028
1029 bool
1030 current_function_has_exception_handlers (void)
1031 {
1032   int i;
1033
1034   for (i = cfun->eh->last_region_number; i > 0; --i)
1035     {
1036       struct eh_region *region;
1037
1038       region = VEC_index (eh_region, cfun->eh->region_array, i);
1039       if (region
1040           && region->region_number == i
1041           && region->type != ERT_THROW)
1042         return true;
1043     }
1044
1045   return false;
1046 }
1047 \f
1048 /* A subroutine of duplicate_eh_regions.  Search the region tree under O
1049    for the minimum and maximum region numbers.  Update *MIN and *MAX.  */
1050
1051 static void
1052 duplicate_eh_regions_0 (eh_region o, int *min, int *max)
1053 {
1054   int i;
1055
1056   if (o->aka)
1057     {
1058       i = bitmap_first_set_bit (o->aka);
1059       if (i < *min)
1060         *min = i;
1061       i = bitmap_last_set_bit (o->aka);
1062       if (i > *max)
1063         *max = i;
1064     }
1065   if (o->region_number < *min)
1066     *min = o->region_number;
1067   if (o->region_number > *max)
1068     *max = o->region_number;
1069
1070   if (o->inner)
1071     {
1072       o = o->inner;
1073       duplicate_eh_regions_0 (o, min, max);
1074       while (o->next_peer)
1075         {
1076           o = o->next_peer;
1077           duplicate_eh_regions_0 (o, min, max);
1078         }
1079     }
1080 }
1081
1082 /* A subroutine of duplicate_eh_regions.  Copy the region tree under OLD.
1083    Root it at OUTER, and apply EH_OFFSET to the region number.  Don't worry
1084    about the other internal pointers just yet, just the tree-like pointers.  */
1085
1086 static eh_region
1087 duplicate_eh_regions_1 (eh_region old, eh_region outer, int eh_offset)
1088 {
1089   eh_region ret, n;
1090
1091   ret = n = GGC_NEW (struct eh_region);
1092
1093   *n = *old;
1094   n->outer = outer;
1095   n->next_peer = NULL;
1096   if (old->aka)
1097     {
1098       unsigned i;
1099       bitmap_iterator bi;
1100       n->aka = BITMAP_GGC_ALLOC ();
1101
1102       EXECUTE_IF_SET_IN_BITMAP (old->aka, 0, i, bi)
1103       {
1104         bitmap_set_bit (n->aka, i + eh_offset);
1105         VEC_replace (eh_region, cfun->eh->region_array, i + eh_offset, n);
1106       }
1107     }
1108
1109   n->region_number += eh_offset;
1110   VEC_replace (eh_region, cfun->eh->region_array, n->region_number, n);
1111
1112   if (old->inner)
1113     {
1114       old = old->inner;
1115       n = n->inner = duplicate_eh_regions_1 (old, ret, eh_offset);
1116       while (old->next_peer)
1117         {
1118           old = old->next_peer;
1119           n = n->next_peer = duplicate_eh_regions_1 (old, ret, eh_offset);
1120         }
1121     }
1122
1123   return ret;
1124 }
1125
1126 /* Duplicate the EH regions of IFUN, rooted at COPY_REGION, into current
1127    function and root the tree below OUTER_REGION.  Remap labels using MAP
1128    callback.  The special case of COPY_REGION of 0 means all regions.  */
1129
1130 int
1131 duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
1132                       void *data, int copy_region, int outer_region)
1133 {
1134   eh_region cur, prev_try, outer, *splice;
1135   int i, min_region, max_region, eh_offset, cfun_last_region_number;
1136   int num_regions;
1137
1138   if (!ifun->eh)
1139     return 0;
1140 #ifdef ENABLE_CHECKING
1141   verify_eh_tree (ifun);
1142 #endif
1143
1144   /* Find the range of region numbers to be copied.  The interface we 
1145      provide here mandates a single offset to find new number from old,
1146      which means we must look at the numbers present, instead of the
1147      count or something else.  */
1148   if (copy_region > 0)
1149     {
1150       min_region = INT_MAX;
1151       max_region = 0;
1152
1153       cur = VEC_index (eh_region, ifun->eh->region_array, copy_region);
1154       duplicate_eh_regions_0 (cur, &min_region, &max_region);
1155     }
1156   else
1157     min_region = 1, max_region = ifun->eh->last_region_number;
1158   num_regions = max_region - min_region + 1;
1159   cfun_last_region_number = cfun->eh->last_region_number;
1160   eh_offset = cfun_last_region_number + 1 - min_region;
1161
1162   /* If we've not yet created a region array, do so now.  */
1163   cfun->eh->last_region_number = cfun_last_region_number + num_regions;
1164   VEC_safe_grow_cleared (eh_region, gc, cfun->eh->region_array,
1165                          cfun->eh->last_region_number + 1);
1166
1167   /* Locate the spot at which to insert the new tree.  */
1168   if (outer_region > 0)
1169     {
1170       outer = VEC_index (eh_region, cfun->eh->region_array, outer_region);
1171       if (outer)
1172         splice = &outer->inner;
1173       else
1174         splice = &cfun->eh->region_tree;
1175     }
1176   else
1177     {
1178       outer = NULL;
1179       splice = &cfun->eh->region_tree;
1180     }
1181   while (*splice)
1182     splice = &(*splice)->next_peer;
1183
1184   if (!ifun->eh->region_tree)
1185     {
1186       if (outer)
1187         for (i = cfun_last_region_number + 1;
1188              i <= cfun->eh->last_region_number; i++)
1189           {
1190             VEC_replace (eh_region, cfun->eh->region_array, i, outer);
1191             if (outer->aka == NULL)
1192               outer->aka = BITMAP_GGC_ALLOC ();
1193             bitmap_set_bit (outer->aka, i);
1194           }
1195       return eh_offset;
1196     }
1197
1198   /* Copy all the regions in the subtree.  */
1199   if (copy_region > 0)
1200     {
1201       cur = VEC_index (eh_region, ifun->eh->region_array, copy_region);
1202       *splice = duplicate_eh_regions_1 (cur, outer, eh_offset);
1203     }
1204   else
1205     {
1206       eh_region n;
1207
1208       cur = ifun->eh->region_tree;
1209       *splice = n = duplicate_eh_regions_1 (cur, outer, eh_offset);
1210       while (cur->next_peer)
1211         {
1212           cur = cur->next_peer;
1213           n = n->next_peer = duplicate_eh_regions_1 (cur, outer, eh_offset);
1214         }
1215     }
1216
1217   /* Remap all the labels in the new regions.  */
1218   for (i = cfun_last_region_number + 1;
1219        VEC_iterate (eh_region, cfun->eh->region_array, i, cur); ++i)
1220     if (cur && cur->tree_label)
1221       cur->tree_label = map (cur->tree_label, data);
1222
1223   /* Search for the containing ERT_TRY region to fix up
1224      the prev_try short-cuts for ERT_CLEANUP regions.  */
1225   prev_try = NULL;
1226   if (outer_region > 0)
1227     for (prev_try =
1228          VEC_index (eh_region, cfun->eh->region_array, outer_region);
1229          prev_try && prev_try->type != ERT_TRY; prev_try = prev_try->outer)
1230       if (prev_try->type == ERT_MUST_NOT_THROW
1231           || (prev_try->type == ERT_ALLOWED_EXCEPTIONS
1232               && !prev_try->u.allowed.type_list))
1233         {
1234           prev_try = NULL;
1235           break;
1236         }
1237
1238   /* Remap all of the internal catch and cleanup linkages.  Since we 
1239      duplicate entire subtrees, all of the referenced regions will have
1240      been copied too.  And since we renumbered them as a block, a simple
1241      bit of arithmetic finds us the index for the replacement region.  */
1242   for (i = cfun_last_region_number + 1;
1243        VEC_iterate (eh_region, cfun->eh->region_array, i, cur); ++i)
1244     {
1245       /* All removed EH that is toplevel in input function is now
1246          in outer EH of output function.  */
1247       if (cur == NULL)
1248         {
1249           gcc_assert (VEC_index
1250                       (eh_region, ifun->eh->region_array,
1251                        i - eh_offset) == NULL);
1252           if (outer)
1253             {
1254               VEC_replace (eh_region, cfun->eh->region_array, i, outer);
1255               if (outer->aka == NULL)
1256                 outer->aka = BITMAP_GGC_ALLOC ();
1257               bitmap_set_bit (outer->aka, i);
1258             }
1259           continue;
1260         }
1261       if (i != cur->region_number)
1262         continue;
1263
1264 #define REMAP(REG) \
1265         (REG) = VEC_index (eh_region, cfun->eh->region_array, \
1266                            (REG)->region_number + eh_offset)
1267
1268       switch (cur->type)
1269         {
1270         case ERT_TRY:
1271           if (cur->u.eh_try.eh_catch)
1272             REMAP (cur->u.eh_try.eh_catch);
1273           if (cur->u.eh_try.last_catch)
1274             REMAP (cur->u.eh_try.last_catch);
1275           break;
1276
1277         case ERT_CATCH:
1278           if (cur->u.eh_catch.next_catch)
1279             REMAP (cur->u.eh_catch.next_catch);
1280           if (cur->u.eh_catch.prev_catch)
1281             REMAP (cur->u.eh_catch.prev_catch);
1282           break;
1283
1284         case ERT_CLEANUP:
1285           if (cur->u.cleanup.prev_try)
1286             REMAP (cur->u.cleanup.prev_try);
1287           else
1288             cur->u.cleanup.prev_try = prev_try;
1289           break;
1290
1291         default:
1292           break;
1293         }
1294
1295 #undef REMAP
1296     }
1297 #ifdef ENABLE_CHECKING
1298   verify_eh_tree (cfun);
1299 #endif
1300
1301   return eh_offset;
1302 }
1303
1304 /* Return true if REGION_A is outer to REGION_B in IFUN.  */
1305
1306 bool
1307 eh_region_outer_p (struct function *ifun, int region_a, int region_b)
1308 {
1309   struct eh_region *rp_a, *rp_b;
1310
1311   gcc_assert (ifun->eh->last_region_number > 0);
1312   gcc_assert (ifun->eh->region_tree);
1313
1314   rp_a = VEC_index (eh_region, ifun->eh->region_array, region_a);
1315   rp_b = VEC_index (eh_region, ifun->eh->region_array, region_b);
1316   gcc_assert (rp_a != NULL);
1317   gcc_assert (rp_b != NULL);
1318
1319   do
1320     {
1321       if (rp_a == rp_b)
1322         return true;
1323       rp_b = rp_b->outer;
1324     }
1325   while (rp_b);
1326
1327   return false;
1328 }
1329
1330 /* Return region number of region that is outer to both if REGION_A and
1331    REGION_B in IFUN.  */
1332
1333 int
1334 eh_region_outermost (struct function *ifun, int region_a, int region_b)
1335 {
1336   struct eh_region *rp_a, *rp_b;
1337   sbitmap b_outer;
1338
1339   gcc_assert (ifun->eh->last_region_number > 0);
1340   gcc_assert (ifun->eh->region_tree);
1341
1342   rp_a = VEC_index (eh_region, ifun->eh->region_array, region_a);
1343   rp_b = VEC_index (eh_region, ifun->eh->region_array, region_b);
1344   gcc_assert (rp_a != NULL);
1345   gcc_assert (rp_b != NULL);
1346
1347   b_outer = sbitmap_alloc (ifun->eh->last_region_number + 1);
1348   sbitmap_zero (b_outer);
1349
1350   do
1351     {
1352       SET_BIT (b_outer, rp_b->region_number);
1353       rp_b = rp_b->outer;
1354     }
1355   while (rp_b);
1356
1357   do
1358     {
1359       if (TEST_BIT (b_outer, rp_a->region_number))
1360         {
1361           sbitmap_free (b_outer);
1362           return rp_a->region_number;
1363         }
1364       rp_a = rp_a->outer;
1365     }
1366   while (rp_a);
1367
1368   sbitmap_free (b_outer);
1369   return -1;
1370 }
1371 \f
1372 static int
1373 t2r_eq (const void *pentry, const void *pdata)
1374 {
1375   const_tree const entry = (const_tree) pentry;
1376   const_tree const data = (const_tree) pdata;
1377
1378   return TREE_PURPOSE (entry) == data;
1379 }
1380
1381 static hashval_t
1382 t2r_hash (const void *pentry)
1383 {
1384   const_tree const entry = (const_tree) pentry;
1385   return TREE_HASH (TREE_PURPOSE (entry));
1386 }
1387
1388 static void
1389 add_type_for_runtime (tree type)
1390 {
1391   tree *slot;
1392
1393   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
1394                                             TREE_HASH (type), INSERT);
1395   if (*slot == NULL)
1396     {
1397       tree runtime = (*lang_eh_runtime_type) (type);
1398       *slot = tree_cons (type, runtime, NULL_TREE);
1399     }
1400 }
1401
1402 static tree
1403 lookup_type_for_runtime (tree type)
1404 {
1405   tree *slot;
1406
1407   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
1408                                             TREE_HASH (type), NO_INSERT);
1409
1410   /* We should have always inserted the data earlier.  */
1411   return TREE_VALUE (*slot);
1412 }
1413
1414 \f
1415 /* Represent an entry in @TTypes for either catch actions
1416    or exception filter actions.  */
1417 struct ttypes_filter GTY(())
1418 {
1419   tree t;
1420   int filter;
1421 };
1422
1423 /* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
1424    (a tree) for a @TTypes type node we are thinking about adding.  */
1425
1426 static int
1427 ttypes_filter_eq (const void *pentry, const void *pdata)
1428 {
1429   const struct ttypes_filter *const entry
1430     = (const struct ttypes_filter *) pentry;
1431   const_tree const data = (const_tree) pdata;
1432
1433   return entry->t == data;
1434 }
1435
1436 static hashval_t
1437 ttypes_filter_hash (const void *pentry)
1438 {
1439   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1440   return TREE_HASH (entry->t);
1441 }
1442
1443 /* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
1444    exception specification list we are thinking about adding.  */
1445 /* ??? Currently we use the type lists in the order given.  Someone
1446    should put these in some canonical order.  */
1447
1448 static int
1449 ehspec_filter_eq (const void *pentry, const void *pdata)
1450 {
1451   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1452   const struct ttypes_filter *data = (const struct ttypes_filter *) pdata;
1453
1454   return type_list_equal (entry->t, data->t);
1455 }
1456
1457 /* Hash function for exception specification lists.  */
1458
1459 static hashval_t
1460 ehspec_filter_hash (const void *pentry)
1461 {
1462   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1463   hashval_t h = 0;
1464   tree list;
1465
1466   for (list = entry->t; list ; list = TREE_CHAIN (list))
1467     h = (h << 5) + (h >> 27) + TREE_HASH (TREE_VALUE (list));
1468   return h;
1469 }
1470
1471 /* Add TYPE (which may be NULL) to crtl->eh.ttype_data, using TYPES_HASH
1472    to speed up the search.  Return the filter value to be used.  */
1473
1474 static int
1475 add_ttypes_entry (htab_t ttypes_hash, tree type)
1476 {
1477   struct ttypes_filter **slot, *n;
1478
1479   slot = (struct ttypes_filter **)
1480     htab_find_slot_with_hash (ttypes_hash, type, TREE_HASH (type), INSERT);
1481
1482   if ((n = *slot) == NULL)
1483     {
1484       /* Filter value is a 1 based table index.  */
1485
1486       n = XNEW (struct ttypes_filter);
1487       n->t = type;
1488       n->filter = VEC_length (tree, crtl->eh.ttype_data) + 1;
1489       *slot = n;
1490
1491       VEC_safe_push (tree, gc, crtl->eh.ttype_data, type);
1492     }
1493
1494   return n->filter;
1495 }
1496
1497 /* Add LIST to crtl->eh.ehspec_data, using EHSPEC_HASH and TYPES_HASH
1498    to speed up the search.  Return the filter value to be used.  */
1499
1500 static int
1501 add_ehspec_entry (htab_t ehspec_hash, htab_t ttypes_hash, tree list)
1502 {
1503   struct ttypes_filter **slot, *n;
1504   struct ttypes_filter dummy;
1505
1506   dummy.t = list;
1507   slot = (struct ttypes_filter **)
1508     htab_find_slot (ehspec_hash, &dummy, INSERT);
1509
1510   if ((n = *slot) == NULL)
1511     {
1512       /* Filter value is a -1 based byte index into a uleb128 buffer.  */
1513
1514       n = XNEW (struct ttypes_filter);
1515       n->t = list;
1516       n->filter = -(VARRAY_ACTIVE_SIZE (crtl->eh.ehspec_data) + 1);
1517       *slot = n;
1518
1519       /* Generate a 0 terminated list of filter values.  */
1520       for (; list ; list = TREE_CHAIN (list))
1521         {
1522           if (targetm.arm_eabi_unwinder)
1523             VARRAY_PUSH_TREE (crtl->eh.ehspec_data, TREE_VALUE (list));
1524           else
1525             {
1526               /* Look up each type in the list and encode its filter
1527                  value as a uleb128.  */
1528               push_uleb128 (&crtl->eh.ehspec_data,
1529                   add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
1530             }
1531         }
1532       if (targetm.arm_eabi_unwinder)
1533         VARRAY_PUSH_TREE (crtl->eh.ehspec_data, NULL_TREE);
1534       else
1535         VARRAY_PUSH_UCHAR (crtl->eh.ehspec_data, 0);
1536     }
1537
1538   return n->filter;
1539 }
1540
1541 /* Generate the action filter values to be used for CATCH and
1542    ALLOWED_EXCEPTIONS regions.  When using dwarf2 exception regions,
1543    we use lots of landing pads, and so every type or list can share
1544    the same filter value, which saves table space.  */
1545
1546 static void
1547 assign_filter_values (void)
1548 {
1549   int i;
1550   htab_t ttypes, ehspec;
1551
1552   crtl->eh.ttype_data = VEC_alloc (tree, gc, 16);
1553   if (targetm.arm_eabi_unwinder)
1554     VARRAY_TREE_INIT (crtl->eh.ehspec_data, 64, "ehspec_data");
1555   else
1556     VARRAY_UCHAR_INIT (crtl->eh.ehspec_data, 64, "ehspec_data");
1557
1558   ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
1559   ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
1560
1561   for (i = cfun->eh->last_region_number; i > 0; --i)
1562     {
1563       struct eh_region *r;
1564
1565       r = VEC_index (eh_region, cfun->eh->region_array, i);
1566
1567       /* Mind we don't process a region more than once.  */
1568       if (!r || r->region_number != i)
1569         continue;
1570
1571       switch (r->type)
1572         {
1573         case ERT_CATCH:
1574           /* Whatever type_list is (NULL or true list), we build a list
1575              of filters for the region.  */
1576           r->u.eh_catch.filter_list = NULL_TREE;
1577
1578           if (r->u.eh_catch.type_list != NULL)
1579             {
1580               /* Get a filter value for each of the types caught and store
1581                  them in the region's dedicated list.  */
1582               tree tp_node = r->u.eh_catch.type_list;
1583
1584               for (;tp_node; tp_node = TREE_CHAIN (tp_node))
1585                 {
1586                   int flt = add_ttypes_entry (ttypes, TREE_VALUE (tp_node));
1587                   tree flt_node = build_int_cst (NULL_TREE, flt);
1588
1589                   r->u.eh_catch.filter_list
1590                     = tree_cons (NULL_TREE, flt_node, r->u.eh_catch.filter_list);
1591                 }
1592             }
1593           else
1594             {
1595               /* Get a filter value for the NULL list also since it will need
1596                  an action record anyway.  */
1597               int flt = add_ttypes_entry (ttypes, NULL);
1598               tree flt_node = build_int_cst (NULL_TREE, flt);
1599
1600               r->u.eh_catch.filter_list
1601                 = tree_cons (NULL_TREE, flt_node, r->u.eh_catch.filter_list);
1602             }
1603
1604           break;
1605
1606         case ERT_ALLOWED_EXCEPTIONS:
1607           r->u.allowed.filter
1608             = add_ehspec_entry (ehspec, ttypes, r->u.allowed.type_list);
1609           break;
1610
1611         default:
1612           break;
1613         }
1614     }
1615
1616   htab_delete (ttypes);
1617   htab_delete (ehspec);
1618 }
1619
1620 /* Emit SEQ into basic block just before INSN (that is assumed to be
1621    first instruction of some existing BB and return the newly
1622    produced block.  */
1623 static basic_block
1624 emit_to_new_bb_before (rtx seq, rtx insn)
1625 {
1626   rtx last;
1627   basic_block bb;
1628   edge e;
1629   edge_iterator ei;
1630
1631   /* If there happens to be a fallthru edge (possibly created by cleanup_cfg
1632      call), we don't want it to go into newly created landing pad or other EH
1633      construct.  */
1634   for (ei = ei_start (BLOCK_FOR_INSN (insn)->preds); (e = ei_safe_edge (ei)); )
1635     if (e->flags & EDGE_FALLTHRU)
1636       force_nonfallthru (e);
1637     else
1638       ei_next (&ei);
1639   last = emit_insn_before (seq, insn);
1640   if (BARRIER_P (last))
1641     last = PREV_INSN (last);
1642   bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb);
1643   update_bb_for_insn (bb);
1644   bb->flags |= BB_SUPERBLOCK;
1645   return bb;
1646 }
1647
1648 /* Generate the code to actually handle exceptions, which will follow the
1649    landing pads.  */
1650
1651 static void
1652 build_post_landing_pads (void)
1653 {
1654   int i;
1655
1656   for (i = cfun->eh->last_region_number; i > 0; --i)
1657     {
1658       struct eh_region *region;
1659       rtx seq;
1660
1661       region = VEC_index (eh_region, cfun->eh->region_array, i);
1662       /* Mind we don't process a region more than once.  */
1663       if (!region || region->region_number != i)
1664         continue;
1665
1666       switch (region->type)
1667         {
1668         case ERT_TRY:
1669           /* ??? Collect the set of all non-overlapping catch handlers
1670                all the way up the chain until blocked by a cleanup.  */
1671           /* ??? Outer try regions can share landing pads with inner
1672              try regions if the types are completely non-overlapping,
1673              and there are no intervening cleanups.  */
1674
1675           region->post_landing_pad = gen_label_rtx ();
1676
1677           start_sequence ();
1678
1679           emit_label (region->post_landing_pad);
1680
1681           /* ??? It is mighty inconvenient to call back into the
1682              switch statement generation code in expand_end_case.
1683              Rapid prototyping sez a sequence of ifs.  */
1684           {
1685             struct eh_region *c;
1686             for (c = region->u.eh_try.eh_catch; c ; c = c->u.eh_catch.next_catch)
1687               {
1688                 if (c->u.eh_catch.type_list == NULL)
1689                   emit_jump (c->label);
1690                 else
1691                   {
1692                     /* Need for one cmp/jump per type caught. Each type
1693                        list entry has a matching entry in the filter list
1694                        (see assign_filter_values).  */
1695                     tree tp_node = c->u.eh_catch.type_list;
1696                     tree flt_node = c->u.eh_catch.filter_list;
1697
1698                     for (; tp_node; )
1699                       {
1700                         emit_cmp_and_jump_insns
1701                           (crtl->eh.filter,
1702                            GEN_INT (tree_low_cst (TREE_VALUE (flt_node), 0)),
1703                            EQ, NULL_RTX,
1704                            targetm.eh_return_filter_mode (), 0, c->label);
1705
1706                         tp_node = TREE_CHAIN (tp_node);
1707                         flt_node = TREE_CHAIN (flt_node);
1708                       }
1709                   }
1710               }
1711           }
1712
1713           /* We delay the generation of the _Unwind_Resume until we generate
1714              landing pads.  We emit a marker here so as to get good control
1715              flow data in the meantime.  */
1716           region->resume
1717             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1718           emit_barrier ();
1719
1720           seq = get_insns ();
1721           end_sequence ();
1722
1723           emit_to_new_bb_before (seq, region->u.eh_try.eh_catch->label);
1724
1725           break;
1726
1727         case ERT_ALLOWED_EXCEPTIONS:
1728           region->post_landing_pad = gen_label_rtx ();
1729
1730           start_sequence ();
1731
1732           emit_label (region->post_landing_pad);
1733
1734           emit_cmp_and_jump_insns (crtl->eh.filter,
1735                                    GEN_INT (region->u.allowed.filter),
1736                                    EQ, NULL_RTX,
1737                                    targetm.eh_return_filter_mode (), 0, region->label);
1738
1739           /* We delay the generation of the _Unwind_Resume until we generate
1740              landing pads.  We emit a marker here so as to get good control
1741              flow data in the meantime.  */
1742           region->resume
1743             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1744           emit_barrier ();
1745
1746           seq = get_insns ();
1747           end_sequence ();
1748
1749           emit_to_new_bb_before (seq, region->label);
1750           break;
1751
1752         case ERT_CLEANUP:
1753         case ERT_MUST_NOT_THROW:
1754           region->post_landing_pad = region->label;
1755           break;
1756
1757         case ERT_CATCH:
1758         case ERT_THROW:
1759           /* Nothing to do.  */
1760           break;
1761
1762         default:
1763           gcc_unreachable ();
1764         }
1765     }
1766 }
1767
1768 /* Replace RESX patterns with jumps to the next handler if any, or calls to
1769    _Unwind_Resume otherwise.  */
1770
1771 static void
1772 connect_post_landing_pads (void)
1773 {
1774   int i;
1775
1776   for (i = cfun->eh->last_region_number; i > 0; --i)
1777     {
1778       struct eh_region *region;
1779       struct eh_region *outer;
1780       rtx seq;
1781       rtx barrier;
1782
1783       region = VEC_index (eh_region, cfun->eh->region_array, i);
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         {
1802           edge e;
1803           basic_block src, dest;
1804
1805           emit_jump (outer->post_landing_pad);
1806           src = BLOCK_FOR_INSN (region->resume);
1807           dest = BLOCK_FOR_INSN (outer->post_landing_pad);
1808           while (EDGE_COUNT (src->succs) > 0)
1809             remove_edge (EDGE_SUCC (src, 0));
1810           e = make_edge (src, dest, 0);
1811           e->probability = REG_BR_PROB_BASE;
1812           e->count = src->count;
1813         }
1814       else
1815         {
1816           emit_library_call (unwind_resume_libfunc, LCT_THROW,
1817                              VOIDmode, 1, crtl->eh.exc_ptr, ptr_mode);
1818
1819           /* What we just emitted was a throwing libcall, so it got a
1820              barrier automatically added after it.  If the last insn in
1821              the libcall sequence isn't the barrier, it's because the
1822              target emits multiple insns for a call, and there are insns
1823              after the actual call insn (which are redundant and would be
1824              optimized away).  The barrier is inserted exactly after the
1825              call insn, so let's go get that and delete the insns after
1826              it, because below we need the barrier to be the last insn in
1827              the sequence.  */
1828           delete_insns_since (NEXT_INSN (last_call_insn ()));
1829         }
1830
1831       seq = get_insns ();
1832       end_sequence ();
1833       barrier = emit_insn_before (seq, region->resume);
1834       /* Avoid duplicate barrier.  */
1835       gcc_assert (BARRIER_P (barrier));
1836       delete_insn (barrier);
1837       delete_insn (region->resume);
1838
1839       /* ??? From tree-ssa we can wind up with catch regions whose
1840          label is not instantiated, but whose resx is present.  Now
1841          that we've dealt with the resx, kill the region.  */
1842       if (region->label == NULL && region->type == ERT_CLEANUP)
1843         remove_eh_handler (region);
1844     }
1845 }
1846
1847 \f
1848 static void
1849 dw2_build_landing_pads (void)
1850 {
1851   int i;
1852
1853   for (i = cfun->eh->last_region_number; i > 0; --i)
1854     {
1855       struct eh_region *region;
1856       rtx seq;
1857       basic_block bb;
1858       edge e;
1859
1860       region = VEC_index (eh_region, cfun->eh->region_array, i);
1861       /* Mind we don't process a region more than once.  */
1862       if (!region || region->region_number != i)
1863         continue;
1864
1865       if (region->type != ERT_CLEANUP
1866           && region->type != ERT_TRY
1867           && region->type != ERT_ALLOWED_EXCEPTIONS)
1868         continue;
1869
1870       start_sequence ();
1871
1872       region->landing_pad = gen_label_rtx ();
1873       emit_label (region->landing_pad);
1874
1875 #ifdef HAVE_exception_receiver
1876       if (HAVE_exception_receiver)
1877         emit_insn (gen_exception_receiver ());
1878       else
1879 #endif
1880 #ifdef HAVE_nonlocal_goto_receiver
1881         if (HAVE_nonlocal_goto_receiver)
1882           emit_insn (gen_nonlocal_goto_receiver ());
1883         else
1884 #endif
1885           { /* Nothing */ }
1886
1887       emit_move_insn (crtl->eh.exc_ptr,
1888                       gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
1889       emit_move_insn (crtl->eh.filter,
1890                       gen_rtx_REG (targetm.eh_return_filter_mode (),
1891                                    EH_RETURN_DATA_REGNO (1)));
1892
1893       seq = get_insns ();
1894       end_sequence ();
1895
1896       bb = emit_to_new_bb_before (seq, region->post_landing_pad);
1897       e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
1898       e->count = bb->count;
1899       e->probability = REG_BR_PROB_BASE;
1900     }
1901 }
1902
1903 \f
1904 struct sjlj_lp_info
1905 {
1906   int directly_reachable;
1907   int action_index;
1908   int dispatch_index;
1909   int call_site_index;
1910 };
1911
1912 static bool
1913 sjlj_find_directly_reachable_regions (struct sjlj_lp_info *lp_info)
1914 {
1915   rtx insn;
1916   bool found_one = false;
1917
1918   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
1919     {
1920       struct eh_region *region;
1921       enum reachable_code rc;
1922       tree type_thrown;
1923       rtx note;
1924
1925       if (! INSN_P (insn))
1926         continue;
1927
1928       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1929       if (!note || INTVAL (XEXP (note, 0)) <= 0)
1930         continue;
1931
1932       region = VEC_index (eh_region, cfun->eh->region_array, INTVAL (XEXP (note, 0)));
1933       if (!region)
1934         continue;
1935
1936       type_thrown = NULL_TREE;
1937       if (region->type == ERT_THROW)
1938         {
1939           type_thrown = region->u.eh_throw.type;
1940           region = region->outer;
1941         }
1942
1943       /* Find the first containing region that might handle the exception.
1944          That's the landing pad to which we will transfer control.  */
1945       rc = RNL_NOT_CAUGHT;
1946       for (; region; region = region->outer)
1947         {
1948           rc = reachable_next_level (region, type_thrown, NULL, false);
1949           if (rc != RNL_NOT_CAUGHT)
1950             break;
1951         }
1952       if (rc == RNL_MAYBE_CAUGHT || rc == RNL_CAUGHT)
1953         {
1954           lp_info[region->region_number].directly_reachable = 1;
1955           found_one = true;
1956         }
1957     }
1958
1959   return found_one;
1960 }
1961
1962 static void
1963 sjlj_assign_call_site_values (rtx dispatch_label, struct sjlj_lp_info *lp_info)
1964 {
1965   htab_t ar_hash;
1966   int i, index;
1967
1968   /* First task: build the action table.  */
1969
1970   VARRAY_UCHAR_INIT (crtl->eh.action_record_data, 64, "action_record_data");
1971   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
1972
1973   for (i = cfun->eh->last_region_number; i > 0; --i)
1974     if (lp_info[i].directly_reachable)
1975       {
1976         struct eh_region *r = VEC_index (eh_region, cfun->eh->region_array, i);
1977
1978         r->landing_pad = dispatch_label;
1979         lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
1980         if (lp_info[i].action_index != -1)
1981           crtl->uses_eh_lsda = 1;
1982       }
1983
1984   htab_delete (ar_hash);
1985
1986   /* Next: assign dispatch values.  In dwarf2 terms, this would be the
1987      landing pad label for the region.  For sjlj though, there is one
1988      common landing pad from which we dispatch to the post-landing pads.
1989
1990      A region receives a dispatch index if it is directly reachable
1991      and requires in-function processing.  Regions that share post-landing
1992      pads may share dispatch indices.  */
1993   /* ??? Post-landing pad sharing doesn't actually happen at the moment
1994      (see build_post_landing_pads) so we don't bother checking for it.  */
1995
1996   index = 0;
1997   for (i = cfun->eh->last_region_number; i > 0; --i)
1998     if (lp_info[i].directly_reachable)
1999       lp_info[i].dispatch_index = index++;
2000
2001   /* Finally: assign call-site values.  If dwarf2 terms, this would be
2002      the region number assigned by convert_to_eh_region_ranges, but
2003      handles no-action and must-not-throw differently.  */
2004
2005   call_site_base = 1;
2006   for (i = cfun->eh->last_region_number; i > 0; --i)
2007     if (lp_info[i].directly_reachable)
2008       {
2009         int action = lp_info[i].action_index;
2010
2011         /* Map must-not-throw to otherwise unused call-site index 0.  */
2012         if (action == -2)
2013           index = 0;
2014         /* Map no-action to otherwise unused call-site index -1.  */
2015         else if (action == -1)
2016           index = -1;
2017         /* Otherwise, look it up in the table.  */
2018         else
2019           index = add_call_site (GEN_INT (lp_info[i].dispatch_index), action);
2020
2021         lp_info[i].call_site_index = index;
2022       }
2023 }
2024
2025 static void
2026 sjlj_mark_call_sites (struct sjlj_lp_info *lp_info)
2027 {
2028   int last_call_site = -2;
2029   rtx insn, mem;
2030
2031   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
2032     {
2033       struct eh_region *region;
2034       int this_call_site;
2035       rtx note, before, p;
2036
2037       /* Reset value tracking at extended basic block boundaries.  */
2038       if (LABEL_P (insn))
2039         last_call_site = -2;
2040
2041       if (! INSN_P (insn))
2042         continue;
2043
2044       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2045
2046       /* Calls that are known to not throw need not be marked.  */
2047       if (note && INTVAL (XEXP (note, 0)) <= 0)
2048         continue;
2049
2050       if (note)
2051         region = VEC_index (eh_region, cfun->eh->region_array, INTVAL (XEXP (note, 0)));
2052       else
2053         region = NULL;
2054
2055       if (!region)
2056         {
2057           /* Calls (and trapping insns) without notes are outside any
2058              exception handling region in this function.  Mark them as
2059              no action.  */
2060           if (CALL_P (insn)
2061               || (flag_non_call_exceptions
2062                   && may_trap_p (PATTERN (insn))))
2063             this_call_site = -1;
2064           else
2065             continue;
2066         }
2067       else
2068         this_call_site = lp_info[region->region_number].call_site_index;
2069
2070       if (this_call_site == last_call_site)
2071         continue;
2072
2073       /* Don't separate a call from it's argument loads.  */
2074       before = insn;
2075       if (CALL_P (insn))
2076         before = find_first_parameter_load (insn, NULL_RTX);
2077
2078       start_sequence ();
2079       mem = adjust_address (crtl->eh.sjlj_fc, TYPE_MODE (integer_type_node),
2080                             sjlj_fc_call_site_ofs);
2081       emit_move_insn (mem, GEN_INT (this_call_site));
2082       p = get_insns ();
2083       end_sequence ();
2084
2085       emit_insn_before (p, before);
2086       last_call_site = this_call_site;
2087     }
2088 }
2089
2090 /* Construct the SjLj_Function_Context.  */
2091
2092 static void
2093 sjlj_emit_function_enter (rtx dispatch_label)
2094 {
2095   rtx fn_begin, fc, mem, seq;
2096   bool fn_begin_outside_block;
2097
2098   fc = crtl->eh.sjlj_fc;
2099
2100   start_sequence ();
2101
2102   /* We're storing this libcall's address into memory instead of
2103      calling it directly.  Thus, we must call assemble_external_libcall
2104      here, as we can not depend on emit_library_call to do it for us.  */
2105   assemble_external_libcall (eh_personality_libfunc);
2106   mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
2107   emit_move_insn (mem, eh_personality_libfunc);
2108
2109   mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
2110   if (crtl->uses_eh_lsda)
2111     {
2112       char buf[20];
2113       rtx sym;
2114
2115       ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", current_function_funcdef_no);
2116       sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
2117       SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_LOCAL;
2118       emit_move_insn (mem, sym);
2119     }
2120   else
2121     emit_move_insn (mem, const0_rtx);
2122
2123 #ifdef DONT_USE_BUILTIN_SETJMP
2124   {
2125     rtx x;
2126     x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
2127                                  TYPE_MODE (integer_type_node), 1,
2128                                  plus_constant (XEXP (fc, 0),
2129                                                 sjlj_fc_jbuf_ofs), Pmode);
2130
2131     emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
2132                              TYPE_MODE (integer_type_node), 0, dispatch_label);
2133     add_reg_br_prob_note (get_insns (), REG_BR_PROB_BASE/100);
2134   }
2135 #else
2136   expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
2137                                dispatch_label);
2138 #endif
2139
2140   emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
2141                      1, XEXP (fc, 0), Pmode);
2142
2143   seq = get_insns ();
2144   end_sequence ();
2145
2146   /* ??? Instead of doing this at the beginning of the function,
2147      do this in a block that is at loop level 0 and dominates all
2148      can_throw_internal instructions.  */
2149
2150   fn_begin_outside_block = true;
2151   for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
2152     if (NOTE_P (fn_begin))
2153       {
2154         if (NOTE_KIND (fn_begin) == NOTE_INSN_FUNCTION_BEG)
2155           break;
2156         else if (NOTE_INSN_BASIC_BLOCK_P (fn_begin))
2157           fn_begin_outside_block = false;
2158       }
2159
2160   if (fn_begin_outside_block)
2161     insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));
2162   else
2163     emit_insn_after (seq, fn_begin);
2164 }
2165
2166 /* Call back from expand_function_end to know where we should put
2167    the call to unwind_sjlj_unregister_libfunc if needed.  */
2168
2169 void
2170 sjlj_emit_function_exit_after (rtx after)
2171 {
2172   crtl->eh.sjlj_exit_after = after;
2173 }
2174
2175 static void
2176 sjlj_emit_function_exit (void)
2177 {
2178   rtx seq;
2179   edge e;
2180   edge_iterator ei;
2181
2182   start_sequence ();
2183
2184   emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
2185                      1, XEXP (crtl->eh.sjlj_fc, 0), Pmode);
2186
2187   seq = get_insns ();
2188   end_sequence ();
2189
2190   /* ??? Really this can be done in any block at loop level 0 that
2191      post-dominates all can_throw_internal instructions.  This is
2192      the last possible moment.  */
2193
2194   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
2195     if (e->flags & EDGE_FALLTHRU)
2196       break;
2197   if (e)
2198     {
2199       rtx insn;
2200
2201       /* Figure out whether the place we are supposed to insert libcall
2202          is inside the last basic block or after it.  In the other case
2203          we need to emit to edge.  */
2204       gcc_assert (e->src->next_bb == EXIT_BLOCK_PTR);
2205       for (insn = BB_HEAD (e->src); ; insn = NEXT_INSN (insn))
2206         {
2207           if (insn == crtl->eh.sjlj_exit_after)
2208             {
2209               if (LABEL_P (insn))
2210                 insn = NEXT_INSN (insn);
2211               emit_insn_after (seq, insn);
2212               return;
2213             }
2214           if (insn == BB_END (e->src))
2215             break;
2216         }
2217       insert_insn_on_edge (seq, e);
2218     }
2219 }
2220
2221 static void
2222 sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info)
2223 {
2224   enum machine_mode unwind_word_mode = targetm.unwind_word_mode ();
2225   enum machine_mode filter_mode = targetm.eh_return_filter_mode ();
2226   int i, first_reachable;
2227   rtx mem, dispatch, seq, fc;
2228   rtx before;
2229   basic_block bb;
2230   edge e;
2231
2232   fc = crtl->eh.sjlj_fc;
2233
2234   start_sequence ();
2235
2236   emit_label (dispatch_label);
2237
2238 #ifndef DONT_USE_BUILTIN_SETJMP
2239   expand_builtin_setjmp_receiver (dispatch_label);
2240 #endif
2241
2242   /* Load up dispatch index, exc_ptr and filter values from the
2243      function context.  */
2244   mem = adjust_address (fc, TYPE_MODE (integer_type_node),
2245                         sjlj_fc_call_site_ofs);
2246   dispatch = copy_to_reg (mem);
2247
2248   mem = adjust_address (fc, unwind_word_mode, sjlj_fc_data_ofs);
2249   if (unwind_word_mode != ptr_mode)
2250     {
2251 #ifdef POINTERS_EXTEND_UNSIGNED
2252       mem = convert_memory_address (ptr_mode, mem);
2253 #else
2254       mem = convert_to_mode (ptr_mode, mem, 0);
2255 #endif
2256     }
2257   emit_move_insn (crtl->eh.exc_ptr, mem);
2258
2259   mem = adjust_address (fc, unwind_word_mode,
2260                         sjlj_fc_data_ofs + GET_MODE_SIZE (unwind_word_mode));
2261   if (unwind_word_mode != filter_mode)
2262     mem = convert_to_mode (filter_mode, mem, 0);
2263   emit_move_insn (crtl->eh.filter, mem);
2264
2265   /* Jump to one of the directly reachable regions.  */
2266   /* ??? This really ought to be using a switch statement.  */
2267
2268   first_reachable = 0;
2269   for (i = cfun->eh->last_region_number; i > 0; --i)
2270     {
2271       if (! lp_info[i].directly_reachable)
2272         continue;
2273
2274       if (! first_reachable)
2275         {
2276           first_reachable = i;
2277           continue;
2278         }
2279
2280       emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index),
2281                                EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0,
2282                                ((struct eh_region *)VEC_index (eh_region, cfun->eh->region_array, i))
2283                                 ->post_landing_pad);
2284     }
2285
2286   seq = get_insns ();
2287   end_sequence ();
2288
2289   before = (((struct eh_region *)VEC_index (eh_region, cfun->eh->region_array, first_reachable))
2290             ->post_landing_pad);
2291
2292   bb = emit_to_new_bb_before (seq, before);
2293   e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
2294   e->count = bb->count;
2295   e->probability = REG_BR_PROB_BASE;
2296 }
2297
2298 static void
2299 sjlj_build_landing_pads (void)
2300 {
2301   struct sjlj_lp_info *lp_info;
2302
2303   lp_info = XCNEWVEC (struct sjlj_lp_info, cfun->eh->last_region_number + 1);
2304
2305   if (sjlj_find_directly_reachable_regions (lp_info))
2306     {
2307       rtx dispatch_label = gen_label_rtx ();
2308       int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node,
2309                                         TYPE_MODE (sjlj_fc_type_node),
2310                                         TYPE_ALIGN (sjlj_fc_type_node));
2311       crtl->eh.sjlj_fc
2312         = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
2313                               int_size_in_bytes (sjlj_fc_type_node),
2314                               align);
2315
2316       sjlj_assign_call_site_values (dispatch_label, lp_info);
2317       sjlj_mark_call_sites (lp_info);
2318
2319       sjlj_emit_function_enter (dispatch_label);
2320       sjlj_emit_dispatch_table (dispatch_label, lp_info);
2321       sjlj_emit_function_exit ();
2322     }
2323
2324   free (lp_info);
2325 }
2326
2327 void
2328 finish_eh_generation (void)
2329 {
2330   basic_block bb;
2331
2332   /* Nothing to do if no regions created.  */
2333   if (cfun->eh->region_tree == NULL)
2334     return;
2335
2336   /* The object here is to provide find_basic_blocks with detailed
2337      information (via reachable_handlers) on how exception control
2338      flows within the function.  In this first pass, we can include
2339      type information garnered from ERT_THROW and ERT_ALLOWED_EXCEPTIONS
2340      regions, and hope that it will be useful in deleting unreachable
2341      handlers.  Subsequently, we will generate landing pads which will
2342      connect many of the handlers, and then type information will not
2343      be effective.  Still, this is a win over previous implementations.  */
2344
2345   /* These registers are used by the landing pads.  Make sure they
2346      have been generated.  */
2347   get_exception_pointer ();
2348   get_exception_filter ();
2349
2350   /* Construct the landing pads.  */
2351
2352   assign_filter_values ();
2353   build_post_landing_pads ();
2354   connect_post_landing_pads ();
2355   if (USING_SJLJ_EXCEPTIONS)
2356     sjlj_build_landing_pads ();
2357   else
2358     dw2_build_landing_pads ();
2359
2360   crtl->eh.built_landing_pads = 1;
2361
2362   /* We've totally changed the CFG.  Start over.  */
2363   find_exception_handler_labels ();
2364   break_superblocks ();
2365   if (USING_SJLJ_EXCEPTIONS
2366       /* Kludge for Alpha/Tru64 (see alpha_gp_save_rtx).  */
2367       || single_succ_edge (ENTRY_BLOCK_PTR)->insns.r)
2368     commit_edge_insertions ();
2369   FOR_EACH_BB (bb)
2370     {
2371       edge e;
2372       edge_iterator ei;
2373       bool eh = false;
2374       for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
2375         {
2376           if (e->flags & EDGE_EH)
2377             {
2378               remove_edge (e);
2379               eh = true;
2380             }
2381           else
2382             ei_next (&ei);
2383         }
2384       if (eh)
2385         rtl_make_eh_edge (NULL, bb, BB_END (bb));
2386     }
2387 }
2388 \f
2389 static hashval_t
2390 ehl_hash (const void *pentry)
2391 {
2392   const struct ehl_map_entry *const entry
2393     = (const struct ehl_map_entry *) pentry;
2394
2395   /* 2^32 * ((sqrt(5) - 1) / 2) */
2396   const hashval_t scaled_golden_ratio = 0x9e3779b9;
2397   return CODE_LABEL_NUMBER (entry->label) * scaled_golden_ratio;
2398 }
2399
2400 static int
2401 ehl_eq (const void *pentry, const void *pdata)
2402 {
2403   const struct ehl_map_entry *const entry
2404     = (const struct ehl_map_entry *) pentry;
2405   const struct ehl_map_entry *const data
2406     = (const struct ehl_map_entry *) pdata;
2407
2408   return entry->label == data->label;
2409 }
2410
2411 /* This section handles removing dead code for flow.  */
2412
2413 /* Remove LABEL from exception_handler_label_map.  */
2414
2415 static void
2416 remove_exception_handler_label (rtx label)
2417 {
2418   struct ehl_map_entry **slot, tmp;
2419
2420   /* If exception_handler_label_map was not built yet,
2421      there is nothing to do.  */
2422   if (crtl->eh.exception_handler_label_map == NULL)
2423     return;
2424
2425   tmp.label = label;
2426   slot = (struct ehl_map_entry **)
2427     htab_find_slot (crtl->eh.exception_handler_label_map, &tmp, NO_INSERT);
2428   gcc_assert (slot);
2429
2430   htab_clear_slot (crtl->eh.exception_handler_label_map, (void **) slot);
2431 }
2432
2433 /* Splice REGION from the region tree and replace it by REPLACE etc.  */
2434
2435 static void
2436 remove_eh_handler_and_replace (struct eh_region *region,
2437                                struct eh_region *replace)
2438 {
2439   struct eh_region **pp, **pp_start, *p, *outer, *inner;
2440   rtx lab;
2441
2442   outer = region->outer;
2443   /* For the benefit of efficiently handling REG_EH_REGION notes,
2444      replace this region in the region array with its containing
2445      region.  Note that previous region deletions may result in
2446      multiple copies of this region in the array, so we have a
2447      list of alternate numbers by which we are known.  */
2448
2449   VEC_replace (eh_region, cfun->eh->region_array, region->region_number,
2450                replace);
2451   if (region->aka)
2452     {
2453       unsigned i;
2454       bitmap_iterator bi;
2455
2456       EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, bi)
2457         {
2458           VEC_replace (eh_region, cfun->eh->region_array, i, replace);
2459         }
2460     }
2461
2462   if (replace)
2463     {
2464       if (!replace->aka)
2465         replace->aka = BITMAP_GGC_ALLOC ();
2466       if (region->aka)
2467         bitmap_ior_into (replace->aka, region->aka);
2468       bitmap_set_bit (replace->aka, region->region_number);
2469     }
2470
2471   if (crtl->eh.built_landing_pads)
2472     lab = region->landing_pad;
2473   else
2474     lab = region->label;
2475   if (lab)
2476     remove_exception_handler_label (lab);
2477
2478   if (outer)
2479     pp_start = &outer->inner;
2480   else
2481     pp_start = &cfun->eh->region_tree;
2482   for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
2483     continue;
2484   *pp = region->next_peer;
2485
2486   if (replace)
2487     pp_start = &replace->inner;
2488   else
2489     pp_start = &cfun->eh->region_tree;
2490   inner = region->inner;
2491   if (inner)
2492     {
2493       for (p = inner; p->next_peer ; p = p->next_peer)
2494         p->outer = replace;
2495       p->outer = replace;
2496
2497       p->next_peer = *pp_start;
2498       *pp_start = inner;
2499     }
2500
2501   if (region->type == ERT_CATCH)
2502     {
2503       struct eh_region *eh_try, *next, *prev;
2504
2505       for (eh_try = region->next_peer;
2506            eh_try->type == ERT_CATCH;
2507            eh_try = eh_try->next_peer)
2508         continue;
2509       gcc_assert (eh_try->type == ERT_TRY);
2510
2511       next = region->u.eh_catch.next_catch;
2512       prev = region->u.eh_catch.prev_catch;
2513
2514       if (next)
2515         next->u.eh_catch.prev_catch = prev;
2516       else
2517         eh_try->u.eh_try.last_catch = prev;
2518       if (prev)
2519         prev->u.eh_catch.next_catch = next;
2520       else
2521         {
2522           eh_try->u.eh_try.eh_catch = next;
2523           if (! next)
2524             remove_eh_handler (eh_try);
2525         }
2526     }
2527 }
2528
2529 /* Splice REGION from the region tree and replace it by the outer region
2530    etc.  */
2531
2532 static void
2533 remove_eh_handler (struct eh_region *region)
2534 {
2535   remove_eh_handler_and_replace (region, region->outer);
2536 }
2537
2538 /* LABEL heads a basic block that is about to be deleted.  If this
2539    label corresponds to an exception region, we may be able to
2540    delete the region.  */
2541
2542 void
2543 maybe_remove_eh_handler (rtx label)
2544 {
2545   struct ehl_map_entry **slot, tmp;
2546   struct eh_region *region;
2547
2548   /* ??? After generating landing pads, it's not so simple to determine
2549      if the region data is completely unused.  One must examine the
2550      landing pad and the post landing pad, and whether an inner try block
2551      is referencing the catch handlers directly.  */
2552   if (crtl->eh.built_landing_pads)
2553     return;
2554
2555   tmp.label = label;
2556   slot = (struct ehl_map_entry **)
2557     htab_find_slot (crtl->eh.exception_handler_label_map, &tmp, NO_INSERT);
2558   if (! slot)
2559     return;
2560   region = (*slot)->region;
2561   if (! region)
2562     return;
2563
2564   /* Flow will want to remove MUST_NOT_THROW regions as unreachable
2565      because there is no path to the fallback call to terminate.
2566      But the region continues to affect call-site data until there
2567      are no more contained calls, which we don't see here.  */
2568   if (region->type == ERT_MUST_NOT_THROW)
2569     {
2570       htab_clear_slot (crtl->eh.exception_handler_label_map, (void **) slot);
2571       region->label = NULL_RTX;
2572     }
2573   else
2574     remove_eh_handler (region);
2575 }
2576
2577 /* Remove Eh region R that has turned out to have no code in its handler.  */
2578
2579 void
2580 remove_eh_region (int r)
2581 {
2582   struct eh_region *region;
2583
2584   region = VEC_index (eh_region, cfun->eh->region_array, r);
2585   remove_eh_handler (region);
2586 }
2587
2588 /* Invokes CALLBACK for every exception handler label.  Only used by old
2589    loop hackery; should not be used by new code.  */
2590
2591 void
2592 for_each_eh_label (void (*callback) (rtx))
2593 {
2594   htab_traverse (crtl->eh.exception_handler_label_map, for_each_eh_label_1,
2595                  (void *) &callback);
2596 }
2597
2598 static int
2599 for_each_eh_label_1 (void **pentry, void *data)
2600 {
2601   struct ehl_map_entry *entry = *(struct ehl_map_entry **)pentry;
2602   void (*callback) (rtx) = *(void (**) (rtx)) data;
2603
2604   (*callback) (entry->label);
2605   return 1;
2606 }
2607
2608 /* Invoke CALLBACK for every exception region in the current function.  */
2609
2610 void
2611 for_each_eh_region (void (*callback) (struct eh_region *))
2612 {
2613   int i, n = cfun->eh->last_region_number;
2614   for (i = 1; i <= n; ++i)
2615     {
2616       struct eh_region *region;
2617
2618       region = VEC_index (eh_region, cfun->eh->region_array, i);
2619       if (region)
2620         (*callback) (region);
2621     }
2622 }
2623 \f
2624 /* This section describes CFG exception edges for flow.  */
2625
2626 /* For communicating between calls to reachable_next_level.  */
2627 struct reachable_info
2628 {
2629   tree types_caught;
2630   tree types_allowed;
2631   void (*callback) (struct eh_region *, void *);
2632   void *callback_data;
2633 };
2634
2635 /* A subroutine of reachable_next_level.  Return true if TYPE, or a
2636    base class of TYPE, is in HANDLED.  */
2637
2638 static int
2639 check_handled (tree handled, tree type)
2640 {
2641   tree t;
2642
2643   /* We can check for exact matches without front-end help.  */
2644   if (! lang_eh_type_covers)
2645     {
2646       for (t = handled; t ; t = TREE_CHAIN (t))
2647         if (TREE_VALUE (t) == type)
2648           return 1;
2649     }
2650   else
2651     {
2652       for (t = handled; t ; t = TREE_CHAIN (t))
2653         if ((*lang_eh_type_covers) (TREE_VALUE (t), type))
2654           return 1;
2655     }
2656
2657   return 0;
2658 }
2659
2660 /* A subroutine of reachable_next_level.  If we are collecting a list
2661    of handlers, add one.  After landing pad generation, reference
2662    it instead of the handlers themselves.  Further, the handlers are
2663    all wired together, so by referencing one, we've got them all.
2664    Before landing pad generation we reference each handler individually.
2665
2666    LP_REGION contains the landing pad; REGION is the handler.  */
2667
2668 static void
2669 add_reachable_handler (struct reachable_info *info,
2670                        struct eh_region *lp_region, struct eh_region *region)
2671 {
2672   if (! info)
2673     return;
2674
2675   if (crtl->eh.built_landing_pads)
2676     info->callback (lp_region, info->callback_data);
2677   else
2678     info->callback (region, info->callback_data);
2679 }
2680
2681 /* Process one level of exception regions for reachability.
2682    If TYPE_THROWN is non-null, then it is the *exact* type being
2683    propagated.  If INFO is non-null, then collect handler labels
2684    and caught/allowed type information between invocations.  */
2685
2686 static enum reachable_code
2687 reachable_next_level (struct eh_region *region, tree type_thrown,
2688                       struct reachable_info *info,
2689                       bool maybe_resx)
2690 {
2691   switch (region->type)
2692     {
2693     case ERT_CLEANUP:
2694       /* Before landing-pad generation, we model control flow
2695          directly to the individual handlers.  In this way we can
2696          see that catch handler types may shadow one another.  */
2697       add_reachable_handler (info, region, region);
2698       return RNL_MAYBE_CAUGHT;
2699
2700     case ERT_TRY:
2701       {
2702         struct eh_region *c;
2703         enum reachable_code ret = RNL_NOT_CAUGHT;
2704
2705         for (c = region->u.eh_try.eh_catch; c ; c = c->u.eh_catch.next_catch)
2706           {
2707             /* A catch-all handler ends the search.  */
2708             if (c->u.eh_catch.type_list == NULL)
2709               {
2710                 add_reachable_handler (info, region, c);
2711                 return RNL_CAUGHT;
2712               }
2713
2714             if (type_thrown)
2715               {
2716                 /* If we have at least one type match, end the search.  */
2717                 tree tp_node = c->u.eh_catch.type_list;
2718
2719                 for (; tp_node; tp_node = TREE_CHAIN (tp_node))
2720                   {
2721                     tree type = TREE_VALUE (tp_node);
2722
2723                     if (type == type_thrown
2724                         || (lang_eh_type_covers
2725                             && (*lang_eh_type_covers) (type, type_thrown)))
2726                       {
2727                         add_reachable_handler (info, region, c);
2728                         return RNL_CAUGHT;
2729                       }
2730                   }
2731
2732                 /* If we have definitive information of a match failure,
2733                    the catch won't trigger.  */
2734                 if (lang_eh_type_covers)
2735                   return RNL_NOT_CAUGHT;
2736               }
2737
2738             /* At this point, we either don't know what type is thrown or
2739                don't have front-end assistance to help deciding if it is
2740                covered by one of the types in the list for this region.
2741
2742                We'd then like to add this region to the list of reachable
2743                handlers since it is indeed potentially reachable based on the
2744                information we have.
2745
2746                Actually, this handler is for sure not reachable if all the
2747                types it matches have already been caught. That is, it is only
2748                potentially reachable if at least one of the types it catches
2749                has not been previously caught.  */
2750
2751             if (! info)
2752               ret = RNL_MAYBE_CAUGHT;
2753             else
2754               {
2755                 tree tp_node = c->u.eh_catch.type_list;
2756                 bool maybe_reachable = false;
2757
2758                 /* Compute the potential reachability of this handler and
2759                    update the list of types caught at the same time.  */
2760                 for (; tp_node; tp_node = TREE_CHAIN (tp_node))
2761                   {
2762                     tree type = TREE_VALUE (tp_node);
2763
2764                     if (! check_handled (info->types_caught, type))
2765                       {
2766                         info->types_caught
2767                           = tree_cons (NULL, type, info->types_caught);
2768
2769                         maybe_reachable = true;
2770                       }
2771                   }
2772
2773                 if (maybe_reachable)
2774                   {
2775                     add_reachable_handler (info, region, c);
2776
2777                     /* ??? If the catch type is a base class of every allowed
2778                        type, then we know we can stop the search.  */
2779                     ret = RNL_MAYBE_CAUGHT;
2780                   }
2781               }
2782           }
2783
2784         return ret;
2785       }
2786
2787     case ERT_ALLOWED_EXCEPTIONS:
2788       /* An empty list of types definitely ends the search.  */
2789       if (region->u.allowed.type_list == NULL_TREE)
2790         {
2791           add_reachable_handler (info, region, region);
2792           return RNL_CAUGHT;
2793         }
2794
2795       /* Collect a list of lists of allowed types for use in detecting
2796          when a catch may be transformed into a catch-all.  */
2797       if (info)
2798         info->types_allowed = tree_cons (NULL_TREE,
2799                                          region->u.allowed.type_list,
2800                                          info->types_allowed);
2801
2802       /* If we have definitive information about the type hierarchy,
2803          then we can tell if the thrown type will pass through the
2804          filter.  */
2805       if (type_thrown && lang_eh_type_covers)
2806         {
2807           if (check_handled (region->u.allowed.type_list, type_thrown))
2808             return RNL_NOT_CAUGHT;
2809           else
2810             {
2811               add_reachable_handler (info, region, region);
2812               return RNL_CAUGHT;
2813             }
2814         }
2815
2816       add_reachable_handler (info, region, region);
2817       return RNL_MAYBE_CAUGHT;
2818
2819     case ERT_CATCH:
2820       /* Catch regions are handled by their controlling try region.  */
2821       return RNL_NOT_CAUGHT;
2822
2823     case ERT_MUST_NOT_THROW:
2824       /* Here we end our search, since no exceptions may propagate.
2825         
2826          Local landing pads of ERT_MUST_NOT_THROW instructions are reachable
2827          only via locally handled RESX instructions.  
2828
2829          When we inline a function call, we can bring in new handlers.  In order
2830          to avoid ERT_MUST_NOT_THROW landing pads from being deleted as unreachable
2831          assume that such handlers exists prior for any inlinable call prior
2832          inlining decisions are fixed.  */
2833
2834       if (maybe_resx)
2835         {
2836           add_reachable_handler (info, region, region);
2837           return RNL_CAUGHT;
2838         }
2839       else
2840         return RNL_BLOCKED;
2841
2842     case ERT_THROW:
2843     case ERT_UNKNOWN:
2844       /* Shouldn't see these here.  */
2845       gcc_unreachable ();
2846       break;
2847     default:
2848       gcc_unreachable ();
2849     }
2850 }
2851
2852 /* Invoke CALLBACK on each region reachable from REGION_NUMBER.  */
2853
2854 void
2855 foreach_reachable_handler (int region_number, bool is_resx, bool inlinable_call,
2856                            void (*callback) (struct eh_region *, void *),
2857                            void *callback_data)
2858 {
2859   struct reachable_info info;
2860   struct eh_region *region;
2861   tree type_thrown;
2862
2863   memset (&info, 0, sizeof (info));
2864   info.callback = callback;
2865   info.callback_data = callback_data;
2866
2867   region = VEC_index (eh_region, cfun->eh->region_array, region_number);
2868   if (!region)
2869     return;
2870
2871   type_thrown = NULL_TREE;
2872   if (is_resx)
2873     {
2874       /* A RESX leaves a region instead of entering it.  Thus the
2875          region itself may have been deleted out from under us.  */
2876       if (region == NULL)
2877         return;
2878       region = region->outer;
2879     }
2880   else if (region->type == ERT_THROW)
2881     {
2882       type_thrown = region->u.eh_throw.type;
2883       region = region->outer;
2884     }
2885
2886   while (region)
2887     {
2888       if (reachable_next_level (region, type_thrown, &info,
2889                                 inlinable_call || is_resx) >= RNL_CAUGHT)
2890         break;
2891       /* If we have processed one cleanup, there is no point in
2892          processing any more of them.  Each cleanup will have an edge
2893          to the next outer cleanup region, so the flow graph will be
2894          accurate.  */
2895       if (region->type == ERT_CLEANUP)
2896         region = region->u.cleanup.prev_try;
2897       else
2898         region = region->outer;
2899     }
2900 }
2901
2902 /* Retrieve a list of labels of exception handlers which can be
2903    reached by a given insn.  */
2904
2905 static void
2906 arh_to_landing_pad (struct eh_region *region, void *data)
2907 {
2908   rtx *p_handlers = (rtx *) data;
2909   if (! *p_handlers)
2910     *p_handlers = alloc_INSN_LIST (region->landing_pad, NULL_RTX);
2911 }
2912
2913 static void
2914 arh_to_label (struct eh_region *region, void *data)
2915 {
2916   rtx *p_handlers = (rtx *) data;
2917   *p_handlers = alloc_INSN_LIST (region->label, *p_handlers);
2918 }
2919
2920 rtx
2921 reachable_handlers (rtx insn)
2922 {
2923   bool is_resx = false;
2924   rtx handlers = NULL;
2925   int region_number;
2926
2927   if (JUMP_P (insn)
2928       && GET_CODE (PATTERN (insn)) == RESX)
2929     {
2930       region_number = XINT (PATTERN (insn), 0);
2931       is_resx = true;
2932     }
2933   else
2934     {
2935       rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2936       if (!note || INTVAL (XEXP (note, 0)) <= 0)
2937         return NULL;
2938       region_number = INTVAL (XEXP (note, 0));
2939     }
2940
2941   foreach_reachable_handler (region_number, is_resx, false,
2942                              (crtl->eh.built_landing_pads
2943                               ? arh_to_landing_pad
2944                               : arh_to_label),
2945                              &handlers);
2946
2947   return handlers;
2948 }
2949
2950 /* Determine if the given INSN can throw an exception that is caught
2951    within the function.  */
2952
2953 bool
2954 can_throw_internal_1 (int region_number, bool is_resx, bool inlinable_call)
2955 {
2956   struct eh_region *region;
2957   tree type_thrown;
2958
2959   region = VEC_index (eh_region, cfun->eh->region_array, region_number);
2960   if (!region)
2961     return false;
2962
2963   type_thrown = NULL_TREE;
2964   if (is_resx)
2965     region = region->outer;
2966   else if (region->type == ERT_THROW)
2967     {
2968       type_thrown = region->u.eh_throw.type;
2969       region = region->outer;
2970     }
2971
2972   /* If this exception is ignored by each and every containing region,
2973      then control passes straight out.  The runtime may handle some
2974      regions, which also do not require processing internally.  */
2975   for (; region; region = region->outer)
2976     {
2977       enum reachable_code how = reachable_next_level (region, type_thrown, 0,
2978                                                       inlinable_call || is_resx);
2979       if (how == RNL_BLOCKED)
2980         return false;
2981       if (how != RNL_NOT_CAUGHT)
2982         return true;
2983     }
2984
2985   return false;
2986 }
2987
2988 bool
2989 can_throw_internal (const_rtx insn)
2990 {
2991   rtx note;
2992
2993   if (! INSN_P (insn))
2994     return false;
2995
2996   if (JUMP_P (insn)
2997       && GET_CODE (PATTERN (insn)) == RESX
2998       && XINT (PATTERN (insn), 0) > 0)
2999     return can_throw_internal_1 (XINT (PATTERN (insn), 0), true, false);
3000
3001   if (NONJUMP_INSN_P (insn)
3002       && GET_CODE (PATTERN (insn)) == SEQUENCE)
3003     insn = XVECEXP (PATTERN (insn), 0, 0);
3004
3005   /* Every insn that might throw has an EH_REGION note.  */
3006   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3007   if (!note || INTVAL (XEXP (note, 0)) <= 0)
3008     return false;
3009
3010   return can_throw_internal_1 (INTVAL (XEXP (note, 0)), false, false);
3011 }
3012
3013 /* Determine if the given INSN can throw an exception that is
3014    visible outside the function.  */
3015
3016 bool
3017 can_throw_external_1 (int region_number, bool is_resx, bool inlinable_call)
3018 {
3019   struct eh_region *region;
3020   tree type_thrown;
3021
3022   region = VEC_index (eh_region, cfun->eh->region_array, region_number);
3023   if (!region)
3024     return true;
3025
3026   type_thrown = NULL_TREE;
3027   if (is_resx)
3028     region = region->outer;
3029   else if (region->type == ERT_THROW)
3030     {
3031       type_thrown = region->u.eh_throw.type;
3032       region = region->outer;
3033     }
3034
3035   /* If the exception is caught or blocked by any containing region,
3036      then it is not seen by any calling function.  */
3037   for (; region ; region = region->outer)
3038     if (reachable_next_level (region, type_thrown, NULL,
3039         inlinable_call || is_resx) >= RNL_CAUGHT)
3040       return false;
3041
3042   return true;
3043 }
3044
3045 bool
3046 can_throw_external (const_rtx insn)
3047 {
3048   rtx note;
3049
3050   if (! INSN_P (insn))
3051     return false;
3052
3053   if (JUMP_P (insn)
3054       && GET_CODE (PATTERN (insn)) == RESX
3055       && XINT (PATTERN (insn), 0) > 0)
3056     return can_throw_external_1 (XINT (PATTERN (insn), 0), true, false);
3057
3058   if (NONJUMP_INSN_P (insn)
3059       && GET_CODE (PATTERN (insn)) == SEQUENCE)
3060     insn = XVECEXP (PATTERN (insn), 0, 0);
3061
3062   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3063   if (!note)
3064     {
3065       /* Calls (and trapping insns) without notes are outside any
3066          exception handling region in this function.  We have to
3067          assume it might throw.  Given that the front end and middle
3068          ends mark known NOTHROW functions, this isn't so wildly
3069          inaccurate.  */
3070       return (CALL_P (insn)
3071               || (flag_non_call_exceptions
3072                   && may_trap_p (PATTERN (insn))));
3073     }
3074   if (INTVAL (XEXP (note, 0)) <= 0)
3075     return false;
3076
3077   return can_throw_external_1 (INTVAL (XEXP (note, 0)), false, false);
3078 }
3079
3080 /* Set TREE_NOTHROW and crtl->all_throwers_are_sibcalls.  */
3081
3082 unsigned int
3083 set_nothrow_function_flags (void)
3084 {
3085   rtx insn;
3086
3087   crtl->nothrow = 1;
3088
3089   /* Assume crtl->all_throwers_are_sibcalls until we encounter
3090      something that can throw an exception.  We specifically exempt
3091      CALL_INSNs that are SIBLING_CALL_P, as these are really jumps,
3092      and can't throw.  Most CALL_INSNs are not SIBLING_CALL_P, so this
3093      is optimistic.  */
3094
3095   crtl->all_throwers_are_sibcalls = 1;
3096
3097   /* If we don't know that this implementation of the function will
3098      actually be used, then we must not set TREE_NOTHROW, since
3099      callers must not assume that this function does not throw.  */
3100   if (TREE_NOTHROW (current_function_decl))
3101     return 0;
3102
3103   if (! flag_exceptions)
3104     return 0;
3105
3106   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3107     if (can_throw_external (insn))
3108       {
3109         crtl->nothrow = 0;
3110
3111         if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
3112           {
3113             crtl->all_throwers_are_sibcalls = 0;
3114             return 0;
3115           }
3116       }
3117
3118   for (insn = crtl->epilogue_delay_list; insn;
3119        insn = XEXP (insn, 1))
3120     if (can_throw_external (insn))
3121       {
3122         crtl->nothrow = 0;
3123
3124         if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
3125           {
3126             crtl->all_throwers_are_sibcalls = 0;
3127             return 0;
3128           }
3129       }
3130   if (crtl->nothrow
3131       && (cgraph_function_body_availability (cgraph_node (current_function_decl))
3132           >= AVAIL_AVAILABLE))
3133     TREE_NOTHROW (current_function_decl) = 1;
3134   return 0;
3135 }
3136
3137 struct rtl_opt_pass pass_set_nothrow_function_flags =
3138 {
3139  {
3140   RTL_PASS,
3141   NULL,                                 /* name */
3142   NULL,                                 /* gate */
3143   set_nothrow_function_flags,           /* execute */
3144   NULL,                                 /* sub */
3145   NULL,                                 /* next */
3146   0,                                    /* static_pass_number */
3147   0,                                    /* tv_id */
3148   0,                                    /* properties_required */
3149   0,                                    /* properties_provided */
3150   0,                                    /* properties_destroyed */
3151   0,                                    /* todo_flags_start */
3152   0,                                    /* todo_flags_finish */
3153  }
3154 };
3155
3156 \f
3157 /* Various hooks for unwind library.  */
3158
3159 /* Do any necessary initialization to access arbitrary stack frames.
3160    On the SPARC, this means flushing the register windows.  */
3161
3162 void
3163 expand_builtin_unwind_init (void)
3164 {
3165   /* Set this so all the registers get saved in our frame; we need to be
3166      able to copy the saved values for any registers from frames we unwind.  */
3167   crtl->saves_all_registers = 1;
3168
3169 #ifdef SETUP_FRAME_ADDRESSES
3170   SETUP_FRAME_ADDRESSES ();
3171 #endif
3172 }
3173
3174 rtx
3175 expand_builtin_eh_return_data_regno (tree exp)
3176 {
3177   tree which = CALL_EXPR_ARG (exp, 0);
3178   unsigned HOST_WIDE_INT iwhich;
3179
3180   if (TREE_CODE (which) != INTEGER_CST)
3181     {
3182       error ("argument of %<__builtin_eh_return_regno%> must be constant");
3183       return constm1_rtx;
3184     }
3185
3186   iwhich = tree_low_cst (which, 1);
3187   iwhich = EH_RETURN_DATA_REGNO (iwhich);
3188   if (iwhich == INVALID_REGNUM)
3189     return constm1_rtx;
3190
3191 #ifdef DWARF_FRAME_REGNUM
3192   iwhich = DWARF_FRAME_REGNUM (iwhich);
3193 #else
3194   iwhich = DBX_REGISTER_NUMBER (iwhich);
3195 #endif
3196
3197   return GEN_INT (iwhich);
3198 }
3199
3200 /* Given a value extracted from the return address register or stack slot,
3201    return the actual address encoded in that value.  */
3202
3203 rtx
3204 expand_builtin_extract_return_addr (tree addr_tree)
3205 {
3206   rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3207
3208   if (GET_MODE (addr) != Pmode
3209       && GET_MODE (addr) != VOIDmode)
3210     {
3211 #ifdef POINTERS_EXTEND_UNSIGNED
3212       addr = convert_memory_address (Pmode, addr);
3213 #else
3214       addr = convert_to_mode (Pmode, addr, 0);
3215 #endif
3216     }
3217
3218   /* First mask out any unwanted bits.  */
3219 #ifdef MASK_RETURN_ADDR
3220   expand_and (Pmode, addr, MASK_RETURN_ADDR, addr);
3221 #endif
3222
3223   /* Then adjust to find the real return address.  */
3224 #if defined (RETURN_ADDR_OFFSET)
3225   addr = plus_constant (addr, RETURN_ADDR_OFFSET);
3226 #endif
3227
3228   return addr;
3229 }
3230
3231 /* Given an actual address in addr_tree, do any necessary encoding
3232    and return the value to be stored in the return address register or
3233    stack slot so the epilogue will return to that address.  */
3234
3235 rtx
3236 expand_builtin_frob_return_addr (tree addr_tree)
3237 {
3238   rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL);
3239
3240   addr = convert_memory_address (Pmode, addr);
3241
3242 #ifdef RETURN_ADDR_OFFSET
3243   addr = force_reg (Pmode, addr);
3244   addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
3245 #endif
3246
3247   return addr;
3248 }
3249
3250 /* Set up the epilogue with the magic bits we'll need to return to the
3251    exception handler.  */
3252
3253 void
3254 expand_builtin_eh_return (tree stackadj_tree ATTRIBUTE_UNUSED,
3255                           tree handler_tree)
3256 {
3257   rtx tmp;
3258
3259 #ifdef EH_RETURN_STACKADJ_RTX
3260   tmp = expand_expr (stackadj_tree, crtl->eh.ehr_stackadj,
3261                      VOIDmode, EXPAND_NORMAL);
3262   tmp = convert_memory_address (Pmode, tmp);
3263   if (!crtl->eh.ehr_stackadj)
3264     crtl->eh.ehr_stackadj = copy_to_reg (tmp);
3265   else if (tmp != crtl->eh.ehr_stackadj)
3266     emit_move_insn (crtl->eh.ehr_stackadj, tmp);
3267 #endif
3268
3269   tmp = expand_expr (handler_tree, crtl->eh.ehr_handler,
3270                      VOIDmode, EXPAND_NORMAL);
3271   tmp = convert_memory_address (Pmode, tmp);
3272   if (!crtl->eh.ehr_handler)
3273     crtl->eh.ehr_handler = copy_to_reg (tmp);
3274   else if (tmp != crtl->eh.ehr_handler)
3275     emit_move_insn (crtl->eh.ehr_handler, tmp);
3276
3277   if (!crtl->eh.ehr_label)
3278     crtl->eh.ehr_label = gen_label_rtx ();
3279   emit_jump (crtl->eh.ehr_label);
3280 }
3281
3282 void
3283 expand_eh_return (void)
3284 {
3285   rtx around_label;
3286
3287   if (! crtl->eh.ehr_label)
3288     return;
3289
3290   crtl->calls_eh_return = 1;
3291
3292 #ifdef EH_RETURN_STACKADJ_RTX
3293   emit_move_insn (EH_RETURN_STACKADJ_RTX, const0_rtx);
3294 #endif
3295
3296   around_label = gen_label_rtx ();
3297   emit_jump (around_label);
3298
3299   emit_label (crtl->eh.ehr_label);
3300   clobber_return_register ();
3301
3302 #ifdef EH_RETURN_STACKADJ_RTX
3303   emit_move_insn (EH_RETURN_STACKADJ_RTX, crtl->eh.ehr_stackadj);
3304 #endif
3305
3306 #ifdef HAVE_eh_return
3307   if (HAVE_eh_return)
3308     emit_insn (gen_eh_return (crtl->eh.ehr_handler));
3309   else
3310 #endif
3311     {
3312 #ifdef EH_RETURN_HANDLER_RTX
3313       emit_move_insn (EH_RETURN_HANDLER_RTX, crtl->eh.ehr_handler);
3314 #else
3315       error ("__builtin_eh_return not supported on this target");
3316 #endif
3317     }
3318
3319   emit_label (around_label);
3320 }
3321
3322 /* Convert a ptr_mode address ADDR_TREE to a Pmode address controlled by
3323    POINTERS_EXTEND_UNSIGNED and return it.  */
3324
3325 rtx
3326 expand_builtin_extend_pointer (tree addr_tree)
3327 {
3328   rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL);
3329   int extend;
3330
3331 #ifdef POINTERS_EXTEND_UNSIGNED
3332   extend = POINTERS_EXTEND_UNSIGNED;
3333 #else
3334   /* The previous EH code did an unsigned extend by default, so we do this also
3335      for consistency.  */
3336   extend = 1;
3337 #endif
3338
3339   return convert_modes (targetm.unwind_word_mode (), ptr_mode, addr, extend);
3340 }
3341 \f
3342 /* In the following functions, we represent entries in the action table
3343    as 1-based indices.  Special cases are:
3344
3345          0:     null action record, non-null landing pad; implies cleanups
3346         -1:     null action record, null landing pad; implies no action
3347         -2:     no call-site entry; implies must_not_throw
3348         -3:     we have yet to process outer regions
3349
3350    Further, no special cases apply to the "next" field of the record.
3351    For next, 0 means end of list.  */
3352
3353 struct action_record
3354 {
3355   int offset;
3356   int filter;
3357   int next;
3358 };
3359
3360 static int
3361 action_record_eq (const void *pentry, const void *pdata)
3362 {
3363   const struct action_record *entry = (const struct action_record *) pentry;
3364   const struct action_record *data = (const struct action_record *) pdata;
3365   return entry->filter == data->filter && entry->next == data->next;
3366 }
3367
3368 static hashval_t
3369 action_record_hash (const void *pentry)
3370 {
3371   const struct action_record *entry = (const struct action_record *) pentry;
3372   return entry->next * 1009 + entry->filter;
3373 }
3374
3375 static int
3376 add_action_record (htab_t ar_hash, int filter, int next)
3377 {
3378   struct action_record **slot, *new_ar, tmp;
3379
3380   tmp.filter = filter;
3381   tmp.next = next;
3382   slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT);
3383
3384   if ((new_ar = *slot) == NULL)
3385     {
3386       new_ar = XNEW (struct action_record);
3387       new_ar->offset = VARRAY_ACTIVE_SIZE (crtl->eh.action_record_data) + 1;
3388       new_ar->filter = filter;
3389       new_ar->next = next;
3390       *slot = new_ar;
3391
3392       /* The filter value goes in untouched.  The link to the next
3393          record is a "self-relative" byte offset, or zero to indicate
3394          that there is no next record.  So convert the absolute 1 based
3395          indices we've been carrying around into a displacement.  */
3396
3397       push_sleb128 (&crtl->eh.action_record_data, filter);
3398       if (next)
3399         next -= VARRAY_ACTIVE_SIZE (crtl->eh.action_record_data) + 1;
3400       push_sleb128 (&crtl->eh.action_record_data, next);
3401     }
3402
3403   return new_ar->offset;
3404 }
3405
3406 static int
3407 collect_one_action_chain (htab_t ar_hash, struct eh_region *region)
3408 {
3409   struct eh_region *c;
3410   int next;
3411
3412   /* If we've reached the top of the region chain, then we have
3413      no actions, and require no landing pad.  */
3414   if (region == NULL)
3415     return -1;
3416
3417   switch (region->type)
3418     {
3419     case ERT_CLEANUP:
3420       /* A cleanup adds a zero filter to the beginning of the chain, but
3421          there are special cases to look out for.  If there are *only*
3422          cleanups along a path, then it compresses to a zero action.
3423          Further, if there are multiple cleanups along a path, we only
3424          need to represent one of them, as that is enough to trigger
3425          entry to the landing pad at runtime.  */
3426       next = collect_one_action_chain (ar_hash, region->outer);
3427       if (next <= 0)
3428         return 0;
3429       for (c = region->outer; c ; c = c->outer)
3430         if (c->type == ERT_CLEANUP)
3431           return next;
3432       return add_action_record (ar_hash, 0, next);
3433
3434     case ERT_TRY:
3435       /* Process the associated catch regions in reverse order.
3436          If there's a catch-all handler, then we don't need to
3437          search outer regions.  Use a magic -3 value to record
3438          that we haven't done the outer search.  */
3439       next = -3;
3440       for (c = region->u.eh_try.last_catch; c ; c = c->u.eh_catch.prev_catch)
3441         {
3442           if (c->u.eh_catch.type_list == NULL)
3443             {
3444               /* Retrieve the filter from the head of the filter list
3445                  where we have stored it (see assign_filter_values).  */
3446               int filter
3447                 = TREE_INT_CST_LOW (TREE_VALUE (c->u.eh_catch.filter_list));
3448
3449               next = add_action_record (ar_hash, filter, 0);
3450             }
3451           else
3452             {
3453               /* Once the outer search is done, trigger an action record for
3454                  each filter we have.  */
3455               tree flt_node;
3456
3457               if (next == -3)
3458                 {
3459                   next = collect_one_action_chain (ar_hash, region->outer);
3460
3461                   /* If there is no next action, terminate the chain.  */
3462                   if (next == -1)
3463                     next = 0;
3464                   /* If all outer actions are cleanups or must_not_throw,
3465                      we'll have no action record for it, since we had wanted
3466                      to encode these states in the call-site record directly.
3467                      Add a cleanup action to the chain to catch these.  */
3468                   else if (next <= 0)
3469                     next = add_action_record (ar_hash, 0, 0);
3470                 }
3471
3472               flt_node = c->u.eh_catch.filter_list;
3473               for (; flt_node; flt_node = TREE_CHAIN (flt_node))
3474                 {
3475                   int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node));
3476                   next = add_action_record (ar_hash, filter, next);
3477                 }
3478             }
3479         }
3480       return next;
3481
3482     case ERT_ALLOWED_EXCEPTIONS:
3483       /* An exception specification adds its filter to the
3484          beginning of the chain.  */
3485       next = collect_one_action_chain (ar_hash, region->outer);
3486
3487       /* If there is no next action, terminate the chain.  */
3488       if (next == -1)
3489         next = 0;
3490       /* If all outer actions are cleanups or must_not_throw,
3491          we'll have no action record for it, since we had wanted
3492          to encode these states in the call-site record directly.
3493          Add a cleanup action to the chain to catch these.  */
3494       else if (next <= 0)
3495         next = add_action_record (ar_hash, 0, 0);
3496
3497       return add_action_record (ar_hash, region->u.allowed.filter, next);
3498
3499     case ERT_MUST_NOT_THROW:
3500       /* A must-not-throw region with no inner handlers or cleanups
3501          requires no call-site entry.  Note that this differs from
3502          the no handler or cleanup case in that we do require an lsda
3503          to be generated.  Return a magic -2 value to record this.  */
3504       return -2;
3505
3506     case ERT_CATCH:
3507     case ERT_THROW:
3508       /* CATCH regions are handled in TRY above.  THROW regions are
3509          for optimization information only and produce no output.  */
3510       return collect_one_action_chain (ar_hash, region->outer);
3511
3512     default:
3513       gcc_unreachable ();
3514     }
3515 }
3516
3517 static int
3518 add_call_site (rtx landing_pad, int action)
3519 {
3520   call_site_record record;
3521   
3522   record = GGC_NEW (struct call_site_record);
3523   record->landing_pad = landing_pad;
3524   record->action = action;
3525
3526   VEC_safe_push (call_site_record, gc, crtl->eh.call_site_record, record);
3527
3528   return call_site_base + VEC_length (call_site_record, crtl->eh.call_site_record) - 1;
3529 }
3530
3531 /* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
3532    The new note numbers will not refer to region numbers, but
3533    instead to call site entries.  */
3534
3535 unsigned int
3536 convert_to_eh_region_ranges (void)
3537 {
3538   rtx insn, iter, note;
3539   htab_t ar_hash;
3540   int last_action = -3;
3541   rtx last_action_insn = NULL_RTX;
3542   rtx last_landing_pad = NULL_RTX;
3543   rtx first_no_action_insn = NULL_RTX;
3544   int call_site = 0;
3545
3546   if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL)
3547     return 0;
3548
3549   VARRAY_UCHAR_INIT (crtl->eh.action_record_data, 64, "action_record_data");
3550
3551   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
3552
3553   for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
3554     if (INSN_P (iter))
3555       {
3556         struct eh_region *region;
3557         int this_action;
3558         rtx this_landing_pad;
3559
3560         insn = iter;
3561         if (NONJUMP_INSN_P (insn)
3562             && GET_CODE (PATTERN (insn)) == SEQUENCE)
3563           insn = XVECEXP (PATTERN (insn), 0, 0);
3564
3565         note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3566         if (!note)
3567           {
3568             if (! (CALL_P (insn)
3569                    || (flag_non_call_exceptions
3570                        && may_trap_p (PATTERN (insn)))))
3571               continue;
3572             this_action = -1;
3573             region = NULL;
3574           }
3575         else
3576           {
3577             if (INTVAL (XEXP (note, 0)) <= 0)
3578               continue;
3579             region = VEC_index (eh_region, cfun->eh->region_array, INTVAL (XEXP (note, 0)));
3580             this_action = collect_one_action_chain (ar_hash, region);
3581           }
3582
3583         /* Existence of catch handlers, or must-not-throw regions
3584            implies that an lsda is needed (even if empty).  */
3585         if (this_action != -1)
3586           crtl->uses_eh_lsda = 1;
3587
3588         /* Delay creation of region notes for no-action regions
3589            until we're sure that an lsda will be required.  */
3590         else if (last_action == -3)
3591           {
3592             first_no_action_insn = iter;
3593             last_action = -1;
3594           }
3595
3596         /* Cleanups and handlers may share action chains but not
3597            landing pads.  Collect the landing pad for this region.  */
3598         if (this_action >= 0)
3599           {
3600             struct eh_region *o;
3601             for (o = region; ! o->landing_pad ; o = o->outer)
3602               continue;
3603             this_landing_pad = o->landing_pad;
3604           }
3605         else
3606           this_landing_pad = NULL_RTX;
3607
3608         /* Differing actions or landing pads implies a change in call-site
3609            info, which implies some EH_REGION note should be emitted.  */
3610         if (last_action != this_action
3611             || last_landing_pad != this_landing_pad)
3612           {
3613             /* If we'd not seen a previous action (-3) or the previous
3614                action was must-not-throw (-2), then we do not need an
3615                end note.  */
3616             if (last_action >= -1)
3617               {
3618                 /* If we delayed the creation of the begin, do it now.  */
3619                 if (first_no_action_insn)
3620                   {
3621                     call_site = add_call_site (NULL_RTX, 0);
3622                     note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
3623                                              first_no_action_insn);
3624                     NOTE_EH_HANDLER (note) = call_site;
3625                     first_no_action_insn = NULL_RTX;
3626                   }
3627
3628                 note = emit_note_after (NOTE_INSN_EH_REGION_END,
3629                                         last_action_insn);
3630                 NOTE_EH_HANDLER (note) = call_site;
3631               }
3632
3633             /* If the new action is must-not-throw, then no region notes
3634                are created.  */
3635             if (this_action >= -1)
3636               {
3637                 call_site = add_call_site (this_landing_pad,
3638                                            this_action < 0 ? 0 : this_action);
3639                 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter);
3640                 NOTE_EH_HANDLER (note) = call_site;
3641               }
3642
3643             last_action = this_action;
3644             last_landing_pad = this_landing_pad;
3645           }
3646         last_action_insn = iter;
3647       }
3648
3649   if (last_action >= -1 && ! first_no_action_insn)
3650     {
3651       note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn);
3652       NOTE_EH_HANDLER (note) = call_site;
3653     }
3654
3655   htab_delete (ar_hash);
3656   return 0;
3657 }
3658
3659 struct rtl_opt_pass pass_convert_to_eh_region_ranges =
3660 {
3661  {
3662   RTL_PASS,
3663   "eh_ranges",                          /* name */
3664   NULL,                                 /* gate */
3665   convert_to_eh_region_ranges,          /* execute */
3666   NULL,                                 /* sub */
3667   NULL,                                 /* next */
3668   0,                                    /* static_pass_number */
3669   0,                                    /* tv_id */
3670   0,                                    /* properties_required */
3671   0,                                    /* properties_provided */
3672   0,                                    /* properties_destroyed */
3673   0,                                    /* todo_flags_start */
3674   TODO_dump_func,                       /* todo_flags_finish */
3675  }
3676 };
3677
3678 \f
3679 static void
3680 push_uleb128 (varray_type *data_area, unsigned int value)
3681 {
3682   do
3683     {
3684       unsigned char byte = value & 0x7f;
3685       value >>= 7;
3686       if (value)
3687         byte |= 0x80;
3688       VARRAY_PUSH_UCHAR (*data_area, byte);
3689     }
3690   while (value);
3691 }
3692
3693 static void
3694 push_sleb128 (varray_type *data_area, int value)
3695 {
3696   unsigned char byte;
3697   int more;
3698
3699   do
3700     {
3701       byte = value & 0x7f;
3702       value >>= 7;
3703       more = ! ((value == 0 && (byte & 0x40) == 0)
3704                 || (value == -1 && (byte & 0x40) != 0));
3705       if (more)
3706         byte |= 0x80;
3707       VARRAY_PUSH_UCHAR (*data_area, byte);
3708     }
3709   while (more);
3710 }
3711
3712 \f
3713 #ifndef HAVE_AS_LEB128
3714 static int
3715 dw2_size_of_call_site_table (void)
3716 {
3717   int n = VEC_length (call_site_record, crtl->eh.call_site_record);
3718   int size = n * (4 + 4 + 4);
3719   int i;
3720
3721   for (i = 0; i < n; ++i)
3722     {
3723       struct call_site_record *cs = VEC_index (call_site_record, crtl->eh.call_site_record, i);
3724       size += size_of_uleb128 (cs->action);
3725     }
3726
3727   return size;
3728 }
3729
3730 static int
3731 sjlj_size_of_call_site_table (void)
3732 {
3733   int n = VEC_length (call_site_record, crtl->eh.call_site_record);
3734   int size = 0;
3735   int i;
3736
3737   for (i = 0; i < n; ++i)
3738     {
3739       struct call_site_record *cs = VEC_index (call_site_record, crtl->eh.call_site_record, i);
3740       size += size_of_uleb128 (INTVAL (cs->landing_pad));
3741       size += size_of_uleb128 (cs->action);
3742     }
3743
3744   return size;
3745 }
3746 #endif
3747
3748 static void
3749 dw2_output_call_site_table (void)
3750 {
3751   int n = VEC_length (call_site_record, crtl->eh.call_site_record);
3752   int i;
3753
3754   for (i = 0; i < n; ++i)
3755     {
3756       struct call_site_record *cs = VEC_index (call_site_record, crtl->eh.call_site_record, i);
3757       char reg_start_lab[32];
3758       char reg_end_lab[32];
3759       char landing_pad_lab[32];
3760
3761       ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i);
3762       ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i);
3763
3764       if (cs->landing_pad)
3765         ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L",
3766                                      CODE_LABEL_NUMBER (cs->landing_pad));
3767
3768       /* ??? Perhaps use insn length scaling if the assembler supports
3769          generic arithmetic.  */
3770       /* ??? Perhaps use attr_length to choose data1 or data2 instead of
3771          data4 if the function is small enough.  */
3772 #ifdef HAVE_AS_LEB128
3773       dw2_asm_output_delta_uleb128 (reg_start_lab,
3774                                     current_function_func_begin_label,
3775                                     "region %d start", i);
3776       dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
3777                                     "length");
3778       if (cs->landing_pad)
3779         dw2_asm_output_delta_uleb128 (landing_pad_lab,
3780                                       current_function_func_begin_label,
3781                                       "landing pad");
3782       else
3783         dw2_asm_output_data_uleb128 (0, "landing pad");
3784 #else
3785       dw2_asm_output_delta (4, reg_start_lab,
3786                             current_function_func_begin_label,
3787                             "region %d start", i);
3788       dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
3789       if (cs->landing_pad)
3790         dw2_asm_output_delta (4, landing_pad_lab,
3791                               current_function_func_begin_label,
3792                               "landing pad");
3793       else
3794         dw2_asm_output_data (4, 0, "landing pad");
3795 #endif
3796       dw2_asm_output_data_uleb128 (cs->action, "action");
3797     }
3798
3799   call_site_base += n;
3800 }
3801
3802 static void
3803 sjlj_output_call_site_table (void)
3804 {
3805   int n = VEC_length (call_site_record, crtl->eh.call_site_record);
3806   int i;
3807
3808   for (i = 0; i < n; ++i)
3809     {
3810       struct call_site_record *cs = VEC_index (call_site_record, crtl->eh.call_site_record, i);
3811
3812       dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
3813                                    "region %d landing pad", i);
3814       dw2_asm_output_data_uleb128 (cs->action, "action");
3815     }
3816
3817   call_site_base += n;
3818 }
3819
3820 #ifndef TARGET_UNWIND_INFO
3821 /* Switch to the section that should be used for exception tables.  */
3822
3823 static void
3824 switch_to_exception_section (const char * ARG_UNUSED (fnname))
3825 {
3826   section *s;
3827
3828   if (exception_section)
3829     s = exception_section;
3830   else
3831     {
3832       /* Compute the section and cache it into exception_section,
3833          unless it depends on the function name.  */
3834       if (targetm.have_named_sections)
3835         {
3836           int flags;
3837
3838           if (EH_TABLES_CAN_BE_READ_ONLY)
3839             {
3840               int tt_format =
3841                 ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3842               flags = ((! flag_pic
3843                         || ((tt_format & 0x70) != DW_EH_PE_absptr
3844                             && (tt_format & 0x70) != DW_EH_PE_aligned))
3845                        ? 0 : SECTION_WRITE);
3846             }
3847           else
3848             flags = SECTION_WRITE;
3849
3850 #ifdef HAVE_LD_EH_GC_SECTIONS
3851           if (flag_function_sections)
3852             {
3853               char *section_name = XNEWVEC (char, strlen (fnname) + 32);
3854               sprintf (section_name, ".gcc_except_table.%s", fnname);
3855               s = get_section (section_name, flags, NULL);
3856               free (section_name);
3857             }
3858           else
3859 #endif
3860             exception_section
3861               = s = get_section (".gcc_except_table", flags, NULL);
3862         }
3863       else
3864         exception_section
3865           = s = flag_pic ? data_section : readonly_data_section;
3866     }
3867
3868   switch_to_section (s);
3869 }
3870 #endif
3871
3872
3873 /* Output a reference from an exception table to the type_info object TYPE.
3874    TT_FORMAT and TT_FORMAT_SIZE describe the DWARF encoding method used for
3875    the value.  */
3876
3877 static void
3878 output_ttype (tree type, int tt_format, int tt_format_size)
3879 {
3880   rtx value;
3881   bool is_public = true;
3882
3883   if (type == NULL_TREE)
3884     value = const0_rtx;
3885   else
3886     {
3887       struct varpool_node *node;
3888
3889       type = lookup_type_for_runtime (type);
3890       value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
3891
3892       /* Let cgraph know that the rtti decl is used.  Not all of the
3893          paths below go through assemble_integer, which would take
3894          care of this for us.  */
3895       STRIP_NOPS (type);
3896       if (TREE_CODE (type) == ADDR_EXPR)
3897         {
3898           type = TREE_OPERAND (type, 0);
3899           if (TREE_CODE (type) == VAR_DECL)
3900             {
3901               node = varpool_node (type);
3902               if (node)
3903                 varpool_mark_needed_node (node);
3904               is_public = TREE_PUBLIC (type);
3905             }
3906         }
3907       else
3908         gcc_assert (TREE_CODE (type) == INTEGER_CST);
3909     }
3910
3911   /* Allow the target to override the type table entry format.  */
3912   if (targetm.asm_out.ttype (value))
3913     return;
3914
3915   if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
3916     assemble_integer (value, tt_format_size,
3917                       tt_format_size * BITS_PER_UNIT, 1);
3918   else
3919     dw2_asm_output_encoded_addr_rtx (tt_format, value, is_public, NULL);
3920 }
3921
3922 void
3923 output_function_exception_table (const char * ARG_UNUSED (fnname))
3924 {
3925   int tt_format, cs_format, lp_format, i, n;
3926 #ifdef HAVE_AS_LEB128
3927   char ttype_label[32];
3928   char cs_after_size_label[32];
3929   char cs_end_label[32];
3930 #else
3931   int call_site_len;
3932 #endif
3933   int have_tt_data;
3934   int tt_format_size = 0;
3935
3936   /* Not all functions need anything.  */
3937   if (! crtl->uses_eh_lsda)
3938     return;
3939
3940   if (eh_personality_libfunc)
3941     assemble_external_libcall (eh_personality_libfunc);
3942
3943 #ifdef TARGET_UNWIND_INFO
3944   /* TODO: Move this into target file.  */
3945   fputs ("\t.personality\t", asm_out_file);
3946   output_addr_const (asm_out_file, eh_personality_libfunc);
3947   fputs ("\n\t.handlerdata\n", asm_out_file);
3948   /* Note that varasm still thinks we're in the function's code section.
3949      The ".endp" directive that will immediately follow will take us back.  */
3950 #else
3951   switch_to_exception_section (fnname);
3952 #endif
3953
3954   /* If the target wants a label to begin the table, emit it here.  */
3955   targetm.asm_out.except_table_label (asm_out_file);
3956
3957   have_tt_data = (VEC_length (tree, crtl->eh.ttype_data) > 0
3958                   || VARRAY_ACTIVE_SIZE (crtl->eh.ehspec_data) > 0);
3959
3960   /* Indicate the format of the @TType entries.  */
3961   if (! have_tt_data)
3962     tt_format = DW_EH_PE_omit;
3963   else
3964     {
3965       tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3966 #ifdef HAVE_AS_LEB128
3967       ASM_GENERATE_INTERNAL_LABEL (ttype_label, "LLSDATT",
3968                                    current_function_funcdef_no);
3969 #endif
3970       tt_format_size = size_of_encoded_value (tt_format);
3971
3972       assemble_align (tt_format_size * BITS_PER_UNIT);
3973     }
3974
3975   targetm.asm_out.internal_label (asm_out_file, "LLSDA",
3976                              current_function_funcdef_no);
3977
3978   /* The LSDA header.  */
3979
3980   /* Indicate the format of the landing pad start pointer.  An omitted
3981      field implies @LPStart == @Start.  */
3982   /* Currently we always put @LPStart == @Start.  This field would
3983      be most useful in moving the landing pads completely out of
3984      line to another section, but it could also be used to minimize
3985      the size of uleb128 landing pad offsets.  */
3986   lp_format = DW_EH_PE_omit;
3987   dw2_asm_output_data (1, lp_format, "@LPStart format (%s)",
3988                        eh_data_format_name (lp_format));
3989
3990   /* @LPStart pointer would go here.  */
3991
3992   dw2_asm_output_data (1, tt_format, "@TType format (%s)",
3993                        eh_data_format_name (tt_format));
3994
3995 #ifndef HAVE_AS_LEB128
3996   if (USING_SJLJ_EXCEPTIONS)
3997     call_site_len = sjlj_size_of_call_site_table ();
3998   else
3999     call_site_len = dw2_size_of_call_site_table ();
4000 #endif
4001
4002   /* A pc-relative 4-byte displacement to the @TType data.  */
4003   if (have_tt_data)
4004     {
4005 #ifdef HAVE_AS_LEB128
4006       char ttype_after_disp_label[32];
4007       ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label, "LLSDATTD",
4008                                    current_function_funcdef_no);
4009       dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label,
4010                                     "@TType base offset");
4011       ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
4012 #else
4013       /* Ug.  Alignment queers things.  */
4014       unsigned int before_disp, after_disp, last_disp, disp;
4015
4016       before_disp = 1 + 1;
4017       after_disp = (1 + size_of_uleb128 (call_site_len)
4018                     + call_site_len
4019                     + VARRAY_ACTIVE_SIZE (crtl->eh.action_record_data)
4020                     + (VEC_length (tree, crtl->eh.ttype_data)
4021                        * tt_format_size));
4022
4023       disp = after_disp;
4024       do
4025         {
4026           unsigned int disp_size, pad;
4027
4028           last_disp = disp;
4029           disp_size = size_of_uleb128 (disp);
4030           pad = before_disp + disp_size + after_disp;
4031           if (pad % tt_format_size)
4032             pad = tt_format_size - (pad % tt_format_size);
4033           else
4034             pad = 0;
4035           disp = after_disp + pad;
4036         }
4037       while (disp != last_disp);
4038
4039       dw2_asm_output_data_uleb128 (disp, "@TType base offset");
4040 #endif
4041     }
4042
4043   /* Indicate the format of the call-site offsets.  */
4044 #ifdef HAVE_AS_LEB128
4045   cs_format = DW_EH_PE_uleb128;
4046 #else
4047   cs_format = DW_EH_PE_udata4;
4048 #endif
4049   dw2_asm_output_data (1, cs_format, "call-site format (%s)",
4050                        eh_data_format_name (cs_format));
4051
4052 #ifdef HAVE_AS_LEB128
4053   ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label, "LLSDACSB",
4054                                current_function_funcdef_no);
4055   ASM_GENERATE_INTERNAL_LABEL (cs_end_label, "LLSDACSE",
4056                                current_function_funcdef_no);
4057   dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label,
4058                                 "Call-site table length");
4059   ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label);
4060   if (USING_SJLJ_EXCEPTIONS)
4061     sjlj_output_call_site_table ();
4062   else
4063     dw2_output_call_site_table ();
4064   ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
4065 #else
4066   dw2_asm_output_data_uleb128 (call_site_len,"Call-site table length");
4067   if (USING_SJLJ_EXCEPTIONS)
4068     sjlj_output_call_site_table ();
4069   else
4070     dw2_output_call_site_table ();
4071 #endif
4072
4073   /* ??? Decode and interpret the data for flag_debug_asm.  */
4074   n = VARRAY_ACTIVE_SIZE (crtl->eh.action_record_data);
4075   for (i = 0; i < n; ++i)
4076     dw2_asm_output_data (1, VARRAY_UCHAR (crtl->eh.action_record_data, i),
4077                          (i ? NULL : "Action record table"));
4078
4079   if (have_tt_data)
4080     assemble_align (tt_format_size * BITS_PER_UNIT);
4081
4082   i = VEC_length (tree, crtl->eh.ttype_data);
4083   while (i-- > 0)
4084     {
4085       tree type = VEC_index (tree, crtl->eh.ttype_data, i);
4086       output_ttype (type, tt_format, tt_format_size);
4087     }
4088
4089 #ifdef HAVE_AS_LEB128
4090   if (have_tt_data)
4091       ASM_OUTPUT_LABEL (asm_out_file, ttype_label);
4092 #endif
4093
4094   /* ??? Decode and interpret the data for flag_debug_asm.  */
4095   n = VARRAY_ACTIVE_SIZE (crtl->eh.ehspec_data);
4096   for (i = 0; i < n; ++i)
4097     {
4098       if (targetm.arm_eabi_unwinder)
4099         {
4100           tree type = VARRAY_TREE (crtl->eh.ehspec_data, i);
4101           output_ttype (type, tt_format, tt_format_size);
4102         }
4103       else
4104         dw2_asm_output_data (1, VARRAY_UCHAR (crtl->eh.ehspec_data, i),
4105                              (i ? NULL : "Exception specification table"));
4106     }
4107
4108   switch_to_section (current_function_section ());
4109 }
4110
4111 void
4112 set_eh_throw_stmt_table (struct function *fun, struct htab *table)
4113 {
4114   fun->eh->throw_stmt_table = table;
4115 }
4116
4117 htab_t
4118 get_eh_throw_stmt_table (struct function *fun)
4119 {
4120   return fun->eh->throw_stmt_table;
4121 }
4122
4123 /* Dump EH information to OUT.  */
4124
4125 void
4126 dump_eh_tree (FILE * out, struct function *fun)
4127 {
4128   struct eh_region *i;
4129   int depth = 0;
4130   static const char *const type_name[] = { "unknown", "cleanup", "try", "catch",
4131                                            "allowed_exceptions", "must_not_throw",
4132                                            "throw"
4133                                          };
4134
4135   i = fun->eh->region_tree;
4136   if (!i)
4137     return;
4138
4139   fprintf (out, "Eh tree:\n");
4140   while (1)
4141     {
4142       fprintf (out, "  %*s %i %s", depth * 2, "",
4143                i->region_number, type_name[(int) i->type]);
4144       if (i->tree_label)
4145         {
4146           fprintf (out, " tree_label:");
4147           print_generic_expr (out, i->tree_label, 0);
4148         }
4149       switch (i->type)
4150         {
4151         case ERT_CLEANUP:
4152           if (i->u.cleanup.prev_try)
4153             fprintf (out, " prev try:%i",
4154                      i->u.cleanup.prev_try->region_number);
4155           break;
4156
4157         case ERT_TRY:
4158           {
4159             struct eh_region *c;
4160             fprintf (out, " catch regions:");
4161             for (c = i->u.eh_try.eh_catch; c; c = c->u.eh_catch.next_catch)
4162               fprintf (out, " %i", c->region_number);
4163           }
4164           break;
4165
4166         case ERT_CATCH:
4167           if (i->u.eh_catch.prev_catch)
4168             fprintf (out, " prev: %i",
4169                      i->u.eh_catch.prev_catch->region_number);
4170           if (i->u.eh_catch.next_catch)
4171             fprintf (out, " next %i",
4172                      i->u.eh_catch.next_catch->region_number);
4173           break;
4174
4175         case ERT_ALLOWED_EXCEPTIONS:
4176           fprintf (out, "filter :%i types:", i->u.allowed.filter);
4177           print_generic_expr (out, i->u.allowed.type_list, 0);
4178           break;
4179
4180         case ERT_THROW:
4181           fprintf (out, "type:");
4182           print_generic_expr (out, i->u.eh_throw.type, 0);
4183           break;
4184
4185         case ERT_MUST_NOT_THROW:
4186           break;
4187
4188         case ERT_UNKNOWN:
4189           break;
4190         }
4191       if (i->aka)
4192         {
4193           fprintf (out, " also known as:");
4194           dump_bitmap (out, i->aka);
4195         }
4196       else
4197         fprintf (out, "\n");
4198       /* If there are sub-regions, process them.  */
4199       if (i->inner)
4200         i = i->inner, depth++;
4201       /* If there are peers, process them.  */
4202       else if (i->next_peer)
4203         i = i->next_peer;
4204       /* Otherwise, step back up the tree to the next peer.  */
4205       else
4206         {
4207           do
4208             {
4209               i = i->outer;
4210               depth--;
4211               if (i == NULL)
4212                 return;
4213             }
4214           while (i->next_peer == NULL);
4215           i = i->next_peer;
4216         }
4217     }
4218 }
4219
4220 /* Verify some basic invariants on EH datastructures.  Could be extended to
4221    catch more.  */
4222 void
4223 verify_eh_tree (struct function *fun)
4224 {
4225   struct eh_region *i, *outer = NULL;
4226   bool err = false;
4227   int nvisited = 0;
4228   int count = 0;
4229   int j;
4230   int depth = 0;
4231
4232   if (!fun->eh->region_tree)
4233     return;
4234   for (j = fun->eh->last_region_number; j > 0; --j)
4235     if ((i = VEC_index (eh_region, fun->eh->region_array, j)))
4236       {
4237         if (i->region_number == j)
4238           count++;
4239         if (i->region_number != j && (!i->aka || !bitmap_bit_p (i->aka, j)))
4240           {
4241             error ("region_array is corrupted for region %i",
4242                    i->region_number);
4243             err = true;
4244           }
4245       }
4246   i = fun->eh->region_tree;
4247
4248   while (1)
4249     {
4250       if (VEC_index (eh_region, fun->eh->region_array, i->region_number) != i)
4251         {
4252           error ("region_array is corrupted for region %i", i->region_number);
4253           err = true;
4254         }
4255       if (i->outer != outer)
4256         {
4257           error ("outer block of region %i is wrong", i->region_number);
4258           err = true;
4259         }
4260       if (i->may_contain_throw && outer && !outer->may_contain_throw)
4261         {
4262           error
4263             ("region %i may contain throw and is contained in region that may not",
4264              i->region_number);
4265           err = true;
4266         }
4267       if (depth < 0)
4268         {
4269           error ("negative nesting depth of region %i", i->region_number);
4270           err = true;
4271         }
4272       nvisited++;
4273       /* If there are sub-regions, process them.  */
4274       if (i->inner)
4275         outer = i, i = i->inner, depth++;
4276       /* If there are peers, process them.  */
4277       else if (i->next_peer)
4278         i = i->next_peer;
4279       /* Otherwise, step back up the tree to the next peer.  */
4280       else
4281         {
4282           do
4283             {
4284               i = i->outer;
4285               depth--;
4286               if (i == NULL)
4287                 {
4288                   if (depth != -1)
4289                     {
4290                       error ("tree list ends on depth %i", depth + 1);
4291                       err = true;
4292                     }
4293                   if (count != nvisited)
4294                     {
4295                       error ("array does not match the region tree");
4296                       err = true;
4297                     }
4298                   if (err)
4299                     {
4300                       dump_eh_tree (stderr, fun);
4301                       internal_error ("verify_eh_tree failed");
4302                     }
4303                   return;
4304                 }
4305               outer = i->outer;
4306             }
4307           while (i->next_peer == NULL);
4308           i = i->next_peer;
4309         }
4310     }
4311 }
4312
4313 /* Initialize unwind_resume_libfunc.  */
4314
4315 void
4316 default_init_unwind_resume_libfunc (void)
4317 {
4318   /* The default c++ routines aren't actually c++ specific, so use those.  */
4319   unwind_resume_libfunc =
4320     init_one_libfunc ( USING_SJLJ_EXCEPTIONS ? "_Unwind_SjLj_Resume"
4321                                              : "_Unwind_Resume");
4322 }
4323
4324 \f
4325 static bool
4326 gate_handle_eh (void)
4327 {
4328   return doing_eh (0);
4329 }
4330
4331 /* Complete generation of exception handling code.  */
4332 static unsigned int
4333 rest_of_handle_eh (void)
4334 {
4335   cleanup_cfg (CLEANUP_NO_INSN_DEL);
4336   finish_eh_generation ();
4337   cleanup_cfg (CLEANUP_NO_INSN_DEL);
4338   return 0;
4339 }
4340
4341 struct rtl_opt_pass pass_rtl_eh =
4342 {
4343  {
4344   RTL_PASS,
4345   "eh",                                 /* name */
4346   gate_handle_eh,                       /* gate */
4347   rest_of_handle_eh,                    /* execute */
4348   NULL,                                 /* sub */
4349   NULL,                                 /* next */
4350   0,                                    /* static_pass_number */
4351   TV_JUMP,                              /* tv_id */
4352   0,                                    /* properties_required */
4353   0,                                    /* properties_provided */
4354   0,                                    /* properties_destroyed */
4355   0,                                    /* todo_flags_start */
4356   TODO_dump_func                        /* todo_flags_finish */
4357  }
4358 };
4359
4360 #include "gt-except.h"