OSDN Git Service

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