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