OSDN Git Service

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